Commit c3164b24 authored by Amaury Martiny's avatar Amaury Martiny

Make tx work for tokens

parent 51018cd3
......@@ -126,21 +126,25 @@ class Send extends Component {
*/
validateAmount = debounce(async values => {
try {
if (!values.amount || isNaN(values.amount)) {
const { balance, parityStore, token } = this.props;
const amount = +values.amount;
if (!amount || isNaN(amount)) {
return { amount: 'Please enter a valid amount' };
} else if (values.amount < 0) {
} else if (amount < 0) {
return { amount: 'Please enter a positive amount ' };
} else if (this.props.balance && this.props.balance.lt(values.amount)) {
} else if (balance && balance.lt(amount)) {
return { amount: "You don't have enough balance" };
}
const estimated = await estimateGas(
values,
this.props.token,
this.props.parityStore.api
);
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);
const { balance } = this.props;
if (!balance || isNaN(estimated)) {
throw new Error('No "balance" or "estimated" value.');
}
......@@ -149,7 +153,7 @@ class Send extends Component {
toWei(balance).minus(estimated.mul(toWei(values.gasPrice, 'shannon')))
);
if (values.amount > maxAmount) {
if (amount > maxAmount) {
return { amount: "You don't have enough balance" };
}
} catch (err) {
......
......@@ -3,22 +3,17 @@
//
// SPDX-License-Identifier: BSD-3-Clause
import abi from '@parity/shared/lib/contracts/abi/eip20';
import { action, computed, observable } from 'mobx';
import { BigNumber } from 'bignumber.js';
import { blockNumber$, makeContract$, post$ } from '@parity/light.js';
import { blockNumber$, post$ } from '@parity/light.js';
import { contractForToken, txForErc20, txForEth } from '../utils/estimateGas';
import Debug from '../utils/debug';
import parityStore from './parityStore';
import { txForErc20, txForEth } from '../utils/estimateGas';
const debug = Debug('sendStore');
const GAS_MULT_FACTOR = 1.25; // Since estimateGas is not always accurate, we add a 33% factor for buffer.
const DEFAULT_GAS = new BigNumber(21000 * GAS_MULT_FACTOR); // Default gas amount
export class SendStore {
@observable blockNumber; // Current block number, used to calculate tx confirmations.
@observable estimated = DEFAULT_GAS; // Estimated gas amount for this transaction.
tx = {}; // The actual tx we are sending. No need to be observable.
@observable txStatus; // Status of the tx, see wiki for details.
......@@ -51,33 +46,18 @@ export class SendStore {
return this.blockNumber - +this.txStatus.confirmed.blockNumber;
}
/**
* If it's a token, then return the makeContract$ object.
*/
@computed
get contract () {
if (this.tokenAddress === 'ETH') {
return null;
}
return makeContract$(this.tokenAddress, abi);
}
/**
* Create a transaction.
*/
send = (token, password) => {
const tx =
token.address === 'ETH' ? txForEth(this.tx) : txForErc20(this.tx, token);
const send$ =
token.address === 'ETH'
? post$(txForEth(this.tx))
: this.contract.transfer$(
...txForErc20(this.tx, token).args,
txForErc20(this.tx, token).options
);
? post$(tx)
: contractForToken(token.address).transfer$(...tx.args, tx.options);
debug(
'Sending tx.',
token.address === 'ETH' ? this.txForEth : this.txForErc20
);
debug('Sending tx.', tx);
return new Promise((resolve, reject) => {
send$.subscribe(txStatus => {
......@@ -98,12 +78,6 @@ export class SendStore {
this.blockNumber = blockNumber;
};
@action
setEstimated = estimated => {
this.estimated = estimated.mul(GAS_MULT_FACTOR);
debug('Estimated gas,', +estimated, ', with buffer,', +this.estimated);
};
@action
setTx = tx => {
this.tx = tx;
......
......@@ -3,7 +3,9 @@
//
// SPDX-License-Identifier: BSD-3-Clause
import abi from '@parity/shared/lib/contracts/abi/eip20';
import BigNumber from 'bignumber.js';
import { makeContract$ } from '@parity/light.js';
import memoize from 'lodash/memoize';
import { toWei } from '@parity/api/lib/util/wei';
......@@ -12,6 +14,10 @@ import Debug from './debug';
const debug = Debug('estimateGas');
const GAS_MULT_FACTOR = 1.25; // Since estimateGas is not always accurate, we add a 33% factor for buffer.
export const contractForToken = memoize(tokenAddress =>
makeContract$(tokenAddress, abi)
);
/**
* Estimate the amount of gas for our transaction.
*/
......@@ -23,7 +29,7 @@ export const estimateGas = (tx, token, api) => {
if (token.address === 'ETH') {
return estimateGasForEth(txForEth(tx), api).then(addBuffer);
} else {
return estimateGasForErc20(txForErc20(tx, token), api).then(addBuffer);
return estimateGasForErc20(txForErc20(tx, token), token).then(addBuffer);
}
};
......@@ -31,14 +37,15 @@ export const estimateGas = (tx, token, api) => {
* Estimate gas to transfer in ERC20 contract. Expensive function, so we
* memoize it.
*/
const estimateGasForErc20 = memoize(
txForErc20 =>
this.contract.contractObject.instance.transfer.estimateGas(
txForErc20.options,
txForErc20.args
),
JSON.stringify
);
const estimateGasForErc20 = memoize((txForErc20, token) => {
debug(`Estimating gas for tx on token contract.`, token, txForErc20);
return contractForToken(
token.address
).contractObject.instance.transfer.estimateGas(
txForErc20.options,
txForErc20.args
);
}, JSON.stringify);
/**
* Estimate gas to transfer to an ETH address. Expensive function, so we
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment