Repository navigation
perf(transaction-controller): cache EIP-7702 contract signature verification - #10397
Merged
matthewwalsh0 merged 3 commits intoSep 24, 2026
Merged
Conversation
…ication EIP-7702 capability lookups verify the signature of every contract configured for a chain on every call, with no reuse between calls. Each verification is a full elliptic curve public key recovery, and the lookups run synchronously on paths that fan out across chains and accounts, so the same recoveries are repeated many times over. Memoize the verification result. It is a pure function of the data, signature and public key, so a cached entry can never become stale and needs no invalidation. Also stop `getEIP7702UpgradeContractAddress` verifying every contract for a chain when it only returns the first authentic one.
4 of 7 tasks
pedronfigueiredo
approved these changes
Sep 24, 2026
matthewwalsh0
deleted the
perf/cache-eip7702-contract-signature-verification
branch
September 24, 2026 12:28
Merged
2 of 3 tasks
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 branch was successfully deployed
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
EIP-7702 capability lookups verify the signature of every contract configured for a chain, on every call, with no reuse between calls. Each verification is a full elliptic curve public key recovery.
These lookups run synchronously, and the callers fan out:
isAtomicBatchSupportedresolves the upgrade contract address in addition to checking the account's delegation, andgetCapabilitiesis invoked per account across every requested chain. The same recoveries are therefore repeated many times over within a single request, which can block the JavaScript thread for a noticeable period on mobile.Two changes:
isValidSignatureis a pure function of the data, signature and public key, so a cached entry can never become stale and requires no invalidation — new feature flag data simply produces new keys. The cache is bounded as a precaution. Each configured contract is now verified at most once for the lifetime of the process, regardless of how many chains, accounts or callers are involved.getEIP7702UpgradeContractAddressverified every contract configured for a chain in order to return the first authentic one. It now stops at the first match. Behaviour is unchanged, including the existing fall-through when the first configured contract fails verification.There is no change to public API or to the result of any existing call.
References
N/A
Checklist
Note
Low Risk
Performance-only refactor with unchanged public API and intended identical results; cache keys include public key and separate multi-part data entries to avoid stale or colliding hits.
Overview
Reduces synchronous work on EIP-7702 capability lookups by avoiding repeated elliptic-curve signature recovery for the same contract configuration.
isValidSignaturenow memoizes results (data + signature + public key), with a bounded cache and a test-onlyclearSignatureCache.getEIP7702UpgradeContractAddressno longer validates every configured contract just to return the first authentic one—it stops after the first valid match, whilegetEIP7702ContractAddressesstill filters the full list via sharedgetEIP7702Contracts/isContractAuthentichelpers. Changelog and tests cover cache behavior and the early-exit upgrade lookup.Reviewed by Cursor Bugbot for commit 63f644a. Bugbot is set up for automated code reviews on this repo. Configure here.