@metamask-previews/transaction-pay-controller 31.2.1-preview-1ae799a5c → 31.2.1-preview-e80304db4

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 (100) hide show
  1. package/CHANGELOG.md +1 -20
  2. package/dist/TransactionPayController.d.ts.map +1 -1
  3. package/dist/TransactionPayController.js +5 -4
  4. package/dist/TransactionPayController.js.map +1 -1
  5. package/dist/actions/update-payment-token.d.ts.map +1 -1
  6. package/dist/actions/update-payment-token.js +22 -51
  7. package/dist/actions/update-payment-token.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/strategy/across/AcrossStrategy.d.ts.map +1 -1
  12. package/dist/strategy/across/AcrossStrategy.js +1 -6
  13. package/dist/strategy/across/AcrossStrategy.js.map +1 -1
  14. package/dist/strategy/across/across-quotes.js +4 -7
  15. package/dist/strategy/across/across-quotes.js.map +1 -1
  16. package/dist/strategy/across/across-submit.d.ts.map +1 -1
  17. package/dist/strategy/across/across-submit.js +1 -3
  18. package/dist/strategy/across/across-submit.js.map +1 -1
  19. package/dist/strategy/fiat/FiatStrategy.d.ts +0 -1
  20. package/dist/strategy/fiat/FiatStrategy.d.ts.map +1 -1
  21. package/dist/strategy/fiat/FiatStrategy.js +0 -4
  22. package/dist/strategy/fiat/FiatStrategy.js.map +1 -1
  23. package/dist/strategy/fiat/fiat-direct-musd.d.ts.map +1 -1
  24. package/dist/strategy/fiat/fiat-direct-musd.js +2 -4
  25. package/dist/strategy/fiat/fiat-direct-musd.js.map +1 -1
  26. package/dist/strategy/fiat/fiat-quotes.d.ts.map +1 -1
  27. package/dist/strategy/fiat/fiat-quotes.js +2 -4
  28. package/dist/strategy/fiat/fiat-quotes.js.map +1 -1
  29. package/dist/strategy/fiat/fiat-submit.d.ts.map +1 -1
  30. package/dist/strategy/fiat/fiat-submit.js +2 -5
  31. package/dist/strategy/fiat/fiat-submit.js.map +1 -1
  32. package/dist/strategy/fiat/fiat-test-funding.d.ts.map +1 -1
  33. package/dist/strategy/fiat/fiat-test-funding.js +5 -3
  34. package/dist/strategy/fiat/fiat-test-funding.js.map +1 -1
  35. package/dist/strategy/relay/RelayStrategy.d.ts +0 -4
  36. package/dist/strategy/relay/RelayStrategy.d.ts.map +1 -1
  37. package/dist/strategy/relay/RelayStrategy.js +1 -6
  38. package/dist/strategy/relay/RelayStrategy.js.map +1 -1
  39. package/dist/strategy/relay/relay-quotes.d.ts.map +1 -1
  40. package/dist/strategy/relay/relay-quotes.js +6 -10
  41. package/dist/strategy/relay/relay-quotes.js.map +1 -1
  42. package/dist/strategy/relay/relay-submit-execute.d.ts.map +1 -1
  43. package/dist/strategy/relay/relay-submit-execute.js +1 -3
  44. package/dist/strategy/relay/relay-submit-execute.js.map +1 -1
  45. package/dist/strategy/relay/relay-submit.d.ts.map +1 -1
  46. package/dist/strategy/relay/relay-submit.js +6 -8
  47. package/dist/strategy/relay/relay-submit.js.map +1 -1
  48. package/dist/strategy/relay/relay-validation.d.ts.map +1 -1
  49. package/dist/strategy/relay/relay-validation.js +2 -5
  50. package/dist/strategy/relay/relay-validation.js.map +1 -1
  51. package/dist/strategy/server/ServerStrategy.d.ts.map +1 -1
  52. package/dist/strategy/server/ServerStrategy.js +0 -4
  53. package/dist/strategy/server/ServerStrategy.js.map +1 -1
  54. package/dist/strategy/server/server-quotes.js +4 -7
  55. package/dist/strategy/server/server-quotes.js.map +1 -1
  56. package/dist/strategy/server/server-submit.d.ts.map +1 -1
  57. package/dist/strategy/server/server-submit.js +6 -9
  58. package/dist/strategy/server/server-submit.js.map +1 -1
  59. package/dist/strategy/server/server-validation.d.ts.map +1 -1
  60. package/dist/strategy/server/server-validation.js +1 -3
  61. package/dist/strategy/server/server-validation.js.map +1 -1
  62. package/dist/types.d.ts +25 -60
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/types.js.map +1 -1
  65. package/dist/utils/account.d.ts +0 -54
  66. package/dist/utils/account.d.ts.map +1 -1
  67. package/dist/utils/account.js +0 -124
  68. package/dist/utils/account.js.map +1 -1
  69. package/dist/utils/gas-payment.d.ts +3 -12
  70. package/dist/utils/gas-payment.d.ts.map +1 -1
  71. package/dist/utils/gas-payment.js +2 -2
  72. package/dist/utils/gas-payment.js.map +1 -1
  73. package/dist/utils/max-gas-station.d.ts.map +1 -1
  74. package/dist/utils/max-gas-station.js +5 -9
  75. package/dist/utils/max-gas-station.js.map +1 -1
  76. package/dist/utils/max-quote.js +2 -3
  77. package/dist/utils/max-quote.js.map +1 -1
  78. package/dist/utils/no-op-quote.d.ts +3 -3
  79. package/dist/utils/no-op-quote.d.ts.map +1 -1
  80. package/dist/utils/no-op-quote.js +3 -4
  81. package/dist/utils/no-op-quote.js.map +1 -1
  82. package/dist/utils/perps.d.ts.map +1 -1
  83. package/dist/utils/perps.js +2 -5
  84. package/dist/utils/perps.js.map +1 -1
  85. package/dist/utils/post-quote.js +3 -4
  86. package/dist/utils/post-quote.js.map +1 -1
  87. package/dist/utils/quotes.d.ts.map +1 -1
  88. package/dist/utils/quotes.js +25 -99
  89. package/dist/utils/quotes.js.map +1 -1
  90. package/dist/utils/source-amounts.d.ts.map +1 -1
  91. package/dist/utils/source-amounts.js +4 -25
  92. package/dist/utils/source-amounts.js.map +1 -1
  93. package/dist/utils/token.d.ts +1 -84
  94. package/dist/utils/token.d.ts.map +1 -1
  95. package/dist/utils/token.js +13 -144
  96. package/dist/utils/token.js.map +1 -1
  97. package/dist/utils/validation.d.ts.map +1 -1
  98. package/dist/utils/validation.js +11 -14
  99. package/dist/utils/validation.js.map +1 -1
  100. package/package.json +1 -2
@@ -2,7 +2,6 @@ import { createModuleLogger } from '@metamask/utils';
2
2
  import { BigNumber } from 'bignumber.js';
3
3
  import { NATIVE_TOKEN_ADDRESS, TransactionPayStrategy, } from '../../constants.js';
4
4
  import { projectLogger } from '../../logger.js';
5
- import { getCaipAccountId } from '../../utils/account.js';
6
5
  import { getDirectMoneyMusdEnabled } from '../../utils/feature-flags.js';
7
6
  import { buildCaipAssetType, computeRawFromFiatAmount, getTokenFiatRate, getTokenInfo, } from '../../utils/token.js';
8
7
  import { getRelayQuotes } from '../relay/relay-quotes.js';
