feat(transaction-pay-controller): add Money Account vault deposit and withdraw actions - #9849
Draft
saustrie-consensys wants to merge 3 commits into
Draft
feat(transaction-pay-controller): add Money Account vault deposit and withdraw actions#9849saustrie-consensys wants to merge 3 commits into
saustrie-consensys wants to merge 3 commits into
Conversation
10 tasks
… withdraw actions Money Account mUSD that arrives from an external payout (MoonPay/Iron) can only be vaulted by CHOMP's delayed auto-sweep, and there is no reusable path for redeeming vmUSD straight to a partner deposit address. Add two messenger actions so the client can drive both directions itself.
saustrie-consensys
force-pushed
the
saustrie/vba-money-account-vault-functions
branch
from
August 12, 2026 17:37
7703a9c to
6964382
Compare
…ithdraw
Persist successful deposit/withdraw results for process-lifetime idempotency,
tighten CHOMP matching to exact vault destination and amount, slim the withdraw
request surface, and return { skipped: true } instead of a fake 0x hash when
vaulting is disabled.
Retain successful deposit results for controller-lifetime dedupe, but clear skipped results so enabling vaulting later can retry the same payout hash.
4 tasks
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
Money Account holds mUSD on Monad, and only vault shares (vmUSD) earn yield and are usable for Card spend. Today mUSD that lands on a Money Account from outside a user-initiated MM Pay flow (for example a MoonPay/Iron payout) is only vaulted by CHOMP's delayed auto-sweep, and there is no reusable way to redeem vmUSD and send the resulting mUSD to a partner deposit address in one shot. This PR adds both directions to
TransactionPayControlleras messenger actions so clients can drive them.TransactionPayController:submitMoneyAccountVaultDepositHeadless entrypoint for vaulting a completed payout. The caller passes the Money Account address and the payout transaction hash; the controller resolves the actual mUSD amount and block from chain via the existing
getTransferredAmountFromTxHashhelper rather than trusting a caller-supplied amount, builds the approve/deposit pair with the canonical@metamask/money-account-utilsbuilder, and submits it as an internal sponsored batch withrequireApproval: false. It reuses the CHOMP race guard that already exists for the MM Pay deposit path, so if CHOMP sweeps the same funds first the batch is skipped instead of double-depositing.To make this reusable, the existing
submitMoneyAccountVaultDepositutil was split: the batch submission plus CHOMP pre/post checks now live insubmitMoneyAccountVaultDepositBatch, which works with or without a parentTransactionMeta, and the original function is a thin wrapper over it.Concurrent calls for the same payout hash share one in-flight submission. Successful vault results are retained in an in-memory Map for the controller lifetime so retries return the prior hash without submitting again. Skipped results (
{ skipped: true }when vaulting is disabled) are not retained, so enabling the feature flag later can retry the same payout hash without restarting the app. This is not durable across process restarts.TransactionPayController:submitMoneyAccountVaultWithdrawUser-confirmed exact-out redemption. The request is slim:
{ amountInRaw, moneyAccountAddress, recipient, requestId }. The controller caps the amount at the withdrawable vmUSD-equivalent balance reported byMoneyAccountBalanceService, builds the withdraw and transfer calls withbuildMoneyAccountWithdrawBatch, and submits them as a singleatomic: truebatch withrequireApproval: true. Atomicity matters here: if the redeem and the transfer were separate, CHOMP could re-vault the idle mUSD in between and the transfer would fail. Quote expiry, chain, token, and Iron quote field validation are intentionally out of scope for this action; callers keep those concerns in Ramps / NeoBank layers.Other notes
moneyAccountVaultConfiginRemoteFeatureFlagControllerand are individually gated by deposit/withdraw enablement flags. A disabled deposit returns{ skipped: true }; a disabled withdraw throws.@metamask/money-account-utilswas added as a dependency oftransaction-pay-controller(with the matching tsconfig project references) so the calldata builders stay canonical instead of being reimplemented here.References
Consumer PR: MetaMask/metamask-mobile#34700
Checklist