diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js index 6b72dd3db..59e6fc48d 100644 --- a/embark-ui/src/actions/index.js +++ b/embark-ui/src/actions/index.js @@ -28,6 +28,34 @@ export const account = { failure: (error) => action(ACCOUNT[FAILURE], {error}) }; +export const BLOCKS = createRequestTypes('BLOCKS'); +export const blocks = { + request: (from) => action(BLOCKS[REQUEST], {from}), + success: (blocks) => action(BLOCKS[SUCCESS], {blocks}), + failure: (error) => action(BLOCKS[FAILURE], {error}) +}; + +export const BLOCK = createRequestTypes('BLOCK'); +export const block = { + request: (blockNumber) => action(BLOCK[REQUEST], {blockNumber}), + success: (block) => action(BLOCK[SUCCESS], {block}), + failure: (error) => action(BLOCK[FAILURE], {error}) +}; + +export const TRANSACTIONS = createRequestTypes('TRANSACTIONS'); +export const transactions = { + request: (blockFrom) => action(TRANSACTIONS[REQUEST], {blockFrom}), + success: (transactions) => action(TRANSACTIONS[SUCCESS], {transactions}), + failure: (error) => action(TRANSACTIONS[FAILURE], {error}) +}; + +export const TRANSACTION = createRequestTypes('TRANSACTION'); +export const transaction = { + request: (hash) => action(TRANSACTION[REQUEST], {hash}), + success: (transaction) => action(TRANSACTION[SUCCESS], {transaction}), + failure: (error) => action(TRANSACTION[FAILURE], {error}) +}; + // Processes export const FETCH_PROCESSES = 'FETCH_PROCESSES'; export const RECEIVE_PROCESSES = 'RECEIVE_PROCESSES'; @@ -38,20 +66,6 @@ export const RECEIVE_PROCESS_LOGS = 'RECEIVE_PROCESS_LOGS'; export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS'; export const RECEIVE_NEW_PROCESS_LOG = 'RECEIVE_NEW_PROCESS_LOG'; export const RECEIVE_PROCESS_LOGS_ERROR = 'RECEIVE_PROCESS_LOGS_ERROR'; -// Blocks -export const FETCH_BLOCKS = 'FETCH_BLOCKS'; -export const RECEIVE_BLOCKS = 'RECEIVE_BLOCKS'; -export const RECEIVE_BLOCKS_ERROR = 'RECEIVE_BLOCKS_ERROR'; -export const FETCH_BLOCK = 'FETCH_BLOCK'; -export const RECEIVE_BLOCK = 'RECEIVE_BLOCK'; -export const RECEIVE_BLOCK_ERROR = 'RECEIVE_BLOCK_ERROR'; -// Transactions -export const FETCH_TRANSACTIONS = 'FETCH_TRANSACTIONS'; -export const RECEIVE_TRANSACTIONS = 'RECEIVE_TRANSACTIONS'; -export const RECEIVE_TRANSACTIONS_ERROR = 'RECEIVE_TRANSACTIONS_ERROR'; -export const FETCH_TRANSACTION = 'FETCH_TRANSACTION'; -export const RECEIVE_TRANSACTION = 'RECEIVE_TRANSACTION'; -export const RECEIVE_TRANSACTION_ERROR = 'RECEIVE_TRANSACTION_ERROR'; // BlockHeader export const INIT_BLOCK_HEADER = 'INIT_BLOCK_HEADER'; @@ -104,86 +118,6 @@ export function receiveProcessLogsError(error) { }; } -export function fetchBlocks(from) { - return { - type: FETCH_BLOCKS, - from - }; -} - -export function receiveBlocks(blocks) { - return { - type: RECEIVE_BLOCKS, - blocks - }; -} - -export function receiveBlocksError() { - return { - type: RECEIVE_BLOCKS_ERROR - }; -} - -export function fetchBlock(blockNumber) { - return { - type: FETCH_BLOCK, - blockNumber - }; -} - -export function receiveBlock(block) { - return { - type: RECEIVE_BLOCK, - block - }; -} - -export function receiveBlockError() { - return { - type: RECEIVE_BLOCK_ERROR - }; -} - -export function fetchTransactions(blockFrom) { - return { - type: FETCH_TRANSACTIONS, - blockFrom - }; -} - -export function receiveTransactions(transactions) { - return { - type: RECEIVE_TRANSACTIONS, - transactions - }; -} - -export function receiveTransactionsError() { - return { - type: RECEIVE_TRANSACTIONS_ERROR - }; -} - -export function fetchTransaction(hash) { - return { - type: FETCH_TRANSACTION, - hash - }; -} - -export function receiveTransaction(transaction) { - return { - type: RECEIVE_TRANSACTION, - transaction - }; -} - -export function receiveTransactionError() { - return { - type: RECEIVE_TRANSACTION_ERROR - }; -} - export function initBlockHeader(){ return { type: INIT_BLOCK_HEADER diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js index 322063248..c1cdfaf19 100644 --- a/embark-ui/src/api/index.js +++ b/embark-ui/src/api/index.js @@ -19,20 +19,20 @@ export function fetchAccount(payload) { return get(`/blockchain/accounts/${payload.address}`); } -export function fetchBlocks(from) { - return axios.get(`${constants.httpEndpoint}/blockchain/blocks`, {params: {from}}); +export function fetchBlocks(payload) { + return get('/blockchain/blocks', {params: payload}); } -export function fetchBlock(blockNumber) { - return axios.get(`${constants.httpEndpoint}/blockchain/blocks/${blockNumber}`); +export function fetchBlock(payload) { + return get(`/blockchain/blocks/${payload.blockNumber}`); } -export function fetchTransactions(blockFrom) { - return axios.get(`${constants.httpEndpoint}/blockchain/transactions`, {params: {blockFrom}}); +export function fetchTransactions(payload) { + return get('/blockchain/transactions', {params: payload}); } -export function fetchTransaction(hash) { - return axios.get(`${constants.httpEndpoint}/blockchain/transactions/${hash}`); +export function fetchTransaction(payload) { + return get(`/blockchain/transactions/${payload.hash}`); } export function fetchProcesses() { diff --git a/embark-ui/src/components/Error.js b/embark-ui/src/components/Error.js new file mode 100644 index 000000000..4875504ac --- /dev/null +++ b/embark-ui/src/components/Error.js @@ -0,0 +1,19 @@ +import PropTypes from "prop-types"; +import React from 'react'; +import {Grid} from 'tabler-react'; + +const Error = ({error}) => ( + + +

