Feat: subscription delegation - #10130
Conversation
…ial period handling
…etadata into SubscriptionDelegationService
|
|
||
| ### Changed | ||
|
|
||
| - Accept `'subscription-payment'` as a CHOMP intent / delegation metadata type alongside `'cash-deposit'` and `'cash-withdrawal'`. ([#10130](https://github.com/MetaMask/core/pull/10130)) |
There was a problem hiding this comment.
we should rename the intent and delegation type according to https://consensyssoftware.atlassian.net/jira/software/c/projects/CHOMP/boards/6409/backlog?issueParent=389761&selectedIssue=CHOMP-37
| const ChompIntentTypeStruct = enums([ | ||
| 'cash-deposit', | ||
| 'cash-withdrawal', | ||
| 'subscription-payment', |
| export type ChompIntentType = | ||
| | 'cash-deposit' | ||
| | 'cash-withdrawal' | ||
| | 'subscription-payment'; |
There was a problem hiding this comment.
same as above.
Note that when we support premium vault, we may need add more intent and delegations: cash-deposit-premium, cash-withdrawal-premium
| InvalidDecimals = 'Subscription delegation decimals must be a non-negative integer', | ||
| LossyAmountScale = 'Subscription delegation amount cannot be scaled to token decimals without remainder', | ||
| UnsupportedRecurringInterval = 'Unsupported subscription recurring interval', | ||
| UnsupportedProduct = 'Subscription delegation is only supported for Money Account Plus', |
There was a problem hiding this comment.
will we show this error message to end users? We may use MM Orange? Is it possible to have translations instead?
| /** | ||
| * Storage / CHOMP metadata type for subscription-payment delegations. | ||
| */ | ||
| export const SUBSCRIPTION_PAYMENT_DELEGATION_TYPE = 'subscription-payment'; |
There was a problem hiding this comment.
may need to rename to cash-subscription
… for alpha demos/tests
|
No dependency changes detected. Learn more about Socket for GitHub. 👍 No dependency changes detected in pull request |
…Web Crypto API support
|
@metamaskbot publish-previews |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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 24e683a. Configure here.
|
@metamaskbot publish-previews |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
@metamaskbot publish-previews |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |

Explanation
Money Account Plus crypto subscribe needs a cash-subscription delegation (periodic ERC-20 transfer caveats), not the Shield-style ERC-20 approval path. That workflow was split across clients and backend services with no single Core orchestrator.
This PR adds a stateless
SubscriptionDelegationServicethat owns setup end-to-end and returns adelegationHashforSubscriptionController.startSubscriptionWithCrypto. The controller does not depend on this service; clients callSubscriptionDelegationService:prepareDelegationfirst, then start the subscription with the hash.prepareDelegationflowmoneyAccountVaultConfig(remote feature flags), the delegate from pricingdelegateAddress, and Delegation Framework v1.3.0 enforcers from@metamask/delegation-deployments.checkBalance(unitAmount × minBillingCyclesForBalance).unitAmount/unitDecimals/ token decimals). Offset period-transferstartDatebytrialPeriodDaysonly when the trial is selected.{ delegationHash, disposition: 'created' | 'reused' }.Caveats currently include
ValueLte(0)andERC20TokenPeriodTransfer.Only
MONEY_ACCOUNT_PLUSis supported; Shield continues to use ERC-20 approval.Alpha testing note
This PR does not change
@metamask/chomp-api-service(avoids CHOMP-team CODEOWNERS for alpha).CASH_SUBSCRIPTION_DELEGATION_TYPE('cash-subscription') is defined locally insubscription-controllerfor AUS metadata.Alpha hosts must pass
skipChompInteractions: trueonprepareDelegationso CHOMP verify/intent registration is skipped. AUS persist and local hash computation still run.Production CHOMP intent support for
'cash-subscription'will land in a follow-up that updates@metamask/chomp-api-service. Until then, the default CHOMP-enabled path (skipChompInteractionsunset/false) is dormant and unsupported.Package split
@metamask/subscription-controllerSubscriptionDelegationService, helpers (amount,caveats,fingerprint), messenger actionsprepareDelegation/checkMoneyAccountBalance, localCASH_SUBSCRIPTION_DELEGATION_TYPE, andskipChompInteractionsfor alpha.@metamask/walletDelegationController:signDelegation, Money Account balance, pricing, andRemoteFeatureFlagController:getState.Hosts must register
AuthenticatedUserStorageService,ChompApiService,DelegationController,MoneyAccountBalanceService, andSubscriptionControlleron the root messenger before callingprepareDelegation.RemoteFeatureFlagControlleris already initialized by the default wallet factory. For alpha, still registerChompApiServicefor messenger typing even though it is not called whenskipChompInteractions: true.References
Checklist
Note
High Risk
Orchestrates signed delegations, balance gating, and persisted permissions for subscription billing; incorrect caveat/pricing or reuse logic could authorize wrong periodic transfers or block subscribe flows.
Overview
Adds SubscriptionDelegationService so Money Account Plus crypto subscribe can obtain a cash-subscription delegation hash before
SubscriptionController.startSubscriptionWithCrypto. The controller stays independent; callers useSubscriptionDelegationService:prepareDelegationfirst.prepareDelegationresolves chain (vault feature flags), pricing/delegate/token, buildsValueLte(0)+ERC20TokenPeriodTransfercaveats (trial-awarestartDate), reuses matching Authenticated User Storage delegations when the semantic fingerprint aligns, otherwise signs viaDelegationController, persists to AUS, and optionally verifies/registers CHOMP intents. Returns{ delegationHash, disposition: 'created' | 'reused' }.checkMoneyAccountBalance(and optionalcheckBalanceon prepare) gates on mUSD vsunitAmount × minBillingCyclesForBalance. Alpha hosts should passskipChompInteractions: trueuntil CHOMP accepts'cash-subscription'intent metadata; exportsCASH_SUBSCRIPTION_DELEGATION_TYPElocally. Shield remains ERC-20 approval only.@metamask/walletregisters the service in default initialization and delegates AUS, CHOMP, delegation signing, Money Account balance, pricing, and remote feature flags. Package adds delegation/Money Account dependencies, public exports and error enums, Jest Web Crypto test env for delegation salts, and broad unit tests.Reviewed by Cursor Bugbot for commit 708b52d. Bugbot is set up for automated code reviews on this repo. Configure here.