@@ -150,16 +149,15 @@ function buildRelayRequestFromAmountFiat({ amountFiat, fiatAsset, messenger, req
150
149
  if (!sourceAmountRaw) {
151
150
  return undefined;
152
151
  }
153
- const sourceAssetId = buildCaipAssetType(fiatAsset.chainId, fiatAsset.address);
154
152
  return {
155
153
  from: walletAddress,
156
154
  // Force EXACT_INPUT mode: source amount is pre-calculated from the fiat
157
155
  // amount, so the relay should treat it as a fixed input rather than
158
156
  // computing it from the target.
159
157
  isPostQuote: true,
160
- sourceAccountId: getCaipAccountId(sourceAssetId, walletAddress),
161
- sourceAssetId,
162
158
  sourceBalanceRaw: sourceAmountRaw,
159
+ sourceChainId: fiatAsset.chainId,
160
+ sourceTokenAddress: fiatAsset.address,
163
161
  sourceTokenAmount: sourceAmountRaw,
164
162
  targetAmountMinimum: requiredToken.amountRaw,
165
163
  targetChainId: requiredToken.chainId,
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-quotes.js","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 TransactionPayStrategy,\n} from '../../constants.js';\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionFiatPayment,\n TransactionPayRequiredToken,\n TransactionPayQuote,\n} from '../../types.js';\nimport { getCaipAccountId } from '../../utils/account.js';\nimport { getDirectMoneyMusdEnabled } from '../../utils/feature-flags.js';\nimport {\n buildCaipAssetType,\n computeRawFromFiatAmount,\n getTokenFiatRate,\n getTokenInfo,\n} from '../../utils/token.js';\nimport { getRelayQuotes } from '../relay/relay-quotes.js';\nimport type { RelayQuote } from '../relay/types.js';\nimport type { TransactionPayFiatAsset } from './constants.js';\nimport { getDirectMusdFiatQuote } from './fiat-direct-musd.js';\nimport type { FiatQuote } from './types.js';\nimport {\n deriveFiatAssetForFiatPayment,\n getRampsQuote,\n isMoneyAccountDepositTransaction,\n} from './utils.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-strategy');\n\ntype FiatQuotePipelineOptions = {\n amountFiat: string;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n rampsWalletAddress: Hex;\n requiredTokens: TransactionPayRequiredToken[];\n};\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, uses direct mUSD params (asset, wallet, recipient).\n * Otherwise, uses the standard ETH 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 */\nexport async function getFiatQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const { messenger, transaction } = request;\n\n const state = messenger.call('TransactionPayController:getState');\n const transactionData = state.transactionData[transaction.id];\n const amountFiat = transactionData?.fiatPayment?.amountFiat;\n const requiredTokens = transactionData?.tokens ?? [];\n\n if (\n !amountFiat ||\n !request.fiatPaymentMethod ||\n requiredTokens.length !== 1\n ) {\n return [];\n }\n\n const useDirectMusd =\n getDirectMoneyMusdEnabled(messenger) &&\n isMoneyAccountDepositTransaction(transaction);\n\n if (useDirectMusd) {\n const requiredToken = requiredTokens[0];\n\n const directQuote = await getDirectMusdFiatQuote({\n amountFiat,\n fiatPaymentMethod: request.fiatPaymentMethod,\n messenger,\n moneyAccountAddress: transaction.txParams.from as Hex,\n requiredToken,\n transactionId: transaction.id,\n });\n\n return directQuote ? [directQuote] : [];\n }\n\n return executeFiatQuotePipeline(request, {\n amountFiat,\n fiatAsset: deriveFiatAssetForFiatPayment(transaction, messenger),\n fiatPaymentMethod: request.fiatPaymentMethod,\n rampsWalletAddress: request.from,\n requiredTokens,\n });\n}\n\nasync function executeFiatQuotePipeline(\n request: PayStrategyGetQuotesRequest,\n options: FiatQuotePipelineOptions,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const {\n accountSupports7702,\n from: walletAddress,\n messenger,\n transaction,\n } = request;\n const {\n amountFiat,\n fiatAsset,\n fiatPaymentMethod,\n rampsWalletAddress,\n requiredTokens,\n } = options;\n const transactionId = transaction.id;\n\n try {\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 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 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\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 const sourceAssetId = buildCaipAssetType(\n fiatAsset.chainId,\n fiatAsset.address,\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 sourceAccountId: getCaipAccountId(sourceAssetId, walletAddress),\n sourceAssetId,\n sourceBalanceRaw: sourceAmountRaw,\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, with fees already reconciled\n * to the resolved provider by `RampsController:getQuoteWithFees`.\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"]}
1
+ {"version":3,"file":"fiat-quotes.js","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 TransactionPayStrategy,\n} from '../../constants.js';\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionFiatPayment,\n TransactionPayRequiredToken,\n TransactionPayQuote,\n} from '../../types.js';\nimport { getDirectMoneyMusdEnabled } from '../../utils/feature-flags.js';\nimport {\n buildCaipAssetType,\n computeRawFromFiatAmount,\n getTokenFiatRate,\n getTokenInfo,\n} from '../../utils/token.js';\nimport { getRelayQuotes } from '../relay/relay-quotes.js';\nimport type { RelayQuote } from '../relay/types.js';\nimport type { TransactionPayFiatAsset } from './constants.js';\nimport { getDirectMusdFiatQuote } from './fiat-direct-musd.js';\nimport type { FiatQuote } from './types.js';\nimport {\n deriveFiatAssetForFiatPayment,\n getRampsQuote,\n isMoneyAccountDepositTransaction,\n} from './utils.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-strategy');\n\ntype FiatQuotePipelineOptions = {\n amountFiat: string;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n rampsWalletAddress: Hex;\n requiredTokens: TransactionPayRequiredToken[];\n};\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, uses direct mUSD params (asset, wallet, recipient).\n * Otherwise, uses the standard ETH 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 */\nexport async function getFiatQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const { messenger, transaction } = request;\n\n const state = messenger.call('TransactionPayController:getState');\n const transactionData = state.transactionData[transaction.id];\n const amountFiat = transactionData?.fiatPayment?.amountFiat;\n const requiredTokens = transactionData?.tokens ?? [];\n\n if (\n !amountFiat ||\n !request.fiatPaymentMethod ||\n requiredTokens.length !== 1\n ) {\n return [];\n }\n\n const useDirectMusd =\n getDirectMoneyMusdEnabled(messenger) &&\n isMoneyAccountDepositTransaction(transaction);\n\n if (useDirectMusd) {\n const requiredToken = requiredTokens[0];\n\n const directQuote = await getDirectMusdFiatQuote({\n amountFiat,\n fiatPaymentMethod: request.fiatPaymentMethod,\n messenger,\n moneyAccountAddress: transaction.txParams.from as Hex,\n requiredToken,\n transactionId: transaction.id,\n });\n\n return directQuote ? [directQuote] : [];\n }\n\n return executeFiatQuotePipeline(request, {\n amountFiat,\n fiatAsset: deriveFiatAssetForFiatPayment(transaction, messenger),\n fiatPaymentMethod: request.fiatPaymentMethod,\n rampsWalletAddress: request.from,\n requiredTokens,\n });\n}\n\nasync function executeFiatQuotePipeline(\n request: PayStrategyGetQuotesRequest,\n options: FiatQuotePipelineOptions,\n): Promise<TransactionPayQuote<FiatQuote>[]> {\n const {\n accountSupports7702,\n from: walletAddress,\n messenger,\n transaction,\n } = request;\n const {\n amountFiat,\n fiatAsset,\n fiatPaymentMethod,\n rampsWalletAddress,\n requiredTokens,\n } = options;\n const transactionId = transaction.id;\n\n try {\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 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 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\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, with fees already reconciled\n * to the resolved provider by `RampsController:getQuoteWithFees`.\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-submit.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EAG1B,MAAM,gBAAgB,CAAC;AAexB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAiB5C;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,GAC5C,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAyF/C"}
1
+ {"version":3,"file":"fiat-submit.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EAG1B,MAAM,gBAAgB,CAAC;AAcxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAiB5C;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,GAC5C,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAwF/C"}
@@ -1,7 +1,6 @@
1
1
  import { RampsOrderStatus } from '@metamask/ramps-controller';
2
2
  import { createModuleLogger } from '@metamask/utils';
3
3
  import { projectLogger } from '../../logger.js';
4
- import { getEvmAccountOverride } from '../../utils/account.js';
5
4
  import { prefixError } from '../../utils/error-prefix.js';
6
5
  import { getFiatOrderPollIntervalMs, getFiatOrderPollTimeoutMs, } from '../../utils/feature-flags.js';
7
6
  import { updateTransaction } from '../../utils/transaction.js';
@@ -34,7 +33,6 @@ export async function submitFiatQuotes(request) {
34
33
  const state = messenger.call('TransactionPayController:getState');
35
34
  const transactionData = state.transactionData[transactionId];
36
35
  const walletAddress = getWalletAddress({
37
- messenger,
38
36
  quotes: request.quotes,
39
37
  transaction,
40
38
  accountOverride: transactionData?.accountOverride,
@@ -212,11 +210,10 @@ async function submitRelayAfterFiatCompletion({ order, request, }) {
212
210
  transaction,
213
211
  });
214
212
  }
215
- function getWalletAddress({ messenger, quotes, transaction, accountOverride, }) {
213
+ function getWalletAddress({ quotes, transaction, accountOverride, }) {
216
214
  const address = isDirectMusdMoneyAccountQuote(quotes[0])
217
215
  ? transaction.txParams.from
218
- : (getEvmAccountOverride(messenger, accountOverride) ??
219
- transaction.txParams.from);
216
+ : (accountOverride ?? transaction.txParams.from);
220
217
  if (!address) {
221
218
  throw new Error('Missing wallet address');
222
219
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-submit.js","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RampsOrder } from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n TransactionPayFiatOptions,\n TransactionPayControllerMessenger,\n} from '../../types.js';\nimport { getEvmAccountOverride } from '../../utils/account.js';\nimport { prefixError } from '../../utils/error-prefix.js';\nimport {\n getFiatOrderPollIntervalMs,\n getFiatOrderPollTimeoutMs,\n} from '../../utils/feature-flags.js';\nimport { updateTransaction } from '../../utils/transaction.js';\nimport {\n isDirectMusdMoneyAccountQuote,\n submitDirectMusdAfterFiatCompletion,\n} from './fiat-direct-musd.js';\nimport { submitSimpleRelay } from './fiat-submit-simple.js';\nimport { submitWithTransactionData } from './fiat-submit-with-transaction-data.js';\nimport { fundFiatOrderFromTestSource } from './fiat-test-funding.js';\nimport type { FiatQuote } from './types.js';\nimport {\n deriveFiatAssetForFiatPayment,\n extractProviderCode,\n resolveSourceAmountRaw,\n validateOrderAsset,\n} from './utils.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\nconst POST_RAMP_ERROR_PREFIX = 'Post-Ramp: ';\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const state = messenger.call('TransactionPayController:getState');\n const transactionData = state.transactionData[transactionId];\n\n const walletAddress = getWalletAddress({\n messenger,\n quotes: request.quotes,\n transaction,\n accountOverride: transactionData?.accountOverride,\n });\n\n const fiatPayment = transactionData?.fiatPayment;\n const orderId = fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID');\n }\n\n const providerCode = extractProviderCode(fiatPayment?.rampsQuote?.provider);\n\n if (!providerCode) {\n throw new Error('Missing provider code');\n }\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Persist fiat order metadata',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.fiat = { orderId, provider: providerCode };\n },\n );\n\n log('Starting fiat order polling', {\n orderId,\n providerCode,\n transactionId,\n });\n\n const fiatQuote = request.quotes[0];\n\n if (!fiatQuote) {\n throw new Error('Missing quote');\n }\n\n const fiatOptions = getFiatOptions(messenger);\n\n const order = fiatOptions?.testFundingSource\n ? await fundFiatOrderFromTestSource({\n fiat: fiatOptions,\n messenger,\n quote: fiatQuote,\n transaction,\n })\n : await waitForOrderCompletion({\n messenger,\n orderCode: orderId,\n providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n try {\n await waitForKeyringUnlock(messenger, transactionId);\n\n const result = await submitRelayAfterFiatCompletion({\n order,\n request,\n });\n\n if (result.transactionHash === undefined) {\n throw new Error('Missing transaction hash');\n }\n\n return result;\n } catch (error) {\n throw prefixError(error, POST_RAMP_ERROR_PREFIX);\n }\n}\n\nfunction getFiatOptions(\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatOptions | undefined {\n try {\n return messenger.call('TransactionPayController:getFiatOptions');\n } catch (error) {\n log('Failed to retrieve fiat options', error);\n return undefined;\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const pollIntervalMs = getFiatOrderPollIntervalMs(messenger);\n const pollTimeoutMs = getFiatOrderPollTimeoutMs(messenger);\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= pollTimeoutMs) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatQuote = quotes[0];\n const isDirectMusd = isDirectMusdMoneyAccountQuote(fiatQuote);\n\n if (isDirectMusd) {\n return await submitDirectMusdAfterFiatCompletion({\n order,\n request,\n });\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const baseRequest = fiatQuote.request;\n\n const sourceAmountRaw = await resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress: baseRequest.from,\n });\n\n if (!fiatQuote.original.relayQuote) {\n throw new Error('Missing Relay quote');\n }\n\n const hasNestedCalldata = (transaction.nestedTransactions?.length ?? 0) >= 2;\n\n // Transactions with nested calldata (e.g. moneyAccountDeposit with\n // approve + deposit) need a three-phase flow: discovery quote to learn\n // the target amount, calldata re-encoding, then a delegation quote.\n // Simple deposits (Perps, Predict) skip straight to a single EXACT_INPUT\n // relay quote — cheaper fees, no leftover dust, one fewer request.\n if (hasNestedCalldata) {\n return await submitWithTransactionData({\n baseRequest,\n request,\n sourceAmountRaw,\n transaction,\n });\n }\n\n return await submitSimpleRelay({\n baseRequest,\n request,\n sourceAmountRaw,\n transaction,\n });\n}\n\nfunction getWalletAddress({\n messenger,\n quotes,\n transaction,\n accountOverride,\n}: {\n messenger: TransactionPayControllerMessenger;\n quotes: PayStrategyExecuteRequest<FiatQuote>['quotes'];\n transaction: PayStrategyExecuteRequest<FiatQuote>['transaction'];\n accountOverride: string | undefined;\n}): Hex {\n const address = isDirectMusdMoneyAccountQuote(quotes[0])\n ? transaction.txParams.from\n : (getEvmAccountOverride(messenger, accountOverride) ??\n transaction.txParams.from);\n\n if (!address) {\n throw new Error('Missing wallet address');\n }\n\n return address as Hex;\n}\n\nfunction waitForKeyringUnlock(\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n): Promise<void> {\n const { isUnlocked } = messenger.call('KeyringController:getState');\n\n if (isUnlocked) {\n return Promise.resolve();\n }\n\n log(\n 'KeyringController is locked; waiting for unlock before fiat submit second leg',\n {\n transactionId,\n },\n );\n\n return new Promise((resolve) => {\n const handler = (): void => {\n messenger.unsubscribe('KeyringController:unlock', handler);\n\n log('KeyringController unlocked; resuming fiat submit second leg', {\n transactionId,\n });\n\n resolve();\n };\n\n messenger.subscribe('KeyringController:unlock', handler);\n });\n}\n"]}
1
+ {"version":3,"file":"fiat-submit.js","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOhD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EACL,6BAA6B,EAC7B,mCAAmC,GACpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAErE,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,MAAM,GAAG,GAAG,kBAAkB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAC7D,MAAM,sBAAsB,GAAG,aAAa,CAAC;AAE7C,MAAM,yBAAyB,GAAuB;IACpD,gBAAgB,CAAC,SAAS;IAC1B,gBAAgB,CAAC,MAAM;IACvB,gBAAgB,CAAC,SAAS;CAC3B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA6C;IAE7C,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC3C,MAAM,aAAa,GAAG,WAAW,CAAC,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAClE,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IAE7D,MAAM,aAAa,GAAG,gBAAgB,CAAC;QACrC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW;QACX,eAAe,EAAE,eAAe,EAAE,eAAe;KAClD,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,eAAe,EAAE,WAAW,CAAC;IACjD,MAAM,OAAO,GAAG,WAAW,EAAE,OAAO,CAAC;IAErC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE5E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,iBAAiB,CACf;QACE,aAAa;QACb,SAAS;QACT,IAAI,EAAE,6BAA6B;KACpC,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,WAAW,KAAK,EAAE,CAAC;QACtB,EAAE,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAC5D,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,6BAA6B,EAAE;QACjC,OAAO;QACP,YAAY;QACZ,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAEpC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAG,WAAW,EAAE,iBAAiB;QAC1C,CAAC,CAAC,MAAM,2BAA2B,CAAC;YAChC,IAAI,EAAE,WAAW;YACjB,SAAS;YACT,KAAK,EAAE,SAAS;YAChB,WAAW;SACZ,CAAC;QACJ,CAAC,CAAC,MAAM,sBAAsB,CAAC;YAC3B,SAAS;YACT,SAAS,EAAE,OAAO;YAClB,YAAY;YACZ,aAAa;YACb,aAAa;SACd,CAAC,CAAC;IAEP,GAAG,CAAC,sBAAsB,EAAE;QAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO;QACP,aAAa;KACd,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,oBAAoB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,8BAA8B,CAAC;YAClD,KAAK;YACL,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CACrB,SAA4C;IAE5C,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,sBAAsB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,GAOd;IACC,MAAM,cAAc,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,UAA8B,CAAC;IAEnC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,KAA6B,CAAC;QAElC,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAC1B,0BAA0B,EAC1B,YAAY,EACZ,SAAS,EACT,aAAa,CACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;YAE1B,GAAG,CAAC,mBAAmB,EAAE;gBACvB,WAAW,EAAE,KAAK,CAAC,MAAM;gBACzB,YAAY;gBACZ,aAAa;aACd,CAAC,CAAC;YAEH,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC,SAAS,EAAE,CAAC;gBAChD,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAI,yBAAyB,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,aAAa,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CACb,8CAA8C,UAAU,GAAG,CAC5D,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,8BAA8B,CAAC,EAC5C,KAAK,EACL,OAAO,GAIR;IACC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,aAAa,GAAG,WAAW,CAAC,EAAE,CAAC;IAErC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,YAAY,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC;IAE9D,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,MAAM,mCAAmC,CAAC;YAC/C,KAAK;YACL,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,6BAA6B,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAExE,kBAAkB,CAAC;QACjB,aAAa,EAAE,SAAS;QACxB,WAAW,EAAE,KAAK,CAAC,cAAc;QACjC,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;IAEtC,MAAM,eAAe,GAAG,MAAM,sBAAsB,CAAC;QACnD,SAAS;QACT,KAAK;QACL,SAAS;QACT,aAAa,EAAE,WAAW,CAAC,IAAI;KAChC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,WAAW,CAAC,kBAAkB,EAAE,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAE7E,mEAAmE;IACnE,uEAAuE;IACvE,oEAAoE;IACpE,yEAAyE;IACzE,mEAAmE;IACnE,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,MAAM,yBAAyB,CAAC;YACrC,WAAW;YACX,OAAO;YACP,eAAe;YACf,WAAW;SACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,iBAAiB,CAAC;QAC7B,WAAW;QACX,OAAO;QACP,eAAe;QACf,WAAW;KACZ,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,EACxB,MAAM,EACN,WAAW,EACX,eAAe,GAKhB;IACC,MAAM,OAAO,GAAG,6BAA6B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI;QAC3B,CAAC,CAAC,CAAC,eAAe,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,OAAc,CAAC;AACxB,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAA4C,EAC5C,aAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAEpE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,GAAG,CACD,+EAA+E,EAC/E;QACE,aAAa;KACd,CACF,CAAC;IAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,SAAS,CAAC,WAAW,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC;YAE3D,GAAG,CAAC,6DAA6D,EAAE;gBACjE,aAAa;aACd,CAAC,CAAC;YAEH,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,SAAS,CAAC,SAAS,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { RampsOrder } from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n TransactionPayFiatOptions,\n TransactionPayControllerMessenger,\n} from '../../types.js';\nimport { prefixError } from '../../utils/error-prefix.js';\nimport {\n getFiatOrderPollIntervalMs,\n getFiatOrderPollTimeoutMs,\n} from '../../utils/feature-flags.js';\nimport { updateTransaction } from '../../utils/transaction.js';\nimport {\n isDirectMusdMoneyAccountQuote,\n submitDirectMusdAfterFiatCompletion,\n} from './fiat-direct-musd.js';\nimport { submitSimpleRelay } from './fiat-submit-simple.js';\nimport { submitWithTransactionData } from './fiat-submit-with-transaction-data.js';\nimport { fundFiatOrderFromTestSource } from './fiat-test-funding.js';\nimport type { FiatQuote } from './types.js';\nimport {\n deriveFiatAssetForFiatPayment,\n extractProviderCode,\n resolveSourceAmountRaw,\n validateOrderAsset,\n} from './utils.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\nconst POST_RAMP_ERROR_PREFIX = 'Post-Ramp: ';\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const state = messenger.call('TransactionPayController:getState');\n const transactionData = state.transactionData[transactionId];\n\n const walletAddress = getWalletAddress({\n quotes: request.quotes,\n transaction,\n accountOverride: transactionData?.accountOverride,\n });\n\n const fiatPayment = transactionData?.fiatPayment;\n const orderId = fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID');\n }\n\n const providerCode = extractProviderCode(fiatPayment?.rampsQuote?.provider);\n\n if (!providerCode) {\n throw new Error('Missing provider code');\n }\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Persist fiat order metadata',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.fiat = { orderId, provider: providerCode };\n },\n );\n\n log('Starting fiat order polling', {\n orderId,\n providerCode,\n transactionId,\n });\n\n const fiatQuote = request.quotes[0];\n\n if (!fiatQuote) {\n throw new Error('Missing quote');\n }\n\n const fiatOptions = getFiatOptions(messenger);\n\n const order = fiatOptions?.testFundingSource\n ? await fundFiatOrderFromTestSource({\n fiat: fiatOptions,\n messenger,\n quote: fiatQuote,\n transaction,\n })\n : await waitForOrderCompletion({\n messenger,\n orderCode: orderId,\n providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n try {\n await waitForKeyringUnlock(messenger, transactionId);\n\n const result = await submitRelayAfterFiatCompletion({\n order,\n request,\n });\n\n if (result.transactionHash === undefined) {\n throw new Error('Missing transaction hash');\n }\n\n return result;\n } catch (error) {\n throw prefixError(error, POST_RAMP_ERROR_PREFIX);\n }\n}\n\nfunction getFiatOptions(\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatOptions | undefined {\n try {\n return messenger.call('TransactionPayController:getFiatOptions');\n } catch (error) {\n log('Failed to retrieve fiat options', error);\n return undefined;\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const pollIntervalMs = getFiatOrderPollIntervalMs(messenger);\n const pollTimeoutMs = getFiatOrderPollTimeoutMs(messenger);\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= pollTimeoutMs) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatQuote = quotes[0];\n const isDirectMusd = isDirectMusdMoneyAccountQuote(fiatQuote);\n\n if (isDirectMusd) {\n return await submitDirectMusdAfterFiatCompletion({\n order,\n request,\n });\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const baseRequest = fiatQuote.request;\n\n const sourceAmountRaw = await resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress: baseRequest.from,\n });\n\n if (!fiatQuote.original.relayQuote) {\n throw new Error('Missing Relay quote');\n }\n\n const hasNestedCalldata = (transaction.nestedTransactions?.length ?? 0) >= 2;\n\n // Transactions with nested calldata (e.g. moneyAccountDeposit with\n // approve + deposit) need a three-phase flow: discovery quote to learn\n // the target amount, calldata re-encoding, then a delegation quote.\n // Simple deposits (Perps, Predict) skip straight to a single EXACT_INPUT\n // relay quote — cheaper fees, no leftover dust, one fewer request.\n if (hasNestedCalldata) {\n return await submitWithTransactionData({\n baseRequest,\n request,\n sourceAmountRaw,\n transaction,\n });\n }\n\n return await submitSimpleRelay({\n baseRequest,\n request,\n sourceAmountRaw,\n transaction,\n });\n}\n\nfunction getWalletAddress({\n quotes,\n transaction,\n accountOverride,\n}: {\n quotes: PayStrategyExecuteRequest<FiatQuote>['quotes'];\n transaction: PayStrategyExecuteRequest<FiatQuote>['transaction'];\n accountOverride: Hex | undefined;\n}): Hex {\n const address = isDirectMusdMoneyAccountQuote(quotes[0])\n ? transaction.txParams.from\n : (accountOverride ?? transaction.txParams.from);\n\n if (!address) {\n throw new Error('Missing wallet address');\n }\n\n return address as Hex;\n}\n\nfunction waitForKeyringUnlock(\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n): Promise<void> {\n const { isUnlocked } = messenger.call('KeyringController:getState');\n\n if (isUnlocked) {\n return Promise.resolve();\n }\n\n log(\n 'KeyringController is locked; waiting for unlock before fiat submit second leg',\n {\n transactionId,\n },\n );\n\n return new Promise((resolve) => {\n const handler = (): void => {\n messenger.unsubscribe('KeyringController:unlock', handler);\n\n log('KeyringController unlocked; resuming fiat submit second leg', {\n transactionId,\n });\n\n resolve();\n };\n\n messenger.subscribe('KeyringController:unlock', handler);\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-test-funding.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-test-funding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,kCAAkC,CAAC;AAO1C,OAAO,KAAK,EACV,iCAAiC,EACjC,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAWxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAS5C;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAAC,EAChD,IAAI,EACJ,SAAS,EACT,KAAK,EACL,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,yBAAyB,CAAC;IAChC,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACtC,WAAW,EAAE,eAAe,CAAC;CAC9B,GAAG,OAAO,CAAC,UAAU,CAAC,CA2EtB"}
1
+ {"version":3,"file":"fiat-test-funding.d.ts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-test-funding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,kCAAkC,CAAC;AAO1C,OAAO,KAAK,EACV,iCAAiC,EACjC,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAUxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAS5C;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAAC,EAChD,IAAI,EACJ,SAAS,EACT,KAAK,EACL,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,yBAAyB,CAAC;IAChC,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACtC,WAAW,EAAE,eAAe,CAAC;CAC9B,GAAG,OAAO,CAAC,UAAU,CAAC,CA6EtB"}
@@ -7,7 +7,7 @@ import { BigNumber } from 'bignumber.js';
7
7
  import { NATIVE_TOKEN_ADDRESS } from '../../constants.js';
8
8
  import { projectLogger } from '../../logger.js';
9
9
  import { getNetworkClientId } from '../../utils/provider.js';
10
- import { buildCaipAssetType, getEvmQuoteSource, getLiveTokenBalance, getNativeToken, getTokenInfo, } from '../../utils/token.js';
10
+ import { buildCaipAssetType, getLiveTokenBalance, getNativeToken, getTokenInfo, } from '../../utils/token.js';
11
11
  import { waitForTransactionConfirmed } from '../../utils/transaction.js';
12
12
  import { isDirectMusdMoneyAccountQuote } from './fiat-direct-musd.js';
13
13
  import { deriveFiatAssetForFiatPayment } from './utils.js';
@@ -32,9 +32,11 @@ export async function fundFiatOrderFromTestSource({ fiat, messenger, quote, tran
32
32
  throw new Error('Missing fiat test funding source');
33
33
  }
34
34
  const isDirectMusd = isDirectMusdMoneyAccountQuote(quote);
35
- const quoteSource = getEvmQuoteSource(quote.request);
36
35
  const fiatAsset = isDirectMusd
37
- ? { address: quoteSource.tokenAddress, chainId: quoteSource.chainId }
36
+ ? {
37
+ address: quote.request.sourceTokenAddress,
38
+ chainId: quote.request.sourceChainId,
39
+ }
38
40
  : deriveFiatAssetForFiatPayment(transaction, messenger);
39
41
  const recipient = getFiatFundingRecipient({ quote, transaction });
40
42
  const cryptoAmount = fiat.testAmountOverride ?? quote.original.rampsQuote.quote.amountOut;
@@ -1 +1 @@
1
- {"version":3,"file":"fiat-test-funding.js","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-test-funding.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport type { RampsOrder } from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type {\n TransactionMeta,\n TransactionParams,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { NATIVE_TOKEN_ADDRESS } from '../../constants.js';\nimport { projectLogger } from '../../logger.js';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayFiatOptions,\n TransactionPayQuote,\n} from '../../types.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n buildCaipAssetType,\n getEvmQuoteSource,\n getLiveTokenBalance,\n getNativeToken,\n getTokenInfo,\n} from '../../utils/token.js';\nimport { waitForTransactionConfirmed } from '../../utils/transaction.js';\nimport { isDirectMusdMoneyAccountQuote } from './fiat-direct-musd.js';\nimport type { FiatQuote } from './types.js';\nimport { deriveFiatAssetForFiatPayment } from './utils.js';\nimport { getRawSourceAmountFromOrderCryptoAmount } from './utils.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-test-funding');\nconst TOKEN_TRANSFER_INTERFACE = new Interface([\n 'function transfer(address to, uint256 amount)',\n]);\n\n/**\n * Funds the fiat recipient from a test source instead of waiting for ramps.\n *\n * @param options - Test funding options.\n * @param options.fiat - Fiat local-QA execution options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - Fiat quote being submitted.\n * @param options.transaction - Original transaction metadata.\n * @returns A synthetic completed ramps order for the existing fiat submit flow.\n */\nexport async function fundFiatOrderFromTestSource({\n fiat,\n messenger,\n quote,\n transaction,\n}: {\n fiat: TransactionPayFiatOptions;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<FiatQuote>;\n transaction: TransactionMeta;\n}): Promise<RampsOrder> {\n const fundingSource = fiat.testFundingSource;\n\n if (!fundingSource) {\n throw new Error('Missing fiat test funding source');\n }\n\n const isDirectMusd = isDirectMusdMoneyAccountQuote(quote);\n const quoteSource = getEvmQuoteSource(quote.request);\n const fiatAsset = isDirectMusd\n ? { address: quoteSource.tokenAddress, chainId: quoteSource.chainId }\n : deriveFiatAssetForFiatPayment(transaction, messenger);\n\n const recipient = getFiatFundingRecipient({ quote, transaction });\n const cryptoAmount =\n fiat.testAmountOverride ?? quote.original.rampsQuote.quote.amountOut;\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n throw new Error(\n `Unable to resolve fiat test funding token info for ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n const amountRaw = getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n\n log('Preparing fiat test funding transfer', {\n amountRaw,\n chainId: fiatAsset.chainId,\n fundingSource,\n recipient,\n testAmountOverride: fiat.testAmountOverride,\n });\n\n await assertTestFundingBalances({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n symbol: tokenInfo.symbol,\n });\n\n const txHash = await submitTestFundingTransfer({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n recipient,\n });\n\n log('Fiat test funding complete', {\n amountRaw,\n chainId: fiatAsset.chainId,\n fundingSource,\n recipient,\n txHash,\n });\n\n return {\n cryptoAmount,\n cryptoCurrency: {\n assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),\n chainId: `eip155:${Number(fiatAsset.chainId)}`,\n symbol: tokenInfo.symbol,\n },\n status: RampsOrderStatus.Completed,\n txHash,\n } as RampsOrder;\n}\n\nfunction getFiatFundingRecipient({\n quote,\n transaction,\n}: {\n quote: TransactionPayQuote<FiatQuote>;\n transaction: TransactionMeta;\n}): Hex {\n if (isDirectMusdMoneyAccountQuote(quote)) {\n const moneyAccountAddress = transaction.txParams.from as Hex | undefined;\n\n if (!moneyAccountAddress) {\n throw new Error('Missing Money Account address for fiat test funding');\n }\n\n return moneyAccountAddress;\n }\n\n return quote.request.from;\n}\n\nasync function assertTestFundingBalances({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n symbol,\n}: {\n amountRaw: string;\n fiatAsset: { address: Hex; chainId: Hex };\n fundingSource: Hex;\n messenger: TransactionPayControllerMessenger;\n symbol: string;\n}): Promise<void> {\n const balance = await getLiveTokenBalance(\n messenger,\n fundingSource,\n fiatAsset.chainId,\n fiatAsset.address,\n );\n\n if (new BigNumber(balance).lt(amountRaw)) {\n throw new Error(\n `Fiat test funding source has insufficient ${symbol} on chain ${fiatAsset.chainId}. ` +\n `Required: ${amountRaw}, Available: ${balance}, Source: ${fundingSource}`,\n );\n }\n\n const nativeToken = getNativeToken(fiatAsset.chainId);\n const isNative = isNativeFiatAsset(fiatAsset);\n const nativeBalance = isNative\n ? balance\n : await getLiveTokenBalance(\n messenger,\n fundingSource,\n fiatAsset.chainId,\n nativeToken,\n );\n\n const requiredNativeBalance = isNative ? amountRaw : '0';\n\n if (new BigNumber(nativeBalance).lte(requiredNativeBalance)) {\n throw new Error(\n `Fiat test funding source has insufficient native gas on chain ${fiatAsset.chainId}. ` +\n `Native balance: ${nativeBalance}, Source: ${fundingSource}`,\n );\n }\n}\n\nasync function submitTestFundingTransfer({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n recipient,\n}: {\n amountRaw: string;\n fiatAsset: { address: Hex; chainId: Hex };\n fundingSource: Hex;\n messenger: TransactionPayControllerMessenger;\n recipient: Hex;\n}): Promise<Hex> {\n const networkClientId = getNetworkClientId(messenger, fiatAsset.chainId);\n const params = buildTestFundingTransferParams({\n amountRaw,\n fiatAsset,\n fundingSource,\n recipient,\n });\n\n const result = await messenger.call(\n 'TransactionController:addTransaction',\n params,\n {\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n requireApproval: false,\n type: TransactionType.simpleSend,\n },\n );\n\n const txHash = (await result.result) as Hex;\n\n await waitForTransactionConfirmed(result.transactionMeta.id, messenger);\n\n return txHash;\n}\n\nfunction buildTestFundingTransferParams({\n amountRaw,\n fiatAsset,\n fundingSource,\n recipient,\n}: {\n amountRaw: string;\n fiatAsset: { address: Hex; chainId: Hex };\n fundingSource: Hex;\n recipient: Hex;\n}): TransactionParams {\n if (isNativeFiatAsset(fiatAsset)) {\n return {\n from: fundingSource,\n to: recipient,\n value: toHex(amountRaw),\n };\n }\n\n return {\n data: buildTokenTransferData(recipient, amountRaw),\n from: fundingSource,\n to: fiatAsset.address,\n value: '0x0',\n };\n}\n\nfunction buildTokenTransferData(recipient: Hex, amountRaw: string): Hex {\n return TOKEN_TRANSFER_INTERFACE.encodeFunctionData('transfer', [\n recipient,\n amountRaw,\n ]) as Hex;\n}\n\nfunction isNativeFiatAsset({\n address,\n chainId,\n}: {\n address: Hex;\n chainId: Hex;\n}): boolean {\n const normalizedAddress = address.toLowerCase();\n\n return (\n normalizedAddress === NATIVE_TOKEN_ADDRESS.toLowerCase() ||\n normalizedAddress === getNativeToken(chainId).toLowerCase()\n );\n}\n"]}
1
+ {"version":3,"file":"fiat-test-funding.js","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-test-funding.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport type { RampsOrder } from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type {\n TransactionMeta,\n TransactionParams,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { NATIVE_TOKEN_ADDRESS } from '../../constants.js';\nimport { projectLogger } from '../../logger.js';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayFiatOptions,\n TransactionPayQuote,\n} from '../../types.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n buildCaipAssetType,\n getLiveTokenBalance,\n getNativeToken,\n getTokenInfo,\n} from '../../utils/token.js';\nimport { waitForTransactionConfirmed } from '../../utils/transaction.js';\nimport { isDirectMusdMoneyAccountQuote } from './fiat-direct-musd.js';\nimport type { FiatQuote } from './types.js';\nimport { deriveFiatAssetForFiatPayment } from './utils.js';\nimport { getRawSourceAmountFromOrderCryptoAmount } from './utils.js';\n\nconst log = createModuleLogger(projectLogger, 'fiat-test-funding');\nconst TOKEN_TRANSFER_INTERFACE = new Interface([\n 'function transfer(address to, uint256 amount)',\n]);\n\n/**\n * Funds the fiat recipient from a test source instead of waiting for ramps.\n *\n * @param options - Test funding options.\n * @param options.fiat - Fiat local-QA execution options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - Fiat quote being submitted.\n * @param options.transaction - Original transaction metadata.\n * @returns A synthetic completed ramps order for the existing fiat submit flow.\n */\nexport async function fundFiatOrderFromTestSource({\n fiat,\n messenger,\n quote,\n transaction,\n}: {\n fiat: TransactionPayFiatOptions;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<FiatQuote>;\n transaction: TransactionMeta;\n}): Promise<RampsOrder> {\n const fundingSource = fiat.testFundingSource;\n\n if (!fundingSource) {\n throw new Error('Missing fiat test funding source');\n }\n\n const isDirectMusd = isDirectMusdMoneyAccountQuote(quote);\n const fiatAsset = isDirectMusd\n ? {\n address: quote.request.sourceTokenAddress,\n chainId: quote.request.sourceChainId,\n }\n : deriveFiatAssetForFiatPayment(transaction, messenger);\n\n const recipient = getFiatFundingRecipient({ quote, transaction });\n const cryptoAmount =\n fiat.testAmountOverride ?? quote.original.rampsQuote.quote.amountOut;\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n throw new Error(\n `Unable to resolve fiat test funding token info for ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n const amountRaw = getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n\n log('Preparing fiat test funding transfer', {\n amountRaw,\n chainId: fiatAsset.chainId,\n fundingSource,\n recipient,\n testAmountOverride: fiat.testAmountOverride,\n });\n\n await assertTestFundingBalances({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n symbol: tokenInfo.symbol,\n });\n\n const txHash = await submitTestFundingTransfer({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n recipient,\n });\n\n log('Fiat test funding complete', {\n amountRaw,\n chainId: fiatAsset.chainId,\n fundingSource,\n recipient,\n txHash,\n });\n\n return {\n cryptoAmount,\n cryptoCurrency: {\n assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),\n chainId: `eip155:${Number(fiatAsset.chainId)}`,\n symbol: tokenInfo.symbol,\n },\n status: RampsOrderStatus.Completed,\n txHash,\n } as RampsOrder;\n}\n\nfunction getFiatFundingRecipient({\n quote,\n transaction,\n}: {\n quote: TransactionPayQuote<FiatQuote>;\n transaction: TransactionMeta;\n}): Hex {\n if (isDirectMusdMoneyAccountQuote(quote)) {\n const moneyAccountAddress = transaction.txParams.from as Hex | undefined;\n\n if (!moneyAccountAddress) {\n throw new Error('Missing Money Account address for fiat test funding');\n }\n\n return moneyAccountAddress;\n }\n\n return quote.request.from;\n}\n\nasync function assertTestFundingBalances({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n symbol,\n}: {\n amountRaw: string;\n fiatAsset: { address: Hex; chainId: Hex };\n fundingSource: Hex;\n messenger: TransactionPayControllerMessenger;\n symbol: string;\n}): Promise<void> {\n const balance = await getLiveTokenBalance(\n messenger,\n fundingSource,\n fiatAsset.chainId,\n fiatAsset.address,\n );\n\n if (new BigNumber(balance).lt(amountRaw)) {\n throw new Error(\n `Fiat test funding source has insufficient ${symbol} on chain ${fiatAsset.chainId}. ` +\n `Required: ${amountRaw}, Available: ${balance}, Source: ${fundingSource}`,\n );\n }\n\n const nativeToken = getNativeToken(fiatAsset.chainId);\n const isNative = isNativeFiatAsset(fiatAsset);\n const nativeBalance = isNative\n ? balance\n : await getLiveTokenBalance(\n messenger,\n fundingSource,\n fiatAsset.chainId,\n nativeToken,\n );\n\n const requiredNativeBalance = isNative ? amountRaw : '0';\n\n if (new BigNumber(nativeBalance).lte(requiredNativeBalance)) {\n throw new Error(\n `Fiat test funding source has insufficient native gas on chain ${fiatAsset.chainId}. ` +\n `Native balance: ${nativeBalance}, Source: ${fundingSource}`,\n );\n }\n}\n\nasync function submitTestFundingTransfer({\n amountRaw,\n fiatAsset,\n fundingSource,\n messenger,\n recipient,\n}: {\n amountRaw: string;\n fiatAsset: { address: Hex; chainId: Hex };\n fundingSource: Hex;\n messenger: TransactionPayControllerMessenger;\n recipient: Hex;\n}): Promise<Hex> {\n const networkClientId = getNetworkClientId(messenger, fiatAsset.chainId);\n const params = buildTestFundingTransferParams({\n amountRaw,\n fiatAsset,\n fundingSource,\n recipient,\n });\n\n const result = await messenger.call(\n 'TransactionController:addTransaction',\n params,\n {\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n requireApproval: false,\n type: TransactionType.simpleSend,\n },\n );\n\n const txHash = (await result.result) as Hex;\n\n await waitForTransactionConfirmed(result.transactionMeta.id, messenger);\n\n return txHash;\n}\n\nfunction buildTestFundingTransferParams({\n amountRaw,\n fiatAsset,\n fundingSource,\n recipient,\n}: {\n amountRaw: string;\n fiatAsset: { address: Hex; chainId: Hex };\n fundingSource: Hex;\n recipient: Hex;\n}): TransactionParams {\n if (isNativeFiatAsset(fiatAsset)) {\n return {\n from: fundingSource,\n to: recipient,\n value: toHex(amountRaw),\n };\n }\n\n return {\n data: buildTokenTransferData(recipient, amountRaw),\n from: fundingSource,\n to: fiatAsset.address,\n value: '0x0',\n };\n}\n\nfunction buildTokenTransferData(recipient: Hex, amountRaw: string): Hex {\n return TOKEN_TRANSFER_INTERFACE.encodeFunctionData('transfer', [\n recipient,\n amountRaw,\n ]) as Hex;\n}\n\nfunction isNativeFiatAsset({\n address,\n chainId,\n}: {\n address: Hex;\n chainId: Hex;\n}): boolean {\n const normalizedAddress = address.toLowerCase();\n\n return (\n normalizedAddress === NATIVE_TOKEN_ADDRESS.toLowerCase() ||\n normalizedAddress === getNativeToken(chainId).toLowerCase()\n );\n}\n"]}
@@ -1,9 +1,5 @@
1
1
  import type { PayStrategy, PayStrategyExecuteRequest, PayStrategyGetRefreshIntervalRequest, PayStrategyGetQuotesRequest, TransactionPayQuote } from '../../types.js';
2
2
  import type { RelayQuote } from './types.js';
3
- /**
4
- * Pay strategy that quotes and submits through Relay. Only supports requests
5
- * with an EVM source asset.
6
- */
7
3
  export declare class RelayStrategy implements PayStrategy<RelayQuote> {
8
4
  supports(request: PayStrategyGetQuotesRequest): boolean;
9
5
  getQuotes(request: PayStrategyGetQuotesRequest): Promise<TransactionPayQuote<RelayQuote>[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"RelayStrategy.d.ts","sourceRoot":"","sources":["../../../src/strategy/relay/RelayStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,oCAAoC,EACpC,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AASxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;GAGG;AACH,qBAAa,aAAc,YAAW,WAAW,CAAC,UAAU,CAAC;IAC3D,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAItD;IAEK,SAAS,CACb,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CAE5C;IAEK,kBAAkB,CACtB,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY7B;IAEK,OAAO,CACX,OAAO,EAAE,yBAAyB,CAAC,UAAU,CAAC,GAC7C,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAEhD;CACF"}
1
+ {"version":3,"file":"RelayStrategy.d.ts","sourceRoot":"","sources":["../../../src/strategy/relay/RelayStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EACzB,oCAAoC,EACpC,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAQxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,qBAAa,aAAc,YAAW,WAAW,CAAC,UAAU,CAAC;IAC3D,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAGtD;IAEK,SAAS,CACb,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CAE5C;IAEK,kBAAkB,CACtB,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY7B;IAEK,OAAO,CACX,OAAO,EAAE,yBAAyB,CAAC,UAAU,CAAC,GAC7C,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAEhD;CACF"}
@@ -1,16 +1,11 @@
1
1
  import { getMaxBalanceRefreshInterval, getPayStrategiesConfig, } from '../../utils/feature-flags.js';
2
- import { isEvmQuoteRequest } from '../../utils/token.js';
3
2
  import { getTransaction } from '../../utils/transaction.js';
4
3
  import { getRelayQuotes } from './relay-quotes.js';
5
4
  import { submitRelayQuotes } from './relay-submit.js';
6
- /**
7
- * Pay strategy that quotes and submits through Relay. Only supports requests
8
- * with an EVM source asset.
9
- */
10
5
  export class RelayStrategy {
11
6
  supports(request) {
12
7
  const config = getPayStrategiesConfig(request.messenger);
13
- return config.relay.enabled && request.requests.every(isEvmQuoteRequest);
8
+ return config.relay.enabled;
14
9
  }
15
10
  async getQuotes(request) {
16
11
  return getRelayQuotes(request);
@@ -1 +1 @@
1
- {"version":3,"file":"RelayStrategy.js","sourceRoot":"","sources":["../../../src/strategy/relay/RelayStrategy.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB,QAAQ,CAAC,OAAoC;QAC3C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEzD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAoC;QAEpC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,OAA6C;QAE7C,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAC7C,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,mCAAmC,CAAC;aACxE,eAAe,CAAC,aAAa,CAAC,CAAC;QAElC,IAAI,CAAC,eAAe,EAAE,WAAW,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAE7D,OAAO,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA8C;QAE9C,OAAO,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type {\n PayStrategy,\n PayStrategyExecuteRequest,\n PayStrategyGetRefreshIntervalRequest,\n PayStrategyGetQuotesRequest,\n TransactionPayQuote,\n} from '../../types.js';\nimport {\n getMaxBalanceRefreshInterval,\n getPayStrategiesConfig,\n} from '../../utils/feature-flags.js';\nimport { isEvmQuoteRequest } from '../../utils/token.js';\nimport { getTransaction } from '../../utils/transaction.js';\nimport { getRelayQuotes } from './relay-quotes.js';\nimport { submitRelayQuotes } from './relay-submit.js';\nimport type { RelayQuote } from './types.js';\n\n/**\n * Pay strategy that quotes and submits through Relay. Only supports requests\n * with an EVM source asset.\n */\nexport class RelayStrategy implements PayStrategy<RelayQuote> {\n supports(request: PayStrategyGetQuotesRequest): boolean {\n const config = getPayStrategiesConfig(request.messenger);\n\n return config.relay.enabled && request.requests.every(isEvmQuoteRequest);\n }\n\n async getQuotes(\n request: PayStrategyGetQuotesRequest,\n ): Promise<TransactionPayQuote<RelayQuote>[]> {\n return getRelayQuotes(request);\n }\n\n async getRefreshInterval(\n request: PayStrategyGetRefreshIntervalRequest,\n ): Promise<number | undefined> {\n const { messenger, transactionId } = request;\n const transactionData = messenger.call('TransactionPayController:getState')\n .transactionData[transactionId];\n\n if (!transactionData?.isMaxAmount) {\n return undefined;\n }\n\n const transaction = getTransaction(transactionId, messenger);\n\n return getMaxBalanceRefreshInterval(messenger, transaction);\n }\n\n async execute(\n request: PayStrategyExecuteRequest<RelayQuote>,\n ): ReturnType<PayStrategy<RelayQuote>['execute']> {\n return await submitRelayQuotes(request);\n }\n}\n"]}
1
+ {"version":3,"file":"RelayStrategy.js","sourceRoot":"","sources":["../../../src/strategy/relay/RelayStrategy.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,MAAM,OAAO,aAAa;IACxB,QAAQ,CAAC,OAAoC;QAC3C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAoC;QAEpC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,OAA6C;QAE7C,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAC7C,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,mCAAmC,CAAC;aACxE,eAAe,CAAC,aAAa,CAAC,CAAC;QAElC,IAAI,CAAC,eAAe,EAAE,WAAW,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAE7D,OAAO,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAA8C;QAE9C,OAAO,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type {\n PayStrategy,\n PayStrategyExecuteRequest,\n PayStrategyGetRefreshIntervalRequest,\n PayStrategyGetQuotesRequest,\n TransactionPayQuote,\n} from '../../types.js';\nimport {\n getMaxBalanceRefreshInterval,\n getPayStrategiesConfig,\n} from '../../utils/feature-flags.js';\nimport { getTransaction } from '../../utils/transaction.js';\nimport { getRelayQuotes } from './relay-quotes.js';\nimport { submitRelayQuotes } from './relay-submit.js';\nimport type { RelayQuote } from './types.js';\n\nexport class RelayStrategy implements PayStrategy<RelayQuote> {\n supports(request: PayStrategyGetQuotesRequest): boolean {\n const config = getPayStrategiesConfig(request.messenger);\n return config.relay.enabled;\n }\n\n async getQuotes(\n request: PayStrategyGetQuotesRequest,\n ): Promise<TransactionPayQuote<RelayQuote>[]> {\n return getRelayQuotes(request);\n }\n\n async getRefreshInterval(\n request: PayStrategyGetRefreshIntervalRequest,\n ): Promise<number | undefined> {\n const { messenger, transactionId } = request;\n const transactionData = messenger.call('TransactionPayController:getState')\n .transactionData[transactionId];\n\n if (!transactionData?.isMaxAmount) {\n return undefined;\n }\n\n const transaction = getTransaction(transactionId, messenger);\n\n return getMaxBalanceRefreshInterval(messenger, transaction);\n }\n\n async execute(\n request: PayStrategyExecuteRequest<RelayQuote>,\n ): ReturnType<PayStrategy<RelayQuote>['execute']> {\n return await submitRelayQuotes(request);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"relay-quotes.d.ts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAkDxB,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,YAAY,CAAC;AASpB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CAuD5C"}
1
+ {"version":3,"file":"relay-quotes.d.ts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAgDxB,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,YAAY,CAAC;AASpB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CAuD5C"}
@@ -17,7 +17,7 @@ import { processPostQuotePaymentOverride } from '../../utils/post-quote-payment-
17
17
  import { reservePostQuoteGas } from '../../utils/post-quote.js';
18
18
  import { estimateSourceGas } from '../../utils/quote-gas.js';
19
19
  import { resolveQuoteRecipient } from '../../utils/quote-recipient.js';
20
- import { buildCaipAssetType, getEvmQuoteSource, getNativeToken, getTokenFiatRate, normalizeTokenAddress, TokenAddressTarget, } from '../../utils/token.js';
20
+ import { getNativeToken, getTokenFiatRate, normalizeTokenAddress, TokenAddressTarget, } from '../../utils/token.js';
21
21
  import { getQuotePricing } from '../../utils/trade-type.js';
22
22
  import { TOKEN_TRANSFER_FOUR_BYTE } from './constants.js';
23
23
  import { hasRelayDepositStep } from './deposit-step.js';
@@ -121,8 +121,7 @@ async function getQuoteWithPostQuoteGasHandling(request, fullRequest) {
121
121
  */
122
122
  async function getSingleQuote(request, fullRequest) {
123
123
  const { accountSupports7702: supports7702, messenger, signal, transaction, } = fullRequest;
124
- const { from, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = request;
125
- const { chainId: sourceChainId, tokenAddress: sourceTokenAddress } = getEvmQuoteSource(request);
124
+ const { from, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = request;
126
125
  const slippageDecimal = getSlippage(messenger, sourceChainId, sourceTokenAddress);
127
126
  const slippageTolerance = new BigNumber(slippageDecimal * 100 * 100).toFixed(0);
128
127
  try {
@@ -289,10 +288,9 @@ async function processTransactions(transaction, request, requestBody, messenger)
289
288
  * @returns Normalized request.
290
289
  */
291
290
  function normalizeRequest(request, transaction) {
292
- const { chainId: sourceChainId, tokenAddress: sourceTokenAddress } = getEvmQuoteSource(request);
293
291
  const newRequest = {
294
292
  ...request,
295
- sourceAssetId: buildCaipAssetType(sourceChainId, normalizeTokenAddress(sourceTokenAddress, sourceChainId, TokenAddressTarget.Relay)),
293
+ sourceTokenAddress: normalizeTokenAddress(request.sourceTokenAddress, request.sourceChainId, TokenAddressTarget.Relay),
296
294
  targetTokenAddress: normalizeTokenAddress(request.targetTokenAddress, request.targetChainId, TokenAddressTarget.Relay),
297
295
  };
298
296
  const depositRequest = normalizePerpsDepositRequest(newRequest, transaction, HYPERCORE_USDC_ADDRESS);
@@ -397,13 +395,12 @@ function getFiatRates(messenger, request) {
397
395
  // For HyperLiquid source, the normalized chain/token (HyperCore + Perps USDC)
398
396
  // won't have a fiat rate entry. Use Arbitrum USDC instead since Perps USDC
399
397
  // is pegged 1:1.
400
- const quoteSource = getEvmQuoteSource(request);
401
398
  const sourceChainId = request.isHyperliquidSource
402
399
  ? CHAIN_ID_ARBITRUM
403
- : quoteSource.chainId;
400
+ : request.sourceChainId;
404
401
  const sourceTokenAddress = request.isHyperliquidSource
405
402
  ? ARBITRUM_USDC_ADDRESS
406
- : quoteSource.tokenAddress;
403
+ : request.sourceTokenAddress;
407
404
  const finalSourceTokenAddress = sourceChainId === CHAIN_ID_POLYGON &&
408
405
  sourceTokenAddress === NATIVE_TOKEN_ADDRESS
409
406
  ? getNativeToken(sourceChainId)
@@ -435,8 +432,7 @@ function getFiatRates(messenger, request) {
435
432
  * @returns Total source network cost in USD and fiat.
436
433
  */
437
434
  async function calculateSourceNetworkCost(quote, messenger, request, transaction, accountSupports7702) {
438
- const { from } = request;
439
- const { chainId: sourceChainId, tokenAddress: sourceTokenAddress } = getEvmQuoteSource(request);
435
+ const { from, sourceChainId, sourceTokenAddress } = request;
440
436
  // None of these flows bill origin gas to the user: the execute flow has a
441
437
  // relayer redeem a signed delegation, a HyperLiquid withdrawal's "deposit"
442
438
  // step is an off-chain HL sendAsset signature rather than an on-chain