Skip to content

feat(card): upgrade Money Account to EIP-7702 during Card linkage#30889

Merged
Brunonascdev merged 15 commits into
mainfrom
feat/mm-card-money-account-linkage-upgrade
Jun 3, 2026
Merged

feat(card): upgrade Money Account to EIP-7702 during Card linkage#30889
Brunonascdev merged 15 commits into
mainfrom
feat/mm-card-money-account-linkage-upgrade

Conversation

@Brunonascdev

@Brunonascdev Brunonascdev commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Description

When a user links a Card to a Money Account, the approve transaction is submitted by Sentinel on the user's behalf via a delegation. For Sentinel to redeem that delegation without the Money Account itself signing (and therefore without needing native MON on the account), the Money Account must be EIP-7702-upgraded on the card token chain (Monad, 0x8f). Previously the linkage pre-flight would hard-fail with Money account is not 7702-upgraded on Monad whenever the account had not already been upgraded — most commonly for users who discover the Money Account directly through the Card dashboard CTAs and have never deposited mUSD before. The first revision of this PR attempted to fix that by triggering the Money Account upgrade via CHOMP from the Card controller and polling isAtomicBatchSupported until ready, but confirmed with CHOMP that the /v1/account-upgrade endpoint only stores the signed 7702 authorization and only redeems it lazily on the first mUSD deposit — so the poll could never succeed and the flow timed out at 60s.

This PR removes the explicit pre-flight entirely and relies on the existing Delegation7702PublishHook (app/util/transactions/hooks/delegation-7702-publish.ts:215) to bundle the 7702 authorization atomically with the same Sentinel relay submission that publishes the Card approve. When delegationAddress is undefined for the account on the target chain, the hook signs an EIP-7702 authorization via KeyringController:signEip7702Authorization, attaches it to the relay request as authorizationList, and Sentinel submits both legs as one transaction. The race the original pre-flight was designed to prevent does not actually exist — CHOMP checks on-chain code before redeeming its stored auth and skips it if the account was already deployed by a competing path.

Verified end-to-end on dev-api: linking with a Money Account whose eth_getCode returned 0x on Monad produced one Sentinel submission that confirmed in the usual sponsored-relay window. Post-link, eth_getCode on the account returned 0xef010063c0c19a282a1b52b07dd5a65b58948a07dae32b — the canonical EIP7702StatelessDeleGatorImpl for delegation framework 1.3.0 on chain 143. No 60s hang, no 409 retry, no separate upgrade step.

Key changes:

  • CardController linkage pre-flight simplified — drops the TransactionController:isAtomicBatchSupported check and the Money account is not 7702-upgraded on Monad rejection. Only the Monad gas-sponsorship feature-flag gate remains. The publish hook now owns the 7702 upgrade as part of the same relay submission. Related messenger and type wiring (TransactionControllerIsAtomicBatchSupportedAction and the corresponding messenger delegation) are removed.
  • useMoneyAccountCardLinkage cleanup — removes the is7702Ready gating from canSubmitDelegation so the CTA is enabled regardless of the account's current upgrade state. The useIsMoneyAccount7702Ready hook and its tests are deleted.
  • The Money Account upgrade domain (app/actions/money/index.ts, MoneyAccountUpgradeController) is intentionally left untouched — Card linkage no longer depends on it.

Changelog

CHANGELOG entry: Enabled Card linkage on Money Accounts that have not yet been EIP-7702-upgraded — the upgrade now happens atomically with the linkage approve transaction, so users no longer need a separate upgrade step before linking.

Related issues

Fixes:

Manual testing steps

Feature: Card <> Money Account linkage with automatic EIP-7702 upgrade

  Background:
    Given the app is configured with MM_DEV_API_ENV=dev
    And Monad gas sponsorship is enabled for chain 0x8f

  Scenario: Linking a Card with a Money Account that is not yet 7702-upgraded
    Given I have a Money Account whose eth_getCode on Monad returns "0x"
    When I trigger Card linkage from the Card dashboard CTA
    Then exactly one Sentinel relay submission is created
    And the submission carries both a 7702 authorization for the Money Account and the Card approve
    And the relay confirms within the usual sponsored window (well under 60s)
    And eth_getCode on the Money Account on Monad now returns "0xef0100" followed by the EIP7702StatelessDeleGatorImpl address
    And the Money Account allowance to the Card delegation contract matches the requested amount

  Scenario: Linking a Card with a Money Account that is already 7702-upgraded
    Given I have a Money Account that is already EIP-7702-upgraded on Monad
    When I trigger Card linkage from the Card dashboard CTA
    Then the publish hook detects the existing delegation and does not sign a new authorization
    And the relay confirms the approve as before
    And the Card is linked successfully

  Scenario: Money deposit on an un-upgraded account is unaffected
    Given I have a Money Account whose eth_getCode on Monad returns "0x"
    When I initiate a deposit from the Money home screen
    Then the deposit succeeds via the existing MM Pay path
    And the account is upgraded as part of the deposit transaction

Screenshots/Recordings

Before

N/A

After

N/A

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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

Medium Risk
Changes sponsored relay linkage and on-chain delegation timing for Money Accounts on Monad; incorrect hook behavior could break linking or upgrade, but scope is limited to the card linkage path with updated tests.

Overview
Card–Money Account linking no longer blocks on an upfront EIP-7702 check. CardController.linkMoneyAccountCard drops TransactionController:isAtomicBatchSupported and the "Money account is not 7702-upgraded on Monad" error; only Monad gas sponsorship is validated before submit. Docs now state Delegation7702PublishHook bundles a 7702 authorization with the same sponsored addTransactionBatch approve when needed.

The UI removes useIsMoneyAccount7702Ready (hook + tests) and stops requiring is7702Ready === true in useMoneyAccountCardLinkage for canLink. Messenger/types no longer delegate isAtomicBatchSupported. Tests expect linkage to proceed without a 7702 pre-flight and assert the publish-hook path instead.

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

@Brunonascdev Brunonascdev self-assigned this Jun 1, 2026
@Brunonascdev Brunonascdev requested review from a team as code owners June 1, 2026 18:34
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@mm-token-exchange-service mm-token-exchange-service Bot added the team-card Card Team label Jun 1, 2026
@github-actions github-actions Bot added size-L risk:medium AI analysis: medium risk labels Jun 1, 2026
@github-actions github-actions Bot added size-XL and removed size-L labels Jun 2, 2026
@github-actions github-actions Bot added size-L and removed size-XL labels Jun 3, 2026
@Brunonascdev Brunonascdev removed the request for review from a team June 3, 2026 12:50
@github-actions github-actions Bot added size-M and removed size-L labels Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeMoney, SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are focused on the MetaMask Card (Money) feature:

  1. CardController.ts: Removed the EIP-7702 pre-flight check (isAtomicBatchSupported) from the linkMoneyAccountToCard flow. The 7702 upgrade is now handled atomically by Delegation7702PublishHook. The delegation challenge fetch and signing steps were reordered.

  2. types.ts & card-controller-messenger/index.ts: Removed TransactionControllerIsAtomicBatchSupportedAction from the CardController's allowed actions and messenger, reflecting the removed pre-flight check.

  3. useIsMoneyAccount7702Ready.ts & test: Deleted entirely — the hook that checked EIP-7702 readiness via TransactionController.isAtomicBatchSupported is no longer needed.

  4. useMoneyAccountCardLinkage.tsx: Removed the is7702Ready === true condition from canSubmitDelegation. The card linkage CTA now only requires isMonadSponsorshipEnabled (not the 7702 readiness check), making it easier to reach the link flow.

SmokeMoney is the primary tag — these changes directly affect the Card Add Funds / card linkage flow (SpendingLimit screen, money account card linking). The behavioral change (removing the 7702 readiness gate) needs validation.

SmokeConfirmations is included per the SmokeMoney tag description: 'When selecting SmokeMoney for Card Add Funds or similar flows that execute swaps, also select SmokeConfirmations.' The card linkage flow involves on-chain transactions (approve via addTransactionBatch), and the EIP-7702 atomic batch behavior is confirmations-adjacent.

No other areas (accounts, browser, swaps, snaps, network, identity) are affected by these changes.

Performance Test Selection:
The changes are behavioral/logic changes to the card linkage pre-flight checks — removing a blocking condition and deleting a hook. There are no UI rendering changes, list component changes, data loading changes, or app startup changes that would impact performance metrics. No performance tests are warranted.

View GitHub Actions results

@Brunonascdev Brunonascdev enabled auto-merge June 3, 2026 12:56
@Brunonascdev Brunonascdev added this pull request to the merge queue Jun 3, 2026
Merged via the queue into main with commit 4bf8f51 Jun 3, 2026
203 checks passed
@Brunonascdev Brunonascdev deleted the feat/mm-card-money-account-linkage-upgrade branch June 3, 2026 13:41
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

risk:medium AI analysis: medium risk size-M team-card Card Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants