feat(card): upgrade Money Account to EIP-7702 during Card linkage#30889
Conversation
…mm-card-money-account-linkage-upgrade
|
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-card-money-account-linkage-upgrade
…mm-card-money-account-linkage-upgrade
…mm-card-money-account-linkage-upgrade
…mm-card-money-account-linkage-upgrade
…om:MetaMask/metamask-mobile into feat/mm-card-money-account-linkage-upgrade
…mm-card-money-account-linkage-upgrade
…mm-card-money-account-linkage-upgrade
…om:MetaMask/metamask-mobile into feat/mm-card-money-account-linkage-upgrade
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
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: |
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 withMoney account is not 7702-upgraded on Monadwhenever 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 pollingisAtomicBatchSupporteduntil ready, but confirmed with CHOMP that the/v1/account-upgradeendpoint 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. WhendelegationAddressis undefined for the account on the target chain, the hook signs an EIP-7702 authorization viaKeyringController:signEip7702Authorization, attaches it to the relay request asauthorizationList, 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_getCodereturned0xon Monad produced one Sentinel submission that confirmed in the usual sponsored-relay window. Post-link,eth_getCodeon the account returned0xef010063c0c19a282a1b52b07dd5a65b58948a07dae32b— the canonicalEIP7702StatelessDeleGatorImplfor delegation framework1.3.0on chain 143. No 60s hang, no 409 retry, no separate upgrade step.Key changes:
TransactionController:isAtomicBatchSupportedcheck and theMoney account is not 7702-upgraded on Monadrejection. 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 (TransactionControllerIsAtomicBatchSupportedActionand the corresponding messenger delegation) are removed.useMoneyAccountCardLinkagecleanup — removes theis7702Readygating fromcanSubmitDelegationso the CTA is enabled regardless of the account's current upgrade state. TheuseIsMoneyAccount7702Readyhook and its tests are deleted.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
Screenshots/Recordings
Before
N/A
After
N/A
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
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.linkMoneyAccountCarddropsTransactionController:isAtomicBatchSupportedand the "Money account is not 7702-upgraded on Monad" error; only Monad gas sponsorship is validated before submit. Docs now stateDelegation7702PublishHookbundles a 7702 authorization with the same sponsoredaddTransactionBatchapprove when needed.The UI removes
useIsMoneyAccount7702Ready(hook + tests) and stops requiringis7702Ready === trueinuseMoneyAccountCardLinkageforcanLink. Messenger/types no longer delegateisAtomicBatchSupported. 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.