// @flow import './ConfirmationModal.scss'; import React from 'react'; import translate, { translateRaw } from 'translations'; import Big from 'bignumber.js'; import EthTx from 'ethereumjs-tx'; import { connect } from 'react-redux'; import BaseWallet from 'libs/wallet/base'; import { toUnit, toTokenDisplay } from 'libs/units'; import ERC20 from 'libs/erc20'; import { getTransactionFields } from 'libs/transaction'; import { getTokens } from 'selectors/wallet'; import { getNetworkConfig, getLanguageSelection } from 'selectors/config'; import { getTxFromState } from 'selectors/wallet'; import type { NodeConfig } from 'config/data'; import type { Token, NetworkConfig } from 'config/data'; import Modal from 'components/ui/Modal'; import Identicon from 'components/ui/Identicon'; import Spinner from 'components/ui/Spinner'; import type { BroadcastTransactionStatus } from 'libs/transaction'; type Props = { signedTx: string, transaction: EthTx, wallet: BaseWallet, node: NodeConfig, token: ?Token, network: NetworkConfig, onConfirm: (string, EthTx) => void, onClose: () => void, lang: string, broadCastTxStatus: BroadcastTransactionStatus }; type State = { fromAddress: string, timeToRead: number, hasBroadCasted: boolean }; class ConfirmationModal extends React.Component { props: Props; state: State; constructor(props: Props) { super(props); this.state = { fromAddress: '', timeToRead: 5, hasBroadCasted: false }; } componentWillReceiveProps(newProps: Props) { // Reload address if the wallet changes if (newProps.wallet !== this.props.wallet) { this._setWalletAddress(this.props.wallet); } } componentDidUpdate() { if ( this.state.hasBroadCasted && !this.props.broadCastTxStatus.isBroadcasting ) { this.props.onClose(); } } // Count down 5 seconds before allowing them to confirm readTimer = 0; componentDidMount() { this.readTimer = setInterval(() => { if (this.state.timeToRead > 0) { this.setState({ timeToRead: this.state.timeToRead - 1 }); } else { clearInterval(this.readTimer); } }, 1000); this._setWalletAddress(this.props.wallet); } componentWillUnmount() { clearInterval(this.readTimer); } async _setWalletAddress(wallet: BaseWallet) { // TODO move getAddress to saga const fromAddress = await wallet.getAddress(); this.setState({ fromAddress }); } _decodeTransaction() { const { transaction, token } = this.props; const { to, value, data, gasPrice } = getTransactionFields(transaction); let fixedValue; let toAddress; if (token) { // $FlowFixMe - If you have a token prop, you have data const tokenData = ERC20.$transfer(data); fixedValue = toTokenDisplay(new Big(tokenData.value), token).toString(); toAddress = tokenData.to; } else { fixedValue = toUnit(new Big(value, 16), 'wei', 'ether').toString(); toAddress = to; } return { value: fixedValue, gasPrice: toUnit(new Big(gasPrice, 16), 'wei', 'gwei').toString(), data, toAddress }; } _confirm = () => { if (this.state.timeToRead < 1) { this.props.onConfirm(this.props.signedTx); this.setState({ hasBroadCasted: true }); } }; render() { const { node, token, network, onClose, broadCastTxStatus } = this.props; const { fromAddress, timeToRead } = this.state; const { toAddress, value, gasPrice, data } = this._decodeTransaction(); const buttonPrefix = timeToRead > 0 ? `(${timeToRead}) ` : ''; const buttons = [ { text: buttonPrefix + translateRaw('SENDModal_Yes'), type: 'primary', disabled: timeToRead > 0, onClick: this._confirm }, { text: translateRaw('SENDModal_No'), type: 'default', onClick: onClose } ]; const symbol = token ? token.symbol : network.unit; const isBroadcasting = broadCastTxStatus && broadCastTxStatus.isBroadcasting; return ( {
{isBroadcasting ?
:
{value} {symbol}
  • You are sending from {fromAddress}
  • You are sending to {toAddress}
  • You are sending{' '} {value} {symbol} {' '} with a gas price of {gasPrice} gwei
  • You are interacting with the{' '} {node.network} network provided by{' '} {node.service}
  • {!token &&
  • {data ? You are sending the following data:{' '}