mirror of
https://github.com/embarklabs/embark.git
synced 2025-01-11 14:24:24 +00:00
Adding blocks explorer
This commit is contained in:
parent
27a237ec73
commit
b00ce3c9fa
@ -6,6 +6,7 @@
|
|||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"connected-react-router": "^4.3.0",
|
"connected-react-router": "^4.3.0",
|
||||||
"history": "^4.7.2",
|
"history": "^4.7.2",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.4.1",
|
"react": "^16.4.1",
|
||||||
"react-dom": "^16.4.1",
|
"react-dom": "^16.4.1",
|
||||||
"react-redux": "^5.0.7",
|
"react-redux": "^5.0.7",
|
||||||
|
@ -6,6 +6,10 @@ export const RECEIVE_ACCOUNTS_ERROR = 'RECEIVE_ACCOUNTS_ERROR';
|
|||||||
export const FETCH_PROCESSES = 'FETCH_PROCESSES';
|
export const FETCH_PROCESSES = 'FETCH_PROCESSES';
|
||||||
export const RECEIVE_PROCESSES = 'RECEIVE_PROCESSES';
|
export const RECEIVE_PROCESSES = 'RECEIVE_PROCESSES';
|
||||||
export const RECEIVE_PROCESSES_ERROR = 'RECEIVE_PROCESSES_ERROR';
|
export const RECEIVE_PROCESSES_ERROR = 'RECEIVE_PROCESSES_ERROR';
|
||||||
|
// Blocks
|
||||||
|
export const FETCH_BLOCKS = 'FETCH_BLOCKS';
|
||||||
|
export const RECEIVE_BLOCKS = 'RECEIVE_BLOCKS';
|
||||||
|
export const RECEIVE_BLOCKS_ERROR = 'RECEIVE_BLOCKS_ERROR';
|
||||||
|
|
||||||
export function fetchAccounts() {
|
export function fetchAccounts() {
|
||||||
return {
|
return {
|
||||||
@ -44,3 +48,22 @@ export function receiveProcessesError() {
|
|||||||
type: RECEIVE_PROCESSES_ERROR
|
type: RECEIVE_PROCESSES_ERROR
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fetchBlocks() {
|
||||||
|
return {
|
||||||
|
type: FETCH_BLOCKS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function receiveBlocks(blocks) {
|
||||||
|
return {
|
||||||
|
type: RECEIVE_BLOCKS,
|
||||||
|
blocks
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function receiveBlocksError() {
|
||||||
|
return {
|
||||||
|
type: RECEIVE_BLOCKS_ERROR
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
const BASE_URL = 'http://localhost:8000/embark-api';
|
||||||
|
|
||||||
export function fetchAccounts() {
|
export function fetchAccounts() {
|
||||||
return axios.get('http://localhost:8000/embark-api/blockchain/accounts');
|
return axios.get(`${BASE_URL}/blockchain/accounts`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchBlocks() {
|
||||||
|
return axios.get(`${BASE_URL}/blockchain/blocks`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchProcesses() {
|
export function fetchProcesses() {
|
||||||
return axios.get('http://localhost:8000/embark-api/processes');
|
return axios.get(`${BASE_URL}/processes`);
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,46 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Page,
|
||||||
|
Grid,
|
||||||
|
Card,
|
||||||
|
Table
|
||||||
|
} from "tabler-react";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
|
||||||
const Accounts = ({accounts}) => (
|
const Accounts = ({accounts}) => (
|
||||||
<React.Fragment>
|
<Page.Content title="Accounts">
|
||||||
<h1>Accounts</h1>
|
<Grid.Row>
|
||||||
<table>
|
<Grid.Col>
|
||||||
<thead>
|
<Card>
|
||||||
<tr>
|
<Table
|
||||||
<th>Address</th>
|
responsive
|
||||||
<th>Balance</th>
|
className="card-table table-vcenter text-nowrap"
|
||||||
<th>TX count</th>
|
headerItems={[
|
||||||
<th>Index</th>
|
{content: "Address"},
|
||||||
</tr>
|
{content: "Balance"},
|
||||||
</thead>
|
{content: "TX count"},
|
||||||
<tbody>
|
{content: "Index"}
|
||||||
{accounts.map((account) => {
|
]}
|
||||||
return (
|
bodyItems={
|
||||||
<tr>
|
accounts.map((account) => {
|
||||||
<td>{account.address}</td>
|
return ([
|
||||||
<td>{account.balance} ETH</td>
|
{content: account.address},
|
||||||
<td>{account.transactionCount}</td>
|
{content: account.balance},
|
||||||
<td>{account.index}</td>
|
{content: account.transactionCount},
|
||||||
</tr>
|
{content: account.index}
|
||||||
)
|
]);
|
||||||
})}
|
})
|
||||||
</tbody>
|
}
|
||||||
</table>
|
/>
|
||||||
</React.Fragment>
|
</Card>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid.Row>
|
||||||
|
</Page.Content>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Accounts.propTypes = {
|
||||||
|
accounts: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
export default Accounts;
|
export default Accounts;
|
||||||
|
41
embark-ui/src/components/Blocks.js
Normal file
41
embark-ui/src/components/Blocks.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Page,
|
||||||
|
Grid,
|
||||||
|
Card,
|
||||||
|
Table
|
||||||
|
} from "tabler-react";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
|
||||||
|
const Blocks = ({blocks}) => (
|
||||||
|
<Page.Content title="Blocks">
|
||||||
|
<Grid.Row>
|
||||||
|
<Grid.Col>
|
||||||
|
<Card>
|
||||||
|
<Table
|
||||||
|
responsive
|
||||||
|
className="card-table table-vcenter text-nowrap"
|
||||||
|
headerItems={[{content: "Number"}, {content: "Mined On"}, {content: "Gas Used"}, {content: "TX Count"}]}
|
||||||
|
bodyItems={
|
||||||
|
blocks.map((block) => {
|
||||||
|
return ([
|
||||||
|
{content: block.number},
|
||||||
|
{content: new Date(block.timestamp * 1000).toLocaleString()},
|
||||||
|
{content: block.gasUsed},
|
||||||
|
{content: block.transactions.length}
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid.Row>
|
||||||
|
</Page.Content>
|
||||||
|
);
|
||||||
|
|
||||||
|
Blocks.propTypes = {
|
||||||
|
blocks: [PropTypes.object]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Blocks;
|
46
embark-ui/src/components/ExplorerLayout.js
Normal file
46
embark-ui/src/components/ExplorerLayout.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
Page,
|
||||||
|
Grid,
|
||||||
|
List,
|
||||||
|
} from "tabler-react";
|
||||||
|
|
||||||
|
import AccountsContainer from '../containers/AccountsContainer';
|
||||||
|
import BlocksContainer from '../containers/BlocksContainer';
|
||||||
|
|
||||||
|
const ExplorerLayout = () => (
|
||||||
|
<Grid.Row>
|
||||||
|
<Grid.Col md={3}>
|
||||||
|
<Page.Title className="my-5">Explorer</Page.Title>
|
||||||
|
<div>
|
||||||
|
<List.Group transparent={true}>
|
||||||
|
<List.GroupItem
|
||||||
|
className="d-flex align-items-center"
|
||||||
|
to="/embark/explorer/accounts"
|
||||||
|
icon="users"
|
||||||
|
RootComponent={withRouter(NavLink)}
|
||||||
|
>
|
||||||
|
Accounts
|
||||||
|
</List.GroupItem>
|
||||||
|
<List.GroupItem
|
||||||
|
className="d-flex align-items-center"
|
||||||
|
to="/embark/explorer/blocks"
|
||||||
|
icon="book-open"
|
||||||
|
RootComponent={withRouter(NavLink)}
|
||||||
|
>
|
||||||
|
Blocks
|
||||||
|
</List.GroupItem>
|
||||||
|
</List.Group>
|
||||||
|
</div>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col md={9}>
|
||||||
|
<Switch>
|
||||||
|
<Route exact path="/embark/explorer/accounts" component={AccountsContainer} />
|
||||||
|
<Route exact path="/embark/explorer/blocks" component={BlocksContainer} />
|
||||||
|
</Switch>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid.Row>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default ExplorerLayout;
|
12
embark-ui/src/components/Loading.js
Normal file
12
embark-ui/src/components/Loading.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {Grid, Loader} from 'tabler-react';
|
||||||
|
|
||||||
|
const Loading = () => (
|
||||||
|
<Grid.Row className="align-items-center h-100 mt-5">
|
||||||
|
<Grid.Col>
|
||||||
|
<Loader className="mx-auto" />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid.Row>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Loading;
|
@ -1,21 +1,20 @@
|
|||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import { fetchAccounts } from '../actions';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import {fetchAccounts} from '../actions';
|
||||||
import Accounts from '../components/Accounts';
|
import Accounts from '../components/Accounts';
|
||||||
|
import Loading from '../components/Loading';
|
||||||
|
|
||||||
class AccountsContainer extends Component {
|
class AccountsContainer extends Component {
|
||||||
componentWillMount() {
|
componentDidMount() {
|
||||||
this.props.fetchAccounts();
|
this.props.fetchAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { accounts } = this.props;
|
const {accounts} = this.props;
|
||||||
if (!accounts.data) {
|
if (!accounts.data) {
|
||||||
return (
|
return <Loading />;
|
||||||
<h1>
|
|
||||||
<i>Loading accounts...</i>
|
|
||||||
</h1>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accounts.error) {
|
if (accounts.error) {
|
||||||
@ -23,22 +22,27 @@ class AccountsContainer extends Component {
|
|||||||
<h1>
|
<h1>
|
||||||
<i>Error API...</i>
|
<i>Error API...</i>
|
||||||
</h1>
|
</h1>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accounts accounts={accounts.data} />
|
<Accounts accounts={accounts.data} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return { accounts: state.accounts }
|
return {accounts: state.accounts};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AccountsContainer.propTypes = {
|
||||||
|
accounts: PropTypes.object,
|
||||||
|
fetchAccounts: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchAccounts
|
fetchAccounts
|
||||||
},
|
},
|
||||||
)(AccountsContainer)
|
)(AccountsContainer);
|
||||||
|
48
embark-ui/src/containers/BlocksContainer.js
Normal file
48
embark-ui/src/containers/BlocksContainer.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import {fetchBlocks} from '../actions';
|
||||||
|
import Blocks from '../components/Blocks';
|
||||||
|
import Loading from '../components/Loading';
|
||||||
|
|
||||||
|
class BlocksContainer extends Component {
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.fetchBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {blocks} = this.props;
|
||||||
|
if (!blocks.data) {
|
||||||
|
return <Loading />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocks.error) {
|
||||||
|
return (
|
||||||
|
<h1>
|
||||||
|
<i>Error API...</i>
|
||||||
|
</h1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Blocks blocks={blocks.data} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {blocks: state.blocks};
|
||||||
|
}
|
||||||
|
|
||||||
|
BlocksContainer.propTypes = {
|
||||||
|
blocks: PropTypes.object,
|
||||||
|
fetchBlocks: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
{
|
||||||
|
fetchBlocks
|
||||||
|
},
|
||||||
|
)(BlocksContainer);
|
@ -1,9 +1,11 @@
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {fetchProcesses} from '../actions';
|
|
||||||
import {Tabs, Tab} from 'tabler-react';
|
import {Tabs, Tab} from 'tabler-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import {fetchProcesses} from '../actions';
|
||||||
|
import Loading from '../components/Loading';
|
||||||
|
|
||||||
import "./css/processContainer.css";
|
import "./css/processContainer.css";
|
||||||
|
|
||||||
class ProcessesContainer extends Component {
|
class ProcessesContainer extends Component {
|
||||||
@ -14,11 +16,7 @@ class ProcessesContainer extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const {processes} = this.props;
|
const {processes} = this.props;
|
||||||
if (!processes.data) {
|
if (!processes.data) {
|
||||||
return (
|
return <Loading />;
|
||||||
<h1>
|
|
||||||
<i>Loading processes...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processes.error) {
|
if (processes.error) {
|
||||||
|
12
embark-ui/src/reducers/accountsReducer.js
Normal file
12
embark-ui/src/reducers/accountsReducer.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import {RECEIVE_ACCOUNTS, RECEIVE_ACCOUNTS_ERROR} from "../actions";
|
||||||
|
|
||||||
|
export default function accounts(state = {}, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case RECEIVE_ACCOUNTS:
|
||||||
|
return Object.assign({}, state, {data: action.accounts.data});
|
||||||
|
case RECEIVE_ACCOUNTS_ERROR:
|
||||||
|
return Object.assign({}, state, {error: true});
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
12
embark-ui/src/reducers/blocksReducer.js
Normal file
12
embark-ui/src/reducers/blocksReducer.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import {RECEIVE_BLOCKS, RECEIVE_BLOCKS_ERROR} from "../actions";
|
||||||
|
|
||||||
|
export default function accounts(state = {}, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case RECEIVE_BLOCKS:
|
||||||
|
return Object.assign({}, state, {data: action.blocks.data});
|
||||||
|
case RECEIVE_BLOCKS_ERROR:
|
||||||
|
return Object.assign({}, state, {error: true});
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,12 @@
|
|||||||
import {combineReducers} from 'redux';
|
import {combineReducers} from 'redux';
|
||||||
import {RECEIVE_ACCOUNTS, RECEIVE_ACCOUNTS_ERROR} from "../actions";
|
|
||||||
import processesReducer from './processesReducer';
|
import processesReducer from './processesReducer';
|
||||||
|
import accountsReducer from './accountsReducer';
|
||||||
|
import blocksReducer from './blocksReducer';
|
||||||
|
|
||||||
function accounts(state = {}, action) {
|
const rootReducer = combineReducers({
|
||||||
switch (action.type) {
|
accounts: accountsReducer,
|
||||||
case RECEIVE_ACCOUNTS:
|
processes: processesReducer,
|
||||||
return Object.assign({}, state, {data: action.accounts.data});
|
blocks: blocksReducer
|
||||||
case RECEIVE_ACCOUNTS_ERROR:
|
});
|
||||||
return Object.assign({}, state, {error: true});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rootReducer = combineReducers({accounts, processes: processesReducer});
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Route, Switch} from 'react-router';
|
import {Route, Switch} from 'react-router-dom';
|
||||||
|
|
||||||
import Home from './components/Home';
|
import Home from './components/Home';
|
||||||
import AccountsContainer from './containers/AccountsContainer';
|
|
||||||
import ProcessesContainer from './containers/ProcessesContainer';
|
|
||||||
import NoMatch from './components/NoMatch';
|
import NoMatch from './components/NoMatch';
|
||||||
|
import ExplorerLayout from './components/ExplorerLayout';
|
||||||
|
|
||||||
|
import ProcessesContainer from './containers/ProcessesContainer';
|
||||||
|
|
||||||
const routes = (
|
const routes = (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/embark" component={Home} />
|
<Route exact path="/embark/" component={Home} />
|
||||||
<Route path="/embark/explorer/accounts" component={AccountsContainer} />
|
<Route path="/embark/explorer/" component={ExplorerLayout} />
|
||||||
<Route path="/embark/processes" component={ProcessesContainer} />
|
<Route path="/embark/processes/" component={ProcessesContainer} />
|
||||||
<Route component={NoMatch} />
|
<Route component={NoMatch} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
@ -2,6 +2,19 @@ import * as actions from '../actions';
|
|||||||
import * as api from '../api';
|
import * as api from '../api';
|
||||||
import {all, call, fork, put, takeEvery} from 'redux-saga/effects';
|
import {all, call, fork, put, takeEvery} from 'redux-saga/effects';
|
||||||
|
|
||||||
|
export function *fetchBlocks() {
|
||||||
|
try {
|
||||||
|
const blocks = yield call(api.fetchBlocks);
|
||||||
|
yield put(actions.receiveBlocks(blocks));
|
||||||
|
} catch (e) {
|
||||||
|
yield put(actions.receiveBlocksError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function *watchFetchBlocks() {
|
||||||
|
yield takeEvery(actions.FETCH_BLOCKS, fetchBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
export function *fetchAccounts() {
|
export function *fetchAccounts() {
|
||||||
try {
|
try {
|
||||||
const accounts = yield call(api.fetchAccounts);
|
const accounts = yield call(api.fetchAccounts);
|
||||||
@ -29,5 +42,5 @@ export function *watchFetchProcesses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function *root() {
|
export default function *root() {
|
||||||
yield all([fork(watchFetchAccounts), fork(watchFetchProcesses)]);
|
yield all([fork(watchFetchAccounts), fork(watchFetchProcesses), fork(watchFetchBlocks)]);
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,14 @@ import history from '../history';
|
|||||||
import rootReducer from '../reducers';
|
import rootReducer from '../reducers';
|
||||||
import saga from '../sagas';
|
import saga from '../sagas';
|
||||||
|
|
||||||
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
|
|
||||||
export default function configureStore() {
|
export default function configureStore() {
|
||||||
const sagaMiddleware = createSagaMiddleware();
|
const sagaMiddleware = createSagaMiddleware();
|
||||||
|
|
||||||
const store = createStore(
|
const store = createStore(
|
||||||
connectRouter(history)(rootReducer),
|
connectRouter(history)(rootReducer),
|
||||||
compose(
|
composeEnhancers(
|
||||||
applyMiddleware(
|
applyMiddleware(
|
||||||
routerMiddleware(history),
|
routerMiddleware(history),
|
||||||
sagaMiddleware
|
sagaMiddleware
|
||||||
|
@ -327,6 +327,46 @@ class BlockchainConnector {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
plugin.registerAPICall(
|
||||||
|
'get',
|
||||||
|
'/embark-api/blockchain/blocks',
|
||||||
|
(req, res) => {
|
||||||
|
let from = req.query.from;
|
||||||
|
let limit = req.query.limit || 10;
|
||||||
|
let results = [];
|
||||||
|
async.waterfall([
|
||||||
|
function(callback) {
|
||||||
|
if (from) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
self.getBlockNumber((err, blockNumber) => {
|
||||||
|
if (err) {
|
||||||
|
from = 0;
|
||||||
|
} else {
|
||||||
|
from = blockNumber;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(callback) {
|
||||||
|
async.times(limit, function(n, next) {
|
||||||
|
self.web3.eth.getBlock(from - n, function(err, block) {
|
||||||
|
if (err){
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
results.push(block);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}, function() {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], function () {
|
||||||
|
res.send(results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -334,6 +374,10 @@ class BlockchainConnector {
|
|||||||
return this.web3.eth.defaultAccount;
|
return this.web3.eth.defaultAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBlockNumber(cb) {
|
||||||
|
return this.web3.eth.getBlockNumber(cb);
|
||||||
|
}
|
||||||
|
|
||||||
setDefaultAccount(account) {
|
setDefaultAccount(account) {
|
||||||
this.web3.eth.defaultAccount = account;
|
this.web3.eth.defaultAccount = account;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user