// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity. If not, see . import moment from 'moment'; import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux'; import { Link } from 'react-router'; import { txLink } from '~/3rdparty/etherscan/links'; import IdentityIcon from '~/ui/IdentityIcon'; import IdentityName from '~/ui/IdentityName'; import MethodDecoding from '~/ui/MethodDecoding'; import MethodDecodingStore from '~/ui/MethodDecoding/methodDecodingStore'; import styles from '../txList.css'; class TxRow extends Component { static contextTypes = { api: PropTypes.object.isRequired }; static propTypes = { accountAddresses: PropTypes.array.isRequired, address: PropTypes.string.isRequired, contractAddresses: PropTypes.array.isRequired, netVersion: PropTypes.string.isRequired, tx: PropTypes.object.isRequired, block: PropTypes.object, className: PropTypes.string, historic: PropTypes.bool }; static defaultProps = { historic: true }; state = { isContract: false, isDeploy: false }; methodDecodingStore = MethodDecodingStore.get(this.context.api); componentWillMount () { const { address, tx } = this.props; this .methodDecodingStore .lookup(address, tx) .then((lookup) => { const newState = { isContract: lookup.contract, isDeploy: lookup.deploy }; this.setState(newState); }); } render () { const { address, className, historic, netVersion, tx } = this.props; return ( { this.renderBlockNumber(tx.blockNumber) } { this.renderAddress(tx.from, false) } { this.renderEtherValue(tx.value) }
{ `${tx.hash.substr(2, 6)}...${tx.hash.slice(-6)}` }
{ this.renderAddress(tx.to || tx.creates, !!tx.creates) } ); } renderAddress (address, isDeploy = false) { const isKnownContract = this.getIsKnownContract(address); let esLink = null; if (address && (!isDeploy || isKnownContract)) { esLink = ( ); } return (
{ esLink || 'DEPLOY' }
); } renderEtherValue (_value) { const { api } = this.context; const { isContract, isDeploy } = this.state; // Always show the value if ETH transfer, ie. not // a contract or a deployment const fullValue = !(isContract || isDeploy); const value = api.util.fromWei(_value); if (value.eq(0) && !fullValue) { return
{ ' ' }
; } return (
{ value.toFormat(5) }ETH
); } renderBlockNumber (_blockNumber) { const { block } = this.props; const blockNumber = _blockNumber.toNumber(); return (
{ blockNumber && block ? moment(block.timestamp).fromNow() : null }
{ blockNumber ? _blockNumber.toFormat() : 'Pending' }
); } getIsKnownContract (address) { const { contractAddresses } = this.props; return contractAddresses .map((a) => a.toLowerCase()) .includes(address.toLowerCase()); } addressLink (address) { const { accountAddresses } = this.props; const isAccount = accountAddresses.includes(address); const isContract = this.getIsKnownContract(address); if (isContract) { return `/contracts/${address}`; } if (isAccount) { return `/accounts/${address}`; } return `/addresses/${address}`; } } function mapStateToProps (initState) { const { accounts, contracts } = initState.personal; const accountAddresses = Object.keys(accounts); const contractAddresses = Object.keys(contracts); return (state) => { const { netVersion } = state.nodeStatus; return { accountAddresses, contractAddresses, netVersion }; }; } export default connect( mapStateToProps, null )(TxRow);