Skip to content

feat(transaction-pay-controller): support metamask pay alternate caveats - #32738

Merged
matthewwalsh0 merged 13 commits into
mainfrom
feat/pass-caveats-to-delegation
Jul 13, 2026
Merged

matthewwalsh0 merged 13 commits into
mainfrom
feat/pass-caveats-to-delegation

Conversation

@matthewwalsh0

@matthewwalsh0 matthewwalsh0 commented Jul 2, 2026 •

Copy link
Copy Markdown
Member

Description

What

Mobile now receives an optional isSubsidized flag from TransactionPayController instead of a caveats array. It builds the four subsidized delegation caveats using native caveat builders with per-chain enforcer addresses.

How

  • isSubsidized flag pass-through. TransactionPayControllerInit forwards core's optional isSubsidized argument into Mobile's getDelegationTransaction; when set, a subsidized caveat set is built instead of the default one.
  • Constrained subsidized delegation. Subsidized delegations apply multiple calldata caveats (alongside target and call-count caveats) so the delegation tightly constrains the batch calldata that may be redeemed.
  • Default behavior unchanged. Callers that omit isSubsidized still use Mobile's existing default caveat builder.

Changelog

CHANGELOG entry: null

Related issues

Refs: no public issue

Manual testing steps

N/A - internal plumbing covered by unit test: yarn jest app/util/transactions/delegation.test.ts

Screenshots/Recordings

N/A

Before

N/A

After

N/A

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
  • I've tested with a power user scenario
  • I've instrumented key operations with Sentry traces for production performance metrics

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.

Note

High Risk
Changes delegation signing constraints for subsidized MetaMask Pay flows; incorrect calldata segmentation could allow overly permissive or broken redemptions.

Overview
Adds an optional isSubsidized path from Transaction Pay into getDelegationTransaction. When set, mobile builds subsidized delegation caveats locally instead of the default exact-execution caveats.

Subsidized delegations redeem the full 7702 batch (txParams.to / txParams.data) in single execution mode. Caveats use allowedTargets, limitedCalls (1), and multiple allowedCalldata segments that lock every byte except the Intents API order-ID placeholder, with splits only after selectors of nested calls that contain that placeholder (avoiding spurious splits from selectors embedded in other call args).

Non-subsidized behavior is unchanged when the flag is omitted. @metamask/transaction-pay-controller is bumped to ^24.0.1 (with transaction-controller 68.4.0); coverage is in delegation.test.ts subsidized cases.

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

@metamask-ci metamask-ci Bot added the team-confirmations Push issues to confirmations team label Jul 2, 2026
@metamask-ci

metamask-ci Bot commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

PR template — items to address before "Ready for review"

Warnings — informational, address before merging:

See docs/readme/ready-for-review.md for the full Definition of Ready for Review.

@github-actions github-actions Bot added the size-S label Jul 2, 2026
@socket-security

socket-security Bot commented Jul 4, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​metamask/​transaction-pay-controller@​23.17.4 ⏵ 24.0.199 +110081 +1100100
Updatednpm/​@​metamask/​transaction-controller@​68.2.0 ⏵ 68.4.09810081 +1100100

View full report

@matthewwalsh0 matthewwalsh0 changed the title feat: pass caveats through getDelegationTransaction feat(transaction-pay-controller): pass MetaMask Pay alternate caveats into mobile delegation signing Jul 4, 2026
@metamask-ci metamask-ci Bot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Jul 4, 2026
@matthewwalsh0 matthewwalsh0 changed the title feat(transaction-pay-controller): pass MetaMask Pay alternate caveats into mobile delegation signing feat(transaction-pay-controller): support metaMask pay alternate caveats Jul 4, 2026
@matthewwalsh0 matthewwalsh0 changed the title feat(transaction-pay-controller): support metaMask pay alternate caveats feat(transaction-pay-controller): support metamask pay alternate caveats Jul 4, 2026
@metamask-ci metamask-ci Bot added INVALID-PR-TEMPLATE PR's body doesn't match template and removed INVALID-PR-TEMPLATE PR's body doesn't match template labels Jul 4, 2026
@github-actions github-actions Bot added size-M and removed size-S labels Jul 6, 2026
@matthewwalsh0
matthewwalsh0 force-pushed the feat/pass-caveats-to-delegation branch 2 times, most recently from 819af98 to a499792 Compare July 6, 2026 16:30
@github-actions github-actions Bot added size-L and removed size-M labels Jul 7, 2026
@socket-security

socket-security Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Warning

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Warn Low
Potential code anomaly (AI signal): npm @metamask/transaction-controller is 75.0% likely to have a medium risk anomaly

Notes: The code performs straightforward signature verification using ethers.js, returning true when the recovered signer matches the provided publicKey. While generally safe, the silent catch and potential mismatch between data formatting and signing process should be addressed to avoid silent failures. Overall, a benign utility with moderate input-format sensitivity.

Confidence: 0.75

Severity: 0.50

From: package.json → npm/@metamask/transaction-controller@68.4.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@metamask/transaction-controller@68.4.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@matthewwalsh0
matthewwalsh0 force-pushed the feat/pass-caveats-to-delegation branch from e8d1808 to 673a098 Compare July 7, 2026 14:14
@matthewwalsh0 matthewwalsh0 added the DO-NOT-MERGE Pull requests that should not be merged label Jul 7, 2026
@matthewwalsh0
matthewwalsh0 marked this pull request as ready for review July 7, 2026 15:19
@matthewwalsh0
matthewwalsh0 requested a review from a team as a code owner July 7, 2026 15:19
@github-actions github-actions Bot added the risk:high AI analysis: high risk label Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

⚡ Performance Test Results

ℹ️ Performance test results are currently non-blocking and will not block this PR.

✅ All tests passed · 2 tests · 1 device

📱 Devices tested (1)

Android: Google Pixel 8 Pro (v14.0)

✅ Passed Tests (2)
Test Platform Device Duration Team Recording
Swap flow - ETH to LINK, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 5.54s @swap-bridge-dev-team 📹 Watch
Cross-chain swap flow - ETH to SOL - 50+ accounts, SRP 1 + SRP 2 + SRP 3 Android Google Pixel 8 Pro (v14.0) 6.10s @swap-bridge-dev-team 📹 Watch

Branch: feat/pass-caveats-to-delegation · Build: Normal · Commit: 2c6c006 · View full run

@matthewwalsh0
matthewwalsh0 requested a review from dan437 July 8, 2026 11:00
dan437
dan437 previously approved these changes Jul 9, 2026
@matthewwalsh0
matthewwalsh0 force-pushed the feat/pass-caveats-to-delegation branch from 7d600a6 to 9f885d8 Compare July 10, 2026 15:34
…troller preview

The previewBuilds plugin only rewrites descriptors during `yarn install`
(via its validateProject hook). CI unit-test shards restore node_modules
from the ci-js-deps artifact (which omits .yarn/install-state.gz) and
re-resolve on `yarn test:unit` without the rewrite, failing with
"^23.17.4 not present in lockfile".

Resolutions are applied on every resolution pass, so the yarn test:unit
pre-flight check resolves correctly.
… into mobile delegation signing

Replace caveats parameter with isSubsidized flag on getDelegationTransaction callback.
Mobile now builds the four subsidized caveats using native caveat builders with
per-chain enforcer addresses from the delegation environment.

Subsidized caveat set:
- LimitedCallsCaveat(1) — only one call allowed
- AllowedTargetsCaveat(token) — only to the token address
- AllowedCalldataCaveat(selector, offset 0) — enforce transfer selector
- AllowedCalldataCaveat(recipient+amount, offset 4) — enforce recipient+amount

Split calldata enforcement prevents Relay post-deposit parser from misreading
caveat terms as transfer missing its order ID.

- Update getDelegationTransaction and buildDelegation signatures: caveats? → isSubsidized?
- Add buildSubsidizedCaveats() with token/calldata validation
- Update transaction-pay-controller-init.ts to forward isSubsidized flag
- Add tests for subsidized caveat building and error cases
- Remove old caveats-passing test
…538ab03c

Preview build from MetaMask/core#9298 (feat/pay-subsidized-submit) for
testing the isSubsidized delegation flag, executeVersion: 2 quote request,
and signed metamask execute envelope end-to-end.
Reduce the AllowedCalldata caveat count for subsidized EIP-7702 batch
delegations by splitting the pinned complement only after the selector of
nested calls that contain an order-ID placeholder, folding the selector into
the preceding segment.

- Locate each nested call by its full calldata (not its selector) so selectors
  appearing coincidentally inside a call's arguments (e.g. approve selectors
  nested in a transferAndMulticall body) do not create spurious split points.
- Split only at order-ID-bearing calls; order-ID-free calls (e.g. approve) need
  no boundary and merge into a neighbouring pinned run. Caveat partitioning is
  invisible to Relay, which reads the contiguous calls from the calldata itself.

Every non-placeholder byte remains pinned byte-exact and all order-ID
placeholder windows remain free.
@matthewwalsh0
matthewwalsh0 force-pushed the feat/pass-caveats-to-delegation branch from 202f0a6 to 6afc600 Compare July 13, 2026 09:53
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeAccounts, SmokeConfirmations, SmokeNetworkAbstractions, SmokeNetworkExpansion, SmokeSwap, SmokeStake, SmokeWalletPlatform, SmokeMoney, SmokePerps, SmokeMultiChainAPI, SmokePredictions, SmokeSeedlessOnboarding, SmokeBrowser, SmokeSnaps
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: high
  • AI Confidence: 100%
click to see 🤖 AI reasoning details

E2E Test Selection:
Hard rule (controller-version-update): @MetaMask controller package version updated in package.json: @metamask/transaction-controller, @metamask/transaction-pay-controller. Running all tests.

Performance Test Selection:
The changes are focused on EIP-7702 delegation logic (caveat building, execution building) and controller wiring. These are not performance-sensitive paths - they don't affect app launch, login, onboarding, asset loading, account list rendering, or swap/perps flows. No performance test tags are warranted.

View GitHub Actions results

@sonarqubecloud

Copy link
Copy Markdown

@matthewwalsh0
matthewwalsh0 enabled auto-merge July 13, 2026 11:41
@matthewwalsh0
matthewwalsh0 requested a review from dan437 July 13, 2026 11:41
@matthewwalsh0
matthewwalsh0 added this pull request to the merge queue Jul 13, 2026
Merged via the queue into main with commit 801e05c Jul 13, 2026
269 of 274 checks passed
@matthewwalsh0
matthewwalsh0 deleted the feat/pass-caveats-to-delegation branch July 13, 2026 14:27
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 13, 2026
@metamask-ci metamask-ci Bot added the release-8.4.0 Issue or pull request that will be included in release 8.4.0 label Jul 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

DO-NOT-MERGE Pull requests that should not be merged INVALID-PR-TEMPLATE PR's body doesn't match template release-8.4.0 Issue or pull request that will be included in release 8.4.0 risk:high AI analysis: high risk size-L team-confirmations Push issues to confirmations team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants