Repository navigation
feat(transaction-controller): add approval-time sponsorship/signing hooks - #10109
Merged
pedronfigueiredo merged 4 commits intoSep 22, 2026
Conversation
pedronfigueiredo
temporarily deployed
to
default-branch
September 4, 2026 10:26 — with
GitHub Actions
Inactive
jpuri
previously approved these changes
Sep 4, 2026
matthewwalsh0
requested changes
Sep 7, 2026
pedronfigueiredo
force-pushed
the
pnf/canonical-transaction-approval-preparation-handoff-implementation
branch
2 times, most recently
from
September 10, 2026 09:58
c78867c to
bd526cb
Compare
pedronfigueiredo
force-pushed
the
pnf/canonical-transaction-approval-preparation-handoff-implementation
branch
from
September 16, 2026 09:28
c6c60e0 to
b0c25e6
Compare
matthewwalsh0
requested changes
Sep 21, 2026
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ 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 83fe8f8. Configure here.
matthewwalsh0
previously approved these changes
Sep 21, 2026
pedronfigueiredo
removed this pull request from the merge queue due to a manual request
Sep 21, 2026
matthewwalsh0
previously approved these changes
Sep 22, 2026
pedronfigueiredo
force-pushed
the
pnf/canonical-transaction-approval-preparation-handoff-implementation
branch
from
September 22, 2026 14:23
a352664 to
71e88f2
Compare
OGPoyraz
approved these changes
Sep 22, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Sep 22, 2026
pedronfigueiredo
deleted the
pnf/canonical-transaction-approval-preparation-handoff-implementation
branch
September 22, 2026 15:28
pull Bot
pushed a commit
to Reality2byte/core
that referenced
this pull request
Sep 23, 2026
## Explanation Release `1275.0.0` with a **major** version bump for `@metamask/transaction-controller` and a **minor** version bump for `@metamask/transaction-pay-controller`. - **`@metamask/transaction-controller`** `70.1.0` → `71.0.0` (major) - **`@metamask/transaction-pay-controller`** `29.0.2` → `29.1.0` (minor) ### `@metamask/transaction-controller@71.0.0` **Breaking:** Move sponsorship and signing decisions to optional approval-time `isSponsored` and `shouldSign` hooks ([MetaMask#10109](MetaMask#10109)) - The hooks default to non-sponsored and local signing when omitted. Sponsored transactions skip the `shouldSign` hook and local signing, while transactions that skip local signing retain an existing nonce and require a publish hook. - `isGasFeeSponsored` and `isExternalSign` remain in the public types as deprecated compatibility properties but no longer control the transaction lifecycle; `isGasFeeSponsored` remains available as migration metadata. - Add `TransactionMeta.isGasFeeSponsoredAvailable` and refresh it during approval preparation when simulation is enabled so sponsorship hooks receive current availability without overriding simulation preferences. Other changes: - Add `membershipSubscription` transaction type ([MetaMask#10340](MetaMask#10340)) - Bump `bn.js` from `^5.2.1` to `^5.2.5` ([MetaMask#10362](MetaMask#10362)) ### `@metamask/transaction-pay-controller@29.1.0` - Support subsidized max Relay deposits using atomic `EXACT_OUTPUT` quotes with transaction calls embedded, gated by `payStrategies.relay.atomicMaxEnabled` ([MetaMask#10224](MetaMask#10224)) - Bump `bn.js` from `^5.2.1` to `^5.2.5` ([MetaMask#10362](MetaMask#10362)) - Bump `immer` from `^9.0.6` to `^9.0.21` ([MetaMask#10331](MetaMask#10331)) ### Dependency updates 16 packages had their `@metamask/transaction-controller` dependency range updated to `^71.0.0` with `package.json` changes under this release branch. Changelog entries for those packages will be generated by commenting `@metamaskbot update-changelogs` on this PR. ## References - [MetaMask#10109](MetaMask#10109) — Move sponsorship and signing decisions to optional approval-time hooks - [MetaMask#10340](MetaMask#10340) — Add `membershipSubscription` transaction type - [MetaMask#10224](MetaMask#10224) — Support subsidized max Relay deposits using atomic `EXACT_OUTPUT` quotes ## 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 - [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) - [ ] 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] > **High Risk** > The major transaction-controller release changes core transaction approval, sponsorship, and signing behavior across many downstream packages that depend on it. > > **Overview** > Release **`1275.0.0`** cuts published versions for **`@metamask/transaction-controller`** `71.0.0` (major) and **`@metamask/transaction-pay-controller`** `29.1.0` (minor), and bumps the monorepo root version accordingly. > > The transaction-controller release documents **breaking** approval-time behavior: sponsorship and signing now flow through optional **`isSponsored`** / **`shouldSign`** hooks instead of **`isGasFeeSponsored`** / **`isExternalSign`**, plus a new **`membershipSubscription`** transaction type. This PR mostly **propagates** that major by setting dependent packages’ `@metamask/transaction-controller` ranges to **`^71.0.0`**, updating **`yarn.lock`**, and recording bump entries in package changelogs (including transaction-pay’s dependency bump under `29.1.0`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b93ad54. 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: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This was referenced Sep 24, 2026
Merged
pull Bot
pushed a commit
to Reality2byte/core
that referenced
this pull request
Sep 24, 2026
…Mask#10420) ## Summary Revert MetaMask#10109 using `git revert` (merge commit `3cc3f5e74cefa3da0287d2f377c4fbc802f822a8`). This restores the previous transaction approval, sponsorship, nonce, signing, and publication behavior and removes the approval-time `isSponsored` / `shouldSign` hooks and `isGasFeeSponsoredAvailable` field. The only revert conflict was in the transaction-controller changelog. The 71.0.0 entry was retained as historical documentation for the already-published release; no unrelated changelog changes were made. ## Validation - `yarn workspace @metamask/transaction-controller run test` - `yarn build` - `yarn workspace @metamask/transaction-controller run changelog:validate` - Focused ESLint and Prettier checks on changed TypeScript files - `git diff --cached --check` before committing ## Coordination / risk This reverses a published public API and transaction lifecycle behavior. Confirm whether Extension ([#46060](MetaMask/metamask-extension#46060)) and Mobile ([#35754](MetaMask/metamask-mobile#35754)) depend on the hooks, and coordinate any necessary client changes before merging. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Reverts a published transaction lifecycle and public hook API; clients using `isSponsored`/`shouldSign` or `isGasFeeSponsoredAvailable` must change before merge. > > **Overview** > **Reverts approval-time `isSponsored` / `shouldSign` hooks** and the `isGasFeeSponsoredAvailable` field, restoring the prior sponsorship and signing model driven by transaction metadata and simulation. > > On approval, the controller again **always reserves a nonce and runs the sign path** (unless `isExternalSign`), with `beforeSign` folded into `#signTransaction` instead of running before hook-based policy. Sponsored / externally signed flows use **`isGasFeeSponsored` and `isExternalSign`** set from add-transaction options or from `getGasFeeTokens` (`isGasFeeSponsored` from simulation sponsorship), which skips local signing and can clear the nonce via `getNextNonce` and `checkGasFeeTokenBeforePublish`. > > **Gas fee token plumbing** renames sponsorship availability to `isGasFeeSponsored`, drops approval-time gas-fee refresh in `#prepareTransactionBeforeApproval`, and restores publishing that may broadcast even when `rawTx` is empty. **`hooks` is required** on controller options (no optional hook defaults for sponsorship/signing). Tests drop hook lifecycle coverage and add assertions for the restored metadata behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6b6ccd4. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
pull Bot
pushed a commit
to Reality2byte/core
that referenced
this pull request
Sep 24, 2026
## Explanation Prepare monorepo release **1285.0.0** for `@metamask/transaction-controller@72.0.0` and all **19 direct workspace dependents**. `perps-controller` is now included for the consumer-facing HIP-3 snapshot fix merged in MetaMask#10429, not merely for its development dependencies; `earn-controller` also has an existing production dependency bump. This branch incorporates current `main`, including MetaMask#10429 and MetaMask#10419. No source-code changes are introduced by this PR relative to current `main`. ### Versions in this release | Package | Version | Rationale | | --- | --- | --- | | `transaction-controller` | **72.0.0** | Breaking revert of approval-time sponsorship/signing hooks (MetaMask#10420) | | `subscription-controller` | **10.0.0** | Existing Unreleased breaking subscription type changes (MetaMask#10305, MetaMask#10416) | | `wallet` | **15.0.0** | Its exported default instance/state types expose the breaking subscription and transaction-controller changes | | `transaction-pay-controller` | **29.2.0** | Additional supported pay-strategy flows and server-quote behavior (MetaMask#10342) | | `assets-controller` | 16.1.1 | Dependency updates and previously merged fixes | | `assets-controllers` | 112.0.3 | Dependency updates | | `bridge-controller` | 81.3.1 | Dependency updates | | `bridge-status-controller` | 76.3.1 | Dependency updates | | `client-utils` | 3.0.3 | Dependency update | | `earn-controller` | 13.0.1 | Existing production `account-tree-controller` bump; transaction-controller is dev-only here | | `eip-5792-middleware` | 4.0.1 | Dependency updates | | `gator-permissions-controller` | 6.0.1 | Dependency updates | | `money-account-utils` | 2.0.1 | Dependency updates | | `network-enablement-controller` | 7.0.1 | Dependency updates | | `perps-controller` | **18.0.1** | Fix Terminal v3 HIP-3 snapshot validation (MetaMask#10429); patch bump | | `phishing-controller` | 18.1.1 | Dependency update | | `profile-metrics-controller` | 5.1.1 | Dependency updates | | `shield-controller` | 7.0.2 | Dependency updates | | `smart-transactions-controller` | 27.0.2 | Dependency updates | | `user-operation-controller` | 42.0.1 | Dependency updates | Dependent packages have their Unreleased changelog entries moved to their new release sections. Additional *non-released* transitive dependents receive compatible workspace ranges (`money-account-upgrade-controller`, `network-connection-banner-controller`, `signature-controller`, and unpublished `wallet-cli`); the three published packages receive Unreleased dependency changelog entries. `yarn.lock` is synchronized. Changes to `perps-controller`'s development dependencies are intentionally omitted from its changelog. **Coordination before merge:** The transaction-controller hook revert and the subscription-controller's existing breaking type changes affect consumers. Confirm Extension and Mobile migrations before publishing these three major versions. This is a release candidate, not a published release. ## References - Breaking revert: MetaMask#10420; original published API: MetaMask#10109. - EIP-7702 performance change: MetaMask#10397. - Perps HIP-3 snapshot fix: MetaMask#10429. - Subscription breaking changes: MetaMask#10305, MetaMask#10416. - Client adoption PRs to coordinate: [Extension #46060](MetaMask/metamask-extension#46060), [Mobile #35754](MetaMask/metamask-mobile#35754). They adopt the removed hooks; they are **not** migrations for this revert. ## Validation - `yarn build` - `yarn workspace @metamask/transaction-controller run test` - `yarn workspace @metamask/subscription-controller run test` - `yarn workspace @metamask/transaction-pay-controller run test` - `yarn workspace @metamask/wallet run test` - `yarn workspace @metamask/perps-controller run test` (after incorporating MetaMask#10429) - `yarn changelog:validate`, `yarn constraints`, `yarn install --immutable`, `yarn dedupe --check` - `yarn lint:dependencies` (after removing stale generated bridge-controller `dist` output) - `git diff --check` ## Checklist - [x] Changelogs describe the breaking changes in transaction-controller, subscription-controller, and wallet. - [x] Direct workspace dependents are included, with perps now having a consumer-facing fix (MetaMask#10429). - [ ] Extension and Mobile consumers have been coordinated for these breaking changes before merging this release. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Publishes breaking majors for transaction signing/sponsorship and subscription types that require coordinated Extension/Mobile migrations before consumers upgrade `@metamask/wallet` or `@metamask/transaction-controller`. > > **Overview** > Prepares **monorepo release 1285.0.0** by bumping package versions, moving Unreleased changelog notes into release sections, aligning workspace dependency ranges, and refreshing `yarn.lock`. There are **no application source edits** in this diff—only release metadata for work already on `main`. > > The release centers on **`@metamask/transaction-controller@72.0.0`**, which **reverts** the approval-time `isSponsored` / `shouldSign` hooks in favor of metadata-driven **`isGasFeeSponsored`** and **`isExternalSign`**, drops related exports and `isGasFeeSponsoredAvailable`, and again **requires** a `hooks` object (use `hooks: {}` when empty). **`@metamask/subscription-controller@10.0.0`** ships existing breaking subscription/payment-token type changes (optional period fields, vault-share detection via `isVaultShareToken`, crypto payment failure types). **`@metamask/wallet@15.0.0`** bumps those majors plus related dependents. > > Nineteen direct workspace dependents get compatible semver bumps (mostly patch dependency realignments to `@metamask/transaction-controller@^72.0.0`). Notable published notes include **`@metamask/perps-controller@18.0.1`** (HIP-3 Terminal snapshot validation fix) and **`@metamask/transaction-pay-controller@29.2.0`** (server pay-strategy quoting/submit fixes). Unpublished/transitive packages (`wallet-cli`, `money-account-upgrade-controller`, etc.) get range updates without always cutting new versions. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6017d49. 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: Baptiste Marchand <75846779+baptiste-marchand@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

