diff --git a/package.json b/package.json index 140b33b7a..e9b8f5f3b 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "@types/koa": "2.0.49", "@types/koa-send": "4.1.2", "@types/ledgerhq__hw-transport-webusb": "4.70.0", + "@types/lodash.debounce": "^4.0.6", "@types/lodash.omit": "4.5.6", "@types/mongoose": "5.7.36", "@types/node": "12.12.54", @@ -184,6 +185,7 @@ "is-electron": "2.2.0", "isomorphic-unfetch": "3.0.0", "koa-server-http-proxy": "0.1.0", + "lodash.debounce": "^4.0.8", "lodash.omit": "4.5.0", "lodash.throttle": "4.1.1", "moment": "2.27.0", diff --git a/src/erc20/erc20.ts b/src/erc20/erc20.ts index d08d8b445..69d1483b2 100644 --- a/src/erc20/erc20.ts +++ b/src/erc20/erc20.ts @@ -385,7 +385,7 @@ export class ERC20 implements IERC20 { return { gasPrice: `${gasPrice}`, - gasLimit: "1000000" + gasLimit: `${gasLimit}` }; } diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index bfae1c2ea..69045b6c1 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -35,3 +35,9 @@ export const truncate = (fullStr: string, strLen: number, separator: string) => return fullStr.substr(0, frontChars) + sep + fullStr.substr(fullStr.length - backChars); }; + +export const resolveAddress = (addr: string): string => { + return addr?.startsWith("0x") + ? convertAddress(false, addr) + : addr +}; diff --git a/src/shared/wallet/transfer/transfer.tsx b/src/shared/wallet/transfer/transfer.tsx index b5304b9de..1ce1e93b2 100644 --- a/src/shared/wallet/transfer/transfer.tsx +++ b/src/shared/wallet/transfer/transfer.tsx @@ -9,13 +9,14 @@ import BigNumber from "bignumber.js"; import { Account } from "iotex-antenna/lib/account/account"; import {fromRau, toRau, validateAddress} from "iotex-antenna/lib/account/utils"; import isElectron from "is-electron"; +import debounce from "lodash.debounce" // @ts-ignore import { t } from "onefx/lib/iso-i18n"; // @ts-ignore import Helmet from "onefx/lib/react-helmet"; import {styled} from "onefx/lib/styletron-react"; import * as React from "react"; -import {useEffect, useState} from "react"; +import { useEffect, useState } from "react"; import { connect } from "react-redux"; import { withRouter } from "react-router"; import { RouteComponentProps } from "react-router-dom"; @@ -30,11 +31,11 @@ import { numberFromCommaString, numberWithCommas } from "../../common/vertical-table"; -import {convertAddress} from "../../utils/util"; +import {convertAddress, resolveAddress} from "../../utils/util"; import { BroadcastFailure, BroadcastSuccess } from "../broadcast-status"; import { GasLimitFormInputItem, - GasPriceFormInputItem, IOTX_GAS_LIMIT + GasPriceFormInputItem } from "../contract/cards"; import { getAntenna } from "../get-antenna"; import { FormItemLabel, inputStyle } from "../wallet"; @@ -139,6 +140,15 @@ class TransferForm extends React.PureComponent { isIoAddr: true }; + private readonly handleDataInHexChange: (dataInHex: string) => void; + private readonly handleAmountChange: (amount: string) => void; + + constructor(props: Props) { + super(props); + this.handleDataInHexChange = debounce(this.dataInHexChange, 800); + this.handleAmountChange = debounce(this.amountChange, 800) + } + public componentDidMount(): void { this.updateGasCostLimit(this.props.form); } @@ -365,16 +375,27 @@ class TransferForm extends React.PureComponent { } // tslint:disable-next-line:typedef - private async estimateGasLimit(contractAddress: string, amount: string) { + private async estimateGasLimit(contractAddress: string, amount: string, dataInHex: string) { const {form, tokens = {}, account} = this.props; + const { recipient } = form.getFieldsValue(); const token = tokens[contractAddress ? contractAddress : ""]; - if (token.symbol === "IOTX") { + if (token && token.symbol === "IOTX") { + + const gasRes = await getAntenna().iotx.estimateActionGasConsumption({ + transfer: { + amount: toRau(amount, "Iotx"), + recipient: resolveAddress(recipient), + payload: dataInHex + }, + callerAddress: account?.address || "" + }); + form.setFieldsValue({ - gasLimit: IOTX_GAS_LIMIT + gasLimit: gasRes.gas }) } - if (token.symbol !== "IOTX" && account && amount) { + if (token && token.symbol !== "IOTX" && account && amount) { const erc20Token = Token.getToken(contractAddress); const gasLimit = await erc20Token.estimateTransferGas(account, `${Math.ceil(parseFloat(amount))}`); form.setFieldsValue({gasLimit}) @@ -383,14 +404,21 @@ class TransferForm extends React.PureComponent { this.updateGasCostLimit(this.props.form); } + // tslint:disable-next-line:typedef + private amountChange(amount: string) { + const { form } = this.props; + const { dataInHex, symbol } = form.getFieldsValue(); + this.estimateGasLimit(symbol, amount, dataInHex) + }; + public renderAmountFormItem(): JSX.Element { const { form, tokens = {} } = this.props; const { getFieldDecorator } = form; - const { symbol } = form.getFieldsValue(); + const { symbol, dataInHex } = form.getFieldsValue(); const token = tokens[symbol ? symbol : ""]; const calculateMax = () => { - this.estimateGasLimit(symbol, token.balanceString); + this.estimateGasLimit(symbol, token.balanceString, dataInHex); if (token.symbol === "IOTX") { form.setFieldsValue({ amount: new BigNumber(token.balanceString).minus(this.state.gasCostLimit).valueOf() @@ -417,7 +445,7 @@ class TransferForm extends React.PureComponent { placeholder="1" addonAfter={this.renderSelectTokenSymbol()} onChange={(e) => { - this.estimateGasLimit(symbol, e.target.value) + this.handleAmountChange(e.target.value) }} name="amount" /> @@ -432,6 +460,13 @@ class TransferForm extends React.PureComponent { ); } + // tslint:disable-next-line:typedef + private dataInHexChange(dataInHex: string) { + const { form } = this.props; + const { amount, symbol } = form.getFieldsValue(); + this.estimateGasLimit(symbol, amount, dataInHex) + }; + public renderTransferForm = () => { const { form } = this.props; const { getFieldDecorator } = form; @@ -455,7 +490,9 @@ class TransferForm extends React.PureComponent { {getFieldDecorator("dataInHex", { rules: rulesMap.dataIndex })( - + { + this.handleDataInHexChange(e.target.value) + }}/> )} )} @@ -538,9 +575,7 @@ class TransferForm extends React.PureComponent { const tokenSymbol = tokens[symbol] ? tokens[symbol].symbol : "IOTX"; const dataSource: { [index: string]: string } = { address: address, - toAddress: recipient?.startsWith("0x") - ? convertAddress(false, recipient) - : recipient, + toAddress: resolveAddress(recipient), amount: `${new BigNumber( numberFromCommaString(amount) ).toString()} ${tokenSymbol}`,