@metamask/transaction-pay-controller 23.5.0 → 23.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/dist/TransactionPayController.cjs +0 -17
  3. package/dist/TransactionPayController.cjs.map +1 -1
  4. package/dist/TransactionPayController.d.cts.map +1 -1
  5. package/dist/TransactionPayController.d.mts.map +1 -1
  6. package/dist/TransactionPayController.mjs +1 -18
  7. package/dist/TransactionPayController.mjs.map +1 -1
  8. package/dist/constants.cjs +3 -1
  9. package/dist/constants.cjs.map +1 -1
  10. package/dist/constants.d.cts +2 -0
  11. package/dist/constants.d.cts.map +1 -1
  12. package/dist/constants.d.mts +2 -0
  13. package/dist/constants.d.mts.map +1 -1
  14. package/dist/constants.mjs +2 -0
  15. package/dist/constants.mjs.map +1 -1
  16. package/dist/strategy/fiat/constants.cjs +15 -3
  17. package/dist/strategy/fiat/constants.cjs.map +1 -1
  18. package/dist/strategy/fiat/constants.d.cts +5 -0
  19. package/dist/strategy/fiat/constants.d.cts.map +1 -1
  20. package/dist/strategy/fiat/constants.d.mts +5 -0
  21. package/dist/strategy/fiat/constants.d.mts.map +1 -1
  22. package/dist/strategy/fiat/constants.mjs +15 -3
  23. package/dist/strategy/fiat/constants.mjs.map +1 -1
  24. package/dist/strategy/fiat/fiat-quotes.cjs +83 -16
  25. package/dist/strategy/fiat/fiat-quotes.cjs.map +1 -1
  26. package/dist/strategy/fiat/fiat-quotes.d.cts +5 -7
  27. package/dist/strategy/fiat/fiat-quotes.d.cts.map +1 -1
  28. package/dist/strategy/fiat/fiat-quotes.d.mts +5 -7
  29. package/dist/strategy/fiat/fiat-quotes.d.mts.map +1 -1
  30. package/dist/strategy/fiat/fiat-quotes.mjs +85 -18
  31. package/dist/strategy/fiat/fiat-quotes.mjs.map +1 -1
  32. package/dist/strategy/fiat/fiat-submit.cjs +43 -12
  33. package/dist/strategy/fiat/fiat-submit.cjs.map +1 -1
  34. package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -1
  35. package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -1
  36. package/dist/strategy/fiat/fiat-submit.mjs +43 -12
  37. package/dist/strategy/fiat/fiat-submit.mjs.map +1 -1
  38. package/dist/strategy/fiat/utils.cjs +35 -4
  39. package/dist/strategy/fiat/utils.cjs.map +1 -1
  40. package/dist/strategy/fiat/utils.d.cts +26 -0
  41. package/dist/strategy/fiat/utils.d.cts.map +1 -1
  42. package/dist/strategy/fiat/utils.d.mts +26 -0
  43. package/dist/strategy/fiat/utils.d.mts.map +1 -1
  44. package/dist/strategy/fiat/utils.mjs +34 -5
  45. package/dist/strategy/fiat/utils.mjs.map +1 -1
  46. package/dist/strategy/relay/relay-quotes.cjs +1 -1
  47. package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
  48. package/dist/strategy/relay/relay-quotes.mjs +1 -1
  49. package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
  50. package/dist/types.cjs.map +1 -1
  51. package/dist/types.d.cts +2 -0
  52. package/dist/types.d.cts.map +1 -1
  53. package/dist/types.d.mts +2 -0
  54. package/dist/types.d.mts.map +1 -1
  55. package/dist/types.mjs.map +1 -1
  56. package/dist/utils/feature-flags.cjs +60 -3
  57. package/dist/utils/feature-flags.cjs.map +1 -1
  58. package/dist/utils/feature-flags.d.cts +30 -0
  59. package/dist/utils/feature-flags.d.cts.map +1 -1
  60. package/dist/utils/feature-flags.d.mts +30 -0
  61. package/dist/utils/feature-flags.d.mts.map +1 -1
  62. package/dist/utils/feature-flags.mjs +56 -3
  63. package/dist/utils/feature-flags.mjs.map +1 -1
  64. package/package.json +8 -8
@@ -1,5 +1,5 @@
1
1
  import { TransactionType } from "@metamask/transaction-controller";
2
- import { CHAIN_ID_ARBITRUM, CHAIN_ID_MAINNET, CHAIN_ID_POLYGON, NATIVE_TOKEN_ADDRESS } from "../../constants.mjs";
2
+ import { CHAIN_ID_ARBITRUM, CHAIN_ID_MAINNET, CHAIN_ID_MONAD, CHAIN_ID_POLYGON, MUSD_MONAD_ADDRESS, NATIVE_TOKEN_ADDRESS } from "../../constants.mjs";
3
3
  export const DEFAULT_FIAT_CURRENCY = 'USD';
4
4
  const POLYGON_POL_FIAT_ASSET = {
5
5
  address: '0x0000000000000000000000000000000000001010',
@@ -14,8 +14,20 @@ export const ETH_MAINNET_FIAT_ASSET = {
14
14
  chainId: CHAIN_ID_MAINNET,
15
15
  };
16
16
  export const FIAT_ASSET_ID_BY_TX_TYPE = {
17
- [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,
17
+ [TransactionType.moneyAccountDeposit]: ETH_MAINNET_FIAT_ASSET,
18
18
  [TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,
19
- [TransactionType.perpsDepositAndOrder]: ARBITRUM_ETH_FIAT_ASSET,
19
+ [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,
20
+ };
21
+ export const FIAT_ENABLED_TYPES = [
22
+ TransactionType.moneyAccountDeposit,
23
+ TransactionType.perpsDeposit,
24
+ TransactionType.predictDeposit,
25
+ ];
26
+ /** Fiat asset descriptor for mUSD on Monad. */
27
+ export const MUSD_MONAD_FIAT_ASSET = {
28
+ address: MUSD_MONAD_ADDRESS,
29
+ chainId: CHAIN_ID_MONAD,
20
30
  };
31
+ /** Fixed USD amount used to probe whether any fiat provider can sell mUSD on Monad. */
32
+ export const MUSD_PROBE_AMOUNT_USD = 50;
21
33
  //# sourceMappingURL=constants.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAGnE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACrB,4BAAwB;AAEzB,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAO3C,MAAM,sBAAsB,GAA4B;IACtD,OAAO,EAAE,4CAA4C;IACrD,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,uBAAuB,GAA4B;IACvD,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAEjC;IACF,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,sBAAsB;IACxD,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,uBAAuB;IACvD,CAAC,eAAe,CAAC,oBAAoB,CAAC,EAAE,uBAAuB;CAChE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_MAINNET,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants';\n\nexport const DEFAULT_FIAT_CURRENCY = 'USD';\n\nexport type TransactionPayFiatAsset = {\n address: Hex;\n chainId: Hex;\n};\n\nconst POLYGON_POL_FIAT_ASSET: TransactionPayFiatAsset = {\n address: '0x0000000000000000000000000000000000001010',\n chainId: CHAIN_ID_POLYGON,\n};\n\nconst ARBITRUM_ETH_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_ARBITRUM,\n};\n\nexport const ETH_MAINNET_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_MAINNET,\n};\n\nexport const FIAT_ASSET_ID_BY_TX_TYPE: Partial<\n Record<TransactionType, TransactionPayFiatAsset>\n> = {\n [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,\n [TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,\n [TransactionType.perpsDepositAndOrder]: ARBITRUM_ETH_FIAT_ASSET,\n};\n"]}
1
+ {"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAGnE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACrB,4BAAwB;AAEzB,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAO3C,MAAM,sBAAsB,GAA4B;IACtD,OAAO,EAAE,4CAA4C;IACrD,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,uBAAuB,GAA4B;IACvD,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAEjC;IACF,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,sBAAsB;IAC7D,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,uBAAuB;IACvD,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,sBAAsB;CACzD,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,eAAe,CAAC,mBAAmB;IACnC,eAAe,CAAC,YAAY;IAC5B,eAAe,CAAC,cAAc;CAC/B,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,qBAAqB,GAA4B;IAC5D,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,uFAAuF;AACvF,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_MAINNET,\n CHAIN_ID_MONAD,\n CHAIN_ID_POLYGON,\n MUSD_MONAD_ADDRESS,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants';\n\nexport const DEFAULT_FIAT_CURRENCY = 'USD';\n\nexport type TransactionPayFiatAsset = {\n address: Hex;\n chainId: Hex;\n};\n\nconst POLYGON_POL_FIAT_ASSET: TransactionPayFiatAsset = {\n address: '0x0000000000000000000000000000000000001010',\n chainId: CHAIN_ID_POLYGON,\n};\n\nconst ARBITRUM_ETH_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_ARBITRUM,\n};\n\nexport const ETH_MAINNET_FIAT_ASSET: TransactionPayFiatAsset = {\n address: NATIVE_TOKEN_ADDRESS,\n chainId: CHAIN_ID_MAINNET,\n};\n\nexport const FIAT_ASSET_ID_BY_TX_TYPE: Partial<\n Record<TransactionType, TransactionPayFiatAsset>\n> = {\n [TransactionType.moneyAccountDeposit]: ETH_MAINNET_FIAT_ASSET,\n [TransactionType.perpsDeposit]: ARBITRUM_ETH_FIAT_ASSET,\n [TransactionType.predictDeposit]: POLYGON_POL_FIAT_ASSET,\n};\n\nexport const FIAT_ENABLED_TYPES: TransactionType[] = [\n TransactionType.moneyAccountDeposit,\n TransactionType.perpsDeposit,\n TransactionType.predictDeposit,\n];\n\n/** Fiat asset descriptor for mUSD on Monad. */\nexport const MUSD_MONAD_FIAT_ASSET: TransactionPayFiatAsset = {\n address: MUSD_MONAD_ADDRESS,\n chainId: CHAIN_ID_MONAD,\n};\n\n/** Fixed USD amount used to probe whether any fiat provider can sell mUSD on Monad. */\nexport const MUSD_PROBE_AMOUNT_USD = 50;\n"]}
@@ -5,6 +5,7 @@ const utils_1 = require("@metamask/utils");
5
5
  const bignumber_js_1 = require("bignumber.js");
6
6
  const constants_1 = require("../../constants.cjs");
7
7
  const logger_1 = require("../../logger.cjs");
8
+ const feature_flags_1 = require("../../utils/feature-flags.cjs");
8
9
  const token_1 = require("../../utils/token.cjs");
9
10
  const relay_quotes_1 = require("../relay/relay-quotes.cjs");
10
11
  const constants_2 = require("./constants.cjs");
@@ -13,24 +14,52 @@ const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'fiat-strate
13
14
  /**
14
15
  * Fetches MM Pay fiat strategy quotes using a relay-first estimation flow.
15
16
  *
17
+ * When the direct-to-mUSD flag is enabled and the transaction is a Money
18
+ * Account deposit, probes ramps for mUSD availability on Monad. If viable,
19
+ * uses direct mUSD params (asset, wallet, recipient); otherwise falls back
20
+ * to the standard ETH flow. Both paths share a single quote pipeline.
21
+ *
16
22
  * @param request - Strategy quotes request.
17
23
  * @returns A single combined fiat strategy quote, or an empty array when inputs/quotes are unavailable.
18
- * @remarks
19
- * Flow summary:
20
- * 1. Read `amountFiat` and selected payment method from transaction pay state.
21
- * 2. Build a synthetic relay request from `amountFiat` using source token USD rate.
22
- * 3. Fetch relay quote and compute total relay fee (`provider + source network + target network + MetaMask`).
23
- * 4. Call ramps quotes with `adjustedAmountFiat = amountFiat + relayTotalFeeUsd`.
24
- * 5. Pick the configured ramps provider quote and combine it with relay quote into one fiat strategy quote.
25
24
  */
26
25
  async function getFiatQuotes(request) {
26
+ const { messenger, transaction } = request;
27
+ const useDirectMusd = (0, feature_flags_1.getDirectMoneyMusdEnabled)(messenger) &&
28
+ (0, utils_2.isMoneyAccountDepositTransaction)(transaction);
29
+ if (useDirectMusd) {
30
+ const moneyAccountAddress = transaction.txParams.from;
31
+ const probeOk = await probeMusdFiatAvailability({
32
+ messenger,
33
+ walletAddress: moneyAccountAddress,
34
+ });
35
+ if (probeOk) {
36
+ const directResult = await executeFiatQuotePipeline(request, {
37
+ fiatAsset: constants_2.MUSD_MONAD_FIAT_ASSET,
38
+ rampsWalletAddress: moneyAccountAddress,
39
+ relayRequestOverrides: {
40
+ paymentOverride: constants_1.PaymentOverride.MoneyAccount,
41
+ recipient: moneyAccountAddress,
42
+ },
43
+ });
44
+ if (directResult.length > 0) {
45
+ return directResult;
46
+ }
47
+ }
48
+ }
49
+ return executeFiatQuotePipeline(request, {
50
+ fiatAsset: (0, utils_2.deriveFiatAssetForFiatPayment)(transaction, messenger),
51
+ rampsWalletAddress: request.from,
52
+ });
53
+ }
54
+ exports.getFiatQuotes = getFiatQuotes;
55
+ async function executeFiatQuotePipeline(request, options) {
27
56
  const { accountSupports7702, fiatPaymentMethod, from: walletAddress, messenger, transaction, } = request;
57
+ const { fiatAsset, rampsWalletAddress, relayRequestOverrides } = options;
28
58
  const transactionId = transaction.id;
29
59
  const state = messenger.call('TransactionPayController:getState');
30
60
  const transactionData = state.transactionData[transactionId];
31
61
  const amountFiat = transactionData?.fiatPayment?.amountFiat;
32
- const requiredTokens = getRequiredTokens(transactionData?.tokens);
33
- const fiatAsset = (0, utils_2.deriveFiatAssetForFiatPayment)(transaction, messenger);
62
+ const requiredTokens = transactionData?.tokens ?? [];
34
63
  if (!amountFiat || !fiatPaymentMethod || !requiredTokens.length) {
35
64
  return [];
36
65
  }
@@ -49,18 +78,25 @@ async function getFiatQuotes(request) {
49
78
  if (!relayRequest) {
50
79
  throw new Error('Failed to build relay request from fiat amount');
51
80
  }
81
+ const finalRelayRequest = relayRequestOverrides
82
+ ? { ...relayRequest, ...relayRequestOverrides }
83
+ : relayRequest;
52
84
  const relayQuotes = await (0, relay_quotes_1.getRelayQuotes)({
53
85
  accountSupports7702,
54
86
  from: walletAddress,
55
87
  messenger,
56
- requests: [relayRequest],
88
+ requests: [finalRelayRequest],
57
89
  transaction,
58
90
  });
59
91
  const relayQuote = relayQuotes[0];
60
92
  if (!relayQuote) {
61
93
  throw new Error('No relay quote available for fiat estimation');
62
94
  }
63
- const relayTotalFeeUsd = getRelayTotalFeeUsd(relayQuote);
95
+ const isSourceNative = fiatAsset.address.toLowerCase() === constants_1.NATIVE_TOKEN_ADDRESS.toLowerCase();
96
+ const gasDeductedFromSource = isSourceNative || relayQuote.fees.isSourceGasFeeToken === true;
97
+ const relayTotalFeeUsd = gasDeductedFromSource
98
+ ? getRelayTotalFeeUsd(relayQuote)
99
+ : getNonGasRelayFeeUsd(relayQuote);
64
100
  const adjustedAmountFiat = new bignumber_js_1.BigNumber(amountFiat).plus(relayTotalFeeUsd);
65
101
  if (!adjustedAmountFiat.isFinite() ||
66
102
  !adjustedAmountFiat.gt(0) ||
@@ -75,7 +111,8 @@ async function getFiatQuotes(request) {
75
111
  log('Fiat quote flow', {
76
112
  adjustedAmountFiat: adjustedAmountFiat.toString(10),
77
113
  amountFiat,
78
- paymentMethods: [fiatPaymentMethod],
114
+ isDirectMusd: Boolean(relayRequestOverrides),
115
+ rampsWalletAddress,
79
116
  relayTotalFeeUsd: relayTotalFeeUsd.toString(10),
80
117
  sourceAmountRaw: relayRequest.sourceTokenAmount,
81
118
  transactionId,
@@ -85,11 +122,12 @@ async function getFiatQuotes(request) {
85
122
  fiatAsset,
86
123
  fiatPaymentMethod,
87
124
  messenger,
88
- walletAddress,
125
+ walletAddress: rampsWalletAddress,
89
126
  });
90
127
  messenger.call('TransactionPayController:updateFiatPayment', {
91
128
  callback: (fiatPayment) => {
92
129
  fiatPayment.rampsQuote = fiatQuote;
130
+ fiatPayment.caipAssetId = (0, token_1.buildCaipAssetType)(fiatAsset.chainId, fiatAsset.address);
93
131
  },
94
132
  transactionId,
95
133
  });
@@ -104,12 +142,36 @@ async function getFiatQuotes(request) {
104
142
  }
105
143
  catch (error) {
106
144
  log('Failed to fetch fiat quotes', { error, transactionId });
145
+ messenger.call('TransactionPayController:updateFiatPayment', {
146
+ callback: (fiatPayment) => {
147
+ fiatPayment.rampsQuote = undefined;
148
+ },
149
+ transactionId,
150
+ });
107
151
  }
108
152
  return [];
109
153
  }
110
- exports.getFiatQuotes = getFiatQuotes;
111
- function getRequiredTokens(tokens) {
112
- return tokens?.filter((token) => !token.skipIfBalance) ?? [];
154
+ async function probeMusdFiatAvailability({ messenger, walletAddress, }) {
155
+ try {
156
+ const quotes = await messenger.call('RampsController:getQuotes', {
157
+ amount: constants_2.MUSD_PROBE_AMOUNT_USD,
158
+ assetId: (0, token_1.buildCaipAssetType)(constants_2.MUSD_MONAD_FIAT_ASSET.chainId, constants_2.MUSD_MONAD_FIAT_ASSET.address),
159
+ autoSelectProvider: true,
160
+ fiat: constants_2.DEFAULT_FIAT_CURRENCY,
161
+ restrictToKnownOrNativeProviders: true,
162
+ walletAddress,
163
+ });
164
+ const isAvailable = (quotes.success?.length ?? 0) > 0;
165
+ log('mUSD fiat probe result', {
166
+ isAvailable,
167
+ providerCount: quotes.success?.length ?? 0,
168
+ });
169
+ return isAvailable;
170
+ }
171
+ catch (error) {
172
+ log('mUSD fiat probe failed', { error });
173
+ return false;
174
+ }
113
175
  }
114
176
  async function getRampsQuote({ adjustedAmount, fiatAsset, fiatPaymentMethod, messenger, walletAddress, }) {
115
177
  const quotes = await messenger.call('RampsController:getQuotes', {
@@ -230,6 +292,11 @@ function getRelayTotalFeeUsd(relayQuote) {
230
292
  .plus(relayQuote.fees.targetNetwork.usd)
231
293
  .plus(relayQuote.fees.metaMask.usd);
232
294
  }
295
+ function getNonGasRelayFeeUsd(relayQuote) {
296
+ return new bignumber_js_1.BigNumber(relayQuote.fees.provider.usd)
297
+ .plus(relayQuote.fees.targetNetwork.usd)
298
+ .plus(relayQuote.fees.metaMask.usd);
299
+ }
233
300
  function getMetaMaskFee({ adjustedAmountFiat, amountFiat, }) {
234
301
  return new bignumber_js_1.BigNumber(amountFiat).plus(adjustedAmountFiat).dividedBy(100);
235
302
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Quote as RampsQuote } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TransactionPayStrategy } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayRequiredToken,\n TransactionPayQuote,\n} from '../../types';\nimport {\n buildCaipAssetType,\n computeRawFromFiatAmount,\n getTokenFiatRate,\n getTokenInfo,\n} from '../../utils/token';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport type { RelayQuote } from '../relay/types';\nimport { DEFAULT_FIAT_CURRENCY } from './constants';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment } from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-strategy');\n\n/**\n * Fetches MM Pay fiat strategy quotes using a relay-first estimation flow.\n *\n * @param request - Strategy quotes request.\n * @returns A single combined fiat strategy quote, or an empty array when inputs/quotes are unavailable.\n * @remarks\n * Flow summary:\n * 1. Read `amountFiat` and selected payment method from transaction pay state.\n * 2. Build a synthetic relay request from `amountFiat` using source token USD rate.\n * 3. Fetch relay quote and compute total relay fee (`provider + source network + target network + MetaMask`).\n * 4. Call ramps quotes with `adjustedAmountFiat = amountFiat + relayTotalFeeUsd`.\n * 5. Pick the configured ramps provider quote and combine it with relay quote into one fiat strategy quote.\n */\nexport async function getFiatQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const {\n accountSupports7702,\n fiatPaymentMethod,\n from: walletAddress,\n messenger,\n transaction,\n } = request;\n const transactionId = transaction.id;\n\n const state = messenger.call('TransactionPayController:getState');\n const transactionData = state.transactionData[transactionId];\n const amountFiat = transactionData?.fiatPayment?.amountFiat;\n const requiredTokens = getRequiredTokens(transactionData?.tokens);\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n if (!amountFiat || !fiatPaymentMethod || !requiredTokens.length) {\n return [];\n }\n\n try {\n if (requiredTokens.length > 1) {\n throw new Error(\n 'Multiple required tokens not supported for fiat strategy',\n );\n }\n\n const requiredToken = requiredTokens[0];\n\n const relayRequest = buildRelayRequestFromAmountFiat({\n amountFiat,\n fiatAsset,\n messenger,\n requiredToken,\n walletAddress,\n });\n\n if (!relayRequest) {\n throw new Error('Failed to build relay request from fiat amount');\n }\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702,\n from: walletAddress,\n messenger,\n requests: [relayRequest],\n transaction,\n });\n\n const relayQuote = relayQuotes[0];\n if (!relayQuote) {\n throw new Error('No relay quote available for fiat estimation');\n }\n\n const relayTotalFeeUsd = getRelayTotalFeeUsd(relayQuote);\n const adjustedAmountFiat = new BigNumber(amountFiat).plus(relayTotalFeeUsd);\n\n if (\n !adjustedAmountFiat.isFinite() ||\n !adjustedAmountFiat.gt(0) ||\n !relayTotalFeeUsd.isFinite() ||\n !relayTotalFeeUsd.gte(0)\n ) {\n throw new Error('Invalid fiat amount after relay fee adjustment');\n }\n\n const adjustedAmount = adjustedAmountFiat.toNumber();\n\n if (!Number.isFinite(adjustedAmount) || adjustedAmount <= 0) {\n throw new Error('Invalid fiat amount after relay fee adjustment');\n }\n\n log('Fiat quote flow', {\n adjustedAmountFiat: adjustedAmountFiat.toString(10),\n amountFiat,\n paymentMethods: [fiatPaymentMethod],\n relayTotalFeeUsd: relayTotalFeeUsd.toString(10),\n sourceAmountRaw: relayRequest.sourceTokenAmount,\n transactionId,\n });\n\n const fiatQuote = await getRampsQuote({\n adjustedAmount,\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress,\n });\n\n messenger.call('TransactionPayController:updateFiatPayment', {\n callback: (fiatPayment) => {\n fiatPayment.rampsQuote = fiatQuote;\n },\n transactionId,\n });\n\n return [\n combineQuotes({\n adjustedAmountFiat: adjustedAmountFiat.toString(10),\n amountFiat,\n fiatQuote,\n relayQuote,\n }),\n ];\n } catch (error) {\n log('Failed to fetch fiat quotes', { error, transactionId });\n }\n\n return [];\n}\n\nfunction getRequiredTokens(\n tokens?: TransactionPayRequiredToken[],\n): TransactionPayRequiredToken[] {\n return tokens?.filter((token) => !token.skipIfBalance) ?? [];\n}\n\nasync function getRampsQuote({\n adjustedAmount,\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress,\n}: {\n adjustedAmount: number;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n messenger: PayStrategyGetQuotesRequest['messenger'];\n walletAddress: string;\n}): Promise<RampsQuote> {\n const quotes = await messenger.call('RampsController:getQuotes', {\n amount: adjustedAmount,\n assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),\n autoSelectProvider: true,\n fiat: DEFAULT_FIAT_CURRENCY,\n paymentMethods: [fiatPaymentMethod],\n restrictToKnownOrNativeProviders: true,\n walletAddress,\n });\n\n log('Fetched ramps quotes', {\n quotesCount: quotes.success?.length ?? 0,\n });\n\n const quote = quotes.success?.[0];\n\n if (!quote) {\n throw new Error('No matching ramps quote found for selected provider');\n }\n\n return quote;\n}\n\nfunction buildRelayRequestFromAmountFiat({\n amountFiat,\n fiatAsset,\n messenger,\n requiredToken,\n walletAddress,\n}: {\n amountFiat: string;\n fiatAsset: {\n address: Hex;\n chainId: Hex;\n };\n messenger: PayStrategyGetQuotesRequest['messenger'];\n requiredToken: TransactionPayRequiredToken;\n walletAddress: Hex;\n}): QuoteRequest | undefined {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!sourceFiatRate) {\n return undefined;\n }\n\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n return undefined;\n }\n\n const sourceAmountRaw = computeRawFromFiatAmount(\n amountFiat,\n tokenInfo.decimals,\n sourceFiatRate.usdRate,\n );\n\n if (!sourceAmountRaw) {\n return undefined;\n }\n\n return {\n from: walletAddress,\n // Force EXACT_INPUT mode: source amount is pre-calculated from the fiat\n // amount, so the relay should treat it as a fixed input rather than\n // computing it from the target.\n isPostQuote: true,\n sourceBalanceRaw: sourceAmountRaw,\n sourceChainId: fiatAsset.chainId,\n sourceTokenAddress: fiatAsset.address,\n sourceTokenAmount: sourceAmountRaw,\n targetAmountMinimum: requiredToken.amountRaw,\n targetChainId: requiredToken.chainId,\n targetTokenAddress: requiredToken.address,\n };\n}\n\n/**\n * Combines fiat and relay legs into a single MM Pay fiat strategy quote.\n *\n * @param params - Combined quote inputs.\n * @param params.adjustedAmountFiat - Fiat amount sent to ramps after adding relay fee estimate.\n * @param params.amountFiat - User-entered fiat amount.\n * @param params.fiatQuote - Selected ramps quote.\n * @param params.relayQuote - Estimated relay quote.\n * @returns A single fiat strategy quote with split fee buckets.\n * @remarks\n * Fee mapping contract for MM Pay Fiat strategy:\n * - `fees.provider`: Total provider fee (relay provider/swap fee + ramps provider/network fee).\n * Consumed by UI transaction fee row and tooltip provider fee.\n * - `fees.providerFiat`: Fiat on-ramp provider fees only (`providerFee + networkFee` from ramps quote).\n * Optional breakdown; client can derive relay portion via `provider - providerFiat`.\n * - `fees.sourceNetwork` / `fees.targetNetwork`: Relay settlement network fees.\n * Consumed by UI transaction fee row and tooltip network fee.\n * - `fees.metaMask`: MM Pay fee (currently 100 bps over `amountFiat + adjustedAmountFiat`).\n * Consumed by UI transaction fee row and tooltip MetaMask fee.\n * - `totals.total` should represent Amount + Transaction Fee using the totals pipeline.\n */\nfunction combineQuotes({\n adjustedAmountFiat,\n amountFiat,\n fiatQuote,\n relayQuote,\n}: {\n adjustedAmountFiat: string;\n amountFiat: string;\n fiatQuote: RampsQuote;\n relayQuote: TransactionPayQuote<RelayQuote>;\n}): TransactionPayQuote<FiatQuote> {\n const rampsProviderFee = getRampsProviderFee(fiatQuote);\n const totalProviderFee = new BigNumber(relayQuote.fees.provider.usd)\n .plus(rampsProviderFee)\n .toString(10);\n const rampsProviderFeeStr = rampsProviderFee.toString(10);\n const metaMaskFee = getMetaMaskFee({\n adjustedAmountFiat,\n amountFiat,\n }).toString(10);\n\n return {\n ...relayQuote,\n fees: {\n ...relayQuote.fees,\n metaMask: {\n fiat: metaMaskFee,\n usd: metaMaskFee,\n },\n provider: {\n fiat: totalProviderFee,\n usd: totalProviderFee,\n },\n providerFiat: {\n fiat: rampsProviderFeeStr,\n usd: rampsProviderFeeStr,\n },\n },\n original: {\n rampsQuote: fiatQuote,\n relayQuote: relayQuote.original,\n },\n strategy: TransactionPayStrategy.Fiat,\n };\n}\n\n/**\n * Ramps providers handle network gas fees themselves but report them separately\n * as `networkFee` alongside their `providerFee`. We combine both into a single\n * ramps provider fee for the `providerFiat` breakdown.\n *\n * @param fiatQuote - The ramps quote containing provider and network fees.\n * @returns Combined ramps provider fee as a BigNumber.\n */\nfunction getRampsProviderFee(fiatQuote: RampsQuote): BigNumber {\n return new BigNumber(fiatQuote.quote.providerFee ?? 0).plus(\n fiatQuote.quote.networkFee ?? 0,\n );\n}\n\nfunction getRelayTotalFeeUsd(\n relayQuote: TransactionPayQuote<RelayQuote>,\n): BigNumber {\n return new BigNumber(relayQuote.fees.provider.usd)\n .plus(relayQuote.fees.sourceNetwork.estimate.usd)\n .plus(relayQuote.fees.targetNetwork.usd)\n .plus(relayQuote.fees.metaMask.usd);\n}\n\nfunction getMetaMaskFee({\n adjustedAmountFiat,\n amountFiat,\n}: {\n adjustedAmountFiat: BigNumber.Value;\n amountFiat: BigNumber.Value;\n}): BigNumber {\n return new BigNumber(amountFiat).plus(adjustedAmountFiat).dividedBy(100);\n}\n"]}
1
+ {"version":3,"file":"fiat-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Quote as RampsQuote } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n NATIVE_TOKEN_ADDRESS,\n PaymentOverride,\n TransactionPayStrategy,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionFiatPayment,\n TransactionPayRequiredToken,\n TransactionPayQuote,\n} from '../../types';\nimport { getDirectMoneyMusdEnabled } from '../../utils/feature-flags';\nimport {\n buildCaipAssetType,\n computeRawFromFiatAmount,\n getTokenFiatRate,\n getTokenInfo,\n} from '../../utils/token';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport type { RelayQuote } from '../relay/types';\nimport {\n DEFAULT_FIAT_CURRENCY,\n MUSD_MONAD_FIAT_ASSET,\n MUSD_PROBE_AMOUNT_USD,\n} from './constants';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport {\n deriveFiatAssetForFiatPayment,\n isMoneyAccountDepositTransaction,\n} from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-strategy');\n\n/**\n * Fetches MM Pay fiat strategy quotes using a relay-first estimation flow.\n *\n * When the direct-to-mUSD flag is enabled and the transaction is a Money\n * Account deposit, probes ramps for mUSD availability on Monad. If viable,\n * uses direct mUSD params (asset, wallet, recipient); otherwise falls back\n * to the standard ETH flow. Both paths share a single quote pipeline.\n *\n * @param request - Strategy quotes request.\n * @returns A single combined fiat strategy quote, or an empty array when inputs/quotes are unavailable.\n */\nexport async function getFiatQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const { messenger, transaction } = request;\n\n const useDirectMusd =\n getDirectMoneyMusdEnabled(messenger) &&\n isMoneyAccountDepositTransaction(transaction);\n\n if (useDirectMusd) {\n const moneyAccountAddress = transaction.txParams.from as Hex;\n\n const probeOk = await probeMusdFiatAvailability({\n messenger,\n walletAddress: moneyAccountAddress,\n });\n\n if (probeOk) {\n const directResult = await executeFiatQuotePipeline(request, {\n fiatAsset: MUSD_MONAD_FIAT_ASSET,\n rampsWalletAddress: moneyAccountAddress,\n relayRequestOverrides: {\n paymentOverride: PaymentOverride.MoneyAccount,\n recipient: moneyAccountAddress,\n },\n });\n\n if (directResult.length > 0) {\n return directResult;\n }\n }\n }\n\n return executeFiatQuotePipeline(request, {\n fiatAsset: deriveFiatAssetForFiatPayment(transaction, messenger),\n rampsWalletAddress: request.from,\n });\n}\n\ntype FiatQuotePipelineOptions = {\n fiatAsset: TransactionPayFiatAsset;\n rampsWalletAddress: Hex;\n relayRequestOverrides?: Partial<QuoteRequest>;\n};\n\nasync function executeFiatQuotePipeline(\n request: PayStrategyGetQuotesRequest,\n options: FiatQuotePipelineOptions,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const {\n accountSupports7702,\n fiatPaymentMethod,\n from: walletAddress,\n messenger,\n transaction,\n } = request;\n const { fiatAsset, rampsWalletAddress, relayRequestOverrides } = options;\n const transactionId = transaction.id;\n\n const state = messenger.call('TransactionPayController:getState');\n const transactionData = state.transactionData[transactionId];\n const amountFiat = transactionData?.fiatPayment?.amountFiat;\n const requiredTokens = transactionData?.tokens ?? [];\n\n if (!amountFiat || !fiatPaymentMethod || !requiredTokens.length) {\n return [];\n }\n\n try {\n if (requiredTokens.length > 1) {\n throw new Error(\n 'Multiple required tokens not supported for fiat strategy',\n );\n }\n\n const requiredToken = requiredTokens[0];\n\n const relayRequest = buildRelayRequestFromAmountFiat({\n amountFiat,\n fiatAsset,\n messenger,\n requiredToken,\n walletAddress,\n });\n\n if (!relayRequest) {\n throw new Error('Failed to build relay request from fiat amount');\n }\n\n const finalRelayRequest = relayRequestOverrides\n ? { ...relayRequest, ...relayRequestOverrides }\n : relayRequest;\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702,\n from: walletAddress,\n messenger,\n requests: [finalRelayRequest],\n transaction,\n });\n\n const relayQuote = relayQuotes[0];\n if (!relayQuote) {\n throw new Error('No relay quote available for fiat estimation');\n }\n\n const isSourceNative =\n fiatAsset.address.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();\n const gasDeductedFromSource =\n isSourceNative || relayQuote.fees.isSourceGasFeeToken === true;\n\n const relayTotalFeeUsd = gasDeductedFromSource\n ? getRelayTotalFeeUsd(relayQuote)\n : getNonGasRelayFeeUsd(relayQuote);\n const adjustedAmountFiat = new BigNumber(amountFiat).plus(relayTotalFeeUsd);\n\n if (\n !adjustedAmountFiat.isFinite() ||\n !adjustedAmountFiat.gt(0) ||\n !relayTotalFeeUsd.isFinite() ||\n !relayTotalFeeUsd.gte(0)\n ) {\n throw new Error('Invalid fiat amount after relay fee adjustment');\n }\n\n const adjustedAmount = adjustedAmountFiat.toNumber();\n\n if (!Number.isFinite(adjustedAmount) || adjustedAmount <= 0) {\n throw new Error('Invalid fiat amount after relay fee adjustment');\n }\n\n log('Fiat quote flow', {\n adjustedAmountFiat: adjustedAmountFiat.toString(10),\n amountFiat,\n isDirectMusd: Boolean(relayRequestOverrides),\n rampsWalletAddress,\n relayTotalFeeUsd: relayTotalFeeUsd.toString(10),\n sourceAmountRaw: relayRequest.sourceTokenAmount,\n transactionId,\n });\n\n const fiatQuote = await getRampsQuote({\n adjustedAmount,\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress: rampsWalletAddress,\n });\n\n messenger.call('TransactionPayController:updateFiatPayment', {\n callback: (fiatPayment: TransactionFiatPayment) => {\n fiatPayment.rampsQuote = fiatQuote;\n fiatPayment.caipAssetId = buildCaipAssetType(\n fiatAsset.chainId,\n fiatAsset.address,\n );\n },\n transactionId,\n });\n\n return [\n combineQuotes({\n adjustedAmountFiat: adjustedAmountFiat.toString(10),\n amountFiat,\n fiatQuote,\n relayQuote,\n }),\n ];\n } catch (error) {\n log('Failed to fetch fiat quotes', { error, transactionId });\n\n messenger.call('TransactionPayController:updateFiatPayment', {\n callback: (fiatPayment) => {\n fiatPayment.rampsQuote = undefined;\n },\n transactionId,\n });\n }\n\n return [];\n}\n\nasync function probeMusdFiatAvailability({\n messenger,\n walletAddress,\n}: {\n messenger: PayStrategyGetQuotesRequest['messenger'];\n walletAddress: string;\n}): Promise<boolean> {\n try {\n const quotes = await messenger.call('RampsController:getQuotes', {\n amount: MUSD_PROBE_AMOUNT_USD,\n assetId: buildCaipAssetType(\n MUSD_MONAD_FIAT_ASSET.chainId,\n MUSD_MONAD_FIAT_ASSET.address,\n ),\n autoSelectProvider: true,\n fiat: DEFAULT_FIAT_CURRENCY,\n restrictToKnownOrNativeProviders: true,\n walletAddress,\n });\n\n const isAvailable = (quotes.success?.length ?? 0) > 0;\n\n log('mUSD fiat probe result', {\n isAvailable,\n providerCount: quotes.success?.length ?? 0,\n });\n\n return isAvailable;\n } catch (error) {\n log('mUSD fiat probe failed', { error });\n return false;\n }\n}\n\nasync function getRampsQuote({\n adjustedAmount,\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress,\n}: {\n adjustedAmount: number;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n messenger: PayStrategyGetQuotesRequest['messenger'];\n walletAddress: string;\n}): Promise<RampsQuote> {\n const quotes = await messenger.call('RampsController:getQuotes', {\n amount: adjustedAmount,\n assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),\n autoSelectProvider: true,\n fiat: DEFAULT_FIAT_CURRENCY,\n paymentMethods: [fiatPaymentMethod],\n restrictToKnownOrNativeProviders: true,\n walletAddress,\n });\n\n log('Fetched ramps quotes', {\n quotesCount: quotes.success?.length ?? 0,\n });\n\n const quote = quotes.success?.[0];\n\n if (!quote) {\n throw new Error('No matching ramps quote found for selected provider');\n }\n\n return quote;\n}\n\nfunction buildRelayRequestFromAmountFiat({\n amountFiat,\n fiatAsset,\n messenger,\n requiredToken,\n walletAddress,\n}: {\n amountFiat: string;\n fiatAsset: {\n address: Hex;\n chainId: Hex;\n };\n messenger: PayStrategyGetQuotesRequest['messenger'];\n requiredToken: TransactionPayRequiredToken;\n walletAddress: Hex;\n}): QuoteRequest | undefined {\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!sourceFiatRate) {\n return undefined;\n }\n\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n return undefined;\n }\n\n const sourceAmountRaw = computeRawFromFiatAmount(\n amountFiat,\n tokenInfo.decimals,\n sourceFiatRate.usdRate,\n );\n\n if (!sourceAmountRaw) {\n return undefined;\n }\n\n return {\n from: walletAddress,\n // Force EXACT_INPUT mode: source amount is pre-calculated from the fiat\n // amount, so the relay should treat it as a fixed input rather than\n // computing it from the target.\n isPostQuote: true,\n sourceBalanceRaw: sourceAmountRaw,\n sourceChainId: fiatAsset.chainId,\n sourceTokenAddress: fiatAsset.address,\n sourceTokenAmount: sourceAmountRaw,\n targetAmountMinimum: requiredToken.amountRaw,\n targetChainId: requiredToken.chainId,\n targetTokenAddress: requiredToken.address,\n };\n}\n\n/**\n * Combines fiat and relay legs into a single MM Pay fiat strategy quote.\n *\n * @param params - Combined quote inputs.\n * @param params.adjustedAmountFiat - Fiat amount sent to ramps after adding relay fee estimate.\n * @param params.amountFiat - User-entered fiat amount.\n * @param params.fiatQuote - Selected ramps quote.\n * @param params.relayQuote - Estimated relay quote.\n * @returns A single fiat strategy quote with split fee buckets.\n * @remarks\n * Fee mapping contract for MM Pay Fiat strategy:\n * - `fees.provider`: Total provider fee (relay provider/swap fee + ramps provider/network fee).\n * Consumed by UI transaction fee row and tooltip provider fee.\n * - `fees.providerFiat`: Fiat on-ramp provider fees only (`providerFee + networkFee` from ramps quote).\n * Optional breakdown; client can derive relay portion via `provider - providerFiat`.\n * - `fees.sourceNetwork` / `fees.targetNetwork`: Relay settlement network fees.\n * Consumed by UI transaction fee row and tooltip network fee.\n * - `fees.metaMask`: MM Pay fee (currently 100 bps over `amountFiat + adjustedAmountFiat`).\n * Consumed by UI transaction fee row and tooltip MetaMask fee.\n * - `totals.total` should represent Amount + Transaction Fee using the totals pipeline.\n */\nfunction combineQuotes({\n adjustedAmountFiat,\n amountFiat,\n fiatQuote,\n relayQuote,\n}: {\n adjustedAmountFiat: string;\n amountFiat: string;\n fiatQuote: RampsQuote;\n relayQuote: TransactionPayQuote<RelayQuote>;\n}): TransactionPayQuote<FiatQuote> {\n const rampsProviderFee = getRampsProviderFee(fiatQuote);\n const totalProviderFee = new BigNumber(relayQuote.fees.provider.usd)\n .plus(rampsProviderFee)\n .toString(10);\n const rampsProviderFeeStr = rampsProviderFee.toString(10);\n const metaMaskFee = getMetaMaskFee({\n adjustedAmountFiat,\n amountFiat,\n }).toString(10);\n\n return {\n ...relayQuote,\n fees: {\n ...relayQuote.fees,\n metaMask: {\n fiat: metaMaskFee,\n usd: metaMaskFee,\n },\n provider: {\n fiat: totalProviderFee,\n usd: totalProviderFee,\n },\n providerFiat: {\n fiat: rampsProviderFeeStr,\n usd: rampsProviderFeeStr,\n },\n },\n original: {\n rampsQuote: fiatQuote,\n relayQuote: relayQuote.original,\n },\n strategy: TransactionPayStrategy.Fiat,\n };\n}\n\n/**\n * Ramps providers handle network gas fees themselves but report them separately\n * as `networkFee` alongside their `providerFee`. We combine both into a single\n * ramps provider fee for the `providerFiat` breakdown.\n *\n * @param fiatQuote - The ramps quote containing provider and network fees.\n * @returns Combined ramps provider fee as a BigNumber.\n */\nfunction getRampsProviderFee(fiatQuote: RampsQuote): BigNumber {\n return new BigNumber(fiatQuote.quote.providerFee ?? 0).plus(\n fiatQuote.quote.networkFee ?? 0,\n );\n}\n\nfunction getRelayTotalFeeUsd(\n relayQuote: TransactionPayQuote<RelayQuote>,\n): BigNumber {\n return new BigNumber(relayQuote.fees.provider.usd)\n .plus(relayQuote.fees.sourceNetwork.estimate.usd)\n .plus(relayQuote.fees.targetNetwork.usd)\n .plus(relayQuote.fees.metaMask.usd);\n}\n\nfunction getNonGasRelayFeeUsd(\n relayQuote: TransactionPayQuote<RelayQuote>,\n): BigNumber {\n return new BigNumber(relayQuote.fees.provider.usd)\n .plus(relayQuote.fees.targetNetwork.usd)\n .plus(relayQuote.fees.metaMask.usd);\n}\n\nfunction getMetaMaskFee({\n adjustedAmountFiat,\n amountFiat,\n}: {\n adjustedAmountFiat: BigNumber.Value;\n amountFiat: BigNumber.Value;\n}): BigNumber {\n return new BigNumber(amountFiat).plus(adjustedAmountFiat).dividedBy(100);\n}\n"]}
@@ -3,15 +3,13 @@ import type { FiatQuote } from "./types.cjs";
3
3
  /**
4
4
  * Fetches MM Pay fiat strategy quotes using a relay-first estimation flow.
5
5
  *
6
+ * When the direct-to-mUSD flag is enabled and the transaction is a Money
7
+ * Account deposit, probes ramps for mUSD availability on Monad. If viable,
8
+ * uses direct mUSD params (asset, wallet, recipient); otherwise falls back
9
+ * to the standard ETH flow. Both paths share a single quote pipeline.
10
+ *
6
11
  * @param request - Strategy quotes request.
7
12
  * @returns A single combined fiat strategy quote, or an empty array when inputs/quotes are unavailable.
8
- * @remarks
9
- * Flow summary:
10
- * 1. Read `amountFiat` and selected payment method from transaction pay state.
11
- * 2. Build a synthetic relay request from `amountFiat` using source token USD rate.
12
- * 3. Fetch relay quote and compute total relay fee (`provider + source network + target network + MetaMask`).
13
- * 4. Call ramps quotes with `adjustedAmountFiat = amountFiat + relayTotalFeeUsd`.
14
- * 5. Pick the configured ramps provider quote and combine it with relay quote into one fiat strategy quote.
15
13
  */
16
14
  export declare function getFiatQuotes(request: PayStrategyGetQuotesRequest): Promise<TransactionPayQuote<FiatQuote>[]>;
17
15
  //# sourceMappingURL=fiat-quotes.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-quotes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAWrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AAKzC;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CA6G3C"}
1
+ {"version":3,"file":"fiat-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-quotes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,2BAA2B,EAI3B,mBAAmB,EACpB,wBAAoB;AAgBrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AAQzC;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAmC3C"}
@@ -3,15 +3,13 @@ import type { FiatQuote } from "./types.mjs";
3
3
  /**
4
4
  * Fetches MM Pay fiat strategy quotes using a relay-first estimation flow.
5
5
  *
6
+ * When the direct-to-mUSD flag is enabled and the transaction is a Money
7
+ * Account deposit, probes ramps for mUSD availability on Monad. If viable,
8
+ * uses direct mUSD params (asset, wallet, recipient); otherwise falls back
9
+ * to the standard ETH flow. Both paths share a single quote pipeline.
10
+ *
6
11
  * @param request - Strategy quotes request.
7
12
  * @returns A single combined fiat strategy quote, or an empty array when inputs/quotes are unavailable.
8
- * @remarks
9
- * Flow summary:
10
- * 1. Read `amountFiat` and selected payment method from transaction pay state.
11
- * 2. Build a synthetic relay request from `amountFiat` using source token USD rate.
12
- * 3. Fetch relay quote and compute total relay fee (`provider + source network + target network + MetaMask`).
13
- * 4. Call ramps quotes with `adjustedAmountFiat = amountFiat + relayTotalFeeUsd`.
14
- * 5. Pick the configured ramps provider quote and combine it with relay quote into one fiat strategy quote.
15
13
  */
16
14
  export declare function getFiatQuotes(request: PayStrategyGetQuotesRequest): Promise<TransactionPayQuote<FiatQuote>[]>;
17
15
  //# sourceMappingURL=fiat-quotes.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-quotes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAWrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AAKzC;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CA6G3C"}
1
+ {"version":3,"file":"fiat-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-quotes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,2BAA2B,EAI3B,mBAAmB,EACpB,wBAAoB;AAgBrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AAQzC;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC,CAmC3C"}
@@ -1,33 +1,61 @@
1
1
  import { createModuleLogger } from "@metamask/utils";
2
2
  import { BigNumber } from "bignumber.js";
3
- import { TransactionPayStrategy } from "../../constants.mjs";
3
+ import { NATIVE_TOKEN_ADDRESS, PaymentOverride, TransactionPayStrategy } from "../../constants.mjs";
4
4
  import { projectLogger } from "../../logger.mjs";
5
+ import { getDirectMoneyMusdEnabled } from "../../utils/feature-flags.mjs";
5
6
  import { buildCaipAssetType, computeRawFromFiatAmount, getTokenFiatRate, getTokenInfo } from "../../utils/token.mjs";
6
7
  import { getRelayQuotes } from "../relay/relay-quotes.mjs";
7
- import { DEFAULT_FIAT_CURRENCY } from "./constants.mjs";
8
- import { deriveFiatAssetForFiatPayment } from "./utils.mjs";
8
+ import { DEFAULT_FIAT_CURRENCY, MUSD_MONAD_FIAT_ASSET, MUSD_PROBE_AMOUNT_USD } from "./constants.mjs";
9
+ import { deriveFiatAssetForFiatPayment, isMoneyAccountDepositTransaction } from "./utils.mjs";
9
10
  const log = createModuleLogger(projectLogger, 'fiat-strategy');
10
11
  /**
11
12
  * Fetches MM Pay fiat strategy quotes using a relay-first estimation flow.
12
13
  *
14
+ * When the direct-to-mUSD flag is enabled and the transaction is a Money
15
+ * Account deposit, probes ramps for mUSD availability on Monad. If viable,
16
+ * uses direct mUSD params (asset, wallet, recipient); otherwise falls back
17
+ * to the standard ETH flow. Both paths share a single quote pipeline.
18
+ *
13
19
  * @param request - Strategy quotes request.
14
20
  * @returns A single combined fiat strategy quote, or an empty array when inputs/quotes are unavailable.
15
- * @remarks
16
- * Flow summary:
17
- * 1. Read `amountFiat` and selected payment method from transaction pay state.
18
- * 2. Build a synthetic relay request from `amountFiat` using source token USD rate.
19
- * 3. Fetch relay quote and compute total relay fee (`provider + source network + target network + MetaMask`).
20
- * 4. Call ramps quotes with `adjustedAmountFiat = amountFiat + relayTotalFeeUsd`.
21
- * 5. Pick the configured ramps provider quote and combine it with relay quote into one fiat strategy quote.
22
21
  */
23
22
  export async function getFiatQuotes(request) {
23
+ const { messenger, transaction } = request;
24
+ const useDirectMusd = getDirectMoneyMusdEnabled(messenger) &&
25
+ isMoneyAccountDepositTransaction(transaction);
26
+ if (useDirectMusd) {
27
+ const moneyAccountAddress = transaction.txParams.from;
28
+ const probeOk = await probeMusdFiatAvailability({
29
+ messenger,
30
+ walletAddress: moneyAccountAddress,
31
+ });
32
+ if (probeOk) {
33
+ const directResult = await executeFiatQuotePipeline(request, {
34
+ fiatAsset: MUSD_MONAD_FIAT_ASSET,
35
+ rampsWalletAddress: moneyAccountAddress,
36
+ relayRequestOverrides: {
37
+ paymentOverride: PaymentOverride.MoneyAccount,
38
+ recipient: moneyAccountAddress,
39
+ },
40
+ });
41
+ if (directResult.length > 0) {
42
+ return directResult;
43
+ }
44
+ }
45
+ }
46
+ return executeFiatQuotePipeline(request, {
47
+ fiatAsset: deriveFiatAssetForFiatPayment(transaction, messenger),
48
+ rampsWalletAddress: request.from,
49
+ });
50
+ }
51
+ async function executeFiatQuotePipeline(request, options) {
24
52
  const { accountSupports7702, fiatPaymentMethod, from: walletAddress, messenger, transaction, } = request;
53
+ const { fiatAsset, rampsWalletAddress, relayRequestOverrides } = options;
25
54
  const transactionId = transaction.id;
26
55
  const state = messenger.call('TransactionPayController:getState');
27
56
  const transactionData = state.transactionData[transactionId];
28
57
  const amountFiat = transactionData?.fiatPayment?.amountFiat;
29
- const requiredTokens = getRequiredTokens(transactionData?.tokens);
30
- const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);
58
+ const requiredTokens = transactionData?.tokens ?? [];
31
59
  if (!amountFiat || !fiatPaymentMethod || !requiredTokens.length) {
32
60
  return [];
33
61
  }
@@ -46,18 +74,25 @@ export async function getFiatQuotes(request) {
46
74
  if (!relayRequest) {
47
75
  throw new Error('Failed to build relay request from fiat amount');
48
76
  }
77
+ const finalRelayRequest = relayRequestOverrides
78
+ ? { ...relayRequest, ...relayRequestOverrides }
79
+ : relayRequest;
49
80
  const relayQuotes = await getRelayQuotes({
50
81
  accountSupports7702,
51
82
  from: walletAddress,
52
83
  messenger,
53
- requests: [relayRequest],
84
+ requests: [finalRelayRequest],
54
85
  transaction,
55
86
  });
56
87
  const relayQuote = relayQuotes[0];
57
88
  if (!relayQuote) {
58
89
  throw new Error('No relay quote available for fiat estimation');
59
90
  }
60
- const relayTotalFeeUsd = getRelayTotalFeeUsd(relayQuote);
91
+ const isSourceNative = fiatAsset.address.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
92
+ const gasDeductedFromSource = isSourceNative || relayQuote.fees.isSourceGasFeeToken === true;
93
+ const relayTotalFeeUsd = gasDeductedFromSource
94
+ ? getRelayTotalFeeUsd(relayQuote)
95
+ : getNonGasRelayFeeUsd(relayQuote);
61
96
  const adjustedAmountFiat = new BigNumber(amountFiat).plus(relayTotalFeeUsd);
62
97
  if (!adjustedAmountFiat.isFinite() ||
63
98
  !adjustedAmountFiat.gt(0) ||
@@ -72,7 +107,8 @@ export async function getFiatQuotes(request) {
72
107
  log('Fiat quote flow', {
73
108
  adjustedAmountFiat: adjustedAmountFiat.toString(10),
74
109
  amountFiat,
75
- paymentMethods: [fiatPaymentMethod],
110
+ isDirectMusd: Boolean(relayRequestOverrides),
111
+ rampsWalletAddress,
76
112
  relayTotalFeeUsd: relayTotalFeeUsd.toString(10),
77
113
  sourceAmountRaw: relayRequest.sourceTokenAmount,
78
114
  transactionId,
@@ -82,11 +118,12 @@ export async function getFiatQuotes(request) {
82
118
  fiatAsset,
83
119
  fiatPaymentMethod,
84
120
  messenger,
85
- walletAddress,
121
+ walletAddress: rampsWalletAddress,
86
122
  });
87
123
  messenger.call('TransactionPayController:updateFiatPayment', {
88
124
  callback: (fiatPayment) => {
89
125
  fiatPayment.rampsQuote = fiatQuote;
126
+ fiatPayment.caipAssetId = buildCaipAssetType(fiatAsset.chainId, fiatAsset.address);
90
127
  },
91
128
  transactionId,
92
129
  });
@@ -101,11 +138,36 @@ export async function getFiatQuotes(request) {
101
138
  }
102
139
  catch (error) {
103
140
  log('Failed to fetch fiat quotes', { error, transactionId });
141
+ messenger.call('TransactionPayController:updateFiatPayment', {
142
+ callback: (fiatPayment) => {
143
+ fiatPayment.rampsQuote = undefined;
144
+ },
145
+ transactionId,
146
+ });
104
147
  }
105
148
  return [];
106
149
  }
107
- function getRequiredTokens(tokens) {
108
- return tokens?.filter((token) => !token.skipIfBalance) ?? [];
150
+ async function probeMusdFiatAvailability({ messenger, walletAddress, }) {
151
+ try {
152
+ const quotes = await messenger.call('RampsController:getQuotes', {
153
+ amount: MUSD_PROBE_AMOUNT_USD,
154
+ assetId: buildCaipAssetType(MUSD_MONAD_FIAT_ASSET.chainId, MUSD_MONAD_FIAT_ASSET.address),
155
+ autoSelectProvider: true,
156
+ fiat: DEFAULT_FIAT_CURRENCY,
157
+ restrictToKnownOrNativeProviders: true,
158
+ walletAddress,
159
+ });
160
+ const isAvailable = (quotes.success?.length ?? 0) > 0;
161
+ log('mUSD fiat probe result', {
162
+ isAvailable,
163
+ providerCount: quotes.success?.length ?? 0,
164
+ });
165
+ return isAvailable;
166
+ }
167
+ catch (error) {
168
+ log('mUSD fiat probe failed', { error });
169
+ return false;
170
+ }
109
171
  }
110
172
  async function getRampsQuote({ adjustedAmount, fiatAsset, fiatPaymentMethod, messenger, walletAddress, }) {
111
173
  const quotes = await messenger.call('RampsController:getQuotes', {
@@ -226,6 +288,11 @@ function getRelayTotalFeeUsd(relayQuote) {
226
288
  .plus(relayQuote.fees.targetNetwork.usd)
227
289
  .plus(relayQuote.fees.metaMask.usd);
228
290
  }
291
+ function getNonGasRelayFeeUsd(relayQuote) {
292
+ return new BigNumber(relayQuote.fees.provider.usd)
293
+ .plus(relayQuote.fees.targetNetwork.usd)
294
+ .plus(relayQuote.fees.metaMask.usd);
295
+ }
229
296
  function getMetaMaskFee({ adjustedAmountFiat, amountFiat, }) {
230
297
  return new BigNumber(amountFiat).plus(adjustedAmountFiat).dividedBy(100);
231
298
  }