Related pull requests
Summary
isSponsoredandshouldSignhooks toTransactionController, with named object results for future extensibility.isGasFeeSponsoredandisExternalSignlifecycle properties while retaining them in public types for compatibility;isGasFeeSponsoredremains available as migration metadata.TransactionMeta.isGasFeeSponsoredAvailablebefore sponsorship policy runs.shouldSignreturns true.approvedstatus event.eth_sendRawTransactionwith an empty payload or require the hook to return a transaction hash.Public API
The new hooks are optional. Without them, transactions retain the existing non-sponsored, locally signed behavior.
Approval behavior
approvedand runbeforeSignpreparation.isGasFeeSponsoredAvailablewhen simulation is enabled (or selected-token preflight requires it), then performs the gas-fee-token preflight.isSponsored(default:false).shouldSign, nonce reservation, and local signing.shouldSign(default:true); reserve a nonce and sign only when it returnstrue.approvedstatus after any local nonce reservation, then continue through signing and publication.0xsentinel; the hook may return without a transaction hash.beforeSignalways runs, including when local signing is skipped. Existing nonces are retained on externally prepared transactions. Hook outcomes are transient policy results and are not persisted as transaction metadata.Validation
yarn workspace @metamask/transaction-controller run testyarn workspace @metamask/transaction-controller run buildyarn eslint <changed TypeScript files>yarn prettier --check <changed TypeScript files>yarn changelog:validateThe package test suite, package build, focused ESLint, changed-TypeScript formatting checks, changelog validation, and branch diff check pass.
Note
High Risk
Breaking changes to core transaction approval, nonce, signing, and publish behavior affect every client that relied on deprecated sponsorship/external-sign metadata or simulation-driven sponsorship.
Overview
Breaking: Sponsorship and local signing are no longer driven by
isGasFeeSponsored,isExternalSign, or simulation’s oldisGasFeeSponsoredflag. Integrators must use optional approval-timeisSponsoredandshouldSignhooks (defaults: not sponsored, sign locally).On approval, the controller runs
beforeSign, refreshes gas-fee tokens and setsTransactionMeta.isGasFeeSponsoredAvailablewhen simulation (or token preflight) requires it, then evaluates the hooks. Sponsored flows skipshouldSign, nonce reservation, and local signing. WhenshouldSignis false, existing nonces are kept,beforeSignstill runs, and publication requires apublishhook—the controller will not fall back toeth_sendRawTransactionwith an empty payload.Simulation/gas-fee helpers now expose sponsorship availability (
isGasFeeSponsoredAvailable) instead of treating simulation as the lifecycle policy. Legacy fields remain on types as deprecated migration metadata only. Tests and changelog document the new behavior, including batch gas-fee poller updates and stricter publish paths.Reviewed by Cursor Bugbot for commit 71e88f2. Bugbot is set up for automated code reviews on this repo. Configure here.