Skip to content

feat: add direct mUSD fiat injection flow for Money Account deposits - #9080

Merged
OGPoyraz merged 16 commits into
mainfrom
feat/direct-musd-fiat-for-money-account
Jun 12, 2026
Merged

OGPoyraz merged 16 commits into
mainfrom
feat/direct-musd-fiat-for-money-account

Conversation

@OGPoyraz

@OGPoyraz OGPoyraz commented Jun 10, 2026 •

Copy link
Copy Markdown
Member

Explanation

This PR adds an alternative fiat deposit flow for Money Account behind the useFiatMUSDQuoteToInjectForMoneyAccount feature flag (confirmations_pay_fiat).

Current flow: Fiat provider buys ETH on Mainnet → Relay bridges ETH to Monad, swaps to mUSD, and vaults into the boring vault.

New flow (flag ON + probe succeeds): Fiat provider buys mUSD directly on Monad → delivers to the Money Account address → Relay only vaults (approve + deposit) on the same chain. No bridging or swapping needed.

New flow (flag ON + probe fails): Falls back silently to the current ETH flow.

Key changes

New file: fiat-direct-musd-quotes-for-money-account.ts

  • probeMusdFiatAvailability — lightweight probe that verifies at least one fiat provider can sell mUSD on Monad before committing to the direct path
  • getDirectMusdToMoneyAccountQuotes — quote function that uses MUSD_MONAD_FIAT_ASSET as the fiat asset and delivers to the Money Account address (txParams.from) instead of the user's EVM account

Modified files:

  • FiatStrategy.ts — routes to the new quote function when flag is ON + transaction is moneyAccountDeposit, with fallback to getFiatQuotes if the probe fails or returns empty
  • fiat-submit.ts — detects the direct-mUSD path at submit time by inspecting the stored quote's source chain/token (immune to flag changes between quote and submit), overrides walletAddress and fiatAsset accordingly
  • TransactionPayController.ts — removes eager caipAssetId assignment from the shouldUpdateFiatToken block; caipAssetId is now set by whichever quote function succeeds, eliminating a race condition between the controller's synchronous write and the async quote phase
  • fiat-quotes.ts — exports shared helpers (getRampsQuote, buildRelayRequestFromAmountFiat, combineQuotes, getRelayTotalFeeUsd, getRequiredTokens) for reuse, adds caipAssetId to the updateFiatPayment call
  • utils.ts — exports resolveTransactionType, adds isMoneyAccountDepositTransaction
  • feature-flags.ts — adds useFiatMUSDQuoteToInjectForMoneyAccount to FiatFlags type + getter
  • constants.ts — adds CHAIN_ID_MONAD, MUSD_MONAD_ADDRESS, MUSD_MONAD_FIAT_ASSET, MUSD_PROBE_AMOUNT_USD

Design decisions

  • Provider-agnostic: The probe and quote flow work with any fiat provider that supports mUSD on Monad — not coupled to Transak
  • Separate file for quotes: The direct-mUSD quote function has different enough semantics (different fiat asset, different delivery address, probe gate) to warrant its own file rather than conditionals in getFiatQuotes
  • Modify existing for submit: The submit flow is structurally identical — same poll → resolve amount → 3-phase flow — so only two targeted overrides are needed
  • Single caipAssetId writer: Moving caipAssetId from the controller to the quote functions eliminates a race condition and ensures it always matches the actual quote returned
  • No mobile changes: All routing is handled in core. Mobile callbacks and UI are unchanged

References

  • Plan: Obsidian Plans/transak-musd-inject-money-account.md

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes fiat quote/submit and relay recipient behavior on Money Account deposit paths; mitigated by feature flag, provider probe, and fallback to the legacy ETH flow.

Overview
Adds an optional direct mUSD fiat deposit path for Money Account deposits when confirmations_pay_fiat.directMoneyMusdEnabled is on: probes ramps for mUSD on Monad, then quotes/submits with mUSD delivered to the Money Account (txParams.from) and relay overrides (recipient, paymentOverride: moneyAccount), skipping the ETH→bridge→mUSD path. Probe failure or empty direct quotes fall back to the existing fiat+relay flow.

fiatPayment.caipAssetId is no longer set on payment-method change in TransactionPayController; successful quote paths now set caipAssetId and rampsQuote together in getFiatQuotes. Submit detects the direct route from the stored quote’s mUSD-on-Monad source (not the flag) for wallet address, asset validation, and order polling.

Relay quotes accept an optional recipient; fiat fee adjustment can exclude source-network gas when the source token is not native gas. New Monad/mUSD constants, isMoneyAccountDepositTransaction, and expanded tests for standard and direct flows.

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

@OGPoyraz
OGPoyraz requested review from a team as code owners June 10, 2026 12:10
OGPoyraz added a commit that referenced this pull request Jun 10, 2026
@OGPoyraz
OGPoyraz temporarily deployed to default-branch June 10, 2026 12:10 — with GitHub Actions Inactive
OGPoyraz added a commit that referenced this pull request Jun 10, 2026
@OGPoyraz
OGPoyraz force-pushed the feat/direct-musd-fiat-for-money-account branch from d97ba76 to 4f1e16f Compare June 10, 2026 12:21
OGPoyraz added a commit that referenced this pull request Jun 10, 2026
@OGPoyraz
OGPoyraz force-pushed the feat/direct-musd-fiat-for-money-account branch from 4f1e16f to 436fbe7 Compare June 10, 2026 12:22
OGPoyraz added a commit that referenced this pull request Jun 10, 2026
@OGPoyraz
OGPoyraz force-pushed the feat/direct-musd-fiat-for-money-account branch from 436fbe7 to f19439b Compare June 10, 2026 12:48
@OGPoyraz
OGPoyraz force-pushed the feat/direct-musd-fiat-for-money-account branch from f19439b to 79ef620 Compare June 10, 2026 12:57
@matthewwalsh0
matthewwalsh0 self-requested a review June 10, 2026 16:34
@OGPoyraz
OGPoyraz requested a review from matthewwalsh0 June 11, 2026 13:25
OGPoyraz added 2 commits June 12, 2026 07:57
… QuoteRequest, flag rename, gas overhead and fallback fixes
@OGPoyraz
OGPoyraz requested a review from matthewwalsh0 June 12, 2026 06:20
relayRequestOverrides?: Partial<QuoteRequest>;
};

async function executeFiatQuotePipeline(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️


const relayTotalFeeUsd = gasDeductedFromSource
? getRelayTotalFeeUsd(relayQuote)
: getNonGasRelayFeeUsd(relayQuote);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, if we're using our gas station for the relay quote, won't the user still need to cover the source network cost as it's calculated from the gas fee token so includes the original gas fee plus commission but it will be paid via additional input token?

Similarly, if a native token, there could still be a source network cost?

Do we add this back somewhere else?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is for mUSD flow and Monad transactions are paid by us, this was increasing the total ramps quote unnecessarily, but again as this is just for quoting it's safe for now, I will revisit in case if we need presented fee fixes.

@OGPoyraz
OGPoyraz added this pull request to the merge queue Jun 12, 2026
Merged via the queue into main with commit 295a41c Jun 12, 2026
376 checks passed
@OGPoyraz
OGPoyraz deleted the feat/direct-musd-fiat-for-money-account branch June 12, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants