// Copyright 2015-2018 Parity Technologies (UK) Ltd. // This file is part of Parity. // // SPDX-License-Identifier: BSD-3-Clause import React, { Component } from 'react'; import debounce from 'debounce-promise'; import { estimateGas } from '../../utils/estimateGas'; import { Field, Form } from 'react-final-form'; import { Form as FetherForm, Header } from 'fether-ui'; import { fromWei, toWei } from '@parity/api/lib/util/wei'; import { inject, observer } from 'mobx-react'; import { isAddress } from '@parity/api/lib/util/address'; import { Link } from 'react-router-dom'; import { withProps } from 'recompose'; import TokenBalance from '../../Tokens/TokensList/TokenBalance'; import withBalance from '../../utils/withBalance'; const MAX_GAS_PRICE = 40; // In Gwei const MIN_GAS_PRICE = 3; // Safelow gas price from GasStation, in Gwei @inject('parityStore', 'sendStore', 'tokensStore') @withProps(({ match: { params: { tokenAddress } }, tokensStore }) => ({ token: tokensStore.tokens[tokenAddress] })) @withBalance @observer class Send extends Component { handleSubmit = values => { const { history, sendStore, token } = this.props; sendStore.setTx(values); history.push(`/send/${token.address}/signer`); }; render () { const { sendStore: { tx }, token } = this.props; return (
Close } title={token &&

Send {token.name}

} />
(
)} /> ]} onClick={null} // To disable cursor:pointer on card // TODO Can this be done better? token={token} />
); } /** * Estimate gas amount, and validate that the user has enough balance to make * the tx. */ validateAmount = debounce(async values => { try { const { balance, parityStore, token } = this.props; const amount = +values.amount; if (!amount || isNaN(amount)) { return { amount: 'Please enter a valid amount' }; } else if (amount < 0) { return { amount: 'Please enter a positive amount ' }; } else if (balance && balance.lt(amount)) { return { amount: "You don't have enough balance" }; } if (token.address !== 'ETH') { // No need to estimate gas for tokens. // TODO Make sure that user has enough ETH balance return; } const estimated = await estimateGas(values, token, parityStore.api); if (!balance || isNaN(estimated)) { throw new Error('No "balance" or "estimated" value.'); } // Calculate the max amount the user can send const maxAmount = +fromWei( toWei(balance).minus(estimated.mul(toWei(values.gasPrice, 'shannon'))) ); if (amount > maxAmount) { return { amount: "You don't have enough balance" }; } } catch (err) { return { amount: 'Failed estimating balance, please try again' }; } }, 1000); validateForm = values => { const errors = {}; if (!isAddress(values.to)) { errors.to = 'Please enter a valid Ethereum address'; } return Object.keys(errors).length ? errors : this.validateAmount(values); }; } export default Send;