From 2af45a656fb120fbddfce07b62cb96fde8d2d951 Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Tue, 7 Dec 2021 00:17:26 +0530 Subject: [PATCH] Adding validations for advance gas fee input fields (#12879) --- app/_locales/en/messages.json | 22 +++++++ .../advanced-gas-fee-gas-limit.js | 63 ++++++++++++------- .../advanced-gas-fee-gas-limit.test.js | 52 +++++++++++++-- .../advanced-gas-fee-gas-limit/index.scss | 2 + .../advanced-gas-fee-inputs.js | 2 +- .../base-fee-input/base-fee-input.js | 52 ++++++++++++++- .../base-fee-input/basefee-input.test.js | 60 +++++++++++++++++- .../priority-fee-input/priority-fee-input.js | 49 +++++++++++++-- .../priority-fee-input.test.js | 6 +- .../advanced-gas-fee-popover.js | 6 +- .../advanced-gas-fee-popover.test.js | 2 +- .../advanced-gas-fee-save.js | 7 ++- ...FeePopover.js => advancedGasFeePopover.js} | 17 ++--- .../advanced-gas-fee-popover/context/index.js | 2 +- .../edit-gas-item/index.scss | 2 +- ui/hooks/gasFeeInput/useGasFeeInputs.js | 31 ++++----- ui/pages/send/send.constants.js | 4 ++ 17 files changed, 307 insertions(+), 72 deletions(-) rename ui/components/app/advanced-gas-fee-popover/context/{advanceGasFeePopover.js => advancedGasFeePopover.js} (56%) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index f9b478e99..14fa980cf 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -810,12 +810,25 @@ "editGasLimitOutOfBounds": { "message": "Gas limit must be at least $1" }, + "editGasLimitOutOfBoundsV2": { + "message": "Gas limit must be greater than $1 and less than $2", + "description": "$1 is the minimum limit for gas and $2 is the maximum limit" + }, "editGasLimitTooltip": { "message": "Gas limit is the maximum units of gas you are willing to use. Units of gas are a multiplier to “Max priority fee” and “Max fee”." }, "editGasLow": { "message": "Low" }, + "editGasMaxBaseFeeHigh": { + "message": "Max base fee is higher than necessary" + }, + "editGasMaxBaseFeeImbalance": { + "message": "Max base fee cannot be lower than priority fee" + }, + "editGasMaxBaseFeeLow": { + "message": "Max base fee is low for current network conditions" + }, "editGasMaxFeeHigh": { "message": "Max fee is higher than necessary" }, @@ -831,12 +844,21 @@ "editGasMaxPriorityFeeBelowMinimum": { "message": "Max priority fee must be greater than 0 GWEI" }, + "editGasMaxPriorityFeeBelowMinimumV2": { + "message": "Priority fee must be at least 1 GWEI" + }, "editGasMaxPriorityFeeHigh": { "message": "Max priority fee is higher than necessary. You may pay more than needed." }, + "editGasMaxPriorityFeeHighV2": { + "message": "Priority fee is higher than necessary. You may pay more than needed" + }, "editGasMaxPriorityFeeLow": { "message": "Max priority fee is low for current network conditions" }, + "editGasMaxPriorityFeeLowV2": { + "message": "Priority fee is low for current network conditions" + }, "editGasMaxPriorityFeeTooltip": { "message": "Max priority fee (aka “miner tip”) goes directly to miners and incentivizes them to prioritize your transaction. You’ll most often pay your max setting" }, diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js index 4c60cc8fe..8cb52318a 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js @@ -1,25 +1,38 @@ import React, { useEffect, useState } from 'react'; import { useGasFeeContext } from '../../../../contexts/gasFee'; +import { bnGreaterThan, bnLessThan } from '../../../../helpers/utils/util'; import { TYPOGRAPHY } from '../../../../helpers/constants/design-system'; import { useI18nContext } from '../../../../hooks/useI18nContext'; -import Box from '../../../ui/box'; +import { MAX_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; import Button from '../../../ui/button'; import FormField from '../../../ui/form-field'; import I18nValue from '../../../ui/i18n-value'; import Typography from '../../../ui/typography'; -import { useAdvanceGasFeePopoverContext } from '../context'; +import { useAdvancedGasFeePopoverContext } from '../context'; + +const validateGasLimit = (gasLimit, minimumGasLimitDec) => { + return bnLessThan(gasLimit, minimumGasLimitDec) || + bnGreaterThan(gasLimit, MAX_GAS_LIMIT_DEC) + ? 'editGasLimitOutOfBoundsV2' + : null; +}; const AdvancedGasFeeGasLimit = () => { const t = useI18nContext(); const { setDirty, setGasLimit: setGasLimitInContext, - } = useAdvanceGasFeePopoverContext(); - const { gasLimit: gasLimitInTransaction } = useGasFeeContext(); + setHasError, + } = useAdvancedGasFeePopoverContext(); + const { + gasLimit: gasLimitInTransaction, + minimumGasLimitDec, + } = useGasFeeContext(); const [isEditing, setEditing] = useState(false); const [gasLimit, setGasLimit] = useState(gasLimitInTransaction); + const [gasLimitError, setGasLimitError] = useState(); const updateGasLimit = (value) => { setGasLimit(value); @@ -28,11 +41,19 @@ const AdvancedGasFeeGasLimit = () => { useEffect(() => { setGasLimitInContext(gasLimit); - }, [gasLimit, setGasLimitInContext]); + const error = validateGasLimit(gasLimit, minimumGasLimitDec); + setGasLimitError(error); + setHasError(Boolean(error)); + }, [gasLimit, minimumGasLimitDec, setGasLimitInContext, setHasError]); if (isEditing) { return ( { } return ( - - + + + + {gasLimit} + - + + ); }; diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js index 2b355f632..de913b08c 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js @@ -8,7 +8,7 @@ import mockState from '../../../../../test/data/mock-state.json'; import { GasFeeContextProvider } from '../../../../contexts/gasFee'; import configureStore from '../../../../store/store'; -import { AdvanceGasFeePopoverContextProvider } from '../context'; +import { AdvancedGasFeePopoverContextProvider } from '../context'; import AdvancedGasFeeGasLimit from './advanced-gas-fee-gas-limit'; jest.mock('../../../../store/actions', () => ({ @@ -20,7 +20,7 @@ jest.mock('../../../../store/actions', () => ({ removePollingTokenFromAppState: jest.fn(), })); -const render = (txProps) => { +const render = (contextProps) => { const store = configureStore({ metamask: { ...mockState.metamask, @@ -42,12 +42,12 @@ const render = (txProps) => { transaction={{ userFeeLevel: 'custom', txParams: { gas: '0x5208' }, - ...txProps, }} + {...contextProps} > - + - + , store, ); @@ -65,4 +65,46 @@ describe('AdvancedGasFeeGasLimit', () => { fireEvent.click(screen.queryByText('Edit')); expect(document.getElementsByTagName('input')[0]).toHaveValue(21000); }); + + it('should show error if gas limit is not in range', () => { + render(); + fireEvent.click(screen.queryByText('Edit')); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 20000 }, + }); + expect( + screen.queryByText( + 'Gas limit must be greater than 20999 and less than 7920027', + ), + ).toBeInTheDocument(); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 8000000 }, + }); + expect( + screen.queryByText( + 'Gas limit must be greater than 20999 and less than 7920027', + ), + ).toBeInTheDocument(); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 7000000 }, + }); + expect( + screen.queryByText( + 'Gas limit must be greater than 20999 and less than 7920027', + ), + ).not.toBeInTheDocument(); + }); + + it('should validate gas limit against minimumGasLimit it is passed to context', () => { + render({ minimumGasLimit: '0x7530' }); + fireEvent.click(screen.queryByText('Edit')); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 25000 }, + }); + expect( + screen.queryByText( + 'Gas limit must be greater than 29999 and less than 7920027', + ), + ).toBeInTheDocument(); + }); }); diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/index.scss b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/index.scss index bf88a1dc1..562a00db3 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/index.scss +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/index.scss @@ -1,4 +1,6 @@ .advanced-gas-fee-gas-limit { + display: flex; + align-items: center; white-space: nowrap; > * { diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/advanced-gas-fee-inputs.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/advanced-gas-fee-inputs.js index c191d36f6..070e2f7b0 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/advanced-gas-fee-inputs.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/advanced-gas-fee-inputs.js @@ -6,7 +6,7 @@ import PriorityFeeInput from './priority-fee-input'; const AdvancedGasFeeInputs = () => { return ( - +
diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js index 194db3026..a2c62e4eb 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js @@ -1,12 +1,14 @@ import React, { useCallback, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import { HIGH_FEE_WARNING_MULTIPLIER } from '../../../../../pages/send/send.constants'; import { PRIORITY_LEVELS } from '../../../../../../shared/constants/gas'; import { divideCurrencies, multiplyCurrencies, } from '../../../../../../shared/modules/conversion.utils'; import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common'; +import { bnGreaterThan, bnLessThan } from '../../../../../helpers/utils/util'; import { decGWEIToHexWEI } from '../../../../../helpers/utils/conversions.util'; import { getAdvancedGasFeeValues } from '../../../../../selectors'; import { useGasFeeContext } from '../../../../../contexts/gasFee'; @@ -18,7 +20,7 @@ import Box from '../../../../ui/box'; import FormField from '../../../../ui/form-field'; import I18nValue from '../../../../ui/i18n-value'; -import { useAdvanceGasFeePopoverContext } from '../../context'; +import { useAdvancedGasFeePopoverContext } from '../../context'; import AdvancedGasFeeInputSubtext from '../../advanced-gas-fee-input-subtext'; const divideCurrencyValues = (value, baseFee) => { @@ -39,11 +41,40 @@ const multiplyCurrencyValues = (baseFee, value, numberOfDecimals) => multiplierBase: 10, }).toNumber(); +const validateBaseFee = (value, gasFeeEstimates, maxPriorityFeePerGas) => { + if (bnGreaterThan(maxPriorityFeePerGas, value)) { + return 'editGasMaxBaseFeeImbalance'; + } + if ( + gasFeeEstimates?.low && + bnLessThan(value, gasFeeEstimates.low.suggestedMaxFeePerGas) + ) { + return 'editGasMaxBaseFeeLow'; + } + if ( + gasFeeEstimates?.high && + bnGreaterThan( + value, + gasFeeEstimates.high.suggestedMaxFeePerGas * HIGH_FEE_WARNING_MULTIPLIER, + ) + ) { + return 'editGasMaxBaseFeeHigh'; + } + return null; +}; + const BaseFeeInput = () => { const t = useI18nContext(); const { gasFeeEstimates, estimateUsed, maxFeePerGas } = useGasFeeContext(); - const { setDirty, setMaxFeePerGas } = useAdvanceGasFeePopoverContext(); + const { + setDirty, + setHasError, + setMaxFeePerGas, + maxPriorityFeePerGas, + } = useAdvancedGasFeePopoverContext(); + const { estimatedBaseFee } = gasFeeEstimates; + const [baseFeeError, setBaseFeeError] = useState(); const { numberOfDecimals: numberOfDecimalsPrimary, } = useUserPreferencedCurrency(PRIMARY); @@ -116,11 +147,26 @@ const BaseFeeInput = () => { useEffect(() => { setMaxFeePerGas(maxBaseFeeGWEI); - }, [maxBaseFeeGWEI, setMaxFeePerGas]); + const error = validateBaseFee( + maxBaseFeeGWEI, + gasFeeEstimates, + maxPriorityFeePerGas, + ); + setBaseFeeError(error); + setHasError(Boolean(error)); + }, [ + gasFeeEstimates, + maxBaseFeeGWEI, + maxPriorityFeePerGas, + setHasError, + setBaseFeeError, + setMaxFeePerGas, + ]); return ( ({ @@ -44,9 +44,9 @@ const render = (txProps) => { ...txProps, }} > - + - + , store, ); @@ -115,4 +115,58 @@ describe('BaseFeeInput', () => { }); expect(screen.queryByText('50')).toBeInTheDocument(); }); + + it('should show error if base fee is less than suggested low value', () => { + render({ + txParams: { + maxFeePerGas: '0x174876E800', + }, + }); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 3 }, + }); + expect( + screen.queryByText('Max base fee is low for current network conditions'), + ).not.toBeInTheDocument(); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 0.01 }, + }); + expect( + screen.queryByText('Max base fee is low for current network conditions'), + ).toBeInTheDocument(); + fireEvent.click(screen.queryByText('Edit in GWEI')); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 10 }, + }); + expect( + screen.queryByText('Max base fee is low for current network conditions'), + ).toBeInTheDocument(); + }); + + it('should show error if base if is more than suggested high value', () => { + render({ + txParams: { + maxFeePerGas: '0x174876E800', + }, + }); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 3 }, + }); + expect( + screen.queryByText('Max base fee is higher than necessary'), + ).not.toBeInTheDocument(); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 10 }, + }); + fireEvent.click(screen.queryByText('Edit in GWEI')); + expect( + screen.queryByText('Max base fee is higher than necessary'), + ).toBeInTheDocument(); + fireEvent.change(document.getElementsByTagName('input')[0], { + target: { value: 500 }, + }); + expect( + screen.queryByText('Max base fee is higher than necessary'), + ).toBeInTheDocument(); + }); }); diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js index 6bf861674..e023a8777 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import { HIGH_FEE_WARNING_MULTIPLIER } from '../../../../../pages/send/send.constants'; import { PRIORITY_LEVELS } from '../../../../../../shared/constants/gas'; import { SECONDARY } from '../../../../../helpers/constants/common'; import { decGWEIToHexWEI } from '../../../../../helpers/utils/conversions.util'; @@ -10,18 +11,48 @@ import { useGasFeeContext } from '../../../../../contexts/gasFee'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { useUserPreferencedCurrency } from '../../../../../hooks/useUserPreferencedCurrency'; import FormField from '../../../../ui/form-field'; +import { bnGreaterThan, bnLessThan } from '../../../../../helpers/utils/util'; -import { useAdvanceGasFeePopoverContext } from '../../context'; +import { useAdvancedGasFeePopoverContext } from '../../context'; import AdvancedGasFeeInputSubtext from '../../advanced-gas-fee-input-subtext'; +const validatePriorityFee = (value, gasFeeEstimates) => { + if (value < 1) { + return 'editGasMaxPriorityFeeBelowMinimumV2'; + } + if ( + gasFeeEstimates?.low && + bnLessThan(value, gasFeeEstimates.low.suggestedMaxPriorityFeePerGas) + ) { + return 'editGasMaxPriorityFeeLowV2'; + } + if ( + gasFeeEstimates?.high && + bnGreaterThan( + value, + gasFeeEstimates.high.suggestedMaxPriorityFeePerGas * + HIGH_FEE_WARNING_MULTIPLIER, + ) + ) { + return 'editGasMaxPriorityFeeHighV2'; + } + return null; +}; + const PriorityFeeInput = () => { const t = useI18nContext(); const advancedGasFeeValues = useSelector(getAdvancedGasFeeValues); const { setDirty, + setHasError, setMaxPriorityFeePerGas, - } = useAdvanceGasFeePopoverContext(); - const { estimateUsed, maxPriorityFeePerGas } = useGasFeeContext(); + } = useAdvancedGasFeePopoverContext(); + const { + estimateUsed, + gasFeeEstimates, + maxPriorityFeePerGas, + } = useGasFeeContext(); + const [priorityFeeError, setPriorityFeeError] = useState(); const [priorityFee, setPriorityFee] = useState(() => { if ( @@ -46,11 +77,21 @@ const PriorityFeeInput = () => { useEffect(() => { setMaxPriorityFeePerGas(priorityFee); - }, [priorityFee, setMaxPriorityFeePerGas]); + const error = validatePriorityFee(priorityFee, gasFeeEstimates); + setPriorityFeeError(error); + setHasError(Boolean(error)); + }, [ + gasFeeEstimates, + priorityFee, + setHasError, + setMaxPriorityFeePerGas, + setPriorityFeeError, + ]); return ( <> ({ @@ -43,9 +43,9 @@ const render = (txProps) => { ...txProps, }} > - + - + , store, ); diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.js index 077d42270..e631fa2b1 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.js @@ -5,7 +5,7 @@ import { useTransactionModalContext } from '../../../contexts/transaction-modal' import Box from '../../ui/box'; import Popover from '../../ui/popover'; -import { AdvanceGasFeePopoverContextProvider } from './context'; +import { AdvancedGasFeePopoverContextProvider } from './context'; import AdvancedGasFeeInputs from './advanced-gas-fee-inputs'; import AdvancedGasFeeGasLimit from './advanced-gas-fee-gas-limit'; import AdvancedGasFeeSaveButton from './advanced-gas-fee-save'; @@ -21,7 +21,7 @@ const AdvancedGasFeePopover = () => { if (currentModal !== 'advancedGasFee') return null; return ( - + { - + ); }; diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js index dd7f0f7a7..b0b78e9f1 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js @@ -64,7 +64,7 @@ describe('AdvancedGasFeePopover', () => { it('should enable save button as input value is changed', () => { render(); fireEvent.change(document.getElementsByTagName('input')[0], { - target: { value: 4 }, + target: { value: 3 }, }); expect(screen.queryByRole('button', { name: 'Save' })).not.toBeDisabled(); }); diff --git a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-save/advanced-gas-fee-save.js b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-save/advanced-gas-fee-save.js index d70f64391..c40f4cad1 100644 --- a/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-save/advanced-gas-fee-save.js +++ b/ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-save/advanced-gas-fee-save.js @@ -6,7 +6,7 @@ import { useGasFeeContext } from '../../../../contexts/gasFee'; import Button from '../../../ui/button'; import I18nValue from '../../../ui/i18n-value'; -import { useAdvanceGasFeePopoverContext } from '../context'; +import { useAdvancedGasFeePopoverContext } from '../context'; import { decGWEIToHexWEI } from '../../../../../shared/modules/conversion.utils'; const AdvancedGasFeeSaveButton = () => { @@ -15,9 +15,10 @@ const AdvancedGasFeeSaveButton = () => { const { isDirty, gasLimit, + hasError, maxFeePerGas, maxPriorityFeePerGas, - } = useAdvanceGasFeePopoverContext(); + } = useAdvancedGasFeePopoverContext(); const onSave = () => { updateTransaction({ @@ -30,7 +31,7 @@ const AdvancedGasFeeSaveButton = () => { }; return ( - ); diff --git a/ui/components/app/advanced-gas-fee-popover/context/advanceGasFeePopover.js b/ui/components/app/advanced-gas-fee-popover/context/advancedGasFeePopover.js similarity index 56% rename from ui/components/app/advanced-gas-fee-popover/context/advanceGasFeePopover.js rename to ui/components/app/advanced-gas-fee-popover/context/advancedGasFeePopover.js index 8a63fe697..853cb8bdc 100644 --- a/ui/components/app/advanced-gas-fee-popover/context/advanceGasFeePopover.js +++ b/ui/components/app/advanced-gas-fee-popover/context/advancedGasFeePopover.js @@ -1,36 +1,39 @@ import React, { createContext, useContext, useState } from 'react'; import PropTypes from 'prop-types'; -export const AdvanceGasFeePopoverContext = createContext({}); +export const AdvancedGasFeePopoverContext = createContext({}); -export const AdvanceGasFeePopoverContextProvider = ({ children }) => { +export const AdvancedGasFeePopoverContextProvider = ({ children }) => { const [gasLimit, setGasLimit] = useState(); const [maxFeePerGas, setMaxFeePerGas] = useState(); const [maxPriorityFeePerGas, setMaxPriorityFeePerGas] = useState(); const [isDirty, setDirty] = useState(); + const [hasError, setHasError] = useState(false); return ( - {children} - + ); }; -export function useAdvanceGasFeePopoverContext() { - return useContext(AdvanceGasFeePopoverContext); +export function useAdvancedGasFeePopoverContext() { + return useContext(AdvancedGasFeePopoverContext); } -AdvanceGasFeePopoverContextProvider.propTypes = { +AdvancedGasFeePopoverContextProvider.propTypes = { children: PropTypes.node.isRequired, }; diff --git a/ui/components/app/advanced-gas-fee-popover/context/index.js b/ui/components/app/advanced-gas-fee-popover/context/index.js index f9181147b..f959b46af 100644 --- a/ui/components/app/advanced-gas-fee-popover/context/index.js +++ b/ui/components/app/advanced-gas-fee-popover/context/index.js @@ -1 +1 @@ -export * from './advanceGasFeePopover'; +export * from './advancedGasFeePopover'; diff --git a/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss b/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss index 8d9e8ee4c..039949c8c 100644 --- a/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss +++ b/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss @@ -15,7 +15,7 @@ background-color: $primary-2; } - &-selected { + &--selected { background-color: $ui-1; } diff --git a/ui/hooks/gasFeeInput/useGasFeeInputs.js b/ui/hooks/gasFeeInput/useGasFeeInputs.js index e2d37eec5..f10ea74fd 100644 --- a/ui/hooks/gasFeeInput/useGasFeeInputs.js +++ b/ui/hooks/gasFeeInput/useGasFeeInputs.js @@ -23,6 +23,21 @@ import { useMaxPriorityFeePerGasInput } from './useMaxPriorityFeePerGasInput'; import { useGasEstimates } from './useGasEstimates'; import { useTransactionFunctions } from './useTransactionFunctions'; +/** + * In EIP_1559_V2 implementation as used by useGasfeeInputContext() the use of this hook is evolved. + * It is no longer used to keep transient state of advance gas fee inputs. + * Transient state of inputs is maintained locally in /ui/components/app/advance-gas-fee-popover component. + * + * This hook is used now as source of shared data about transaction, it shares details of gas fee in transaction, + * estimate used, is EIP-1559 supported and other details. It also have methods to update transaction. + * + * Transaction is used as single source of truth and as transaction is updated the fields shared by hook are + * also updated using useEffect hook. + * + * It will be useful to plan a task to create a new hook of this shared information from this hook. + * Methods like setEstimateToUse, onManualChange are deprecated in context of EIP_1559_V2 implementation. + */ + /** * @typedef {Object} GasFeeInputReturnType * @property {DecGweiString} [maxFeePerGas] - the maxFeePerGas input value. @@ -318,24 +333,10 @@ export function useGasFeeInputs( gasWarnings, hasGasErrors, hasSimulationError, + minimumGasLimitDec: hexToDecimal(minimumGasLimit), supportsEIP1559, supportsEIP1559V2, updateTransaction, updateTransactionUsingGasFeeEstimates, }; } - -/** - * In EIP_1559_V2 implementation as used by useGasfeeInputContext() the use of this hook is evolved. - * It is no longer used to keep transient state of advance gas fee inputs. - * Transient state of inputs is maintained locally in /ui/components/app/advance-gas-fee-popover component. - * - * This hook is used now as source of shared data about transaction, it shares details of gas fee in transaction, - * estimate used, is EIP-1559 supported and other details. It also have methods to update transaction. - * - * Transaction is used as single source of truth and as transaction is updated the fields shared by hook are - * also updated using useEffect hook. - * - * It will be useful to plan a task to create a new hook of this shared information from this hook. - * Methods like setEstimateToUse, onManualChange are deprecated in context of EIP_1559_V2 implementation. - */ diff --git a/ui/pages/send/send.constants.js b/ui/pages/send/send.constants.js index 699775c96..44bea2873 100644 --- a/ui/pages/send/send.constants.js +++ b/ui/pages/send/send.constants.js @@ -7,8 +7,10 @@ import { addHexPrefix } from '../../../app/scripts/lib/util'; const MIN_GAS_PRICE_DEC = '0'; const MIN_GAS_PRICE_HEX = parseInt(MIN_GAS_PRICE_DEC, 10).toString(16); const MIN_GAS_LIMIT_DEC = '21000'; +const MAX_GAS_LIMIT_DEC = '7920027'; const MIN_GAS_LIMIT_HEX = parseInt(MIN_GAS_LIMIT_DEC, 10).toString(16); +const HIGH_FEE_WARNING_MULTIPLIER = 1.5; const MIN_GAS_PRICE_GWEI = addHexPrefix( conversionUtil(MIN_GAS_PRICE_HEX, { fromDenomination: 'WEI', @@ -45,6 +47,8 @@ const ENS_UNKNOWN_ERROR = 'ensUnknownError'; const ENS_REGISTRATION_ERROR = 'ensRegistrationError'; export { + MAX_GAS_LIMIT_DEC, + HIGH_FEE_WARNING_MULTIPLIER, INSUFFICIENT_FUNDS_ERROR, INSUFFICIENT_TOKENS_ERROR, INVALID_RECIPIENT_ADDRESS_ERROR,