Use trace API for decentralized transaction list (#2784)
* Using traces when available to get accounts transactions (#2148) * Fixed traceMode detection and transactions rendering (#2148) * [WIP] Use Redux Thunk in main UI => Async Actions (#2148) * Using Redux for Transaction / Block / Methods... (#2148) * Use BigNumber comparedTo function to sort txs (#2148)
This commit is contained in:
committed by
Jaco Greeff
parent
479657b23b
commit
76cded7fa4
@@ -37,7 +37,10 @@ class Transactions extends Component {
|
||||
contacts: PropTypes.object,
|
||||
contracts: PropTypes.object,
|
||||
tokens: PropTypes.object,
|
||||
isTest: PropTypes.bool
|
||||
isTest: PropTypes.bool,
|
||||
traceMode: PropTypes.bool,
|
||||
blocks: PropTypes.object,
|
||||
transactionsInfo: PropTypes.object
|
||||
}
|
||||
|
||||
state = {
|
||||
@@ -47,7 +50,24 @@ class Transactions extends Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.getTransactions();
|
||||
if (this.props.traceMode !== undefined) {
|
||||
this.getTransactions(this.props);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps (newProps) {
|
||||
if (this.props.traceMode === undefined && newProps.traceMode !== undefined) {
|
||||
this.getTransactions(newProps);
|
||||
return;
|
||||
}
|
||||
|
||||
const hasChanged = [ 'isTest', 'address' ]
|
||||
.map(key => newProps[key] !== this.props[key])
|
||||
.reduce((truth, keyTruth) => truth || keyTruth, false);
|
||||
|
||||
if (hasChanged) {
|
||||
this.getTransactions(newProps);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -81,60 +101,127 @@ class Transactions extends Component {
|
||||
{ this.renderRows() }
|
||||
</tbody>
|
||||
</table>
|
||||
<div className={ styles.etherscan }>
|
||||
Transaction list powered by <a href='https://etherscan.io/' target='_blank'>etherscan.io</a>
|
||||
</div>
|
||||
{ this.renderEtherscanFooter() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderEtherscanFooter () {
|
||||
const { traceMode } = this.props;
|
||||
|
||||
if (traceMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.etherscan }>
|
||||
Transaction list powered by <a href='https://etherscan.io/' target='_blank'>etherscan.io</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderRows () {
|
||||
const { address, accounts, contacts, contracts, tokens, isTest } = this.props;
|
||||
const { address, accounts, contacts, contracts, tokens, isTest, blocks, transactionsInfo } = this.props;
|
||||
const { transactions } = this.state;
|
||||
|
||||
return (transactions || []).map((transaction, index) => {
|
||||
return (
|
||||
<Transaction
|
||||
key={ index }
|
||||
transaction={ transaction }
|
||||
address={ address }
|
||||
accounts={ accounts }
|
||||
contacts={ contacts }
|
||||
contracts={ contracts }
|
||||
tokens={ tokens }
|
||||
isTest={ isTest } />
|
||||
);
|
||||
});
|
||||
return (transactions || [])
|
||||
.sort((tA, tB) => {
|
||||
return tB.blockNumber.comparedTo(tA.blockNumber);
|
||||
})
|
||||
.slice(0, 25)
|
||||
.map((transaction, index) => {
|
||||
const { blockNumber, hash } = transaction;
|
||||
|
||||
const block = blocks[blockNumber.toString()];
|
||||
const transactionInfo = transactionsInfo[hash];
|
||||
|
||||
return (
|
||||
<Transaction
|
||||
key={ index }
|
||||
block={ block }
|
||||
transactionInfo={ transactionInfo }
|
||||
transaction={ transaction }
|
||||
address={ address }
|
||||
accounts={ accounts }
|
||||
contacts={ contacts }
|
||||
contracts={ contracts }
|
||||
tokens={ tokens }
|
||||
isTest={ isTest } />
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getTransactions = () => {
|
||||
const { isTest, address } = this.props;
|
||||
getTransactions = (props) => {
|
||||
const { isTest, address, traceMode } = props;
|
||||
|
||||
return etherscan.account
|
||||
.transactions(address, 0, isTest)
|
||||
.then((transactions) => {
|
||||
return this
|
||||
.fetchTransactions(isTest, address, traceMode)
|
||||
.then(transactions => {
|
||||
this.setState({
|
||||
transactions,
|
||||
loading: false
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fetchTransactions = (isTest, address, traceMode) => {
|
||||
if (traceMode) {
|
||||
return this.fetchTraceTransactions(address);
|
||||
}
|
||||
|
||||
return this.fetchEtherscanTransactions(isTest, address);
|
||||
}
|
||||
|
||||
fetchEtherscanTransactions = (isTest, address) => {
|
||||
return etherscan.account
|
||||
.transactions(address, 0, isTest)
|
||||
.catch((error) => {
|
||||
console.error('getTransactions', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchTraceTransactions = (address) => {
|
||||
return Promise
|
||||
.all([
|
||||
this.context.api.trace
|
||||
.filter({
|
||||
fromBlock: 0,
|
||||
fromAddress: address
|
||||
}),
|
||||
this.context.api.trace
|
||||
.filter({
|
||||
fromBlock: 0,
|
||||
toAddress: address
|
||||
})
|
||||
])
|
||||
.then(([fromTransactions, toTransactions]) => {
|
||||
const transactions = [].concat(fromTransactions, toTransactions);
|
||||
|
||||
return transactions.map(transaction => ({
|
||||
from: transaction.action.from,
|
||||
to: transaction.action.to,
|
||||
blockNumber: transaction.blockNumber,
|
||||
hash: transaction.transactionHash
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { isTest } = state.nodeStatus;
|
||||
const { isTest, traceMode } = state.nodeStatus;
|
||||
const { accounts, contacts, contracts } = state.personal;
|
||||
const { tokens } = state.balances;
|
||||
const { blocks, transactions } = state.blockchain;
|
||||
|
||||
return {
|
||||
isTest,
|
||||
traceMode,
|
||||
accounts,
|
||||
contacts,
|
||||
contracts,
|
||||
tokens
|
||||
tokens,
|
||||
blocks,
|
||||
transactionsInfo: transactions
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user