@metamask/transaction-pay-controller 23.8.0 → 23.9.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 (114) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/dist/TransactionPayController-method-action-types.cjs.map +1 -1
  3. package/dist/TransactionPayController-method-action-types.d.cts +12 -1
  4. package/dist/TransactionPayController-method-action-types.d.cts.map +1 -1
  5. package/dist/TransactionPayController-method-action-types.d.mts +12 -1
  6. package/dist/TransactionPayController-method-action-types.d.mts.map +1 -1
  7. package/dist/TransactionPayController-method-action-types.mjs.map +1 -1
  8. package/dist/TransactionPayController.cjs +16 -3
  9. package/dist/TransactionPayController.cjs.map +1 -1
  10. package/dist/TransactionPayController.d.cts +10 -2
  11. package/dist/TransactionPayController.d.cts.map +1 -1
  12. package/dist/TransactionPayController.d.mts +10 -2
  13. package/dist/TransactionPayController.d.mts.map +1 -1
  14. package/dist/TransactionPayController.mjs +16 -3
  15. package/dist/TransactionPayController.mjs.map +1 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +2 -2
  18. package/dist/index.d.cts.map +1 -1
  19. package/dist/index.d.mts +2 -2
  20. package/dist/index.d.mts.map +1 -1
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/strategy/fiat/constants.cjs +1 -3
  23. package/dist/strategy/fiat/constants.cjs.map +1 -1
  24. package/dist/strategy/fiat/constants.d.cts +0 -2
  25. package/dist/strategy/fiat/constants.d.cts.map +1 -1
  26. package/dist/strategy/fiat/constants.d.mts +0 -2
  27. package/dist/strategy/fiat/constants.d.mts.map +1 -1
  28. package/dist/strategy/fiat/constants.mjs +0 -2
  29. package/dist/strategy/fiat/constants.mjs.map +1 -1
  30. package/dist/strategy/fiat/fiat-direct-musd.cjs +246 -0
  31. package/dist/strategy/fiat/fiat-direct-musd.cjs.map +1 -0
  32. package/dist/strategy/fiat/fiat-direct-musd.d.cts +47 -0
  33. package/dist/strategy/fiat/fiat-direct-musd.d.cts.map +1 -0
  34. package/dist/strategy/fiat/fiat-direct-musd.d.mts +47 -0
  35. package/dist/strategy/fiat/fiat-direct-musd.d.mts.map +1 -0
  36. package/dist/strategy/fiat/fiat-direct-musd.mjs +240 -0
  37. package/dist/strategy/fiat/fiat-direct-musd.mjs.map +1 -0
  38. package/dist/strategy/fiat/fiat-quotes.cjs +27 -79
  39. package/dist/strategy/fiat/fiat-quotes.cjs.map +1 -1
  40. package/dist/strategy/fiat/fiat-quotes.d.cts +2 -3
  41. package/dist/strategy/fiat/fiat-quotes.d.cts.map +1 -1
  42. package/dist/strategy/fiat/fiat-quotes.d.mts +2 -3
  43. package/dist/strategy/fiat/fiat-quotes.d.mts.map +1 -1
  44. package/dist/strategy/fiat/fiat-quotes.mjs +28 -80
  45. package/dist/strategy/fiat/fiat-quotes.mjs.map +1 -1
  46. package/dist/strategy/fiat/fiat-submit-simple.cjs +3 -0
  47. package/dist/strategy/fiat/fiat-submit-simple.cjs.map +1 -1
  48. package/dist/strategy/fiat/fiat-submit-simple.d.cts.map +1 -1
  49. package/dist/strategy/fiat/fiat-submit-simple.d.mts.map +1 -1
  50. package/dist/strategy/fiat/fiat-submit-simple.mjs +3 -0
  51. package/dist/strategy/fiat/fiat-submit-simple.mjs.map +1 -1
  52. package/dist/strategy/fiat/fiat-submit-with-transaction-data.cjs +5 -2
  53. package/dist/strategy/fiat/fiat-submit-with-transaction-data.cjs.map +1 -1
  54. package/dist/strategy/fiat/fiat-submit-with-transaction-data.d.cts.map +1 -1
  55. package/dist/strategy/fiat/fiat-submit-with-transaction-data.d.mts.map +1 -1
  56. package/dist/strategy/fiat/fiat-submit-with-transaction-data.mjs +5 -2
  57. package/dist/strategy/fiat/fiat-submit-with-transaction-data.mjs.map +1 -1
  58. package/dist/strategy/fiat/fiat-submit.cjs +57 -35
  59. package/dist/strategy/fiat/fiat-submit.cjs.map +1 -1
  60. package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -1
  61. package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -1
  62. package/dist/strategy/fiat/fiat-submit.mjs +57 -35
  63. package/dist/strategy/fiat/fiat-submit.mjs.map +1 -1
  64. package/dist/strategy/fiat/fiat-test-funding.cjs +166 -0
  65. package/dist/strategy/fiat/fiat-test-funding.cjs.map +1 -0
  66. package/dist/strategy/fiat/fiat-test-funding.d.cts +21 -0
  67. package/dist/strategy/fiat/fiat-test-funding.d.cts.map +1 -0
  68. package/dist/strategy/fiat/fiat-test-funding.d.mts +21 -0
  69. package/dist/strategy/fiat/fiat-test-funding.d.mts.map +1 -0
  70. package/dist/strategy/fiat/fiat-test-funding.mjs +162 -0
  71. package/dist/strategy/fiat/fiat-test-funding.mjs.map +1 -0
  72. package/dist/strategy/fiat/types.cjs.map +1 -1
  73. package/dist/strategy/fiat/types.d.cts +1 -1
  74. package/dist/strategy/fiat/types.d.cts.map +1 -1
  75. package/dist/strategy/fiat/types.d.mts +1 -1
  76. package/dist/strategy/fiat/types.d.mts.map +1 -1
  77. package/dist/strategy/fiat/types.mjs.map +1 -1
  78. package/dist/strategy/fiat/utils.cjs +33 -1
  79. package/dist/strategy/fiat/utils.cjs.map +1 -1
  80. package/dist/strategy/fiat/utils.d.cts +21 -1
  81. package/dist/strategy/fiat/utils.d.cts.map +1 -1
  82. package/dist/strategy/fiat/utils.d.mts +21 -1
  83. package/dist/strategy/fiat/utils.d.mts.map +1 -1
  84. package/dist/strategy/fiat/utils.mjs +33 -2
  85. package/dist/strategy/fiat/utils.mjs.map +1 -1
  86. package/dist/tests/messenger-mock.cjs +3 -0
  87. package/dist/tests/messenger-mock.cjs.map +1 -1
  88. package/dist/tests/messenger-mock.d.cts +1 -0
  89. package/dist/tests/messenger-mock.d.cts.map +1 -1
  90. package/dist/tests/messenger-mock.d.mts +1 -0
  91. package/dist/tests/messenger-mock.d.mts.map +1 -1
  92. package/dist/tests/messenger-mock.mjs +3 -0
  93. package/dist/tests/messenger-mock.mjs.map +1 -1
  94. package/dist/types.cjs.map +1 -1
  95. package/dist/types.d.cts +11 -0
  96. package/dist/types.d.cts.map +1 -1
  97. package/dist/types.d.mts +11 -0
  98. package/dist/types.d.mts.map +1 -1
  99. package/dist/types.mjs.map +1 -1
  100. package/dist/utils/feature-flags.cjs +7 -1
  101. package/dist/utils/feature-flags.cjs.map +1 -1
  102. package/dist/utils/feature-flags.d.cts +1 -0
  103. package/dist/utils/feature-flags.d.cts.map +1 -1
  104. package/dist/utils/feature-flags.d.mts +1 -0
  105. package/dist/utils/feature-flags.d.mts.map +1 -1
  106. package/dist/utils/feature-flags.mjs +5 -0
  107. package/dist/utils/feature-flags.mjs.map +1 -1
  108. package/dist/utils/quotes.cjs +6 -4
  109. package/dist/utils/quotes.cjs.map +1 -1
  110. package/dist/utils/quotes.d.cts.map +1 -1
  111. package/dist/utils/quotes.d.mts.map +1 -1
  112. package/dist/utils/quotes.mjs +6 -4
  113. package/dist/utils/quotes.mjs.map +1 -1
  114. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiat-test-funding.cjs","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';\nimport { projectLogger } from '../../logger';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayFiatOptions,\n TransactionPayQuote,\n} from '../../types';\nimport { getNetworkClientId } from '../../utils/provider';\nimport {\n buildCaipAssetType,\n getLiveTokenBalance,\n getNativeToken,\n getTokenInfo,\n} from '../../utils/token';\nimport { waitForTransactionConfirmed } from '../../utils/transaction';\nimport { isDirectMusdMoneyAccountQuote } from './fiat-direct-musd';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment } from './utils';\nimport { getRawSourceAmountFromOrderCryptoAmount } from './utils';\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"]}
