feat(transaction-controller): support saved gas fee levels - #8993
Merged
Merged
Conversation
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
2 times, most recently
from
June 3, 2026 16:45
83cc6ba to
ba63c2b
Compare
4 of 7 tasks
pedronfigueiredo
marked this pull request as ready for review
June 8, 2026 13:23
pedronfigueiredo
temporarily deployed
to
default-branch
June 8, 2026 13:24 — with
GitHub Actions
Inactive
vinistevam
previously approved these changes
Jun 9, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jun 9, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jun 11, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jun 11, 2026
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
June 11, 2026 09:11
ba63c2b to
b620f8f
Compare
Contributor
Author
|
@metamaskbot publish-preview |
Contributor
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
June 11, 2026 11:50
b620f8f to
a8ca11c
Compare
Contributor
Author
|
@metamaskbot publish-preview |
Contributor
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
June 11, 2026 12:12
a8ca11c to
1a8241c
Compare
Contributor
Author
|
@metamaskbot publish-preview |
Contributor
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
June 12, 2026 16:48
1a8241c to
69d8cef
Compare
dan437
previously approved these changes
Jun 15, 2026
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
July 3, 2026 10:49
69d8cef to
2ecedf3
Compare
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
July 7, 2026 12:49
7c33a6f to
0d8540e
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0d8540e. Configure here.
dan437
previously approved these changes
Jul 9, 2026
…even when a level is set Revert an unrelated edit to the already-released 68.0.0 changelog entry that crept in from a prior rebase, and fix getUserFeeLevel to return CUSTOM whenever savedGasFees includes an explicit maxBaseFee, priorityFee, or gasPrice override, even if a level is also present. Without this, GasFeePoller would treat the transaction as fully level-tracked and silently overwrite the custom override on the next automatic gas fee update. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…eeLevel when actually applied Cursor Bugbot flagged that a saved gas fee level (e.g. 'high') could be reflected in txMeta.userFeeLevel even when the resolved fee wasn't actually derived from that level - specifically when the gas fee flow returns a flat eth_gasPrice-type estimate, or when the flow throws and a raw eth_gasPrice RPC fallback is used. In both cases there are no per-level values to select from, so labelling userFeeLevel with the saved level was misleading. Track whether the suggested fee was actually derived from a per-level lookup and only preserve the saved level in userFeeLevel when it was; otherwise fall back to CUSTOM.
pedronfigueiredo
force-pushed
the
pnf/save-custom-gas-settings
branch
from
July 10, 2026 12:52
ccbd85a to
7435162
Compare
dan437
previously approved these changes
Jul 10, 2026
…eased 68.3.0 section to Unreleased The rebase auto-merge placed our saved-gas-fee-levels changelog entry under the already-released [68.3.0] section instead of [Unreleased], since that's where the surrounding context lines used to live before 68.3.0 was cut. Move it back to [Unreleased].
pedronfigueiredo
enabled auto-merge
July 10, 2026 13:08
dan437
approved these changes
Jul 10, 2026
Closed
2 tasks done
DDDDDanica
pushed a commit
to MetaMask/metamask-extension
that referenced
this pull request
Jul 14, 2026
## **Description** Re-introduces saved gas fee preferences for confirmations. Users can save low, medium, high, or custom gas settings from the gas edit modal and reuse that preference for future send or dapp transactions on the same account and chain. Dapp-proposed fees still take precedence when present, and MM Pay/Swaps flows are excluded. Related PRs: - MetaMask/core#8993 - MetaMask/metamask-mobile#31649 ## **Changelog** CHANGELOG entry: Added the ability to save gas fee preferences per account and network. ## **Related issues** Fixes: ## **Manual testing steps** 1. Start a send transaction on account 1 and network A. 2. Open the gas edit modal and select low, medium, high, or custom. 3. Save the preference and open another transaction on account 1 and network A. 4. Confirm the saved gas preference is presented by default. 5. Switch to another account or network and confirm the saved preference is not reused. 6. Open a dapp transaction with proposed gas fees and confirm the dapp-proposed fees take precedence. <!-- ## **Screenshots/Recordings** ### **Before** ### **After** --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes persisted preference shape and transaction default gas behavior; migration clears legacy chain-scoped fees, which can reset saved settings for some users. > > **Overview** > Reintroduces **saved gas fee preferences** scoped by **account and chain**, so confirmations can default to the user’s last low/medium/high/custom choice for that sender on that network. > > **Preferences and persistence:** `advancedGasFee` moves from chain-only to **chain → account →** `AdvancedGasFeePreferences` (including `userFeeLevel`). `setAdvancedGasFee` requires `account`, normalizes addresses, supports per-account clear when `gasFeePreferences` is omitted, and typed prefs replace loose string maps. UI adds `usePersistGasFeePreference` and wires save/select paths in gas modals and estimate hooks; `getAdvancedGasFeeValues` reads the **selected account** on the current chain. > > **Transaction wiring:** `getSavedGasFees` takes full `TransactionMeta`, looks up prefs by `from` + `chainId`, maps to `SavedGasFees`, and returns nothing for **MetaMask Pay** transactions. Bumps `@metamask/transaction-controller` to **^69.0.0** and `@metamask/wallet` to **^7.0.1**. > > **Migration 218:** Converts or drops legacy chain-scoped fee blobs; keeps valid account-scoped data (lowercase keys); clears unmigratable legacy/malformed entries. Fixtures and mock state move to version **218**. > > **Metrics:** Gas metrics add `gas_fee_presented` from default estimates and share `dappSuggested` → `dapp_proposed` normalization for selected vs presented levels. > > LavaMoat policy updates are dependency graph alignment for nested `transaction-controller` copies. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9310301. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
pull Bot
pushed a commit
to Reality2byte/metamask-extension
that referenced
this pull request
Jul 14, 2026
## **Description** Re-introduces saved gas fee preferences for confirmations. Users can save low, medium, high, or custom gas settings from the gas edit modal and reuse that preference for future send or dapp transactions on the same account and chain. Dapp-proposed fees still take precedence when present, and MM Pay/Swaps flows are excluded. Related PRs: - MetaMask/core#8993 - MetaMask/metamask-mobile#31649 ## **Changelog** CHANGELOG entry: Added the ability to save gas fee preferences per account and network. ## **Related issues** Fixes: ## **Manual testing steps** 1. Start a send transaction on account 1 and network A. 2. Open the gas edit modal and select low, medium, high, or custom. 3. Save the preference and open another transaction on account 1 and network A. 4. Confirm the saved gas preference is presented by default. 5. Switch to another account or network and confirm the saved preference is not reused. 6. Open a dapp transaction with proposed gas fees and confirm the dapp-proposed fees take precedence. <!-- ## **Screenshots/Recordings** ### **Before** ### **After** --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes persisted preference shape and transaction default gas behavior; migration clears legacy chain-scoped fees, which can reset saved settings for some users. > > **Overview** > Reintroduces **saved gas fee preferences** scoped by **account and chain**, so confirmations can default to the user’s last low/medium/high/custom choice for that sender on that network. > > **Preferences and persistence:** `advancedGasFee` moves from chain-only to **chain → account →** `AdvancedGasFeePreferences` (including `userFeeLevel`). `setAdvancedGasFee` requires `account`, normalizes addresses, supports per-account clear when `gasFeePreferences` is omitted, and typed prefs replace loose string maps. UI adds `usePersistGasFeePreference` and wires save/select paths in gas modals and estimate hooks; `getAdvancedGasFeeValues` reads the **selected account** on the current chain. > > **Transaction wiring:** `getSavedGasFees` takes full `TransactionMeta`, looks up prefs by `from` + `chainId`, maps to `SavedGasFees`, and returns nothing for **MetaMask Pay** transactions. Bumps `@metamask/transaction-controller` to **^69.0.0** and `@metamask/wallet` to **^7.0.1**. > > **Migration 218:** Converts or drops legacy chain-scoped fee blobs; keeps valid account-scoped data (lowercase keys); clears unmigratable legacy/malformed entries. Fixtures and mock state move to version **218**. > > **Metrics:** Gas metrics add `gas_fee_presented` from default estimates and share `dappSuggested` → `dapp_proposed` normalization for selected vs presented levels. > > LavaMoat policy updates are dependency graph alignment for nested `transaction-controller` copies. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9310301. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
pull Bot
pushed a commit
to Reality2byte/metamask-mobile
that referenced
this pull request
Jul 14, 2026
## Summary - Persist custom gas fee settings from the advanced gas modals. - Read saved gas preferences when building fee options for send confirmations. - Wire mobile PreferencesController and TransactionController integration for saved gas fee preferences. ## Related PRs - MetaMask/metamask-extension#43317 - MetaMask/core#8993 ## Testing - `yarn jest app/components/Views/confirmations/components/modals/advanced-eip1559-modal/advanced-eip1559-modal.test.tsx app/components/Views/confirmations/components/modals/advanced-gas-price-modal/advanced-gas-price-modal.test.tsx app/components/Views/confirmations/hooks/gas/useGasFeeEstimateLevelOptions.test.ts app/components/Views/confirmations/hooks/gas/useGasPriceEstimateOption.test.ts app/components/Views/confirmations/hooks/gas/usePersistGasFeePreference.test.ts app/core/Engine/controllers/preferences-controller-init.test.ts app/core/Engine/controllers/transaction-controller/metrics_properties/gas.test.ts app/core/Engine/controllers/transaction-controller/transaction-controller-init.test.ts` (8 suites, 78 tests). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how default and custom gas fees are stored and applied for sends; incorrect lookup or validation could affect fee defaults, though saves are gated on complete custom values and covered by new tests. > > **Overview** > Adds **per-account, per-chain persistence** for gas choices so confirmations can reuse the user’s last fee level or custom values. > > On save, confirmation gas flows call **`usePersistGasFeePreference`**, which writes to **`PreferencesController.setAdvancedGasFee`** (`advancedGasFee` is persisted state). Advanced EIP-1559 and legacy gas price modals share **`useAdvancedGasFeeModal`**, which blocks save when custom fees are incomplete and persists mapped preferences (e.g. max base / priority fee). Preset estimate levels and gas-price estimate options persist the selected **`userFeeLevel`** as well. > > **`TransactionController`** is upgraded to **69.0.0** and receives a **`getSavedGasFees`** hook that reads those preferences for the transaction’s `from` address and chain. Gas metrics now report **`dapp_proposed`** when **`UserFeeLevel.DAPP_SUGGESTED`** is selected. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3041ea6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This was referenced Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Explanation
This expands transaction-controller saved gas fee handling so clients can resolve saved preferences with full transaction metadata instead of only a chain ID. That lets consumers key saved gas settings by both chain and account while keeping the controller API responsible for applying saved fees.
The saved gas payload now supports gas fee estimate levels (
low,medium,high) and legacy customgasPricevalues in addition to EIP-1559 custom fee values. Saved estimate levels reuse the current gas fee flow estimate for the saved level; custom values override only the specific saved fields.Transactions that already include gas fee params continue to use those initial params, so dapp-proposed fees keep precedence over saved preferences. Swap transaction types continue to skip saved gas fees.
References
Related PRs:
Checklist
Note
Medium Risk
Breaking callback signature and changed gas-fee precedence logic can misprice dApp txs or break extension/mobile until consumers update; changes are confined to gas fee application paths with substantial test coverage.
Overview
Breaking change:
getSavedGasFeesnow receives fullTransactionMetainstead of chain ID so clients can key saved preferences by chain and account. TheSavedGasFeesshape adds optional estimatelevel, legacygasPrice, and makes EIP-1559 fields optional.Gas fee application in
updateGasFeesnow skips saved lookup when the tx already has initial gas params (dapp fees win), still skips internal txs, and can pick low/medium/high from the current gas fee flow when only a level is saved. CustommaxBaseFee/priorityFee/gasPriceoverride specific fields;userFeeLevelstays on the saved level only when pricing is truly level-derived (otherwisecustom).Deprecated incoming transaction constructor options and restored no-op
startIncomingTransactionPolling/stopIncomingTransactionPollingfor backward compatibility, with tests.Reviewed by Cursor Bugbot for commit a173b00. Bugbot is set up for automated code reviews on this repo. Configure here.