From 88faef7e19228652e2bfb339ffc3392926ee985d Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Wed, 12 Jan 2022 00:47:56 +0530 Subject: [PATCH] Adding user setting option for EIP-1559 V2 (#13242) --- app/_locales/en/messages.json | 16 ++++ app/scripts/controllers/app-state.js | 12 +++ app/scripts/controllers/preferences.js | 9 ++ app/scripts/controllers/transactions/index.js | 7 +- app/scripts/metamask-controller.js | 6 ++ ui/components/app/app-components.scss | 1 + ...m-page-container-content.component.test.js | 3 +- .../confirm-page-container.component.js | 2 + .../enableEIP1559V2-notice.js | 94 +++++++++++++++++++ .../enableEIP1559V2-notice/index.js | 1 + .../enableEIP1559V2-notice/index.scss | 33 +++++++ .../edit-gas-fee-button.test.js | 9 +- .../transaction-detail.component.test.js | 9 +- .../transaction-list-item.component.js | 10 +- ui/ducks/metamask/metamask.js | 4 + ui/hooks/gasFeeInput/test-utils.js | 5 + ui/hooks/gasFeeInput/useGasFeeInputs.js | 7 +- ui/hooks/gasFeeInput/useGasFeeInputs.test.js | 6 +- ui/pages/confirm-approve/confirm-approve.js | 9 +- .../confirm-transaction-base.component.js | 7 +- .../confirm-transaction-base.container.js | 3 + .../experimental-tab.component.js | 55 ++++++++++- .../experimental-tab.container.js | 4 + ui/pages/settings/index.scss | 4 + ui/pages/swaps/fee-card/fee-card.test.js | 6 +- ui/pages/swaps/view-quote/view-quote.js | 9 +- ui/selectors/selectors.js | 4 + ui/store/actions.js | 16 ++++ 28 files changed, 297 insertions(+), 54 deletions(-) create mode 100644 ui/components/app/confirm-page-container/enableEIP1559V2-notice/enableEIP1559V2-notice.js create mode 100644 ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.js create mode 100644 ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.scss diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 08de0b075..fadb4033f 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -933,6 +933,22 @@ "enableAutoDetect": { "message": " Enable Autodetect" }, + "enableEIP1559V2": { + "message": "Enable Enhanced Gas Fee UI" + }, + "enableEIP1559V2AlertMessage": { + "message": "We've updated how gas fee estimation and customization works." + }, + "enableEIP1559V2ButtonText": { + "message": "Turn on Enhanced Gas Fee UI in Settings" + }, + "enableEIP1559V2Description": { + "message": "We've updated how gas estimation and customization works. Turn on if you'd like to use the new gas experience. $1", + "description": "$1 here is Learn More link" + }, + "enableEIP1559V2Header": { + "message": "New gas experience" + }, "enableFromSettings": { "message": " Enable it from Settings." }, diff --git a/app/scripts/controllers/app-state.js b/app/scripts/controllers/app-state.js index 4d9ef9ebe..3ddc7b858 100644 --- a/app/scripts/controllers/app-state.js +++ b/app/scripts/controllers/app-state.js @@ -31,6 +31,7 @@ export default class AppStateController extends EventEmitter { recoveryPhraseReminderHasBeenShown: false, recoveryPhraseReminderLastShown: new Date().getTime(), collectiblesDetectionNoticeDismissed: false, + enableEIP1559V2NoticeDismissed: false, showTestnetMessageInDropdown: true, trezorModel: null, ...initState, @@ -270,4 +271,15 @@ export default class AppStateController extends EventEmitter { collectiblesDetectionNoticeDismissed, }); } + + /** + * A setter for the `enableEIP1559V2NoticeDismissed` property + * + * @param enableEIP1559V2NoticeDismissed + */ + setEnableEIP1559V2NoticeDismissed(enableEIP1559V2NoticeDismissed) { + this.store.updateState({ + enableEIP1559V2NoticeDismissed, + }); + } } diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index c51e7d46a..037359453 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -167,6 +167,15 @@ export default class PreferencesController { this.store.updateState({ advancedGasFee: val }); } + /** + * Setter for the `eip1559V2Enabled` property + * + * @param {object} val - holds the eip1559V2Enabled that the user set as experimental settings. + */ + setEIP1559V2Enabled(val) { + this.store.updateState({ eip1559V2Enabled: val }); + } + /** * Add new methodData to state, to avoid requesting this information again through Infura * diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 555d892e3..09f5f94c0 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -441,7 +441,8 @@ export default class TransactionController extends EventEmitter { } if (eip1559Compatibility) { - if (process.env.EIP_1559_V2 && Boolean(advancedGasFeeDefaultValues)) { + const { eip1559V2Enabled } = this.preferencesStore.getState(); + if (eip1559V2Enabled && Boolean(advancedGasFeeDefaultValues)) { txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE; txMeta.txParams.maxFeePerGas = decGWEIToHexWEI( advancedGasFeeDefaultValues.maxBaseFee, @@ -458,7 +459,7 @@ export default class TransactionController extends EventEmitter { // then we set maxFeePerGas and maxPriorityFeePerGas to the suggested gasPrice. txMeta.txParams.maxFeePerGas = txMeta.txParams.gasPrice; txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.gasPrice; - if (process.env.EIP_1559_V2) { + if (eip1559V2Enabled) { txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED; } else { txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE; @@ -472,7 +473,7 @@ export default class TransactionController extends EventEmitter { txMeta.origin === 'metamask' ) { txMeta.userFeeLevel = GAS_RECOMMENDATIONS.MEDIUM; - } else if (process.env.EIP_1559_V2) { + } else if (eip1559V2Enabled) { txMeta.userFeeLevel = PRIORITY_LEVELS.DAPP_SUGGESTED; } else { txMeta.userFeeLevel = CUSTOM_GAS_ESTIMATE; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 528c36d55..f5ef9cfef 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1188,6 +1188,9 @@ export default class MetamaskController extends EventEmitter { setAdvancedGasFee: preferencesController.setAdvancedGasFee.bind( preferencesController, ), + setEIP1559V2Enabled: preferencesController.setEIP1559V2Enabled.bind( + preferencesController, + ), // CollectiblesController addCollectible: collectiblesController.addCollectible.bind( @@ -1246,6 +1249,9 @@ export default class MetamaskController extends EventEmitter { setCollectiblesDetectionNoticeDismissed: appStateController.setCollectiblesDetectionNoticeDismissed.bind( appStateController, ), + setEnableEIP1559V2NoticeDismissed: appStateController.setEnableEIP1559V2NoticeDismissed.bind( + appStateController, + ), // EnsController tryReverseResolveAddress: ensController.reverseResolveAddress.bind( ensController, diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index 87e0b8921..2327f7d01 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -9,6 +9,7 @@ @import 'asset-list-item/asset-list-item'; @import 'cancel-speedup-popover/index'; @import 'confirm-page-container/index'; +@import 'confirm-page-container/enableEIP1559V2-notice'; @import 'collectibles-items/index'; @import 'collectibles-tab/index'; @import 'collectible-details/index'; diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.test.js b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.test.js index 3ccdb21e9..5b86da60f 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.test.js +++ b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.test.js @@ -11,6 +11,7 @@ describe('Confirm Page Container Content', () => { provider: { type: 'test', }, + eip1559V2Enabled: false, }, }; @@ -41,8 +42,6 @@ describe('Confirm Page Container Content', () => { }); it('render ConfirmPageContainer component with simulation error', async () => { - process.env.EIP_1559_V2 = false; - const { queryByText, getByText } = renderWithProvider( , store, diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index 7767159ed..dc23050e9 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -16,6 +16,7 @@ import AdvancedGasFeePopover from '../advanced-gas-fee-popover'; import EditGasFeePopover from '../edit-gas-fee-popover/edit-gas-fee-popover'; import EditGasPopover from '../edit-gas-popover'; +import EnableEIP1559V2Notice from './enableEIP1559V2-notice'; import { ConfirmPageContainerHeader, ConfirmPageContainerContent, @@ -204,6 +205,7 @@ export default class ConfirmPageContainer extends Component { )} + {contentComponent || ( + + + + + + + ); +} + +EnableEIP1559V2Notice.propTypes = { + isFirstAlert: PropTypes.bool, +}; diff --git a/ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.js b/ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.js new file mode 100644 index 000000000..c616b7286 --- /dev/null +++ b/ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.js @@ -0,0 +1 @@ +export { default } from './enableEIP1559V2-notice'; diff --git a/ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.scss b/ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.scss new file mode 100644 index 000000000..9615bd0ac --- /dev/null +++ b/ui/components/app/confirm-page-container/enableEIP1559V2-notice/index.scss @@ -0,0 +1,33 @@ +.enableEIP1559V2-notice { + &__dialog { + position: relative; + } + + &__close-button { + background-color: transparent; + position: absolute; + right: 0; + top: 0; + + &::after { + position: absolute; + content: '\00D7'; + font-size: 29px; + font-weight: 200; + color: var(--black); + background-color: transparent; + top: 0; + right: 12px; + cursor: pointer; + } + } + + a.enableEIP1559V2-notice__link { + @include H7; + + padding: 0; + justify-content: flex-start; + font-weight: bold; + font-size: 0.75rem; + } +} diff --git a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.test.js b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.test.js index 25e070d41..5c08fe457 100644 --- a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.test.js +++ b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.test.js @@ -35,6 +35,7 @@ const render = ({ componentProps, contextProps } = {}) => { }, }, gasFeeEstimates: mockEstimates[GAS_ESTIMATE_TYPES.FEE_MARKET], + eip1559V2Enabled: true, }, }); @@ -47,14 +48,6 @@ const render = ({ componentProps, contextProps } = {}) => { }; describe('EditGasFeeButton', () => { - beforeEach(() => { - process.env.EIP_1559_V2 = true; - }); - - afterEach(() => { - process.env.EIP_1559_V2 = false; - }); - it('should render edit link with text low if low gas estimates are selected', () => { render({ contextProps: { transaction: { userFeeLevel: 'low' } } }); expect(screen.queryByText('🐢')).toBeInTheDocument(); diff --git a/ui/components/app/transaction-detail/transaction-detail.component.test.js b/ui/components/app/transaction-detail/transaction-detail.component.test.js index 5850a2a15..7a0396377 100644 --- a/ui/components/app/transaction-detail/transaction-detail.component.test.js +++ b/ui/components/app/transaction-detail/transaction-detail.component.test.js @@ -31,6 +31,7 @@ const render = ({ componentProps, contextProps } = {}) => { }, }, gasFeeEstimates: mockEstimates[GAS_ESTIMATE_TYPES.FEE_MARKET], + eip1559V2Enabled: true, }, }); @@ -50,14 +51,6 @@ const render = ({ componentProps, contextProps } = {}) => { }; describe('TransactionDetail', () => { - beforeEach(() => { - process.env.EIP_1559_V2 = true; - }); - - afterEach(() => { - process.env.EIP_1559_V2 = false; - }); - it('should render edit link with text low if low gas estimates are selected', () => { render({ contextProps: { transaction: { userFeeLevel: 'low' } } }); expect(screen.queryByText('🐢')).toBeInTheDocument(); diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.js b/ui/components/app/transaction-list-item/transaction-list-item.component.js index 0fc8e7542..cb6752309 100644 --- a/ui/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.js @@ -26,7 +26,10 @@ import { TransactionModalContextProvider, useTransactionModalContext, } from '../../../contexts/transaction-modal'; -import { checkNetworkAndAccountSupports1559 } from '../../../selectors'; +import { + checkNetworkAndAccountSupports1559, + getEIP1559V2Enabled, +} from '../../../selectors'; import { isLegacyTransaction } from '../../../helpers/utils/transactions.util'; import { useMetricEvent } from '../../../hooks/useMetricEvent'; import Button from '../../ui/button'; @@ -280,14 +283,13 @@ const TransactionListItem = (props) => { const { transactionGroup } = props; const [editGasMode, setEditGasMode] = useState(); const transaction = transactionGroup.primaryTransaction; - const EIP_1559_V2_ENABLED = - process.env.EIP_1559_V2 === true || process.env.EIP_1559_V2 === 'true'; + const eip1559V2Enabled = useSelector(getEIP1559V2Enabled); const supportsEIP1559 = useSelector(checkNetworkAndAccountSupports1559) && !isLegacyTransaction(transaction?.txParams); - const supportsEIP1559V2 = EIP_1559_V2_ENABLED && supportsEIP1559; + const supportsEIP1559V2 = eip1559V2Enabled && supportsEIP1559; return ( { const { metamask: { diff --git a/ui/hooks/gasFeeInput/test-utils.js b/ui/hooks/gasFeeInput/test-utils.js index 117d4f7cc..926cb757f 100644 --- a/ui/hooks/gasFeeInput/test-utils.js +++ b/ui/hooks/gasFeeInput/test-utils.js @@ -12,6 +12,7 @@ import { import { checkNetworkAndAccountSupports1559, getCurrentCurrency, + getEIP1559V2Enabled, getSelectedAccount, getShouldShowFiat, getPreferences, @@ -96,6 +97,7 @@ export const HIGH_FEE_MARKET_ESTIMATE_RETURN_VALUE = { export const generateUseSelectorRouter = ({ checkNetworkAndAccountSupports1559Response, shouldShowFiat = true, + eip1559V2Enabled = false, } = {}) => (selector) => { if (selector === getConversionRate) { return MOCK_ETH_USD_CONVERSION_RATE; @@ -135,6 +137,9 @@ export const generateUseSelectorRouter = ({ if (selector === checkNetworkAndAccountSupports1559) { return checkNetworkAndAccountSupports1559Response; } + if (selector === getEIP1559V2Enabled) { + return eip1559V2Enabled; + } return undefined; }; diff --git a/ui/hooks/gasFeeInput/useGasFeeInputs.js b/ui/hooks/gasFeeInput/useGasFeeInputs.js index 63b5b3fe6..3e076076a 100644 --- a/ui/hooks/gasFeeInput/useGasFeeInputs.js +++ b/ui/hooks/gasFeeInput/useGasFeeInputs.js @@ -11,6 +11,7 @@ import { GAS_FORM_ERRORS } from '../../helpers/constants/gas'; import { checkNetworkAndAccountSupports1559, getAdvancedInlineGasShown, + getEIP1559V2Enabled, } from '../../selectors'; import { hexToDecimal } from '../../helpers/utils/conversions.util'; import { isLegacyTransaction } from '../../helpers/utils/transactions.util'; @@ -93,15 +94,13 @@ export function useGasFeeInputs( minimumGasLimit = '0x5208', editGasMode = EDIT_GAS_MODES.MODIFY_IN_PLACE, ) { - const EIP_1559_V2_ENABLED = - // This is a string in unit tests but is a boolean in the browser - process.env.EIP_1559_V2 === true || process.env.EIP_1559_V2 === 'true'; + const eip1559V2Enabled = useSelector(getEIP1559V2Enabled); const supportsEIP1559 = useSelector(checkNetworkAndAccountSupports1559) && !isLegacyTransaction(transaction?.txParams); - const supportsEIP1559V2 = supportsEIP1559 && EIP_1559_V2_ENABLED; + const supportsEIP1559V2 = supportsEIP1559 && eip1559V2Enabled; // We need the gas estimates from the GasFeeController in the background. // Calling this hooks initiates polling for new gas estimates and returns the diff --git a/ui/hooks/gasFeeInput/useGasFeeInputs.test.js b/ui/hooks/gasFeeInput/useGasFeeInputs.test.js index 8b3f1e9e3..c3c722c18 100644 --- a/ui/hooks/gasFeeInput/useGasFeeInputs.test.js +++ b/ui/hooks/gasFeeInput/useGasFeeInputs.test.js @@ -324,13 +324,9 @@ describe('useGasFeeInputs', () => { useSelector.mockImplementation( generateUseSelectorRouter({ checkNetworkAndAccountSupports1559Response: true, + eip1559V2Enabled: true, }), ); - process.env.EIP_1559_V2 = true; - }); - - afterEach(() => { - process.env.EIP_1559_V2 = false; }); it('return true for fee_market transaction type', () => { diff --git a/ui/pages/confirm-approve/confirm-approve.js b/ui/pages/confirm-approve/confirm-approve.js index 20ad652d2..b8b5bb287 100644 --- a/ui/pages/confirm-approve/confirm-approve.js +++ b/ui/pages/confirm-approve/confirm-approve.js @@ -35,6 +35,7 @@ import { getRpcPrefsForCurrentProvider, getIsMultiLayerFeeNetwork, checkNetworkAndAccountSupports1559, + getEIP1559V2Enabled, } from '../../selectors'; import { useApproveTransaction } from '../../hooks/useApproveTransaction'; import { currentNetworkTxListSelector } from '../../selectors/transactions'; @@ -50,10 +51,6 @@ const isAddressLedgerByFromAddress = (address) => (state) => { return isAddressLedger(state, address); }; -// eslint-disable-next-line prefer-destructuring -const EIP_1559_V2_ENABLED = - process.env.EIP_1559_V2 === true || process.env.EIP_1559_V2 === 'true'; - export default function ConfirmApprove() { const dispatch = useDispatch(); const { id: paramsTransactionId } = useParams(); @@ -89,8 +86,8 @@ export default function ConfirmApprove() { hexTransactionTotal, } = useSelector((state) => transactionFeeSelector(state, transaction)); - const supportsEIP1559V2 = - EIP_1559_V2_ENABLED && networkAndAccountSupports1559; + const eip1559V2Enabled = useSelector(getEIP1559V2Enabled); + const supportsEIP1559V2 = eip1559V2Enabled && networkAndAccountSupports1559; const currentToken = (tokens && tokens.find(({ address }) => diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index efbd680a4..67e53af49 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -63,10 +63,6 @@ import { MIN_GAS_LIMIT_DEC } from '../send/send.constants'; import TransactionAlerts from './transaction-alerts'; -// eslint-disable-next-line prefer-destructuring -const EIP_1559_V2_ENABLED = - process.env.EIP_1559_V2 === true || process.env.EIP_1559_V2 === 'true'; - const renderHeartBeatIfNotInTest = () => process.env.IN_TEST ? null : ; @@ -147,6 +143,7 @@ export default class ConfirmTransactionBase extends Component { supportsEIP1559: PropTypes.bool, hardwareWalletRequiresConnection: PropTypes.bool, isMultiLayerFeeNetwork: PropTypes.bool, + eip1559V2Enabled: PropTypes.bool, }; state = { @@ -974,7 +971,7 @@ export default class ConfirmTransactionBase extends Component { } supportsEIP1559V2 = - EIP_1559_V2_ENABLED && + this.props.eip1559V2Enabled && this.props.supportsEIP1559 && !isLegacyTransaction(this.props.txData); diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js index 03ddd85f1..8b13a1034 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -36,6 +36,7 @@ import { getUseTokenDetection, getTokenList, getIsMultiLayerFeeNetwork, + getEIP1559V2Enabled, } from '../../selectors'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { @@ -197,6 +198,7 @@ const mapStateToProps = (state, ownProps) => { ); const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state); + const eip1559V2Enabled = getEIP1559V2Enabled(state); return { balance, @@ -248,6 +250,7 @@ const mapStateToProps = (state, ownProps) => { hardwareWalletRequiresConnection, isMultiLayerFeeNetwork, chainId, + eip1559V2Enabled, }; }; diff --git a/ui/pages/settings/experimental-tab/experimental-tab.component.js b/ui/pages/settings/experimental-tab/experimental-tab.component.js index 1dc9cb549..212d8bbb5 100644 --- a/ui/pages/settings/experimental-tab/experimental-tab.component.js +++ b/ui/pages/settings/experimental-tab/experimental-tab.component.js @@ -14,7 +14,9 @@ export default class ExperimentalTab extends PureComponent { useCollectibleDetection: PropTypes.bool, setUseCollectibleDetection: PropTypes.func, setOpenSeaEnabled: PropTypes.func, - openSeaEnabled: PropTypes.func, + openSeaEnabled: PropTypes.bool, + eip1559V2Enabled: PropTypes.bool, + setEIP1559V2Enabled: PropTypes.func, }; renderTokenDetectionToggle() { @@ -134,12 +136,63 @@ export default class ExperimentalTab extends PureComponent { ); } + renderEIP1559V2EnabledToggle() { + const EIP_1559_V2_ENABLED = + // This is a string in unit tests but is a boolean in the browser + process.env.EIP_1559_V2 === true || process.env.EIP_1559_V2 === 'true'; + if (!EIP_1559_V2_ENABLED) { + return null; + } + const { t } = this.context; + const { eip1559V2Enabled, setEIP1559V2Enabled } = this.props; + + return ( +
+
+ {t('enableEIP1559V2')} +
+ {t('enableEIP1559V2Description', [ + + {t('learnMoreUpperCase')} + , + ])} +
+
+
+
+ { + this.context.metricsEvent({ + eventOpts: { + category: 'Settings', + action: 'Enabled/Disable OpenSea', + name: 'Enabled/Disable OpenSea', + }, + }); + setEIP1559V2Enabled(!value); + }} + offLabel={t('off')} + onLabel={t('on')} + /> +
+
+
+ ); + } + render() { return (
{this.renderTokenDetectionToggle()} {this.renderOpenSeaEnabledToggle()} {this.renderCollectibleDetectionToggle()} + {this.renderEIP1559V2EnabledToggle()}
); } diff --git a/ui/pages/settings/experimental-tab/experimental-tab.container.js b/ui/pages/settings/experimental-tab/experimental-tab.container.js index ac26f10ab..195d01e88 100644 --- a/ui/pages/settings/experimental-tab/experimental-tab.container.js +++ b/ui/pages/settings/experimental-tab/experimental-tab.container.js @@ -5,11 +5,13 @@ import { setUseTokenDetection, setUseCollectibleDetection, setOpenSeaEnabled, + setEIP1559V2Enabled, } from '../../../store/actions'; import { getUseTokenDetection, getUseCollectibleDetection, getOpenSeaEnabled, + getEIP1559V2Enabled, } from '../../../selectors'; import ExperimentalTab from './experimental-tab.component'; @@ -18,6 +20,7 @@ const mapStateToProps = (state) => { useTokenDetection: getUseTokenDetection(state), useCollectibleDetection: getUseCollectibleDetection(state), openSeaEnabled: getOpenSeaEnabled(state), + eip1559V2Enabled: getEIP1559V2Enabled(state), }; }; @@ -27,6 +30,7 @@ const mapDispatchToProps = (dispatch) => { setUseCollectibleDetection: (val) => dispatch(setUseCollectibleDetection(val)), setOpenSeaEnabled: (val) => dispatch(setOpenSeaEnabled(val)), + setEIP1559V2Enabled: (val) => dispatch(setEIP1559V2Enabled(val)), }; }; diff --git a/ui/pages/settings/index.scss b/ui/pages/settings/index.scss index b10a15b37..78b4af992 100644 --- a/ui/pages/settings/index.scss +++ b/ui/pages/settings/index.scss @@ -205,6 +205,10 @@ color: var(--dusty-gray); padding-top: 5px; + + a { + color: var(--Blue-500); + } } &__content-item-col { diff --git a/ui/pages/swaps/fee-card/fee-card.test.js b/ui/pages/swaps/fee-card/fee-card.test.js index 27dba700d..16f43da8d 100644 --- a/ui/pages/swaps/fee-card/fee-card.test.js +++ b/ui/pages/swaps/fee-card/fee-card.test.js @@ -14,6 +14,7 @@ import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network'; import { checkNetworkAndAccountSupports1559, + getEIP1559V2Enabled, getPreferences, getSelectedAccount, } from '../../../selectors'; @@ -133,7 +134,6 @@ describe('FeeCard', () => { }); it('renders the component with EIP-1559 V2 enabled', () => { - process.env.EIP_1559_V2 = true; useGasFeeEstimates.mockImplementation(() => ({ gasFeeEstimates: {} })); useSelector.mockImplementation((selector) => { if (selector === getPreferences) { @@ -141,6 +141,9 @@ describe('FeeCard', () => { useNativeCurrencyAsPrimaryCurrency: true, }; } + if (selector === getEIP1559V2Enabled) { + return true; + } if (selector === getSelectedAccount) { return { balance: '0x440aa47cc2556', @@ -180,6 +183,5 @@ describe('FeeCard', () => { expect( document.querySelector('.fee-card__top-bordered-row'), ).toMatchSnapshot(); - process.env.EIP_1559_V2 = false; }); }); diff --git a/ui/pages/swaps/view-quote/view-quote.js b/ui/pages/swaps/view-quote/view-quote.js index 47dbaaf6e..d2fb50d93 100644 --- a/ui/pages/swaps/view-quote/view-quote.js +++ b/ui/pages/swaps/view-quote/view-quote.js @@ -46,6 +46,7 @@ import { isHardwareWallet, getHardwareWalletType, checkNetworkAndAccountSupports1559, + getEIP1559V2Enabled, } from '../../../selectors'; import { getNativeCurrency, getTokens } from '../../../ducks/metamask/metamask'; @@ -103,15 +104,12 @@ import CountdownTimer from '../countdown-timer'; import SwapsFooter from '../swaps-footer'; import ViewQuotePriceDifference from './view-quote-price-difference'; -// eslint-disable-next-line prefer-destructuring -const EIP_1559_V2_ENABLED = - process.env.EIP_1559_V2 === true || process.env.EIP_1559_V2 === 'true'; - export default function ViewQuote() { const history = useHistory(); const dispatch = useDispatch(); const t = useContext(I18nContext); const metaMetricsEvent = useContext(MetaMetricsContext); + const eip1559V2Enabled = useSelector(getEIP1559V2Enabled); const [dispatchedSafeRefetch, setDispatchedSafeRefetch] = useState(false); const [submitClicked, setSubmitClicked] = useState(false); @@ -689,8 +687,7 @@ export default function ViewQuote() { }, }; - const supportsEIP1559V2 = - EIP_1559_V2_ENABLED && networkAndAccountSupports1559; + const supportsEIP1559V2 = eip1559V2Enabled && networkAndAccountSupports1559; return ( { + dispatch(showLoadingIndication()); + log.debug(`background.setEIP1559V2Enabled`); + try { + await promisifiedBackground.setEIP1559V2Enabled(val); + } finally { + dispatch(hideLoadingIndication()); + } + }; +} + export function setIpfsGateway(val) { return (dispatch) => { dispatch(showLoadingIndication()); @@ -3100,6 +3112,10 @@ export function setCollectiblesDetectionNoticeDismissed() { return promisifiedBackground.setCollectiblesDetectionNoticeDismissed(true); } +export function setEnableEIP1559V2NoticeDismissed() { + return promisifiedBackground.setEnableEIP1559V2NoticeDismissed(true); +} + // QR Hardware Wallets export async function submitQRHardwareCryptoHDKey(cbor) { await promisifiedBackground.submitQRHardwareCryptoHDKey(cbor);