+ {error} +

+
+
+); + +Error.propTypes = { + error: PropTypes.string +}; + +export default Error; diff --git a/embark-ui/src/containers/AccountContainer.js b/embark-ui/src/containers/AccountContainer.js index 562380d2e..0b291195c 100644 --- a/embark-ui/src/containers/AccountContainer.js +++ b/embark-ui/src/containers/AccountContainer.js @@ -7,6 +7,7 @@ import {account as accountAction} from '../actions'; import Account from '../components/Account'; import NoMatch from "../components/NoMatch"; import Transactions from '../components/Transactions'; +import Error from '../components/Error'; class AccountContainer extends Component { componentDidMount() { @@ -14,7 +15,11 @@ class AccountContainer extends Component { } render() { - const {account} = this.props; + const {account, error} = this.props; + if (error) { + return ; + } + if (!account) { return ; } @@ -29,6 +34,9 @@ class AccountContainer extends Component { } function mapStateToProps(state, props) { + if(state.accounts.error) { + return {error: state.accounts.error}; + } if(state.accounts.data) { return {account: state.accounts.data.find(account => account.address === props.match.params.address)}; } @@ -38,7 +46,8 @@ function mapStateToProps(state, props) { AccountContainer.propTypes = { match: PropTypes.object, account: PropTypes.object, - fetchAccount: PropTypes.func + fetchAccount: PropTypes.func, + error: PropTypes.string }; export default withRouter(connect( diff --git a/embark-ui/src/containers/AccountsContainer.js b/embark-ui/src/containers/AccountsContainer.js index 3bfdb59a4..0aa9fe248 100644 --- a/embark-ui/src/containers/AccountsContainer.js +++ b/embark-ui/src/containers/AccountsContainer.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import {accounts as accountsAction} from '../actions'; import Accounts from '../components/Accounts'; import Loading from '../components/Loading'; +import Error from '../components/Error'; class AccountsContainer extends Component { componentDidMount() { @@ -13,16 +14,12 @@ class AccountsContainer extends Component { render() { const {accounts} = this.props; - if (!accounts.data) { - return ; + if (accounts.error) { + return ; } - if (accounts.error) { - return ( -

- Error API... -

- ); + if (!accounts.data) { + return ; } return ( diff --git a/embark-ui/src/containers/BlockContainer.js b/embark-ui/src/containers/BlockContainer.js index aef7e1d5c..9d8de292c 100644 --- a/embark-ui/src/containers/BlockContainer.js +++ b/embark-ui/src/containers/BlockContainer.js @@ -3,8 +3,9 @@ import {connect} from 'react-redux'; import PropTypes from 'prop-types'; import {withRouter} from 'react-router-dom'; -import {fetchBlock} from '../actions'; +import {block as blockAction} from '../actions'; import Block from '../components/Block'; +import Error from "../components/Error"; import NoMatch from "../components/NoMatch"; import Transactions from '../components/Transactions'; @@ -14,7 +15,10 @@ class BlockContainer extends Component { } render() { - const {block} = this.props; + const {block, error} = this.props; + if (error) { + return ; + } if (!block) { return ; } @@ -29,6 +33,9 @@ class BlockContainer extends Component { } function mapStateToProps(state, props) { + if(state.blocks.error) { + return {error: state.blocks.error}; + } if(state.blocks.data) { return {block: state.blocks.data.find(block => block.number.toString() === props.match.params.blockNumber)}; } @@ -38,12 +45,13 @@ function mapStateToProps(state, props) { BlockContainer.propTypes = { match: PropTypes.object, block: PropTypes.object, - fetchBlock: PropTypes.func + fetchBlock: PropTypes.func, + error: PropTypes.string }; export default withRouter(connect( mapStateToProps, { - fetchBlock + fetchBlock: blockAction.request } )(BlockContainer)); diff --git a/embark-ui/src/containers/BlocksContainer.js b/embark-ui/src/containers/BlocksContainer.js index 985990a8a..c2c4d2648 100644 --- a/embark-ui/src/containers/BlocksContainer.js +++ b/embark-ui/src/containers/BlocksContainer.js @@ -2,10 +2,11 @@ import React, {Component} from 'react'; import {connect} from 'react-redux'; import PropTypes from 'prop-types'; -import {fetchBlocks} from '../actions'; +import {blocks as blocksAction} from '../actions'; import Blocks from '../components/Blocks'; import Loading from '../components/Loading'; import LoadMore from '../components/LoadMore'; +import Error from '../components/Error'; class BlocksContainer extends Component { componentDidMount() { @@ -23,16 +24,12 @@ class BlocksContainer extends Component { render() { const {blocks} = this.props; - if (!blocks.data) { - return ; + if (blocks.error) { + return ; } - if (blocks.error) { - return ( -

- Error API... -

- ); + if (!blocks.data) { + return ; } return ( @@ -56,6 +53,6 @@ BlocksContainer.propTypes = { export default connect( mapStateToProps, { - fetchBlocks + fetchBlocks: blocksAction.request }, )(BlocksContainer); diff --git a/embark-ui/src/containers/TransactionContainer.js b/embark-ui/src/containers/TransactionContainer.js index 2d98b3b15..323445496 100644 --- a/embark-ui/src/containers/TransactionContainer.js +++ b/embark-ui/src/containers/TransactionContainer.js @@ -3,7 +3,8 @@ import {connect} from 'react-redux'; import PropTypes from 'prop-types'; import {withRouter} from 'react-router-dom'; -import {fetchTransaction} from '../actions'; +import {transaction as transactionAction} from '../actions'; +import Error from "../components/Error"; import NoMatch from "../components/NoMatch"; import Transaction from '../components/Transaction'; @@ -13,7 +14,10 @@ class TransactionContainer extends Component { } render() { - const {transaction} = this.props; + const {transaction, error} = this.props; + if (error) { + return ; + } if (!transaction) { return ; } @@ -27,6 +31,9 @@ class TransactionContainer extends Component { } function mapStateToProps(state, props) { + if(state.transactions.error) { + return {error: state.transactions.error}; + } if(state.transactions.data) { return {transaction: state.transactions.data.find(transaction => transaction.hash === props.match.params.hash)}; } @@ -36,12 +43,13 @@ function mapStateToProps(state, props) { TransactionContainer.propTypes = { match: PropTypes.object, transaction: PropTypes.object, - fetchTransaction: PropTypes.func + fetchTransaction: PropTypes.func, + error: PropTypes.string }; export default withRouter(connect( mapStateToProps, { - fetchTransaction + fetchTransaction: transactionAction.request } )(TransactionContainer)); diff --git a/embark-ui/src/containers/TransactionsContainer.js b/embark-ui/src/containers/TransactionsContainer.js index 7e7edc810..01c6eebd0 100644 --- a/embark-ui/src/containers/TransactionsContainer.js +++ b/embark-ui/src/containers/TransactionsContainer.js @@ -2,10 +2,11 @@ import React, {Component} from 'react'; import {connect} from 'react-redux'; import PropTypes from 'prop-types'; -import {fetchTransactions} from '../actions'; +import {transactions as transactionsAction} from '../actions'; import Transactions from '../components/Transactions'; import Loading from '../components/Loading'; import LoadMore from '../components/LoadMore'; +import Error from '../components/Error'; class TransactionsContainer extends Component { componentDidMount() { @@ -23,16 +24,12 @@ class TransactionsContainer extends Component { render() { const {transactions} = this.props; - if (!transactions.data) { - return ; + if (transactions.error) { + return ; } - if (transactions.error) { - return ( -

- Error API... -

- ); + if (!transactions.data) { + return ; } return ( @@ -56,6 +53,6 @@ TransactionsContainer.propTypes = { export default connect( mapStateToProps, { - fetchTransactions + fetchTransactions: transactionsAction.request }, )(TransactionsContainer); diff --git a/embark-ui/src/reducers/accountsReducer.js b/embark-ui/src/reducers/accountsReducer.js index e02fb3c2e..49f297537 100644 --- a/embark-ui/src/reducers/accountsReducer.js +++ b/embark-ui/src/reducers/accountsReducer.js @@ -8,18 +8,18 @@ export default function accounts(state = {}, action) { switch (action.type) { case actions.ACCOUNTS[actions.SUCCESS]: return { - ...state, data: [...action.accounts.data, ...state.data || []] + ...state, error: null, data: [...action.accounts.data, ...state.data || []] .filter(filterAccount) }; case actions.ACCOUNTS[actions.FAILURE]: - return Object.assign({}, state, {error: true}); + return Object.assign({}, state, {error: action.error}); case actions.ACCOUNT[actions.SUCCESS]: return { - ...state, data: [action.account.data, ...state.data || []] + ...state, error: null, data: [action.account.data, ...state.data || []] .filter(filterAccount) }; case actions.ACCOUNT[actions.FAILURE]: - return Object.assign({}, state, {error: true}); + return Object.assign({}, state, {error: action.error}); default: return state; } diff --git a/embark-ui/src/reducers/blocksReducer.js b/embark-ui/src/reducers/blocksReducer.js index 124f96a76..6e9102cc3 100644 --- a/embark-ui/src/reducers/blocksReducer.js +++ b/embark-ui/src/reducers/blocksReducer.js @@ -1,4 +1,4 @@ -import {RECEIVE_BLOCK, RECEIVE_BLOCK_ERROR, RECEIVE_BLOCKS, RECEIVE_BLOCKS_ERROR} from "../actions"; +import * as actions from "../actions"; function sortBlock(a, b) { return b.number - a.number; @@ -10,22 +10,22 @@ function filterBlock(block, index, self) { export default function blocks(state = {}, action) { switch (action.type) { - case RECEIVE_BLOCKS: + case actions.BLOCKS[actions.SUCCESS]: return { - ...state, data: [...action.blocks.data, ...state.data || []] + ...state, error: null, data: [...action.blocks.data, ...state.data || []] .filter(filterBlock) .sort(sortBlock) }; - case RECEIVE_BLOCKS_ERROR: - return Object.assign({}, state, {error: true}); - case RECEIVE_BLOCK: + case actions.BLOCKS[actions.FAILURE]: + return Object.assign({}, state, {error: action.error}); + case actions.BLOCK[actions.SUCCESS]: return { - ...state, data: [action.block.data, ...state.data || []] + ...state, error: null, data: [action.block.data, ...state.data || []] .filter(filterBlock) .sort(sortBlock) }; - case RECEIVE_BLOCK_ERROR: - return Object.assign({}, state, {error: true}); + case actions.BLOCK[actions.FAILURE]: + return Object.assign({}, state, {error: action.error}); default: return state; } diff --git a/embark-ui/src/reducers/transactionsReducer.js b/embark-ui/src/reducers/transactionsReducer.js index a2cc6b5ee..23b353ffa 100644 --- a/embark-ui/src/reducers/transactionsReducer.js +++ b/embark-ui/src/reducers/transactionsReducer.js @@ -1,4 +1,4 @@ -import {RECEIVE_TRANSACTION, RECEIVE_TRANSACTION_ERROR, RECEIVE_TRANSACTIONS, RECEIVE_TRANSACTIONS_ERROR} from "../actions"; +import * as actions from "../actions"; const BN_FACTOR = 10000; @@ -14,22 +14,22 @@ function filterTransaction(tx, index, self) { export default function transactions(state = {}, action) { switch (action.type) { - case RECEIVE_TRANSACTIONS: + case actions.TRANSACTIONS[actions.SUCCESS]: return { - ...state, data: [...action.transactions.data, ...state.data || []] + ...state, error: null, data: [...action.transactions.data, ...state.data || []] .filter(filterTransaction) .sort(sortTransaction) }; - case RECEIVE_TRANSACTIONS_ERROR: - return Object.assign({}, state, {error: true}); - case RECEIVE_TRANSACTION: + case actions.TRANSACTIONS[actions.FAILURE]: + return Object.assign({}, state, {error: action.error}); + case actions.TRANSACTION[actions.SUCCESS]: return { - ...state, data: [action.transaction.data, ...state.data || []] + ...state, error: null, data: [action.transaction.data, ...state.data || []] .filter(filterTransaction) .sort(sortTransaction) }; - case RECEIVE_TRANSACTION_ERROR: - return Object.assign({}, state, {error: true}); + case actions.TRANSACTION[actions.FAILURE]: + return Object.assign({}, state, {error: action.error}); default: return state; } diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index 1a19a6e2d..3139ff377 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -3,7 +3,7 @@ import * as api from '../api'; import {eventChannel} from 'redux-saga'; import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects'; -const {account, accounts} = actions; +const {account, accounts, block, blocks, transaction, transactions} = actions; function *fetchEntity(entity, apiFn, id) { const {response, error} = yield call(apiFn, id); @@ -15,58 +15,26 @@ function *fetchEntity(entity, apiFn, id) { } export const fetchAccount = fetchEntity.bind(null, account, api.fetchAccount); +export const fetchBlock = fetchEntity.bind(null, block, api.fetchBlock); +export const fetchTransaction = fetchEntity.bind(null, transaction, api.fetchTransaction); export const fetchAccounts = fetchEntity.bind(null, accounts, api.fetchAccounts); - -export function *fetchTransaction(payload) { - try { - const transaction = yield call(api.fetchTransaction, payload.hash); - yield put(actions.receiveTransaction(transaction)); - } catch (e) { - yield put(actions.receiveTransactionError()); - } -} +export const fetchBlocks = fetchEntity.bind(null, blocks, api.fetchBlocks); +export const fetchTransactions = fetchEntity.bind(null, transactions, api.fetchTransactions); export function *watchFetchTransaction() { - yield takeEvery(actions.FETCH_TRANSACTION, fetchTransaction); -} - -export function *fetchTransactions(payload) { - try { - const transactions = yield call(api.fetchTransactions, payload.blockFrom); - yield put(actions.receiveTransactions(transactions)); - } catch (e) { - yield put(actions.receiveTransactionsError()); - } + yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction); } export function *watchFetchTransactions() { - yield takeEvery(actions.FETCH_TRANSACTIONS, fetchTransactions); -} - -export function *fetchBlock(payload) { - try { - const block = yield call(api.fetchBlock, payload.blockNumber); - yield put(actions.receiveBlock(block)); - } catch (e) { - yield put(actions.receiveBlockError()); - } + yield takeEvery(actions.TRANSACTIONS[actions.REQUEST], fetchTransactions); } export function *watchFetchBlock() { - yield takeEvery(actions.FETCH_BLOCK, fetchBlock); -} - -export function *fetchBlocks(payload) { - try { - const blocks = yield call(api.fetchBlocks, payload.from); - yield put(actions.receiveBlocks(blocks)); - } catch (e) { - yield put(actions.receiveBlocksError()); - } + yield takeEvery(actions.BLOCK[actions.REQUEST], fetchBlock); } export function *watchFetchBlocks() { - yield takeEvery(actions.FETCH_BLOCKS, fetchBlocks); + yield takeEvery(actions.BLOCKS[actions.REQUEST], fetchBlocks); } export function *watchFetchAccount() { @@ -119,8 +87,8 @@ export function *initBlockHeader() { const channel = yield call(createChannel, socket); while (true) { yield take(channel); - yield put({type: actions.FETCH_BLOCKS}); - yield put({type: actions.FETCH_TRANSACTIONS}); + yield put({type: actions.BLOCKS[actions.REQUEST]}); + yield put({type: actions.TRANSACTIONS[actions.REQUEST]}); } } diff --git a/lib/modules/blockchain_connector/index.js b/lib/modules/blockchain_connector/index.js index 207bc5c5f..9b8baeb74 100644 --- a/lib/modules/blockchain_connector/index.js +++ b/lib/modules/blockchain_connector/index.js @@ -320,7 +320,10 @@ class BlockchainConnector { 'get', '/embark-api/blockchain/blocks/:blockNumber', (req, res) => { - self.getBlock(req.params.blockNumber, (_err, block) => { + self.getBlock(req.params.blockNumber, (err, block) => { + if(err){ + self.logger.error(err); + } res.send(block); }); } @@ -340,7 +343,10 @@ class BlockchainConnector { 'get', '/embark-api/blockchain/transactions/:hash', (req, res) => { - self.getTransaction(req.params.hash, (_err, transaction) => { + self.getTransaction(req.params.hash, (err, transaction) => { + if(err){ + self.logger.error(err); + } res.send(transaction); }); }