Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial port to redux #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dev-api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const cors = require('@koa/cors')
const app = new Koa()
const router = new Router()

router.get('/generate/eth/:type/:provider/:pair', ctx => {
router.get('/generate/:name/:type/:provider/:pair', ctx => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

ctx.body = JSON.stringify({
contract: "#include <eosiolib/eosio.hpp>\n#include <eosiolib/singleton.hpp>\n#include \"oraclized.hpp\"\n\nusing namespace eosio;\n\nstruct price\n{\n uint64_t value;\n uint8_t decimals;\n \n\n EOSLIB_SERIALIZE(price, (value)(decimals))\n};\n\n\ntypedef oraclized<N(ethbtc), 2000, 15, price> ethbtc_data;\ntypedef singleton<N(master), account_name> oraclize_master;\n\nclass YOUR_CONTRACT_NAME : public eosio::contract\n{\nprivate:\n\n ethbtc_data ethbtc;\n\n account_name master;\n\npublic:\n using contract::contract;\n\n YOUR_CONTRACT_NAME(account_name s) : contract(s), ethbtc(_self, _self)\n {\n master = oraclize_master(_self, _self).get_or_create(_self, N(undefined));\n }\n\n void setup(account_name administrator, account_name master, account_name registry)\n {\n require_auth(_self);\n oraclize_master(_self, _self).set(master, _self);\n ask_data(administrator, registry, \"0x363e7fe8b47534460fd06dafd5e18a542fe1aaa78038d7ca5e84694f99a788e5\");\n \n }\n\n void ask_data(account_name administrator, account_name registry, std::string data)\n {\n action(permission_level{_self, N(active)},\n registry, N(ask),\n std::make_tuple(_self, data))\n .send();\n }\n \n void pushuint(account_name oracle, std::string data_id, uint64_t data) \n {\n require_auth(oracle);\n \n }\n \n void pushstr(account_name oracle, std::string data_id, std::string data) \n {\n require_auth(oracle);\n \n }\n \n void pushprice(account_name oracle, std::string data_id, price data) \n {\n require_auth(oracle);\n \n if (strcmp(data_id.c_str(), \"0x363e7fe8b47534460fd06dafd5e18a542fe1aaa78038d7ca5e84694f99a788e5\") == 0) \n {\n ethbtc.set(data, oracle);\n }\n }\n};\n\nEOSIO_ABI(YOUR_CONTRACT_NAME, (setup)(pushuint)(pushstr)(pushprice))",
instructions: 'eos_contract_instructions'
Expand Down
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
"@types/html-webpack-plugin": "^2.30.4",
"@types/node": "^10.5.2",
"@types/react-dom": "^16.0.6",
"@types/react-redux": "^6.0.5",
"@types/react-router-dom": "^4.2.7",
"@types/redux": "^3.6.0",
"@types/redux-saga": "^0.10.5",
"@types/webpack": "^4.4.7",
"@types/webpack-env": "^1.13.6",
"clean-webpack-plugin": "^0.1.19",
Expand All @@ -21,15 +24,19 @@
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-emotion": "^9.2.6",
"react-redux": "^5.0.7",
"react-router-dom": "^4.3.1",
"redux": "^4.0.0",
"redux-act": "^1.7.4",
"redux-saga": "^0.16.0",
"svg-url-loader": "^2.3.2",
"ts-loader": "^4.4.2",
"ts-node": "^7.0.0",
"tsconfig-paths": "^3.4.2",
"typescript": "^2.9.2",
"webpack": "^4.16.1",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.4",
"ts-node": "^7.0.0"
"webpack-dev-server": "^3.1.4"
},
"scripts": {
"start": "webpack-dev-server --config=webpack.dev.config.js",
Expand Down
14 changes: 14 additions & 0 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createAction } from 'redux-act'

import { Category, Contract, Instructions } from 'reducers'

export interface FormToSend {
provider: string
pair: string
updateAfter: string
retireAfter: string
}

export const setConfig = createAction('set fetched config', (res: Category[]) => res)
export const setResults = createAction('set contract results', (res: { contract: Contract, instructions: Instructions }) => res)
export const sendForm = createAction('send form with params', (res: FormToSend) => res)
30 changes: 25 additions & 5 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
import { BrowserRouter } from 'react-router-dom'
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux'
import createSagaMiddleware from 'redux-saga'
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'

import reducer from 'reducers'
import rootSaga from 'sagas'

declare global {
interface Window {
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__: typeof compose
}
}

const MOUNT_NODE = document.getElementById('app')

const render = (App: JSX.Element) => {
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const sagaMiddleware = createSagaMiddleware()
const store = createStore(reducer, composeEnhancers(applyMiddleware(sagaMiddleware)))

sagaMiddleware.run(rootSaga as any)

const render = (App: any) => {
ReactDOM.render((
<BrowserRouter>
<App/>
</BrowserRouter>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
), MOUNT_NODE)
}

Expand Down
Empty file added src/components/Flex/index.ts
Empty file.
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const API_URL = "http://localhost:3091"
export const API_URL = "http://localhost:8081"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3091 is the new default port for both dev-api and production api

Copy link
Collaborator Author

@MaxSvargal MaxSvargal Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be move to a config file

18 changes: 7 additions & 11 deletions src/containers/Construct/ConstructForm.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import React, { PureComponent } from 'react'
import styled from 'react-emotion'

import ListItem from './ListItem'
import { Category } from './index'
import InputNumber from 'components/Input/Number'
import { Category } from 'reducers'
import { FormToSend } from 'actions'

export interface State {
provider: string
pair: string
updateAfter: string
retireAfter: string
}
import InputNumber from 'components/Input/Number'
import ListItem from './ListItem'

export interface Props {
data?: Category[]
onSubmit: (form: State) => void
onSubmit: (form: FormToSend) => void
}

export default class ConstructForm extends PureComponent<Props, State> {
export default class ConstructForm extends PureComponent<Props, FormToSend> {
state = {
provider: '',
pair: '',
Expand All @@ -35,6 +30,7 @@ export default class ConstructForm extends PureComponent<Props, State> {
this.props.onSubmit(this.state)

render() {
console.log(this.props)
const { data } = this.props
if (!data) return <div />

Expand Down
64 changes: 13 additions & 51 deletions src/containers/Construct/index.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,36 @@
import React, { PureComponent } from 'react'

import { API_URL } from 'config'

import ConstructForm, { State as Form } from './ConstructForm'
import { connect } from 'react-redux'
import { withRouter } from 'react-router'
import { History } from 'history'

import Page from 'components/Page'
import ConstructForm from './ConstructForm'
import { StoreState } from 'reducers'
import { sendForm, FormToSend } from 'actions'

interface Props {
history: History
config: StoreState['config']
sendForm: (a: FormToSend) => void
}

export interface Category {
name: string
types?: string[] // not needed
providers?: {
id: string
name: string
types: string[]
}[]
}

interface StateNew {
categories: {
name: string,
meta?: {
providers: {
id: string
name: string
types: string[]
}[]
}
}[]
}

interface State {
categories?: Category[]
}

// TEMP
declare global {
interface Window { store: any; }
}

class ConstructPage extends PureComponent<Props, State> {
state = {
categories: null
} as State

onFormSubmit = (form: Form) => {
window.store = { form }
class ConstructPage extends PureComponent<Props> {
onFormSubmit = (form: FormToSend) => {
this.props.sendForm(form)
this.props.history.push('contractCode')
}

async componentWillMount() {
const res = await fetch(`${API_URL}/config`)
const json = await res.json() as { categories: Category[] }
this.setState(json)
}

render() {
return (
<Page title='Choose data to receive'>
<ConstructForm
data={this.state.categories}
data={this.props.config}
onSubmit={this.onFormSubmit} />
</Page>
)
}
}

export default withRouter(ConstructPage as any)
const mapStateToProps = ({ config }: StoreState) => ({ config })
const mapDispatchToProps = { sendForm }
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(ConstructPage as any))
25 changes: 25 additions & 0 deletions src/containers/Construct/saga.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { take, call, put, fork } from 'redux-saga/effects'

import { setConfig, sendForm, setResults } from 'actions'
import { API_URL } from 'config'

function* requestConfig() {
const res = yield call(fetch, `${API_URL}/config`)
const { categories } = yield res.json()
yield put(setConfig(categories))
}

function* requestResults() {
while (true) {
const { payload } = yield take(sendForm)
const { provider, pair, updateAfter, retireAfter } = payload
const res = yield call(fetch, `${API_URL}/generate/eos/crypto/${provider}/${pair}?updatefreq=${updateAfter}&lifetime=${retireAfter}`)
const result = yield res.json()
yield put(setResults(result))
}
}

export default function* constructSaga() {
yield fork(requestConfig)
yield fork(requestResults)
}
9 changes: 1 addition & 8 deletions src/containers/ContractCode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { PureComponent, DetailedHTMLProps } from 'react'
import React, { PureComponent } from 'react'
import styled from 'react-emotion'

import Page from 'components/Page'
Expand All @@ -17,13 +17,6 @@ export default class ContractCodePage extends PureComponent<Props, State> {
instructions: ''
} as State

async componentWillMount() {
const { form: { provider, pair, updateAfter, retireAfter } } = window.store
const res = await fetch(`${API_URL}/generate/eos/crypto/${provider}/${pair}?updatefreq=${updateAfter}&lifetime=${retireAfter}`)
const json = await res.json() as State
this.setState(json)
}

render() {
return (
<Page title='Contract Code'>
Expand Down
37 changes: 37 additions & 0 deletions src/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { createReducer } from 'redux-act'
import { combineReducers } from 'redux'

import { setConfig, setResults } from 'actions'

export type Contract = string
export type Instructions = string

export interface Category {
name: string
types?: string[] // not needed
providers?: {
id: string
name: string
types: string[]
}[]
}

export interface StoreState {
config: Category[],
contract: Contract,
instructions: Instructions
}

export const config = createReducer({
[setConfig.toString()]: (_, payload: Category[]) => payload
}, [])

export const contract = createReducer({
[setResults.toString()]: (_, { contract }) => contract
}, '')

export const instructions = createReducer({
[setResults.toString()]: (_, { instructions }) => instructions
}, '')

export default combineReducers({ config, contract, instructions })
31 changes: 31 additions & 0 deletions src/sagas/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { all, take, call, put, fork } from 'redux-saga/effects'

import { setConfig, sendForm, setResults } from 'actions'
import { API_URL } from 'config'

function* requestConfig() {
const res = yield call(fetch, `${API_URL}/config`)
const { categories } = yield res.json()
yield put(setConfig(categories))
}

function* requestResults() {
while (true) {
try {
const { payload } = yield take(sendForm)
const { provider, pair, updateAfter, retireAfter } = payload
const res = yield call(fetch, `${API_URL}/generate/eos/crypto/${provider}/${pair}?updatefreq=${updateAfter}&lifetime=${retireAfter}`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameters can contain special chars, we should encodeURIComponent() every parameter.

const result = yield res.json()
yield put(setResults(result))
} catch (err) {
console.log(err)
}
}
}

export default function* constructSaga() {
yield all([
fork(requestConfig),
fork(requestResults)
])
}
Loading