@@ -0,0 +1,21 @@
1
+ import type { RampsOrder } from "@metamask/ramps-controller";
2
+ import type { TransactionMeta } from "@metamask/transaction-controller";
3
+ import type { TransactionPayControllerMessenger, TransactionPayFiatOptions, TransactionPayQuote } from "../../types.cjs";
4
+ import type { FiatQuote } from "./types.cjs";
5
+ /**
6
+ * Funds the fiat recipient from a test source instead of waiting for ramps.
7
+ *
8
+ * @param options - Test funding options.
9
+ * @param options.fiat - Fiat local-QA execution options.
10
+ * @param options.messenger - Controller messenger.
11
+ * @param options.quote - Fiat quote being submitted.
12
+ * @param options.transaction - Original transaction metadata.
13
+ * @returns A synthetic completed ramps order for the existing fiat submit flow.
14
+ */
15
+ export declare function fundFiatOrderFromTestSource({ fiat, messenger, quote, transaction, }: {
16
+ fiat: TransactionPayFiatOptions;
17
+ messenger: TransactionPayControllerMessenger;
18
+ quote: TransactionPayQuote<FiatQuote>;
19
+ transaction: TransactionMeta;
20
+ }): Promise<RampsOrder>;
21
+ //# sourceMappingURL=fiat-test-funding.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiat-test-funding.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-test-funding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,mCAAmC;AAG7D,OAAO,KAAK,EACV,eAAe,EAEhB,yCAAyC;AAO1C,OAAO,KAAK,EACV,iCAAiC,EACjC,yBAAyB,EACzB,mBAAmB,EACpB,wBAAoB;AAUrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AASzC;;;;;;;;;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"}
@@ -0,0 +1,21 @@
1
+ import type { RampsOrder } from "@metamask/ramps-controller";
2
+ import type { TransactionMeta } from "@metamask/transaction-controller";
3
+ import type { TransactionPayControllerMessenger, TransactionPayFiatOptions, TransactionPayQuote } from "../../types.mjs";
4
+ import type { FiatQuote } from "./types.mjs";
5
+ /**
6
+ * Funds the fiat recipient from a test source instead of waiting for ramps.
7
+ *
8
+ * @param options - Test funding options.
9
+ * @param options.fiat - Fiat local-QA execution options.
10
+ * @param options.messenger - Controller messenger.
11
+ * @param options.quote - Fiat quote being submitted.
12
+ * @param options.transaction - Original transaction metadata.
13
+ * @returns A synthetic completed ramps order for the existing fiat submit flow.
14
+ */
15
+ export declare function fundFiatOrderFromTestSource({ fiat, messenger, quote, transaction, }: {
16
+ fiat: TransactionPayFiatOptions;
17
+ messenger: TransactionPayControllerMessenger;
18
+ quote: TransactionPayQuote<FiatQuote>;
19
+ transaction: TransactionMeta;
20
+ }): Promise<RampsOrder>;
21
+ //# sourceMappingURL=fiat-test-funding.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiat-test-funding.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-test-funding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,mCAAmC;AAG7D,OAAO,KAAK,EACV,eAAe,EAEhB,yCAAyC;AAO1C,OAAO,KAAK,EACV,iCAAiC,EACjC,yBAAyB,EACzB,mBAAmB,EACpB,wBAAoB;AAUrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AASzC;;;;;;;;;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"}
@@ -0,0 +1,162 @@
1
+ import { Interface } from "@ethersproject/abi";
2
+ import { ORIGIN_METAMASK, toHex } from "@metamask/controller-utils";
3
+ import { RampsOrderStatus } from "@metamask/ramps-controller";
4
+ import { TransactionType } from "@metamask/transaction-controller";
5
+ import { createModuleLogger } from "@metamask/utils";
6
+ import { BigNumber } from "bignumber.js";
7
+ import { NATIVE_TOKEN_ADDRESS } from "../../constants.mjs";
8
+ import { projectLogger } from "../../logger.mjs";
9
+ import { getNetworkClientId } from "../../utils/provider.mjs";
10
+ import { buildCaipAssetType, getLiveTokenBalance, getNativeToken, getTokenInfo } from "../../utils/token.mjs";
11
+ import { waitForTransactionConfirmed } from "../../utils/transaction.mjs";
12
+ import { isDirectMusdMoneyAccountQuote } from "./fiat-direct-musd.mjs";
13
+ import { deriveFiatAssetForFiatPayment } from "./utils.mjs";
14
+ import { getRawSourceAmountFromOrderCryptoAmount } from "./utils.mjs";
15
+ const log = createModuleLogger(projectLogger, 'fiat-test-funding');
16
+ const TOKEN_TRANSFER_INTERFACE = new Interface([
17
+ 'function transfer(address to, uint256 amount)',
18
+ ]);
19
+ /**
20
+ * Funds the fiat recipient from a test source instead of waiting for ramps.
21
+ *
22
+ * @param options - Test funding options.
23
+ * @param options.fiat - Fiat local-QA execution options.
24
+ * @param options.messenger - Controller messenger.
25
+ * @param options.quote - Fiat quote being submitted.
26
+ * @param options.transaction - Original transaction metadata.
27
+ * @returns A synthetic completed ramps order for the existing fiat submit flow.
28
+ */
29
+ export async function fundFiatOrderFromTestSource({ fiat, messenger, quote, transaction, }) {
30
+ const fundingSource = fiat.testFundingSource;
31
+ if (!fundingSource) {
32
+ throw new Error('Missing fiat test funding source');
33
+ }
34
+ const isDirectMusd = isDirectMusdMoneyAccountQuote(quote);
35
+ const fiatAsset = isDirectMusd
36
+ ? {
37
+ address: quote.request.sourceTokenAddress,
38
+ chainId: quote.request.sourceChainId,
39
+ }
40
+ : deriveFiatAssetForFiatPayment(transaction, messenger);
41
+ const recipient = getFiatFundingRecipient({ quote, transaction });
42
+ const cryptoAmount = fiat.testAmountOverride ?? quote.original.rampsQuote.quote.amountOut;
43
+ const tokenInfo = getTokenInfo(messenger, fiatAsset.address, fiatAsset.chainId);
44
+ if (!tokenInfo) {
45
+ throw new Error(`Unable to resolve fiat test funding token info for ${fiatAsset.address} on chain ${fiatAsset.chainId}`);
46
+ }
47
+ const amountRaw = getRawSourceAmountFromOrderCryptoAmount({
48
+ cryptoAmount,
49
+ decimals: tokenInfo.decimals,
50
+ });
51
+ log('Preparing fiat test funding transfer', {
52
+ amountRaw,
53
+ chainId: fiatAsset.chainId,
54
+ fundingSource,
55
+ recipient,
56
+ testAmountOverride: fiat.testAmountOverride,
57
+ });
58
+ await assertTestFundingBalances({
59
+ amountRaw,
60
+ fiatAsset,
61
+ fundingSource,
62
+ messenger,
63
+ symbol: tokenInfo.symbol,
64
+ });
65
+ const txHash = await submitTestFundingTransfer({
66
+ amountRaw,
67
+ fiatAsset,
68
+ fundingSource,
69
+ messenger,
70
+ recipient,
71
+ });
72
+ log('Fiat test funding complete', {
73
+ amountRaw,
74
+ chainId: fiatAsset.chainId,
75
+ fundingSource,
76
+ recipient,
77
+ txHash,
78
+ });
79
+ return {
80
+ cryptoAmount,
81
+ cryptoCurrency: {
82
+ assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),
83
+ chainId: `eip155:${Number(fiatAsset.chainId)}`,
84
+ symbol: tokenInfo.symbol,
85
+ },
86
+ status: RampsOrderStatus.Completed,
87
+ txHash,
88
+ };
89
+ }
90
+ function getFiatFundingRecipient({ quote, transaction, }) {
91
+ if (isDirectMusdMoneyAccountQuote(quote)) {
92
+ const moneyAccountAddress = transaction.txParams.from;
93
+ if (!moneyAccountAddress) {
94
+ throw new Error('Missing Money Account address for fiat test funding');
95
+ }
96
+ return moneyAccountAddress;
97
+ }
98
+ return quote.request.from;
99
+ }
100
+ async function assertTestFundingBalances({ amountRaw, fiatAsset, fundingSource, messenger, symbol, }) {
101
+ const balance = await getLiveTokenBalance(messenger, fundingSource, fiatAsset.chainId, fiatAsset.address);
102
+ if (new BigNumber(balance).lt(amountRaw)) {
103
+ throw new Error(`Fiat test funding source has insufficient ${symbol} on chain ${fiatAsset.chainId}. ` +
104
+ `Required: ${amountRaw}, Available: ${balance}, Source: ${fundingSource}`);
105
+ }
106
+ const nativeToken = getNativeToken(fiatAsset.chainId);
107
+ const isNative = isNativeFiatAsset(fiatAsset);
108
+ const nativeBalance = isNative
109
+ ? balance
110
+ : await getLiveTokenBalance(messenger, fundingSource, fiatAsset.chainId, nativeToken);
111
+ const requiredNativeBalance = isNative ? amountRaw : '0';
112
+ if (new BigNumber(nativeBalance).lte(requiredNativeBalance)) {
113
+ throw new Error(`Fiat test funding source has insufficient native gas on chain ${fiatAsset.chainId}. ` +
114
+ `Native balance: ${nativeBalance}, Source: ${fundingSource}`);
115
+ }
116
+ }
117
+ async function submitTestFundingTransfer({ amountRaw, fiatAsset, fundingSource, messenger, recipient, }) {
118
+ const networkClientId = getNetworkClientId(messenger, fiatAsset.chainId);
119
+ const params = buildTestFundingTransferParams({
120
+ amountRaw,
121
+ fiatAsset,
122
+ fundingSource,
123
+ recipient,
124
+ });
125
+ const result = await messenger.call('TransactionController:addTransaction', params, {
126
+ isInternal: true,
127
+ networkClientId,
128
+ origin: ORIGIN_METAMASK,
129
+ requireApproval: false,
130
+ type: TransactionType.simpleSend,
131
+ });
132
+ const txHash = (await result.result);
133
+ await waitForTransactionConfirmed(result.transactionMeta.id, messenger);
134
+ return txHash;
135
+ }
136
+ function buildTestFundingTransferParams({ amountRaw, fiatAsset, fundingSource, recipient, }) {
137
+ if (isNativeFiatAsset(fiatAsset)) {
138
+ return {
139
+ from: fundingSource,
140
+ to: recipient,
141
+ value: toHex(amountRaw),
142
+ };
143
+ }
144
+ return {
145
+ data: buildTokenTransferData(recipient, amountRaw),
146
+ from: fundingSource,
147
+ to: fiatAsset.address,
148
+ value: '0x0',
149
+ };
150
+ }
151
+ function buildTokenTransferData(recipient, amountRaw) {
152
+ return TOKEN_TRANSFER_INTERFACE.encodeFunctionData('transfer', [
153
+ recipient,
154
+ amountRaw,
155
+ ]);
156
+ }
157
+ function isNativeFiatAsset({ address, chainId, }) {
158
+ const normalizedAddress = address.toLowerCase();
159
+ return (normalizedAddress === NATIVE_TOKEN_ADDRESS.toLowerCase() ||
160
+ normalizedAddress === getNativeToken(chainId).toLowerCase());
161
+ }
162
+ //# sourceMappingURL=fiat-test-funding.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fiat-test-funding.mjs","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';\nimport { projectLogger } from '../../logger';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayFiatOptions,\n TransactionPayQuote,\n} from '../../types';\nimport { getNetworkClientId } from '../../utils/provider';\nimport {\n buildCaipAssetType,\n getLiveTokenBalance,\n getNativeToken,\n getTokenInfo,\n} from '../../utils/token';\nimport { waitForTransactionConfirmed } from '../../utils/transaction';\nimport { isDirectMusdMoneyAccountQuote } from './fiat-direct-musd';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment } from './utils';\nimport { getRawSourceAmountFromOrderCryptoAmount } from './utils';\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 +1 @@
1
- {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Quote } from '@metamask/ramps-controller';\n\nimport type { RelayQuote } from '../relay/types';\n\nexport type FiatQuote = {\n rampsQuote: Quote;\n relayQuote: RelayQuote;\n};\n"]}
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Quote } from '@metamask/ramps-controller';\n\nimport type { RelayQuote } from '../relay/types';\n\nexport type FiatQuote = {\n rampsQuote: Quote;\n relayQuote?: RelayQuote;\n};\n"]}
@@ -2,6 +2,6 @@ import type { Quote } from "@metamask/ramps-controller";
2
2
  import type { RelayQuote } from "../relay/types.cjs";
