Skip to content

fix(transaction-controller): harden gas fee token preflight - #10071

Merged
jpuri merged 4 commits into
mainfrom
fix/gas-fee-token-preflight-predict-claim
Sep 7, 2026
Merged

fix(transaction-controller): harden gas fee token preflight#10071
jpuri merged 4 commits into
mainfrom
fix/gas-fee-token-preflight-predict-claim

Conversation

@jpuri

@jpuri jpuri commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Explanation

Predict claim on Mobile (Polygon Safe wallets) can fail during gas-station preflight when a gas fee token (e.g. pUSD) is pre-selected but Sentinel returns an empty gasFeeTokens list and native POL is insufficient.

Two controller bugs contribute to confusing failures and bad publish fallbacks:

  1. isNativeBalanceSufficientForGas treated missing maxFeePerGas/gasPrice as zero, so gas × 0 = 0 made every wallet look able to pay native gas. That could clear selectedGasFeeToken while gas estimates were still in flight (common with skipInitialGasEstimate), leading to publishes with intrinsic gas too low: gas 0.
  2. checkGasFeeTokenBeforePublish set isExternalSign: true and cleared nonce before validating the selected token. When validation failed (Gas fee token not found and insufficient native balance), transaction metadata could remain in external-sign mode even though signing was never completed.

This PR hardens both paths:

  • balance.ts: return insufficient when gas or fee fields are unset, so pre-selected gas fee tokens are not cleared prematurely.
  • gas-fee-tokens.ts: only enable external sign after the selected token is confirmed in freshly fetched gasFeeTokens; on failure, persist refreshed tokens but reset isExternalSign to false before throwing.

No breaking API changes. Scope is limited to @metamask/transaction-controller publish-time gas-fee-token gating.

References

https://consensyssoftware.atlassian.net/browse/CONF-1725

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes publish-path balance and gas-fee-token validation; incorrect behavior could block valid publishes or alter signing mode, but scope is limited to preflight gating with targeted tests.

Overview
Hardens publish-time gas fee token gating in @metamask/transaction-controller so pre-selected tokens are not dropped and external-sign state is not left inconsistent when preflight fails.

isNativeBalanceSufficientForGas now returns insufficient when gas or fee fields (maxFeePerGas / gasPrice) are unset, instead of treating missing values as zero. That stops in-flight gas estimates (e.g. with skipInitialGasEstimate) from looking like free native gas and clearing a selected gas fee token too early.

checkGasFeeTokenBeforePublish only sets isExternalSign: true and clears nonce after confirming the selected token appears in freshly fetched gasFeeTokens. If the token is missing, it persists the refreshed token list, resets isExternalSign to false, then throws—avoiding metadata stuck in external-sign mode after a failed preflight.

Tests and an Unreleased changelog entry cover the new behavior.

Reviewed by Cursor Bugbot for commit 3556002. Bugbot is set up for automated code reviews on this repo. Configure here.

@jpuri
jpuri requested review from a team as code owners September 2, 2026 04:58
@jpuri
jpuri marked this pull request as draft September 2, 2026 04:58
@jpuri
jpuri marked this pull request as ready for review September 2, 2026 05:06
@jpuri
jpuri enabled auto-merge September 2, 2026 05:06
@OGPoyraz
OGPoyraz removed their request for review September 3, 2026 10:00
@matthewwalsh0
matthewwalsh0 requested a review from dan437 September 3, 2026 11:01
dan437
dan437 previously approved these changes Sep 4, 2026
Avoid treating native balance as sufficient when gas estimates are still
pending, and do not leave isExternalSign enabled when the selected gas fee
token fails preflight validation.
@jpuri
jpuri force-pushed the fix/gas-fee-token-preflight-predict-claim branch from 447935c to 3556002 Compare September 7, 2026 04:38
@jpuri
jpuri requested a review from dan437 September 7, 2026 06:36
@jpuri
jpuri added this pull request to the merge queue Sep 7, 2026
Merged via the queue into main with commit 00efaa8 Sep 7, 2026
140 checks passed
@jpuri
jpuri deleted the fix/gas-fee-token-preflight-predict-claim branch September 7, 2026 08:55
@cursor cursor Bot mentioned this pull request Sep 7, 2026
4 tasks
github-merge-queue Bot pushed a commit that referenced this pull request Sep 7, 2026
## Explanation

Release @metamask/transaction-controller.

## References

https://consensyssoftware.atlassian.net/browse/CONF-1725

## Checklist

- [X] I've updated the test suite for new or updated code as appropriate
- [X] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [X] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [X] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> The release propagates a transaction-controller fix in gas preflight
and external-sign handling, which affects signing and fee flows across
many packages even though the diff is mostly version bumps.
> 
> **Overview**
> This release cuts **`@metamask/transaction-controller` `69.8.1`** and
rolls it through the monorepo as **`1238.0.0`**.
> 
> The patch fixes **gas fee token preflight**: pending gas estimates are
no longer treated as zero-cost native gas, and **`isExternalSign` is
cleared when preflight validation fails**
([#10071](#10071)). Dependent
packages (assets, bridge, wallet, phishing, smart transactions, and
others) only bump their **`@metamask/transaction-controller`** range to
**`^69.8.1`** and record the bump in their changelogs; **`yarn.lock`**
is updated accordingly. There is no new application logic outside
**`transaction-controller`** in this diff.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a795ef5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants