diff options
Improve customize gas modal error handling
Diffstat (limited to 'ui/app/components')
-rw-r--r-- | ui/app/components/customize-gas-modal/index.js | 144 | ||||
-rw-r--r-- | ui/app/components/pending-tx/confirm-send-ether.js | 2 | ||||
-rw-r--r-- | ui/app/components/send/send-constants.js | 20 | ||||
-rw-r--r-- | ui/app/components/send/send-utils.js | 39 | ||||
-rw-r--r-- | ui/app/components/send/send-v2-container.js | 8 |
5 files changed, 177 insertions, 36 deletions
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js index 744891c47..710ee24c0 100644 --- a/ui/app/components/customize-gas-modal/index.js +++ b/ui/app/components/customize-gas-modal/index.js @@ -6,23 +6,46 @@ const actions = require('../../actions') const GasModalCard = require('./gas-modal-card') const { - MIN_GAS_PRICE, - MIN_GAS_LIMIT, + MIN_GAS_PRICE_DEC, + MIN_GAS_LIMIT_DEC, + MIN_GAS_PRICE_GWEI, } = require('../send/send-constants') -const { conversionUtil, multiplyCurrencies } = require('../../conversion-util') +const { + isBalanceSufficient, +} = require('../send/send-utils') + +const { + conversionUtil, + multiplyCurrencies, + conversionGreaterThan, +} = require('../../conversion-util') const { getGasPrice, getGasLimit, conversionRateSelector, + getSendAmount, + getSelectedToken, + getSendFrom, + getCurrentAccountWithSendEtherInfo, + getSelectedTokenToFiatRate, } = require('../../selectors') function mapStateToProps (state) { + const selectedToken = getSelectedToken(state) + const currentAccount = getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state) + const conversionRate = conversionRateSelector(state) + return { gasPrice: getGasPrice(state), gasLimit: getGasLimit(state), - conversionRate: conversionRateSelector(state), + conversionRate, + amount: getSendAmount(state), + balance: currentAccount.balance, + primaryCurrency: selectedToken && selectedToken.symbol, + selectedToken, + amountConversionRate: selectedToken ? getSelectedTokenToFiatRate(state) : conversionRate, } } @@ -39,15 +62,26 @@ inherits(CustomizeGasModal, Component) function CustomizeGasModal (props) { Component.call(this) + const gasPrice = props.gasPrice || MIN_GAS_PRICE_DEC + const gasLimit = props.gasLimit || MIN_GAS_LIMIT_DEC + + const gasTotal = multiplyCurrencies(gasLimit, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) + this.state = { - gasPrice: props.gasPrice || MIN_GAS_PRICE, - gasLimit: props.gasLimit || MIN_GAS_LIMIT, + gasPrice, + gasLimit, + gasTotal, + error: null, } } module.exports = connect(mapStateToProps, mapDispatchToProps)(CustomizeGasModal) -CustomizeGasModal.prototype.save = function (gasPrice, gasLimit) { +CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) { const { updateGasPrice, updateGasLimit, @@ -55,41 +89,101 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit) { updateGasTotal } = this.props - const newGasTotal = multiplyCurrencies(gasLimit, gasPrice, { - toNumericBase: 'hex', - multiplicandBase: 16, - multiplierBase: 16, - }) - updateGasPrice(gasPrice) updateGasLimit(gasLimit) - updateGasTotal(newGasTotal) + updateGasTotal(gasTotal) hideModal() } +CustomizeGasModal.prototype.validate = function ({ gasTotal, gasLimit }) { + const { + amount, + balance, + primaryCurrency, + selectedToken, + amountConversionRate, + conversionRate, + } = this.props + + let error = null + + const balanceIsSufficient = isBalanceSufficient({ + amount, + gasTotal, + balance, + primaryCurrency, + selectedToken, + amountConversionRate, + conversionRate, + }) + + if (!balanceIsSufficient) { + error = 'Insufficient balance for current gas total' + } + + const gasLimitTooLow = gasLimit && conversionGreaterThan( + { + value: MIN_GAS_LIMIT_DEC, + fromNumericBase: 'dec', + conversionRate, + }, + { + value: gasLimit, + fromNumericBase: 'hex', + }, + ) + + if (gasLimitTooLow) { + error = 'Gas limit must be at least 21000' + } + + this.setState({ error }) + return error +} + CustomizeGasModal.prototype.convertAndSetGasLimit = function (newGasLimit) { - const convertedGasLimit = conversionUtil(newGasLimit, { + const { gasPrice } = this.state + + const gasLimit = conversionUtil(newGasLimit, { fromNumericBase: 'dec', toNumericBase: 'hex', }) - this.setState({ gasLimit: convertedGasLimit }) + const gasTotal = multiplyCurrencies(gasLimit, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) + + this.validate({ gasTotal, gasLimit }) + + this.setState({ gasTotal, gasLimit }) } CustomizeGasModal.prototype.convertAndSetGasPrice = function (newGasPrice) { - const convertedGasPrice = conversionUtil(newGasPrice, { + const { gasLimit } = this.state + + const gasPrice = conversionUtil(newGasPrice, { fromNumericBase: 'dec', toNumericBase: 'hex', fromDenomination: 'GWEI', toDenomination: 'WEI', }) - this.setState({ gasPrice: convertedGasPrice }) + const gasTotal = multiplyCurrencies(gasLimit, gasPrice, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + }) + + this.validate({ gasTotal }) + + this.setState({ gasTotal, gasPrice }) } CustomizeGasModal.prototype.render = function () { const { hideModal, conversionRate } = this.props - const { gasPrice, gasLimit } = this.state + const { gasPrice, gasLimit, gasTotal, error } = this.state const convertedGasPrice = conversionUtil(gasPrice, { fromNumericBase: 'hex', @@ -120,7 +214,7 @@ CustomizeGasModal.prototype.render = function () { h(GasModalCard, { value: convertedGasPrice, - min: MIN_GAS_PRICE, + min: MIN_GAS_PRICE_GWEI, // max: 1000, step: 1, onChange: value => this.convertAndSetGasPrice(value), @@ -130,7 +224,7 @@ CustomizeGasModal.prototype.render = function () { h(GasModalCard, { value: convertedGasLimit, - min: MIN_GAS_LIMIT, + min: 1, // max: 100000, step: 1, onChange: value => this.convertAndSetGasLimit(value), @@ -141,6 +235,10 @@ CustomizeGasModal.prototype.render = function () { ]), h('div.send-v2__customize-gas__footer', {}, [ + + error && h('div.send-v2__customize-gas__error-message', [ + error, + ]), h('div.send-v2__customize-gas__revert', { onClick: () => console.log('Revert'), @@ -151,8 +249,8 @@ CustomizeGasModal.prototype.render = function () { onClick: this.props.hideModal, }, ['CANCEL']), - h('div.send-v2__customize-gas__save', { - onClick: () => this.save(gasPrice, gasLimit), + h(`div.send-v2__customize-gas__save${error ? '__error' : ''}`, { + onClick: () => !error && this.save(gasPrice, gasLimit, gasTotal), }, ['SAVE']), ]) diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 7162c7122..64da630f6 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -50,7 +50,7 @@ ConfirmSendEther.prototype.getAmount = function () { const { conversionRate, currentCurrency } = this.props const txMeta = this.gatherTxMeta() const txParams = txMeta.txParams || {} - console.log(`conversionRate, currentCurrency`, conversionRate, currentCurrency); + const FIAT = conversionUtil(txParams.value, { fromNumericBase: 'hex', toNumericBase: 'dec', diff --git a/ui/app/components/send/send-constants.js b/ui/app/components/send/send-constants.js index a819a8c28..8b56607cc 100644 --- a/ui/app/components/send/send-constants.js +++ b/ui/app/components/send/send-constants.js @@ -3,12 +3,19 @@ const { multiplyCurrencies } = require('../../conversion-util') const MIN_GAS_PRICE_GWEI = '1' const GWEI_FACTOR = '1e9' -const MIN_GAS_PRICE = multiplyCurrencies(GWEI_FACTOR, MIN_GAS_PRICE_GWEI, { +const MIN_GAS_PRICE_HEX = multiplyCurrencies(GWEI_FACTOR, MIN_GAS_PRICE_GWEI, { multiplicandBase: 16, multiplierBase: 16, + toNumericBase: 'hex', +}) +const MIN_GAS_PRICE_DEC = multiplyCurrencies(GWEI_FACTOR, MIN_GAS_PRICE_GWEI, { + multiplicandBase: 16, + multiplierBase: 16, + toNumericBase: 'dec', }) -const MIN_GAS_LIMIT = (21000).toString(16) -const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT, MIN_GAS_PRICE, { +const MIN_GAS_LIMIT_HEX = (21000).toString(16) +const MIN_GAS_LIMIT_DEC = 21000 +const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT_HEX, MIN_GAS_PRICE_HEX, { toNumericBase: 'hex', multiplicandBase: 16, multiplierBase: 16, @@ -16,8 +23,9 @@ const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT, MIN_GAS_PRICE, { module.exports = { MIN_GAS_PRICE_GWEI, - GWEI_FACTOR, - MIN_GAS_PRICE, - MIN_GAS_LIMIT, + MIN_GAS_PRICE_HEX, + MIN_GAS_PRICE_DEC, + MIN_GAS_LIMIT_HEX, + MIN_GAS_LIMIT_DEC, MIN_GAS_TOTAL, } diff --git a/ui/app/components/send/send-utils.js b/ui/app/components/send/send-utils.js new file mode 100644 index 000000000..bf096d610 --- /dev/null +++ b/ui/app/components/send/send-utils.js @@ -0,0 +1,39 @@ +const { addCurrencies, conversionGreaterThan } = require('../../conversion-util') + +function isBalanceSufficient({ + amount, + gasTotal, + balance, + primaryCurrency, + selectedToken, + amountConversionRate, + conversionRate, +}) { + const totalAmount = addCurrencies(amount, gasTotal, { + aBase: 16, + bBase: 16, + toNumericBase: 'hex', + }) + + const balanceIsSufficient = conversionGreaterThan( + { + value: balance, + fromNumericBase: 'hex', + fromCurrency: primaryCurrency, + conversionRate, + }, + { + value: totalAmount, + fromNumericBase: 'hex', + conversionRate: amountConversionRate, + fromCurrency: selectedToken || primaryCurrency, + conversionRate: amountConversionRate, + }, + ) + + return balanceIsSufficient +} + +module.exports = { + isBalanceSufficient, +}
\ No newline at end of file diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js index 80b52a3ab..fb2634de2 100644 --- a/ui/app/components/send/send-v2-container.js +++ b/ui/app/components/send/send-v2-container.js @@ -17,6 +17,7 @@ const { getAddressBook, getSendFrom, getCurrentCurrency, + getSelectedTokenToFiatRate, } = require('../../selectors') module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther) @@ -26,7 +27,6 @@ function mapStateToProps (state) { const selectedAddress = getSelectedAddress(state) const selectedToken = getSelectedToken(state) const tokenExchangeRates = state.metamask.tokenExchangeRates - const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state) const conversionRate = conversionRateSelector(state) let data; @@ -40,11 +40,7 @@ function mapStateToProps (state) { primaryCurrency = selectedToken.symbol - tokenToFiatRate = multiplyCurrencies( - conversionRate, - selectedTokenExchangeRate, - { toNumericBase: 'dec' } - ) + tokenToFiatRate = getSelectedTokenToFiatRate(state) } return { |