3
3
  export type FiatQuote = {
4
4
  rampsQuote: Quote;
5
- relayQuote: RelayQuote;
5
+ relayQuote?: RelayQuote;
6
6
  };
7
7
  //# sourceMappingURL=types.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,mCAAmC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AAEjD,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,KAAK,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC"}
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,mCAAmC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AAEjD,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,KAAK,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC"}
@@ -2,6 +2,6 @@ import type { Quote } from "@metamask/ramps-controller";
2
2
  import type { RelayQuote } from "../relay/types.mjs";
3
3
  export type FiatQuote = {
4
4
  rampsQuote: Quote;
5
- relayQuote: RelayQuote;
5
+ relayQuote?: RelayQuote;
6
6
  };
7
7
  //# sourceMappingURL=types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,mCAAmC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AAEjD,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,KAAK,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC"}
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,mCAAmC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AAEjD,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,KAAK,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Quote } from '@metamask/ramps-controller';\n\nimport type { RelayQuote } from '../relay/types';\n\nexport type FiatQuote = {\n rampsQuote: Quote;\n relayQuote: RelayQuote;\n};\n"]}
1
+ {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Quote } from '@metamask/ramps-controller';\n\nimport type { RelayQuote } from '../relay/types';\n\nexport type FiatQuote = {\n rampsQuote: Quote;\n relayQuote?: RelayQuote;\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractProviderCode = exports.validateRelayRateDrift = exports.getRawSourceAmountFromOrderCryptoAmount = exports.resolveSourceAmountRaw = exports.isMoneyAccountDepositTransaction = exports.resolveTransactionType = exports.deriveFiatAssetForFiatPayment = void 0;
3
+ exports.extractProviderCode = exports.validateRelayRateDrift = exports.getRawSourceAmountFromOrderCryptoAmount = exports.resolveSourceAmountRaw = exports.getRampsQuote = exports.isMoneyAccountDepositTransaction = exports.resolveTransactionType = exports.deriveFiatAssetForFiatPayment = void 0;
4
4
  const transaction_controller_1 = require("@metamask/transaction-controller");
5
5
  const utils_1 = require("@metamask/utils");
6
6
  const bignumber_js_1 = require("bignumber.js");
@@ -52,6 +52,38 @@ function isMoneyAccountDepositTransaction(transaction) {
52
52
  transaction_controller_1.TransactionType.moneyAccountDeposit);
53
53
  }
54
54
  exports.isMoneyAccountDepositTransaction = isMoneyAccountDepositTransaction;
55
+ /**
56
+ * Fetches the first matching Ramps quote for a fiat asset and payment method.
57
+ *
58
+ * @param options - Quote options.
59
+ * @param options.adjustedAmount - Fiat amount sent to Ramps.
60
+ * @param options.errorMessage - Error thrown when no matching quote is returned.
61
+ * @param options.fiatAsset - Fiat asset to buy.
62
+ * @param options.fiatPaymentMethod - Selected fiat payment method.
63
+ * @param options.messenger - Controller messenger.
64
+ * @param options.walletAddress - Wallet address that receives the on-ramped asset.
65
+ * @returns The first matching Ramps quote.
66
+ */
67
+ async function getRampsQuote({ adjustedAmount, errorMessage = 'No matching ramps quote found for selected provider', fiatAsset, fiatPaymentMethod, messenger, walletAddress, }) {
68
+ const quotes = await messenger.call('RampsController:getQuotes', {
69
+ amount: adjustedAmount,
70
+ assetId: (0, token_1.buildCaipAssetType)(fiatAsset.chainId, fiatAsset.address),
71
+ autoSelectProvider: true,
72
+ fiat: constants_1.DEFAULT_FIAT_CURRENCY,
73
+ paymentMethods: [fiatPaymentMethod],
74
+ restrictToKnownOrNativeProviders: true,
75
+ walletAddress,
76
+ });
77
+ log('Fetched ramps quotes', {
78
+ quotesCount: quotes.success?.length ?? 0,
79
+ });
80
+ const quote = quotes.success?.[0];
81
+ if (!quote) {
82
+ throw new Error(errorMessage);
83
+ }
84
+ return quote;
85
+ }
86
+ exports.getRampsQuote = getRampsQuote;
55
87
  /**
56
88
  * Resolves the raw source amount for a completed fiat order.
57
89
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RampsOrder } from '@metamask/ramps-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type { TransactionPayControllerMessenger } from '../../types';\nimport {\n getFiatAssetPerTransactionType,\n getFiatEnabledTypes,\n} from '../../utils/feature-flags';\nimport { getTokenInfo } from '../../utils/token';\nimport { getTransferredAmountFromTxHash } from '../../utils/transaction';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport { FIAT_ENABLED_TYPES } from './constants';\n\nconst log = createModuleLogger(projectLogger, 'fiat-utils');\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatAsset {\n const enabledTypes = getFiatEnabledTypes(messenger);\n const txType = resolveTransactionType(transaction, enabledTypes);\n\n return getFiatAssetPerTransactionType(messenger, txType);\n}\n\n/**\n * Resolves the effective transaction type for fiat strategy purposes.\n *\n * For non-batch transactions returns the transaction's own type.\n * For batch transactions returns the first nested transaction type\n * that appears in the enabled types list, or the batch type itself\n * if no nested type matches.\n *\n * @param transaction - The transaction metadata to inspect.\n * @param enabledTypes - Transaction types eligible for fiat payment.\n * @returns The resolved transaction type, or `undefined`.\n */\nexport function resolveTransactionType(\n transaction: TransactionMeta,\n enabledTypes: TransactionType[],\n): TransactionType | undefined {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && enabledTypes.includes(tx.type),\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n\n/**\n * Checks whether a transaction is a Money Account deposit.\n *\n * Handles both direct `moneyAccountDeposit` transactions and EIP-7702\n * batch transactions that contain a `moneyAccountDeposit` nested call.\n * Uses {@link resolveTransactionType} with `FIAT_ENABLED_TYPES` to\n * correctly skip non-deposit nested types (e.g. `tokenMethodApprove`).\n *\n * @param transaction - The transaction metadata to inspect.\n * @returns `true` if the transaction is a Money Account deposit.\n */\nexport function isMoneyAccountDepositTransaction(\n transaction: TransactionMeta,\n): boolean {\n return (\n resolveTransactionType(transaction, FIAT_ENABLED_TYPES) ===\n TransactionType.moneyAccountDeposit\n );\n}\n\n/**\n * Resolves the raw source amount for a completed fiat order.\n *\n * Attempts to read the actual transferred amount from the on-chain transaction\n * identified by `order.txHash`. If the on-chain read fails or returns\n * no amount, falls back to computing the amount from `order.cryptoAmount`.\n *\n * @param options - The resolution options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.order - The completed on-ramp order.\n * @param options.fiatAsset - The fiat asset describing the expected token.\n * @param options.walletAddress - Recipient wallet address for on-chain lookup.\n * @returns The raw (atomic) source amount as a decimal string.\n */\nexport async function resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n order: RampsOrder;\n fiatAsset: TransactionPayFiatAsset;\n walletAddress: Hex;\n}): Promise<string> {\n if (order.txHash) {\n try {\n const onChainAmount = await getTransferredAmountFromTxHash({\n messenger,\n txHash: order.txHash,\n chainId: fiatAsset.chainId,\n tokenAddress: fiatAsset.address,\n walletAddress,\n });\n\n if (onChainAmount) {\n log('Resolved source amount from on-chain transaction', {\n txHash: order.txHash,\n onChainAmount,\n });\n return onChainAmount;\n }\n } catch (error) {\n log(\n 'Failed to read on-chain amount, falling back to order.cryptoAmount',\n { txHash: order.txHash, error },\n );\n }\n }\n\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 token info for fiat asset ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n return getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount: order.cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nexport function getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the relay exchange rate hasn't drifted significantly between\n * the original quoting phase and the post-settlement discovery quote.\n *\n * Compares the USD output/input ratio from both quotes. This normalises for\n * different source amounts (quoting phase uses a theoretical amount, discovery\n * uses the actual settled amount) so the comparison reflects genuine rate\n * movement rather than amount differences.\n *\n * @param options - The validation options.\n * @param options.originalQuote - Relay quote from the original quoting phase.\n * @param options.discoveryQuote - Relay quote from the post-settlement discovery.\n * @param options.maxRateDriftPercent - Maximum allowed rate drift percentage.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nexport function validateRelayRateDrift({\n originalQuote,\n discoveryQuote,\n maxRateDriftPercent,\n transactionId,\n}: {\n originalQuote: RelayQuote;\n discoveryQuote: RelayQuote;\n maxRateDriftPercent: number;\n transactionId: string;\n}): void {\n const originalIn = new BigNumber(originalQuote.details.currencyIn.amountUsd);\n const originalOut = new BigNumber(\n originalQuote.details.currencyOut.amountUsd,\n );\n const discoveryIn = new BigNumber(\n discoveryQuote.details.currencyIn.amountUsd,\n );\n const discoveryOut = new BigNumber(\n discoveryQuote.details.currencyOut.amountUsd,\n );\n\n if (\n !originalIn.gt(0) ||\n !originalOut.gt(0) ||\n !discoveryIn.gt(0) ||\n !discoveryOut.gt(0)\n ) {\n return;\n }\n\n const originalRate = originalOut.dividedBy(originalIn);\n const discoveryRate = discoveryOut.dividedBy(discoveryIn);\n\n const driftPercent = originalRate\n .minus(discoveryRate)\n .dividedBy(originalRate)\n .multipliedBy(100);\n\n log('Relay rate drift check', {\n originalRate: originalRate.toFixed(6),\n discoveryRate: discoveryRate.toFixed(6),\n driftPercent: driftPercent.toFixed(2),\n maxRateDriftPercent,\n transactionId,\n });\n\n if (driftPercent.gt(maxRateDriftPercent)) {\n throw new Error(\n `Relay rate drift too high for transaction ` +\n `${driftPercent.toFixed(2)}% exceeds ${maxRateDriftPercent}% max`,\n );\n }\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * Accepts the canonical provider code (e.g. `transak-native`) and, for\n * backwards compatibility, the legacy path form (e.g. `/providers/transak-native`).\n *\n * @param provider - Canonical provider code, or legacy provider path.\n * @returns The provider code, or `null` if the format is invalid.\n */\nexport function extractProviderCode(\n provider: string | undefined,\n): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n\n if (parts[0] === 'providers') {\n return parts[1] ?? null;\n }\n\n return parts.length === 1 ? parts[0] : null;\n}\n"]}
1
+ {"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Quote as RampsQuote,\n RampsOrder,\n} from '@metamask/ramps-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type { TransactionPayControllerMessenger } from '../../types';\nimport {\n getFiatAssetPerTransactionType,\n getFiatEnabledTypes,\n} from '../../utils/feature-flags';\nimport { buildCaipAssetType, getTokenInfo } from '../../utils/token';\nimport { getTransferredAmountFromTxHash } from '../../utils/transaction';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport { DEFAULT_FIAT_CURRENCY, FIAT_ENABLED_TYPES } from './constants';\n\nconst log = createModuleLogger(projectLogger, 'fiat-utils');\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatAsset {\n const enabledTypes = getFiatEnabledTypes(messenger);\n const txType = resolveTransactionType(transaction, enabledTypes);\n\n return getFiatAssetPerTransactionType(messenger, txType);\n}\n\n/**\n * Resolves the effective transaction type for fiat strategy purposes.\n *\n * For non-batch transactions returns the transaction's own type.\n * For batch transactions returns the first nested transaction type\n * that appears in the enabled types list, or the batch type itself\n * if no nested type matches.\n *\n * @param transaction - The transaction metadata to inspect.\n * @param enabledTypes - Transaction types eligible for fiat payment.\n * @returns The resolved transaction type, or `undefined`.\n */\nexport function resolveTransactionType(\n transaction: TransactionMeta,\n enabledTypes: TransactionType[],\n): TransactionType | undefined {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && enabledTypes.includes(tx.type),\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n\n/**\n * Checks whether a transaction is a Money Account deposit.\n *\n * Handles both direct `moneyAccountDeposit` transactions and EIP-7702\n * batch transactions that contain a `moneyAccountDeposit` nested call.\n * Uses {@link resolveTransactionType} with `FIAT_ENABLED_TYPES` to\n * correctly skip non-deposit nested types (e.g. `tokenMethodApprove`).\n *\n * @param transaction - The transaction metadata to inspect.\n * @returns `true` if the transaction is a Money Account deposit.\n */\nexport function isMoneyAccountDepositTransaction(\n transaction: TransactionMeta,\n): boolean {\n return (\n resolveTransactionType(transaction, FIAT_ENABLED_TYPES) ===\n TransactionType.moneyAccountDeposit\n );\n}\n\n/**\n * Fetches the first matching Ramps quote for a fiat asset and payment method.\n *\n * @param options - Quote options.\n * @param options.adjustedAmount - Fiat amount sent to Ramps.\n * @param options.errorMessage - Error thrown when no matching quote is returned.\n * @param options.fiatAsset - Fiat asset to buy.\n * @param options.fiatPaymentMethod - Selected fiat payment method.\n * @param options.messenger - Controller messenger.\n * @param options.walletAddress - Wallet address that receives the on-ramped asset.\n * @returns The first matching Ramps quote.\n */\nexport async function getRampsQuote({\n adjustedAmount,\n errorMessage = 'No matching ramps quote found for selected provider',\n fiatAsset,\n fiatPaymentMethod,\n messenger,\n walletAddress,\n}: {\n adjustedAmount: number;\n errorMessage?: string;\n fiatAsset: TransactionPayFiatAsset;\n fiatPaymentMethod: string;\n messenger: TransactionPayControllerMessenger;\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(errorMessage);\n }\n\n return quote;\n}\n\n/**\n * Resolves the raw source amount for a completed fiat order.\n *\n * Attempts to read the actual transferred amount from the on-chain transaction\n * identified by `order.txHash`. If the on-chain read fails or returns\n * no amount, falls back to computing the amount from `order.cryptoAmount`.\n *\n * @param options - The resolution options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.order - The completed on-ramp order.\n * @param options.fiatAsset - The fiat asset describing the expected token.\n * @param options.walletAddress - Recipient wallet address for on-chain lookup.\n * @returns The raw (atomic) source amount as a decimal string.\n */\nexport async function resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n order: RampsOrder;\n fiatAsset: TransactionPayFiatAsset;\n walletAddress: Hex;\n}): Promise<string> {\n if (order.txHash) {\n try {\n const onChainAmount = await getTransferredAmountFromTxHash({\n messenger,\n txHash: order.txHash,\n chainId: fiatAsset.chainId,\n tokenAddress: fiatAsset.address,\n walletAddress,\n });\n\n if (onChainAmount) {\n log('Resolved source amount from on-chain transaction', {\n txHash: order.txHash,\n onChainAmount,\n });\n return onChainAmount;\n }\n } catch (error) {\n log(\n 'Failed to read on-chain amount, falling back to order.cryptoAmount',\n { txHash: order.txHash, error },\n );\n }\n }\n\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 token info for fiat asset ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n return getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount: order.cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nexport function getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the relay exchange rate hasn't drifted significantly between\n * the original quoting phase and the post-settlement discovery quote.\n *\n * Compares the USD output/input ratio from both quotes. This normalises for\n * different source amounts (quoting phase uses a theoretical amount, discovery\n * uses the actual settled amount) so the comparison reflects genuine rate\n * movement rather than amount differences.\n *\n * @param options - The validation options.\n * @param options.originalQuote - Relay quote from the original quoting phase.\n * @param options.discoveryQuote - Relay quote from the post-settlement discovery.\n * @param options.maxRateDriftPercent - Maximum allowed rate drift percentage.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nexport function validateRelayRateDrift({\n originalQuote,\n discoveryQuote,\n maxRateDriftPercent,\n transactionId,\n}: {\n originalQuote: RelayQuote;\n discoveryQuote: RelayQuote;\n maxRateDriftPercent: number;\n transactionId: string;\n}): void {\n const originalIn = new BigNumber(originalQuote.details.currencyIn.amountUsd);\n const originalOut = new BigNumber(\n originalQuote.details.currencyOut.amountUsd,\n );\n const discoveryIn = new BigNumber(\n discoveryQuote.details.currencyIn.amountUsd,\n );\n const discoveryOut = new BigNumber(\n discoveryQuote.details.currencyOut.amountUsd,\n );\n\n if (\n !originalIn.gt(0) ||\n !originalOut.gt(0) ||\n !discoveryIn.gt(0) ||\n !discoveryOut.gt(0)\n ) {\n return;\n }\n\n const originalRate = originalOut.dividedBy(originalIn);\n const discoveryRate = discoveryOut.dividedBy(discoveryIn);\n\n const driftPercent = originalRate\n .minus(discoveryRate)\n .dividedBy(originalRate)\n .multipliedBy(100);\n\n log('Relay rate drift check', {\n originalRate: originalRate.toFixed(6),\n discoveryRate: discoveryRate.toFixed(6),\n driftPercent: driftPercent.toFixed(2),\n maxRateDriftPercent,\n transactionId,\n });\n\n if (driftPercent.gt(maxRateDriftPercent)) {\n throw new Error(\n `Relay rate drift too high for transaction ` +\n `${driftPercent.toFixed(2)}% exceeds ${maxRateDriftPercent}% max`,\n );\n }\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * Accepts the canonical provider code (e.g. `transak-native`) and, for\n * backwards compatibility, the legacy path form (e.g. `/providers/transak-native`).\n *\n * @param provider - Canonical provider code, or legacy provider path.\n * @returns The provider code, or `null` if the format is invalid.\n */\nexport function extractProviderCode(\n provider: string | undefined,\n): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n\n if (parts[0] === 'providers') {\n return parts[1] ?? null;\n }\n\n return parts.length === 1 ? parts[0] : null;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { RampsOrder } from "@metamask/ramps-controller";
1
+ import type { Quote as RampsQuote, RampsOrder } from "@metamask/ramps-controller";
2
2
  import type { TransactionMeta } from "@metamask/transaction-controller";
3
3
  import { TransactionType } from "@metamask/transaction-controller";
4
4
  import type { Hex } from "@metamask/utils";
@@ -31,6 +31,26 @@ export declare function resolveTransactionType(transaction: TransactionMeta, ena
31
31
  * @returns `true` if the transaction is a Money Account deposit.
32
32
  */
33
33
  export declare function isMoneyAccountDepositTransaction(transaction: TransactionMeta): boolean;
34
+ /**
35
+ * Fetches the first matching Ramps quote for a fiat asset and payment method.
36
+ *
37
+ * @param options - Quote options.
38
+ * @param options.adjustedAmount - Fiat amount sent to Ramps.
39
+ * @param options.errorMessage - Error thrown when no matching quote is returned.
40
+ * @param options.fiatAsset - Fiat asset to buy.
41
+ * @param options.fiatPaymentMethod - Selected fiat payment method.
42
+ * @param options.messenger - Controller messenger.
43
+ * @param options.walletAddress - Wallet address that receives the on-ramped asset.
44
+ * @returns The first matching Ramps quote.
45
+ */
46
+ export declare function getRampsQuote({ adjustedAmount, errorMessage, fiatAsset, fiatPaymentMethod, messenger, walletAddress, }: {
47
+ adjustedAmount: number;
48
+ errorMessage?: string;
49
+ fiatAsset: TransactionPayFiatAsset;
50
+ fiatPaymentMethod: string;
51
+ messenger: TransactionPayControllerMessenger;
52
+ walletAddress: string;
53
+ }): Promise<RampsQuote>;
34
54
  /**
35
55
  * Resolves the raw source amount for a completed fiat order.
36
56
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mCAAmC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,EAAE,eAAe,EAAE,yCAAyC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAOrE,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAoB;AAK3D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAKzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,eAAe,EAC5B,YAAY,EAAE,eAAe,EAAE,GAC9B,eAAe,GAAG,SAAS,CAU7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAKT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CA2CP;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAYf"}
1
+ {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,IAAI,UAAU,EACnB,UAAU,EACX,mCAAmC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,EAAE,eAAe,EAAE,yCAAyC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAOrE,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAoB;AAK3D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAKzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,eAAe,EAC5B,YAAY,EAAE,eAAe,EAAE,GAC9B,eAAe,GAAG,SAAS,CAU7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAKT;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,EAClC,cAAc,EACd,YAAoE,EACpE,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,uBAAuB,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,iCAAiC,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CA2CP;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAYf"}
@@ -1,4 +1,4 @@
1
- import type { RampsOrder } from "@metamask/ramps-controller";
1
+ import type { Quote as RampsQuote, RampsOrder } from "@metamask/ramps-controller";
2
2
  import type { TransactionMeta } from "@metamask/transaction-controller";
3
3
  import { TransactionType } from "@metamask/transaction-controller";
4
4
  import type { Hex } from "@metamask/utils";
@@ -31,6 +31,26 @@ export declare function resolveTransactionType(transaction: TransactionMeta, ena
31
31
  * @returns `true` if the transaction is a Money Account deposit.
32
32
  */
33
33
  export declare function isMoneyAccountDepositTransaction(transaction: TransactionMeta): boolean;
34
+ /**
35
+ * Fetches the first matching Ramps quote for a fiat asset and payment method.
36
+ *
37
+ * @param options - Quote options.
38
+ * @param options.adjustedAmount - Fiat amount sent to Ramps.
39
+ * @param options.errorMessage - Error thrown when no matching quote is returned.
40
+ * @param options.fiatAsset - Fiat asset to buy.
41
+ * @param options.fiatPaymentMethod - Selected fiat payment method.
42
+ * @param options.messenger - Controller messenger.
43
+ * @param options.walletAddress - Wallet address that receives the on-ramped asset.
44
+ * @returns The first matching Ramps quote.
45
+ */
46
+ export declare function getRampsQuote({ adjustedAmount, errorMessage, fiatAsset, fiatPaymentMethod, messenger, walletAddress, }: {
47
+ adjustedAmount: number;
48
+ errorMessage?: string;
49
+ fiatAsset: TransactionPayFiatAsset;
50
+ fiatPaymentMethod: string;
51
+ messenger: TransactionPayControllerMessenger;
52
+ walletAddress: string;
53
+ }): Promise<RampsQuote>;
34
54
  /**
35
55
  * Resolves the raw source amount for a completed fiat order.
36
56
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mCAAmC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,EAAE,eAAe,EAAE,yCAAyC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAOrE,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAoB;AAK3D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAKzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,eAAe,EAC5B,YAAY,EAAE,eAAe,EAAE,GAC9B,eAAe,GAAG,SAAS,CAU7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAKT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CA2CP;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAYf"}
1
+ {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,IAAI,UAAU,EACnB,UAAU,EACX,mCAAmC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,EAAE,eAAe,EAAE,yCAAyC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAOrE,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAuB;AACjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAoB;AAK3D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAKzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,eAAe,EAC5B,YAAY,EAAE,eAAe,EAAE,GAC9B,eAAe,GAAG,SAAS,CAU7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAKT;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,EAClC,cAAc,EACd,YAAoE,EACpE,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,EAAE;IACD,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,uBAAuB,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,iCAAiC,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,aAAa,EAAE,UAAU,CAAC;IAC1B,cAAc,EAAE,UAAU,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CA2CP;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAYf"}
@@ -3,9 +3,9 @@ import { createModuleLogger } from "@metamask/utils";
3
3
  import { BigNumber } from "bignumber.js";
4
4
  import { projectLogger } from "../../logger.mjs";
5
5
  import { getFiatAssetPerTransactionType, getFiatEnabledTypes } from "../../utils/feature-flags.mjs";
6
- import { getTokenInfo } from "../../utils/token.mjs";
6
+ import { buildCaipAssetType, getTokenInfo } from "../../utils/token.mjs";
7
7
  import { getTransferredAmountFromTxHash } from "../../utils/transaction.mjs";
8
- import { FIAT_ENABLED_TYPES } from "./constants.mjs";
8
+ import { DEFAULT_FIAT_CURRENCY, FIAT_ENABLED_TYPES } from "./constants.mjs";
9
9
  const log = createModuleLogger(projectLogger, 'fiat-utils');
10
10
  export function deriveFiatAssetForFiatPayment(transaction, messenger) {
11
11
  const enabledTypes = getFiatEnabledTypes(messenger);
@@ -46,6 +46,37 @@ export function isMoneyAccountDepositTransaction(transaction) {
46
46
  return (resolveTransactionType(transaction, FIAT_ENABLED_TYPES) ===
47
47
  TransactionType.moneyAccountDeposit);
48
48
  }
49
+ /**
50
+ * Fetches the first matching Ramps quote for a fiat asset and payment method.
51
+ *
52
+ * @param options - Quote options.
53
+ * @param options.adjustedAmount - Fiat amount sent to Ramps.
54
+ * @param options.errorMessage - Error thrown when no matching quote is returned.
55
+ * @param options.fiatAsset - Fiat asset to buy.
56
+ * @param options.fiatPaymentMethod - Selected fiat payment method.
57
+ * @param options.messenger - Controller messenger.
58
+ * @param options.walletAddress - Wallet address that receives the on-ramped asset.
59
+ * @returns The first matching Ramps quote.
60
+ */
61
+ export async function getRampsQuote({ adjustedAmount, errorMessage = 'No matching ramps quote found for selected provider', fiatAsset, fiatPaymentMethod, messenger, walletAddress, }) {
62
+ const quotes = await messenger.call('RampsController:getQuotes', {
63
+ amount: adjustedAmount,
64
+ assetId: buildCaipAssetType(fiatAsset.chainId, fiatAsset.address),
65
+ autoSelectProvider: true,
66
+ fiat: DEFAULT_FIAT_CURRENCY,
67
+ paymentMethods: [fiatPaymentMethod],
68
+ restrictToKnownOrNativeProviders: true,
69
+ walletAddress,
70
+ });
71
+ log('Fetched ramps quotes', {
72
+ quotesCount: quotes.success?.length ?? 0,
73
+ });
74
+ const quote = quotes.success?.[0];
75
+ if (!quote) {
76
+ throw new Error(errorMessage);
77
+ }
78
+ return quote;
79
+ }
49
80
  /**
50
81
  * Resolves the raw source amount for a completed fiat order.
51
82
  *