// 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 (
);
}
/**
* 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 ${token.symbol} 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 ETH 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;