Add a minimumGasLimit to the original gas customization modal (#9623)

* Add a minimumGasLimit to the gas customization modal in swaps

* Update app/_locales/en/messages.json

Co-authored-by: Mark Stacey <markjstacey@gmail.com>

* Set default for minimum gas limit in gas-modal-page-container.container and make required in sub components

* Update unit tests

* Default value for minimumGasLimit in advanced-gas-inputs.component.js

* Preserve existing gasLimitTooLow message key by creating new gasLimitTooLowWithDynamicFee

* Fix failing unit test

Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Co-authored-by: Erik Marks <rekmarks@protonmail.com>
feature/default_network_editable
Dan J Miller 4 years ago committed by GitHub
parent 397e3a2c7f
commit 7925a767b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/_locales/en/messages.json
  2. 15
      ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js
  3. 3
      ui/app/components/app/gas-customization/advanced-gas-inputs/tests/advanced-gas-input-component.test.js
  4. 3
      ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js
  5. 5
      ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
  6. 6
      ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
  7. 2
      ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
  8. 10
      ui/app/pages/swaps/view-quote/view-quote.js

@ -708,6 +708,10 @@
"gasLimitTooLow": { "gasLimitTooLow": {
"message": "Gas limit must be at least 21000" "message": "Gas limit must be at least 21000"
}, },
"gasLimitTooLowWithDynamicFee": {
"message": "Gas limit must be at least $1",
"description": "$1 is the custom gas limit, in decimal."
},
"gasPrice": { "gasPrice": {
"message": "Gas Price (GWEI)" "message": "Gas Price (GWEI)"
}, },

@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import classnames from 'classnames' import classnames from 'classnames'
import { debounce } from 'lodash' import { debounce } from 'lodash'
import Tooltip from '../../../ui/tooltip' import Tooltip from '../../../ui/tooltip'
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'
export default class AdvancedGasInputs extends Component { export default class AdvancedGasInputs extends Component {
static contextTypes = { static contextTypes = {
@ -18,6 +19,11 @@ export default class AdvancedGasInputs extends Component {
customPriceIsSafe: PropTypes.bool, customPriceIsSafe: PropTypes.bool,
isSpeedUp: PropTypes.bool, isSpeedUp: PropTypes.bool,
customGasLimitMessage: PropTypes.string, customGasLimitMessage: PropTypes.string,
minimumGasLimit: PropTypes.number,
}
static defaultProps = {
minimumGasLimit: MIN_GAS_LIMIT_DEC,
} }
constructor (props) { constructor (props) {
@ -84,7 +90,7 @@ export default class AdvancedGasInputs extends Component {
return {} return {}
} }
gasLimitError ({ insufficientBalance, gasLimit }) { gasLimitError ({ insufficientBalance, gasLimit, minimumGasLimit }) {
const { t } = this.context const { t } = this.context
if (insufficientBalance) { if (insufficientBalance) {
@ -92,9 +98,9 @@ export default class AdvancedGasInputs extends Component {
errorText: t('insufficientBalance'), errorText: t('insufficientBalance'),
errorType: 'error', errorType: 'error',
} }
} else if (gasLimit < 21000) { } else if (gasLimit < minimumGasLimit) {
return { return {
errorText: t('gasLimitTooLow'), errorText: t('gasLimitTooLowWithDynamicFee', [minimumGasLimit]),
errorType: 'error', errorType: 'error',
} }
} }
@ -153,6 +159,7 @@ export default class AdvancedGasInputs extends Component {
customPriceIsSafe, customPriceIsSafe,
isSpeedUp, isSpeedUp,
customGasLimitMessage, customGasLimitMessage,
minimumGasLimit,
} = this.props } = this.props
const { const {
gasPrice, gasPrice,
@ -172,7 +179,7 @@ export default class AdvancedGasInputs extends Component {
const { const {
errorText: gasLimitErrorText, errorText: gasLimitErrorText,
errorType: gasLimitErrorType, errorType: gasLimitErrorType,
} = this.gasLimitError({ insufficientBalance, gasLimit }) } = this.gasLimitError({ insufficientBalance, gasLimit, minimumGasLimit })
const gasLimitErrorComponent = gasLimitErrorType ? ( const gasLimitErrorComponent = gasLimitErrorType ? (
<div className={`advanced-gas-inputs__gas-edit-row__${gasLimitErrorType}-text`}> <div className={`advanced-gas-inputs__gas-edit-row__${gasLimitErrorType}-text`}>
{ gasLimitErrorText } { gasLimitErrorText }

@ -17,6 +17,7 @@ describe('Advanced Gas Inputs', function () {
insufficientBalance: false, insufficientBalance: false,
customPriceIsSafe: true, customPriceIsSafe: true,
isSpeedUp: false, isSpeedUp: false,
minimumGasLimit: 21000,
} }
beforeEach(function () { beforeEach(function () {
@ -91,7 +92,7 @@ describe('Advanced Gas Inputs', function () {
assert.equal(renderError.length, 2) assert.equal(renderError.length, 2)
assert.equal(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError') assert.equal(renderError.at(0).text(), 'zeroGasPriceOnSpeedUpError')
assert.equal(renderError.at(1).text(), 'gasLimitTooLow') assert.equal(renderError.at(1).text(), 'gasLimitTooLowWithDynamicFee')
}) })
it('warns when custom gas price is too low', function () { it('warns when custom gas price is too low', function () {

@ -27,6 +27,7 @@ export default class AdvancedTabContent extends Component {
isSpeedUp: PropTypes.bool, isSpeedUp: PropTypes.bool,
isEthereumNetwork: PropTypes.bool, isEthereumNetwork: PropTypes.bool,
customGasLimitMessage: PropTypes.string, customGasLimitMessage: PropTypes.string,
minimumGasLimit: PropTypes.number.isRequired,
} }
renderDataSummary (transactionFee, timeRemaining) { renderDataSummary (transactionFee, timeRemaining) {
@ -67,6 +68,7 @@ export default class AdvancedTabContent extends Component {
transactionFee, transactionFee,
isEthereumNetwork, isEthereumNetwork,
customGasLimitMessage, customGasLimitMessage,
minimumGasLimit,
} = this.props } = this.props
return ( return (
@ -83,6 +85,7 @@ export default class AdvancedTabContent extends Component {
customPriceIsSafe={customPriceIsSafe} customPriceIsSafe={customPriceIsSafe}
isSpeedUp={isSpeedUp} isSpeedUp={isSpeedUp}
customGasLimitMessage={customGasLimitMessage} customGasLimitMessage={customGasLimitMessage}
minimumGasLimit={minimumGasLimit}
/> />
</div> </div>
{ isEthereumNetwork { isEthereumNetwork

@ -53,7 +53,8 @@ export default class GasModalPageContainer extends Component {
customTotalSupplement: PropTypes.string, customTotalSupplement: PropTypes.string,
isSwap: PropTypes.bool, isSwap: PropTypes.bool,
value: PropTypes.string, value: PropTypes.string,
conversionRate: PropTypes.number, conversionRate: PropTypes.string,
minimumGasLimit: PropTypes.number.isRequired,
} }
state = { state = {
@ -98,6 +99,7 @@ export default class GasModalPageContainer extends Component {
}, },
isEthereumNetwork, isEthereumNetwork,
customGasLimitMessage, customGasLimitMessage,
minimumGasLimit,
} = this.props } = this.props
return ( return (
@ -116,6 +118,7 @@ export default class GasModalPageContainer extends Component {
isSpeedUp={isSpeedUp} isSpeedUp={isSpeedUp}
isRetry={isRetry} isRetry={isRetry}
isEthereumNetwork={isEthereumNetwork} isEthereumNetwork={isEthereumNetwork}
minimumGasLimit={minimumGasLimit}
/> />
) )
} }

@ -62,6 +62,7 @@ import {
calcGasTotal, calcGasTotal,
isBalanceSufficient, isBalanceSufficient,
} from '../../../../pages/send/send.utils' } from '../../../../pages/send/send.utils'
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'
import { calcMaxAmount } from '../../../../pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils' import { calcMaxAmount } from '../../../../pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.utils'
import GasModalPageContainer from './gas-modal-page-container.component' import GasModalPageContainer from './gas-modal-page-container.component'
@ -75,6 +76,7 @@ const mapStateToProps = (state, ownProps) => {
customTotalSupplement = '', customTotalSupplement = '',
extraInfoRow = null, extraInfoRow = null,
useFastestButtons = false, useFastestButtons = false,
minimumGasLimit = MIN_GAS_LIMIT_DEC,
} = modalProps || {} } = modalProps || {}
const { transaction = {} } = ownProps const { transaction = {} } = ownProps
const selectedTransaction = isSwap const selectedTransaction = isSwap
@ -202,6 +204,7 @@ const mapStateToProps = (state, ownProps) => {
conversionRate, conversionRate,
value, value,
customTotalSupplement, customTotalSupplement,
minimumGasLimit,
} }
} }
@ -264,6 +267,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
tokenBalance, tokenBalance,
customGasLimit, customGasLimit,
transaction, transaction,
minimumGasLimit,
} = stateProps } = stateProps
const { const {
hideGasButtonGroup: dispatchHideGasButtonGroup, hideGasButtonGroup: dispatchHideGasButtonGroup,
@ -333,7 +337,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
disableSave: ( disableSave: (
insufficientBalance || insufficientBalance ||
(isSpeedUp && customGasPrice === 0) || (isSpeedUp && customGasPrice === 0) ||
customGasLimit < 21000 customGasLimit < minimumGasLimit
), ),
} }
} }

@ -63,6 +63,7 @@ describe('gas-modal-page-container container', function () {
id: 34, id: 34,
}, },
extraInfoRow: { label: 'mockLabel', value: 'mockValue' }, extraInfoRow: { label: 'mockLabel', value: 'mockValue' },
minimumGasLimit: 21000,
}, },
}, },
}, },
@ -170,6 +171,7 @@ describe('gas-modal-page-container container', function () {
id: 34, id: 34,
}, },
value: '0x640000000000000', value: '0x640000000000000',
minimumGasLimit: 21000,
} }
const baseMockOwnProps = { transaction: { id: 34 } } const baseMockOwnProps = { transaction: { id: 34 } }
const tests = [ const tests = [

@ -131,12 +131,11 @@ export default function ViewQuote () {
.round(0) .round(0)
.toString(16) .toString(16)
const maxGasLimit = (customMaxGas || const nonCustomMaxGasLimit = hexMax(
hexMax( (`0x${decimalToHex(usedQuote?.maxGas || 0)}`),
(`0x${decimalToHex(usedQuote?.maxGas || 0)}`), usedGasLimitWithMultiplier,
usedGasLimitWithMultiplier,
)
) )
const maxGasLimit = customMaxGas || nonCustomMaxGasLimit
const gasTotalInWeiHex = calcGasTotal(maxGasLimit, gasPrice) const gasTotalInWeiHex = calcGasTotal(maxGasLimit, gasPrice)
@ -394,6 +393,7 @@ export default function ViewQuote () {
: null : null
), ),
useFastestButtons: true, useFastestButtons: true,
minimumGasLimit: Number(hexToDecimal(nonCustomMaxGasLimit)),
})) }))
const tokenApprovalTextComponent = ( const tokenApprovalTextComponent = (

Loading…
Cancel
Save