mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
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>
This commit is contained in:
parent
397e3a2c7f
commit
7925a767b8
@ -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…
Reference in New Issue
Block a user