@metamask-previews/transaction-pay-controller 26.0.1-preview-a42e8d0d2 → 26.1.0-preview-d2f661012

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 (46) hide show
  1. package/CHANGELOG.md +16 -4
  2. package/dist/TransactionPayController.cjs +6 -13
  3. package/dist/TransactionPayController.cjs.map +1 -1
  4. package/dist/TransactionPayController.d.cts.map +1 -1
  5. package/dist/TransactionPayController.d.mts.map +1 -1
  6. package/dist/TransactionPayController.mjs +6 -13
  7. package/dist/TransactionPayController.mjs.map +1 -1
  8. package/dist/strategy/relay/relay-quotes.cjs +64 -20
  9. package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
  10. package/dist/strategy/relay/relay-quotes.mjs +64 -20
  11. package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
  12. package/dist/strategy/relay/relay-submit.cjs +167 -2
  13. package/dist/strategy/relay/relay-submit.cjs.map +1 -1
  14. package/dist/strategy/relay/relay-submit.d.cts.map +1 -1
  15. package/dist/strategy/relay/relay-submit.d.mts.map +1 -1
  16. package/dist/strategy/relay/relay-submit.mjs +168 -3
  17. package/dist/strategy/relay/relay-submit.mjs.map +1 -1
  18. package/dist/types.cjs.map +1 -1
  19. package/dist/types.d.cts +21 -0
  20. package/dist/types.d.cts.map +1 -1
  21. package/dist/types.d.mts +21 -0
  22. package/dist/types.d.mts.map +1 -1
  23. package/dist/types.mjs.map +1 -1
  24. package/dist/utils/ma-vault-deposit.cjs +69 -31
  25. package/dist/utils/ma-vault-deposit.cjs.map +1 -1
  26. package/dist/utils/ma-vault-deposit.d.cts +11 -2
  27. package/dist/utils/ma-vault-deposit.d.cts.map +1 -1
  28. package/dist/utils/ma-vault-deposit.d.mts +11 -2
  29. package/dist/utils/ma-vault-deposit.d.mts.map +1 -1
  30. package/dist/utils/ma-vault-deposit.mjs +69 -31
  31. package/dist/utils/ma-vault-deposit.mjs.map +1 -1
  32. package/dist/utils/quotes.cjs +25 -15
  33. package/dist/utils/quotes.cjs.map +1 -1
  34. package/dist/utils/quotes.d.cts.map +1 -1
  35. package/dist/utils/quotes.d.mts.map +1 -1
  36. package/dist/utils/quotes.mjs +25 -15
  37. package/dist/utils/quotes.mjs.map +1 -1
  38. package/package.json +8 -8
  39. package/dist/strategy/relay/relay-post-ma-vault.cjs +0 -96
  40. package/dist/strategy/relay/relay-post-ma-vault.cjs.map +0 -1
  41. package/dist/strategy/relay/relay-post-ma-vault.d.cts +0 -25
  42. package/dist/strategy/relay/relay-post-ma-vault.d.cts.map +0 -1
  43. package/dist/strategy/relay/relay-post-ma-vault.d.mts +0 -25
  44. package/dist/strategy/relay/relay-post-ma-vault.d.mts.map +0 -1
  45. package/dist/strategy/relay/relay-post-ma-vault.mjs +0 -92
  46. package/dist/strategy/relay/relay-post-ma-vault.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ma-vault-deposit.mjs","sourceRoot":"","sources":["../../src/utils/ma-vault-deposit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK } from '@metamask/controller-utils';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../logger.js';\nimport { MUSD_MONAD_FIAT_ASSET } from '../strategy/fiat/constants.js';\nimport type { TransactionPayControllerMessenger } from '../types.js';\nimport { findRecentChompVaultDeposit } from './chomp.js';\nimport { prefixError } from './error-prefix.js';\nimport { getNetworkClientId } from './provider.js';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from './transaction.js';\n\nconst log = createModuleLogger(projectLogger, 'ma-vault-deposit');\n\nexport const VAULT_ERROR_PREFIX = 'Vault: ';\n\n/**\n * Submits a Money Account mUSD vault deposit batch on Monad once the source\n * mUSD has settled in the Money Account (fiat on-ramp, Relay bridge, or any\n * other path). Re-encodes the original nested vault calldata with the\n * settled `sourceAmountRaw` via `getAmountData` and submits as a sponsored,\n * internal EIP-7702 batch. Callers decide whether to honour any vault\n * kill-switch by passing `vaultDisabled`.\n *\n * @param options - Submit options.\n * @param options.fromBlock - Block number to start searching for CHOMP deposits.\n * @param options.messenger - Controller messenger.\n * @param options.sourceAmountRaw - Settled mUSD amount in raw units.\n * @param options.transaction - Original Money Account transaction meta.\n * @param options.vaultDisabled - When `true`, skip the vault batch and leave\n * the settled mUSD in the Money Account. Caller-evaluated kill-switch.\n * @returns Hash of the final submitted child transaction, if available.\n */\nexport async function submitMoneyAccountVaultDeposit({\n fromBlock,\n messenger,\n sourceAmountRaw,\n transaction,\n vaultDisabled,\n}: {\n fromBlock?: Hex;\n messenger: TransactionPayControllerMessenger;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n vaultDisabled: boolean;\n}): Promise<{ transactionHash?: Hex }> {\n const transactionId = transaction.id;\n const moneyAccountAddress = transaction.txParams.from as Hex | undefined;\n\n if (!moneyAccountAddress) {\n throw new Error('Missing Money Account address');\n }\n\n if (vaultDisabled) {\n log('Skipping vault deposit because vaultDisabled is true', {\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n });\n\n return { transactionHash: '0x' };\n }\n\n const updatedTransaction =\n getTransaction(transactionId, messenger) ?? transaction;\n const { updates } = await messenger.call(\n 'TransactionPayController:getAmountData',\n {\n amount: sourceAmountRaw,\n transaction: updatedTransaction,\n },\n );\n\n if (!updates.length) {\n throw new Error('No amount updates');\n }\n\n const nestedTransactions = updatedTransaction.nestedTransactions?.map(\n (nestedTransaction) => ({ ...nestedTransaction }),\n );\n\n if (!nestedTransactions?.length) {\n throw new Error('Missing nested transactions');\n }\n\n for (const { nestedTransactionIndex, data } of updates) {\n if (nestedTransactions[nestedTransactionIndex]) {\n nestedTransactions[nestedTransactionIndex].data = data;\n }\n }\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Money Account vault deposit: update vault amount',\n },\n (tx) => {\n for (const { nestedTransactionIndex, data } of updates) {\n if (tx.nestedTransactions?.[nestedTransactionIndex]) {\n tx.nestedTransactions[nestedTransactionIndex].data = data;\n }\n }\n\n if (tx.requiredAssets?.[0]) {\n tx.requiredAssets[0].amount = `0x${BigInt(sourceAmountRaw).toString(\n 16,\n )}`;\n }\n },\n );\n\n // CHOMP pre-check: skip addTransactionBatch entirely if CHOMP has already\n // auto-vaulted the funds during or before the checkout window.\n const preChompHash = await tryFindChompDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n });\n\n if (preChompHash) {\n return { transactionHash: preChompHash };\n }\n\n const networkClientId = getNetworkClientId(\n messenger,\n MUSD_MONAD_FIAT_ASSET.chainId,\n );\n const transactionIds: string[] = [];\n const { end } = collectTransactionIds(\n MUSD_MONAD_FIAT_ASSET.chainId,\n moneyAccountAddress,\n messenger,\n (id) => {\n transactionIds.push(id);\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Add required transaction ID from Money Account vault submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(id);\n },\n );\n },\n );\n\n log('Submitting Money Account vault deposit', {\n moneyAccountAddress,\n nestedTransactionCount: nestedTransactions.length,\n networkClientId,\n sourceAmountRaw,\n transactionId,\n });\n\n try {\n await messenger.call('TransactionController:addTransactionBatch', {\n disableHook: true,\n disableSequential: true,\n disableUpgrade: true,\n from: moneyAccountAddress,\n isGasFeeSponsored: true,\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n requireApproval: false,\n skipInitialGasEstimate: true,\n transactions: nestedTransactions.map((nestedTransaction, index) => ({\n params: {\n data: nestedTransaction.data,\n to: nestedTransaction.to,\n value: nestedTransaction.value ?? '0x0',\n },\n type:\n index === 0\n ? (nestedTransaction.type ?? TransactionType.tokenMethodApprove)\n : TransactionType.contractInteraction,\n })),\n });\n } catch (error) {\n // CHOMP post-check: CHOMP may have won the race between pre-check and\n // submit. Return the CHOMP hash instead of surfacing a Vault-prefixed error.\n const postChompHash = await tryFindChompDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n });\n\n if (postChompHash) {\n return { transactionHash: postChompHash };\n }\n\n throw prefixError(error, VAULT_ERROR_PREFIX);\n } finally {\n end();\n }\n\n log('Submitted Money Account vault deposit', {\n moneyAccountAddress,\n nestedTransactionCount: nestedTransactions.length,\n networkClientId,\n sourceAmountRaw,\n transactionId,\n transactionIds,\n });\n\n if (!transactionIds.length) {\n throw new Error('No transactions submitted');\n }\n\n await Promise.all(\n transactionIds.map((id) => waitForTransactionConfirmed(id, messenger)),\n );\n\n const hash = getTransaction(transactionIds.slice(-1)[0], messenger)?.hash;\n\n if (!hash) {\n throw new Error('Missing transaction hash');\n }\n\n log('Confirmed Money Account vault deposit', {\n hash,\n moneyAccountAddress,\n nestedTransactionCount: nestedTransactions.length,\n networkClientId,\n sourceAmountRaw,\n transactionId,\n transactionIds,\n });\n\n return { transactionHash: hash as Hex };\n}\n\nasync function tryFindChompDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n}: {\n fromBlock: Hex | undefined;\n messenger: TransactionPayControllerMessenger;\n moneyAccountAddress: Hex;\n sourceAmountRaw: string;\n transactionId: string;\n}): Promise<Hex | undefined> {\n if (!fromBlock) {\n return undefined;\n }\n\n try {\n return await findRecentChompVaultDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n });\n } catch (chompError) {\n log('CHOMP check failed', { chompError, transactionId });\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"ma-vault-deposit.mjs","sourceRoot":"","sources":["../../src/utils/ma-vault-deposit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK } from '@metamask/controller-utils';\nimport type {\n BatchTransactionParams,\n NestedTransactionMetadata,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../logger.js';\nimport { MUSD_MONAD_FIAT_ASSET } from '../strategy/fiat/constants.js';\nimport type { TransactionPayControllerMessenger } from '../types.js';\nimport { findRecentChompVaultDeposit } from './chomp.js';\nimport { prefixError } from './error-prefix.js';\nimport { getNetworkClientId } from './provider.js';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from './transaction.js';\n\nconst log = createModuleLogger(projectLogger, 'ma-vault-deposit');\n\nexport const VAULT_ERROR_PREFIX = 'Vault: ';\n\n/**\n * Submits a Money Account mUSD vault deposit batch on Monad once the source\n * mUSD has settled in the Money Account (fiat on-ramp, Relay bridge, or any\n * other path). Re-encodes the original nested vault calldata with the\n * settled `sourceAmountRaw` via `getAmountData` and submits as a sponsored,\n * internal EIP-7702 batch. Callers decide whether to honour any vault\n * kill-switch by passing `vaultDisabled`.\n *\n * @param options - Submit options.\n * @param options.fromBlock - Block number to start searching for CHOMP deposits.\n * @param options.messenger - Controller messenger.\n * @param options.moneyAccountAddress - Money Account address sending the vault\n * deposit. Defaults to `transaction.txParams.from` (the deposit-flow sender);\n * withdraw flows pass it explicitly since their `from` is the funding EOA.\n * @param options.depositCalls - Pre-built vault-deposit batch for withdraw\n * flows, whose parent transaction carries no vault calls. When omitted the\n * batch is derived from the transaction's own nested calls re-encoded via\n * `getAmountData`.\n * @param options.sourceAmountRaw - Settled mUSD amount in raw units.\n * @param options.transaction - Original Money Account transaction meta.\n * @param options.vaultDisabled - When `true`, skip the vault batch and leave\n * the settled mUSD in the Money Account. Caller-evaluated kill-switch.\n * @returns Hash of the final submitted child transaction, if available.\n */\nexport async function submitMoneyAccountVaultDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress: moneyAccountAddressOverride,\n depositCalls,\n sourceAmountRaw,\n transaction,\n vaultDisabled,\n}: {\n fromBlock?: Hex;\n messenger: TransactionPayControllerMessenger;\n moneyAccountAddress?: Hex;\n depositCalls?: BatchTransactionParams[];\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n vaultDisabled: boolean;\n}): Promise<{ transactionHash?: Hex }> {\n const transactionId = transaction.id;\n const moneyAccountAddress = (moneyAccountAddressOverride ??\n transaction.txParams.from) as Hex | undefined;\n\n if (!moneyAccountAddress) {\n throw new Error('Missing Money Account address');\n }\n\n if (vaultDisabled) {\n log('Skipping vault deposit because vaultDisabled is true', {\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n });\n\n return { transactionHash: '0x' };\n }\n\n const nestedTransactions = await resolveVaultDepositBatch({\n depositCalls,\n messenger,\n sourceAmountRaw,\n transaction,\n transactionId,\n });\n\n // CHOMP pre-check: skip addTransactionBatch entirely if CHOMP has already\n // auto-vaulted the funds during or before the checkout window.\n const preChompHash = await tryFindChompDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n });\n\n if (preChompHash) {\n return { transactionHash: preChompHash };\n }\n\n const networkClientId = getNetworkClientId(\n messenger,\n MUSD_MONAD_FIAT_ASSET.chainId,\n );\n const transactionIds: string[] = [];\n const { end } = collectTransactionIds(\n MUSD_MONAD_FIAT_ASSET.chainId,\n moneyAccountAddress,\n messenger,\n (id) => {\n transactionIds.push(id);\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Add required transaction ID from Money Account vault submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(id);\n },\n );\n },\n );\n\n log('Submitting Money Account vault deposit', {\n moneyAccountAddress,\n nestedTransactionCount: nestedTransactions.length,\n networkClientId,\n sourceAmountRaw,\n transactionId,\n });\n\n try {\n await messenger.call('TransactionController:addTransactionBatch', {\n disableHook: true,\n disableSequential: true,\n disableUpgrade: true,\n from: moneyAccountAddress,\n isGasFeeSponsored: true,\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n requireApproval: false,\n skipInitialGasEstimate: true,\n transactions: nestedTransactions.map((nestedTransaction, index) => ({\n params: {\n data: nestedTransaction.data,\n to: nestedTransaction.to,\n value: nestedTransaction.value ?? '0x0',\n },\n type:\n index === 0\n ? (nestedTransaction.type ?? TransactionType.tokenMethodApprove)\n : TransactionType.contractInteraction,\n })),\n });\n } catch (error) {\n // CHOMP post-check: CHOMP may have won the race between pre-check and\n // submit. Return the CHOMP hash instead of surfacing a Vault-prefixed error.\n const postChompHash = await tryFindChompDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n });\n\n if (postChompHash) {\n return { transactionHash: postChompHash };\n }\n\n throw prefixError(error, VAULT_ERROR_PREFIX);\n } finally {\n end();\n }\n\n log('Submitted Money Account vault deposit', {\n moneyAccountAddress,\n nestedTransactionCount: nestedTransactions.length,\n networkClientId,\n sourceAmountRaw,\n transactionId,\n transactionIds,\n });\n\n if (!transactionIds.length) {\n throw new Error('No transactions submitted');\n }\n\n await Promise.all(\n transactionIds.map((id) => waitForTransactionConfirmed(id, messenger)),\n );\n\n const hash = getTransaction(transactionIds.slice(-1)[0], messenger)?.hash;\n\n if (!hash) {\n throw new Error('Missing transaction hash');\n }\n\n log('Confirmed Money Account vault deposit', {\n hash,\n moneyAccountAddress,\n nestedTransactionCount: nestedTransactions.length,\n networkClientId,\n sourceAmountRaw,\n transactionId,\n transactionIds,\n });\n\n return { transactionHash: hash as Hex };\n}\n\n/**\n * Resolves the vault-deposit batch (approve + teller deposit) to submit.\n *\n * Withdraw flows have no vault calls on their own nested transactions, so the\n * caller supplies a freshly built `depositCalls` batch. Deposit flows re-encode\n * their existing nested vault calldata with the settled amount via\n * `getAmountData` and also mutate the parent transaction so its stored calls\n * and `requiredAssets` reflect the settled amount.\n *\n * @param options - Resolution options.\n * @param options.depositCalls - Pre-built deposit batch for withdraw flows.\n * @param options.messenger - Controller messenger.\n * @param options.sourceAmountRaw - Settled mUSD amount in raw units.\n * @param options.transaction - Original Money Account transaction meta.\n * @param options.transactionId - ID of the original transaction.\n * @returns Nested transactions to submit as the vault deposit batch.\n */\nasync function resolveVaultDepositBatch({\n depositCalls,\n messenger,\n sourceAmountRaw,\n transaction,\n transactionId,\n}: {\n depositCalls?: BatchTransactionParams[];\n messenger: TransactionPayControllerMessenger;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n transactionId: string;\n}): Promise<NestedTransactionMetadata[]> {\n if (depositCalls?.length) {\n return depositCalls;\n }\n\n const updatedTransaction =\n getTransaction(transactionId, messenger) ?? transaction;\n const { updates } = await messenger.call(\n 'TransactionPayController:getAmountData',\n {\n amount: sourceAmountRaw,\n transaction: updatedTransaction,\n },\n );\n\n if (!updates.length) {\n throw new Error('No amount updates');\n }\n\n const nestedTransactions = updatedTransaction.nestedTransactions?.map(\n (nestedTransaction) => ({ ...nestedTransaction }),\n );\n\n if (!nestedTransactions?.length) {\n throw new Error('Missing nested transactions');\n }\n\n for (const { nestedTransactionIndex, data } of updates) {\n if (nestedTransactions[nestedTransactionIndex]) {\n nestedTransactions[nestedTransactionIndex].data = data;\n }\n }\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Money Account vault deposit: update vault amount',\n },\n (tx) => {\n for (const { nestedTransactionIndex, data } of updates) {\n if (tx.nestedTransactions?.[nestedTransactionIndex]) {\n tx.nestedTransactions[nestedTransactionIndex].data = data;\n }\n }\n\n if (tx.requiredAssets?.[0]) {\n tx.requiredAssets[0].amount = `0x${BigInt(sourceAmountRaw).toString(\n 16,\n )}`;\n }\n },\n );\n\n return nestedTransactions;\n}\n\nasync function tryFindChompDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n transactionId,\n}: {\n fromBlock: Hex | undefined;\n messenger: TransactionPayControllerMessenger;\n moneyAccountAddress: Hex;\n sourceAmountRaw: string;\n transactionId: string;\n}): Promise<Hex | undefined> {\n if (!fromBlock) {\n return undefined;\n }\n\n try {\n return await findRecentChompVaultDeposit({\n fromBlock,\n messenger,\n moneyAccountAddress,\n sourceAmountRaw,\n });\n } catch (chompError) {\n log('CHOMP check failed', { chompError, transactionId });\n return undefined;\n }\n}\n"]}
@@ -36,7 +36,7 @@ async function updateQuotes(request) {
36
36
  return false;
37
37
  }
38
38
  log('Updating quotes', { transactionId });
39
- const { accountOverride, isMaxAmount, isPostQuote, isHyperliquidSource, isPolymarketDepositWallet, isQuoteRequired, paymentOverride, paymentToken: originalPaymentToken, fiatPayment, refundTo, sourceAmounts, tokens, } = transactionData;
39
+ const { accountOverride, atomic, fiatPayment, isHyperliquidSource, isMaxAmount, isPolymarketDepositWallet, isPostQuote, isQuoteRequired, paymentOverride, paymentToken: originalPaymentToken, refundTo, sourceAmounts, tokens, } = transactionData;
40
40
  const from = accountOverride ?? transaction.txParams.from;
41
41
  const controller = abortPreviousAndCreateController(transactionId);
42
42
  const { signal } = controller;
@@ -58,11 +58,12 @@ async function updateQuotes(request) {
58
58
  return false;
59
59
  }
60
60
  const requests = buildQuoteRequests({
61
+ atomic,
61
62
  from,
62
- isMaxAmount: isMaxAmount ?? false,
63
- isPostQuote,
64
63
  isHyperliquidSource,
64
+ isMaxAmount: isMaxAmount ?? false,
65
65
  isPolymarketDepositWallet,
66
+ isPostQuote,
66
67
  paymentOverride,
67
68
  paymentToken,
68
69
  refundTo,
@@ -96,6 +97,7 @@ async function updateQuotes(request) {
96
97
  isPostQuote,
97
98
  messenger: messenger,
98
99
  paymentToken,
100
+ strategy: executableQuotes[0]?.strategy,
99
101
  totals,
100
102
  transactionId,
101
103
  });
@@ -134,10 +136,11 @@ exports.updateQuotes = updateQuotes;
134
136
  * @param request.messenger - Messenger instance.
135
137
  * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).
136
138
  * @param request.selectedFiatPayment - Selected fiat payment method ID.
139
+ * @param request.strategy - Strategy of the executable quotes.
137
140
  * @param request.totals - Calculated totals.
138
141
  * @param request.transactionId - ID of the transaction to sync.
139
142
  */
140
- function syncTransaction({ batchTransactions, hasQuotes, isPostQuote, messenger, paymentToken, selectedFiatPayment, totals, transactionId, }) {
143
+ function syncTransaction({ batchTransactions, hasQuotes, isPostQuote, messenger, paymentToken, selectedFiatPayment, strategy, totals, transactionId, }) {
141
144
  if (!paymentToken && !selectedFiatPayment) {
142
145
  return;
143
146
  }
@@ -167,6 +170,7 @@ function syncTransaction({ batchTransactions, hasQuotes, isPostQuote, messenger,
167
170
  chainId: paymentToken?.chainId,
168
171
  isPostQuote,
169
172
  networkFeeFiat: totals.fees.sourceNetwork.estimate.usd,
173
+ strategy,
170
174
  targetFiat: totals.targetAmount.usd,
171
175
  tokenAddress: paymentToken?.address,
172
176
  totalFiat: totals.total.usd,
@@ -236,9 +240,10 @@ function clearControllerIfCurrent(transactionId, controller) {
236
240
  * Build quote requests required to retrieve quotes.
237
241
  *
238
242
  * @param request - Request parameters.
243
+ * @param request.atomic - Whether the target transaction is executed atomically with the Relay quote.
239
244
  * @param request.from - Address from which the transaction is sent.
240
- * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
241
245
  * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.
246
+ * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
242
247
  * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.
243
248
  * @param request.isPostQuote - Whether this is a post-quote flow.
244
249
  * @param request.paymentOverride - Optional payment override type for the transaction.
@@ -249,18 +254,19 @@ function clearControllerIfCurrent(transactionId, controller) {
249
254
  * @param request.transactionId - ID of the transaction.
250
255
  * @returns Array of quote requests.
251
256
  */
252
- function buildQuoteRequests({ from, isMaxAmount, isPostQuote, isHyperliquidSource, isPolymarketDepositWallet, paymentOverride, paymentToken, refundTo, sourceAmounts, tokens, transactionId, }) {
257
+ function buildQuoteRequests({ atomic, from, isHyperliquidSource, isMaxAmount, isPolymarketDepositWallet, isPostQuote, paymentOverride, paymentToken, refundTo, sourceAmounts, tokens, transactionId, }) {
253
258
  if (!paymentToken) {
254
259
  return [];
255
260
  }
256
261
  if (isPostQuote) {
257
262
  return buildPostQuoteRequests({
263
+ atomic,
264
+ destinationToken: paymentToken,
258
265
  from,
259
- isMaxAmount,
260
266
  isHyperliquidSource,
267
+ isMaxAmount,
261
268
  isPolymarketDepositWallet,
262
269
  paymentOverride,
263
- destinationToken: paymentToken,
264
270
  refundTo,
265
271
  sourceAmounts,
266
272
  transactionId,
@@ -270,13 +276,15 @@ function buildQuoteRequests({ from, isMaxAmount, isPostQuote, isHyperliquidSourc
270
276
  const requests = (sourceAmounts ?? []).map((sourceAmount) => {
271
277
  const token = tokens.find((singleToken) => singleToken.address === sourceAmount.targetTokenAddress);
272
278
  return {
279
+ atomic,
273
280
  from,
274
281
  isMaxAmount,
275
282
  paymentOverride,
283
+ refundTo,
276
284
  sourceBalanceRaw: paymentToken.balanceRaw,
277
- sourceTokenAmount: sourceAmount.sourceAmountRaw,
278
285
  sourceChainId: paymentToken.chainId,
279
286
  sourceTokenAddress: paymentToken.address,
287
+ sourceTokenAmount: sourceAmount.sourceAmountRaw,
280
288
  targetAmountMinimum: token.allowUnderMinimum ? '0' : token.amountRaw,
281
289
  targetChainId: token.chainId,
282
290
  targetTokenAddress: token.address,
@@ -293,18 +301,19 @@ function buildQuoteRequests({ from, isMaxAmount, isPostQuote, isHyperliquidSourc
293
301
  * and the target is the user's selected destination token (paymentToken).
294
302
  *
295
303
  * @param request - Request parameters.
304
+ * @param request.atomic - Whether the target transaction is executed atomically with the Relay quote.
305
+ * @param request.destinationToken - Destination token (paymentToken in post-quote mode).
296
306
  * @param request.from - Address from which the transaction is sent.
297
- * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
298
307
  * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.
308
+ * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
299
309
  * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.
300
310
  * @param request.paymentOverride - Optional payment override type for the transaction.
301
- * @param request.destinationToken - Destination token (paymentToken in post-quote mode).
302
311
  * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.
303
312
  * @param request.sourceAmounts - Source amounts for the transaction (includes source token info).
304
313
  * @param request.transactionId - ID of the transaction.
305
314
  * @returns Array of quote requests for post-quote flow.
306
315
  */
307
- function buildPostQuoteRequests({ from, isMaxAmount, isHyperliquidSource, isPolymarketDepositWallet, paymentOverride, destinationToken, refundTo, sourceAmounts, transactionId, }) {
316
+ function buildPostQuoteRequests({ atomic, destinationToken, from, isHyperliquidSource, isMaxAmount, isPolymarketDepositWallet, paymentOverride, refundTo, sourceAmounts, transactionId, }) {
308
317
  // Find the source amount where targetTokenAddress matches the destination token
309
318
  const sourceAmount = sourceAmounts?.find((amount) => amount.targetTokenAddress.toLowerCase() ===
310
319
  destinationToken.address.toLowerCase());
@@ -318,17 +327,18 @@ function buildPostQuoteRequests({ from, isMaxAmount, isHyperliquidSource, isPoly
318
327
  return [];
319
328
  }
320
329
  const request = {
330
+ atomic,
321
331
  from,
322
- isMaxAmount,
323
- isPostQuote: true,
324
332
  isHyperliquidSource,
333
+ isMaxAmount,
325
334
  isPolymarketDepositWallet,
335
+ isPostQuote: true,
326
336
  paymentOverride,
327
337
  refundTo,
328
338
  sourceBalanceRaw: sourceAmount.sourceBalanceRaw,
329
- sourceTokenAmount: sourceAmount.sourceAmountRaw,
330
339
  sourceChainId: sourceAmount.sourceChainId,
331
340
  sourceTokenAddress: sourceAmount.sourceTokenAddress,
341
+ sourceTokenAmount: sourceAmount.sourceAmountRaw,
332
342
  targetAmountMinimum: '0',
333
343
  targetChainId: destinationToken.chainId,
334
344
  targetTokenAddress: destinationToken.address,
@@ -1 +1 @@
1
- {"version":3,"file":"quotes.cjs","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionStatus } from '@metamask/transaction-controller';\nimport type { BatchTransaction } from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex, Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { PaymentOverride, TransactionPayStrategy } from '../constants.js';\nimport { projectLogger } from '../logger.js';\nimport type {\n QuoteRequest,\n QuoteErrorInfo,\n TransactionData,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n TransactionPayRequiredToken,\n TransactionPaySourceAmount,\n TransactionPayTotals,\n TransactionPaymentToken,\n UpdateTransactionDataCallback,\n} from '../types.js';\nimport { accountSupports7702 } from './7702.js';\nimport { buildNoOpQuote } from './no-op-quote.js';\nimport {\n checkStrategyQuoteSupport,\n checkStrategySupport,\n getStrategiesByName,\n getStrategyByName,\n} from './strategy.js';\nimport {\n computeTokenAmounts,\n getLiveTokenBalance,\n getTokenFiatRate,\n} from './token.js';\nimport { calculateTotals } from './totals.js';\nimport { getTransaction, updateTransaction } from './transaction.js';\nimport { isQuoteError } from './validation.js';\n\nconst DEFAULT_REFRESH_INTERVAL = 30 * 1000; // 30 Seconds\n\nconst log = createModuleLogger(projectLogger, 'quotes');\n\nconst inFlightQuoteRequests = new Map<string, AbortController>();\n\nexport type UpdateQuotesRequest = {\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[];\n messenger: TransactionPayControllerMessenger;\n transactionData: TransactionData | undefined;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n};\n\n/**\n * Update the quotes for a specific transaction.\n *\n * Calls for the same `transactionId` are serialised: a fresh call aborts any\n * previous in-flight call so a slower stale response cannot overwrite a newer\n * one in state.\n *\n * @param request - Request parameters.\n * @returns Boolean indicating if the quotes were updated. Returns `false` when\n * the call was aborted by a subsequent call for the same transaction.\n */\nexport async function updateQuotes(\n request: UpdateQuotesRequest,\n): Promise<boolean> {\n const {\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n } = request;\n\n const transaction = getTransaction(transactionId, messenger);\n\n if (!transaction || !transactionData) {\n throw new Error('Transaction not found');\n }\n\n if (transaction?.status !== TransactionStatus.unapproved) {\n return false;\n }\n\n log('Updating quotes', { transactionId });\n\n const {\n accountOverride,\n isMaxAmount,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n isQuoteRequired,\n paymentOverride,\n paymentToken: originalPaymentToken,\n fiatPayment,\n refundTo,\n sourceAmounts,\n tokens,\n } = transactionData;\n\n const from = accountOverride ?? (transaction.txParams.from as Hex);\n\n const controller = abortPreviousAndCreateController(transactionId);\n const { signal } = controller;\n\n updateTransactionData(transactionId, (data) => {\n data.isLoading = true;\n data.quoteError = undefined;\n });\n\n try {\n const paymentToken = await refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken: originalPaymentToken,\n signal,\n transactionId,\n updateTransactionData,\n });\n\n if (signal.aborted) {\n log('Quote request aborted before building requests', { transactionId });\n return false;\n }\n\n const requests = buildQuoteRequests({\n from,\n isMaxAmount: isMaxAmount ?? false,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n });\n\n const supports7702 = accountSupports7702(messenger, from);\n\n const { batchTransactions, error, quotes } = await getQuotes(\n transaction,\n from,\n requests,\n paymentToken,\n isQuoteRequired ?? false,\n supports7702,\n getStrategies,\n messenger,\n fiatPayment?.selectedPaymentMethodId,\n signal,\n );\n\n if (signal.aborted) {\n log('Quote request aborted before persisting results', { transactionId });\n return false;\n }\n\n // No-op quotes mark direct routes. They have no fees or amounts and the\n // transaction is signed and submitted locally, so totals and transaction\n // sync must treat them as \"no quotes\".\n const executableQuotes = quotes.filter(\n (quote) => quote.strategy !== TransactionPayStrategy.None,\n );\n\n const totals = calculateTotals({\n fiatPaymentAmount: fiatPayment?.amountFiat,\n isMaxAmount,\n messenger,\n quotes: executableQuotes as TransactionPayQuote<unknown>[],\n tokens,\n transaction,\n });\n\n log('Calculated totals', { transactionId, totals });\n\n syncTransaction({\n batchTransactions,\n selectedFiatPayment: fiatPayment?.selectedPaymentMethodId,\n hasQuotes: executableQuotes.length > 0,\n isPostQuote,\n messenger: messenger as never,\n paymentToken,\n totals,\n transactionId,\n });\n\n updateTransactionData(transactionId, (data) => {\n data.quotes = quotes as never;\n data.quoteError = quotes.length ? undefined : error;\n data.quotesLastUpdated = Date.now();\n data.totals = totals;\n });\n } catch (error) {\n if (signal.aborted) {\n log('Quote request aborted', { transactionId, reason: signal.reason });\n return false;\n }\n throw error;\n } finally {\n if (!signal.aborted) {\n updateTransactionData(transactionId, (data) => {\n data.isLoading = false;\n });\n }\n clearControllerIfCurrent(transactionId, controller);\n }\n\n return true;\n}\n\n/**\n * Sync batch transactions to the transaction meta.\n *\n * @param request - Request object.\n * @param request.batchTransactions - Batch transactions to sync.\n * @param request.hasQuotes - Whether MM Pay produced any quotes for this transaction.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.messenger - Messenger instance.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.selectedFiatPayment - Selected fiat payment method ID.\n * @param request.totals - Calculated totals.\n * @param request.transactionId - ID of the transaction to sync.\n */\nfunction syncTransaction({\n batchTransactions,\n hasQuotes,\n isPostQuote,\n messenger,\n paymentToken,\n selectedFiatPayment,\n totals,\n transactionId,\n}: {\n batchTransactions: BatchTransaction[];\n selectedFiatPayment?: string;\n hasQuotes: boolean;\n isPostQuote?: boolean;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n totals: TransactionPayTotals;\n transactionId: string;\n}): void {\n if (!paymentToken && !selectedFiatPayment) {\n return;\n }\n\n updateTransaction(\n {\n transactionId,\n messenger: messenger as never,\n note: 'Update transaction pay data',\n },\n (tx: TransactionMeta) => {\n tx.batchTransactions = batchTransactions;\n tx.batchTransactionsOptions = {};\n\n // When MM Pay has produced quotes, it owns submission of this transaction\n // via its strategy publish hook, so the parent must be marked externally\n // signed to skip the local `KeyringController:signTransaction` call.\n // When there are no quotes (e.g. user selected the target token as the\n // payment token in a Predict flow), the transaction falls back to normal\n // local signing, so the flag is cleared to allow that.\n // If gas is sponsored, TC owns this field — it is set based on the\n // Sentinel simulation result and must not be cleared here. Same-token\n // flows (e.g. Monad mUSD withdrawal via a Money Account) produce no\n // quotes but still need external sign because the account cannot sign\n // locally.\n if (!tx.isGasFeeSponsored) {\n tx.isExternalSign = hasQuotes;\n }\n\n tx.metamaskPay = {\n bridgeFeeFiat: totals.fees.provider.usd,\n chainId: paymentToken?.chainId,\n isPostQuote,\n networkFeeFiat: totals.fees.sourceNetwork.estimate.usd,\n targetFiat: totals.targetAmount.usd,\n tokenAddress: paymentToken?.address,\n totalFiat: totals.total.usd,\n };\n },\n );\n}\n\n/**\n * Refresh quotes for all transactions if expired.\n *\n * @param messenger - Messenger instance.\n * @param updateTransactionData - Callback to update transaction data.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n */\nexport async function refreshQuotes(\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n): Promise<void> {\n const state = messenger.call('TransactionPayController:getState');\n const transactionIds = Object.keys(state.transactionData);\n\n for (const transactionId of transactionIds) {\n const transactionData = state.transactionData[transactionId];\n const { isLoading, quotes, quotesLastUpdated } = transactionData;\n\n if (isLoading || !quotes?.length) {\n continue;\n }\n\n // No-op quotes mark direct routes and have nothing to refresh. They are\n // regenerated whenever the transaction data changes.\n if (\n quotes.every((quote) => quote.strategy === TransactionPayStrategy.None)\n ) {\n continue;\n }\n\n const strategyName = quotes[0].strategy;\n const strategy = getStrategyByName(strategyName);\n\n const refreshInterval =\n (await strategy.getRefreshInterval?.({\n chainId: quotes[0].request.sourceChainId,\n messenger,\n })) ?? DEFAULT_REFRESH_INTERVAL;\n\n const isExpired = Date.now() - (quotesLastUpdated ?? 0) > refreshInterval;\n\n if (!isExpired) {\n continue;\n }\n\n const isUpdated = await updateQuotes({\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n });\n\n if (isUpdated) {\n log('Refreshed quotes', { transactionId, strategy: strategyName });\n }\n }\n}\n\nfunction abortPreviousAndCreateController(\n transactionId: string,\n): AbortController {\n const previous = inFlightQuoteRequests.get(transactionId);\n\n if (previous && !previous.signal.aborted) {\n log('Aborting previous quote request', { transactionId });\n previous.abort(new Error('Superseded by newer quote request'));\n }\n\n const controller = new AbortController();\n inFlightQuoteRequests.set(transactionId, controller);\n return controller;\n}\n\nfunction clearControllerIfCurrent(\n transactionId: string,\n controller: AbortController,\n): void {\n if (inFlightQuoteRequests.get(transactionId) === controller) {\n inFlightQuoteRequests.delete(transactionId);\n }\n}\n\n/**\n * Build quote requests required to retrieve quotes.\n *\n * @param request - Request parameters.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction.\n * @param request.tokens - Required tokens for the transaction.\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests.\n */\nfunction buildQuoteRequests({\n from,\n isMaxAmount,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n}: {\n from: Hex;\n isMaxAmount: boolean;\n isPostQuote?: boolean;\n isHyperliquidSource?: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n paymentToken: TransactionPaymentToken | undefined;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n tokens: TransactionPayRequiredToken[];\n transactionId: string;\n}): QuoteRequest[] {\n if (!paymentToken) {\n return [];\n }\n\n if (isPostQuote) {\n return buildPostQuoteRequests({\n from,\n isMaxAmount,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n destinationToken: paymentToken,\n refundTo,\n sourceAmounts,\n transactionId,\n });\n }\n\n // Standard flow: source = paymentToken, target = required tokens\n const requests = (sourceAmounts ?? []).map((sourceAmount) => {\n const token = tokens.find(\n (singleToken) => singleToken.address === sourceAmount.targetTokenAddress,\n ) as TransactionPayRequiredToken;\n\n return {\n from,\n isMaxAmount,\n paymentOverride,\n sourceBalanceRaw: paymentToken.balanceRaw,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n sourceChainId: paymentToken.chainId,\n sourceTokenAddress: paymentToken.address,\n targetAmountMinimum: token.allowUnderMinimum ? '0' : token.amountRaw,\n targetChainId: token.chainId,\n targetTokenAddress: token.address,\n };\n });\n\n if (!requests.length) {\n log('No quote requests', { transactionId });\n }\n\n return requests;\n}\n\n/**\n * Build quote requests for post-quote flows.\n * In this flow, the source is the transaction's required token,\n * and the target is the user's selected destination token (paymentToken).\n *\n * @param request - Request parameters.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.destinationToken - Destination token (paymentToken in post-quote mode).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction (includes source token info).\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests for post-quote flow.\n */\nfunction buildPostQuoteRequests({\n from,\n isMaxAmount,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n destinationToken,\n refundTo,\n sourceAmounts,\n transactionId,\n}: {\n from: Hex;\n isMaxAmount: boolean;\n isHyperliquidSource?: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n destinationToken: TransactionPaymentToken;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n transactionId: string;\n}): QuoteRequest[] {\n // Find the source amount where targetTokenAddress matches the destination token\n const sourceAmount = sourceAmounts?.find(\n (amount) =>\n amount.targetTokenAddress.toLowerCase() ===\n destinationToken.address.toLowerCase(),\n );\n\n // Same-token-same-chain cases are already filtered in source-amounts.ts\n if (\n !sourceAmount?.sourceBalanceRaw ||\n !sourceAmount.sourceChainId ||\n !sourceAmount.sourceTokenAddress\n ) {\n log('No valid source amount found for post-quote request', {\n transactionId,\n });\n return [];\n }\n\n const request: QuoteRequest = {\n from,\n isMaxAmount,\n isPostQuote: true,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n refundTo,\n sourceBalanceRaw: sourceAmount.sourceBalanceRaw,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n sourceChainId: sourceAmount.sourceChainId,\n sourceTokenAddress: sourceAmount.sourceTokenAddress,\n targetAmountMinimum: '0',\n targetChainId: destinationToken.chainId,\n targetTokenAddress: destinationToken.address,\n };\n\n log('Post-quote request built', { transactionId, request });\n\n // Currently only single token post-quote flows are supported.\n // Multiple token support would require multiple quotes for each required token.\n return [request];\n}\n\nasync function refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken,\n signal,\n transactionId,\n updateTransactionData,\n}: {\n from: Hex;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n signal: AbortSignal;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n}): Promise<TransactionPaymentToken | undefined> {\n if (!paymentToken) {\n return undefined;\n }\n\n try {\n const fiatRates = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!fiatRates) {\n return paymentToken;\n }\n\n const liveBalance = await getLiveTokenBalance(\n messenger,\n from,\n paymentToken.chainId,\n paymentToken.address,\n );\n\n if (signal.aborted) {\n log('Payment token balance refresh aborted', { transactionId });\n return paymentToken;\n }\n\n const {\n raw: balanceRaw,\n human: balanceHuman,\n usd: balanceUsd,\n fiat: balanceFiat,\n } = computeTokenAmounts(liveBalance, paymentToken.decimals, fiatRates);\n\n const updatedToken = {\n ...paymentToken,\n balanceFiat,\n balanceHuman,\n balanceRaw,\n balanceUsd,\n };\n\n updateTransactionData(transactionId, (data) => {\n data.paymentToken = updatedToken;\n });\n\n log('Refreshed payment token balance', { transactionId, balanceRaw });\n\n return updatedToken;\n } catch (error) {\n log('Failed to refresh payment token balance', { transactionId, error });\n return paymentToken;\n }\n}\n\n/**\n * Retrieve quotes for a transaction.\n *\n * @param transaction - Transaction metadata.\n * @param from - Resolved wallet address (`accountOverride ?? txParams.from`).\n * @param requests - Quote requests.\n * @param paymentToken - Selected payment token, if any.\n * @param isQuoteRequired - Whether a quote is always required for the transaction.\n * @param isAccountEIP7702Compatible - Whether the account supports EIP-7702.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n * @param messenger - Controller messenger.\n * @param fiatPaymentMethod - Selected fiat payment method ID, if applicable.\n * @param signal - Signal that aborts when the quote request is superseded.\n * @returns An object containing batch transactions and quotes.\n */\nasync function getQuotes(\n transaction: TransactionMeta,\n from: Hex,\n requests: QuoteRequest[],\n paymentToken: TransactionPaymentToken | undefined,\n isQuoteRequired: boolean,\n isAccountEIP7702Compatible: boolean,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n messenger: TransactionPayControllerMessenger,\n fiatPaymentMethod?: string,\n signal?: AbortSignal,\n): Promise<{\n batchTransactions: BatchTransaction[];\n error?: QuoteErrorInfo;\n quotes: TransactionPayQuote<Json>[];\n}> {\n const { id: transactionId } = transaction;\n const strategies = getStrategiesByName(\n getStrategies(transaction),\n (strategyName) => {\n log('Skipping unknown strategy', {\n strategy: strategyName,\n transactionId,\n });\n },\n );\n\n if (!requests?.length && !fiatPaymentMethod) {\n // A selected payment token with no conversion requests means the route is\n // direct. Return an explicit no-op quote so clients and the publish hook\n // can distinguish \"no conversion needed\" from \"quote needed but missing\".\n // Not applicable when a quote is always required, as an empty requests\n // list then means the source amounts could not be calculated.\n const noOpQuote =\n paymentToken && !isQuoteRequired\n ? buildNoOpQuote(from, paymentToken)\n : undefined;\n\n if (noOpQuote) {\n log('Built no-op quote for direct route', { transactionId });\n }\n\n return {\n batchTransactions: [],\n quotes: noOpQuote ? [noOpQuote] : [],\n };\n }\n\n const request = {\n accountSupports7702: isAccountEIP7702Compatible,\n fiatPaymentMethod,\n from,\n messenger,\n requests,\n signal,\n transaction,\n };\n\n let error: QuoteErrorInfo | undefined;\n\n for (const { name, strategy } of strategies) {\n try {\n const support = await checkStrategySupport(strategy, request);\n\n if (!support) {\n log('Strategy does not support request', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n const quotes = (await strategy.getQuotes(\n request,\n )) as TransactionPayQuote<Json>[];\n\n if (!quotes.length) {\n log('Strategy returned no quotes', { strategy: name, transactionId });\n continue;\n }\n\n const isQuoteSupported = await checkStrategyQuoteSupport(strategy, {\n messenger,\n quotes,\n signal,\n transaction,\n });\n\n if (!isQuoteSupported) {\n log('Strategy does not support quotes', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n log('Updated', { transactionId, quotes });\n\n const batchTransactions = strategy.getBatchTransactions\n ? await strategy.getBatchTransactions({\n messenger,\n quotes,\n signal,\n })\n : [];\n\n log('Batch transactions', { transactionId, batchTransactions });\n\n return {\n batchTransactions,\n quotes,\n };\n } catch (caughtError) {\n if (signal?.aborted) {\n throw caughtError;\n }\n\n error ??= isQuoteError(caughtError)\n ? caughtError.info\n : { message: (caughtError as Error).message, reason: 'no-quotes' };\n\n log('Strategy failed, trying next', {\n error: caughtError,\n strategy: name,\n transactionId,\n });\n continue;\n }\n }\n\n log('No quotes available', { transactionId });\n\n return {\n batchTransactions: [],\n error,\n quotes: [],\n };\n}\n"]}
1
+ {"version":3,"file":"quotes.cjs","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionStatus } from '@metamask/transaction-controller';\nimport type { BatchTransaction } from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex, Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { PaymentOverride, TransactionPayStrategy } from '../constants.js';\nimport { projectLogger } from '../logger.js';\nimport type {\n QuoteRequest,\n QuoteErrorInfo,\n TransactionData,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n TransactionPayRequiredToken,\n TransactionPaySourceAmount,\n TransactionPayTotals,\n TransactionPaymentToken,\n UpdateTransactionDataCallback,\n} from '../types.js';\nimport { accountSupports7702 } from './7702.js';\nimport { buildNoOpQuote } from './no-op-quote.js';\nimport {\n checkStrategyQuoteSupport,\n checkStrategySupport,\n getStrategiesByName,\n getStrategyByName,\n} from './strategy.js';\nimport {\n computeTokenAmounts,\n getLiveTokenBalance,\n getTokenFiatRate,\n} from './token.js';\nimport { calculateTotals } from './totals.js';\nimport { getTransaction, updateTransaction } from './transaction.js';\nimport { isQuoteError } from './validation.js';\n\nconst DEFAULT_REFRESH_INTERVAL = 30 * 1000; // 30 Seconds\n\nconst log = createModuleLogger(projectLogger, 'quotes');\n\nconst inFlightQuoteRequests = new Map<string, AbortController>();\n\nexport type UpdateQuotesRequest = {\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[];\n messenger: TransactionPayControllerMessenger;\n transactionData: TransactionData | undefined;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n};\n\n/**\n * Update the quotes for a specific transaction.\n *\n * Calls for the same `transactionId` are serialised: a fresh call aborts any\n * previous in-flight call so a slower stale response cannot overwrite a newer\n * one in state.\n *\n * @param request - Request parameters.\n * @returns Boolean indicating if the quotes were updated. Returns `false` when\n * the call was aborted by a subsequent call for the same transaction.\n */\nexport async function updateQuotes(\n request: UpdateQuotesRequest,\n): Promise<boolean> {\n const {\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n } = request;\n\n const transaction = getTransaction(transactionId, messenger);\n\n if (!transaction || !transactionData) {\n throw new Error('Transaction not found');\n }\n\n if (transaction?.status !== TransactionStatus.unapproved) {\n return false;\n }\n\n log('Updating quotes', { transactionId });\n\n const {\n accountOverride,\n atomic,\n fiatPayment,\n isHyperliquidSource,\n isMaxAmount,\n isPolymarketDepositWallet,\n isPostQuote,\n isQuoteRequired,\n paymentOverride,\n paymentToken: originalPaymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n } = transactionData;\n\n const from = accountOverride ?? (transaction.txParams.from as Hex);\n\n const controller = abortPreviousAndCreateController(transactionId);\n const { signal } = controller;\n\n updateTransactionData(transactionId, (data) => {\n data.isLoading = true;\n data.quoteError = undefined;\n });\n\n try {\n const paymentToken = await refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken: originalPaymentToken,\n signal,\n transactionId,\n updateTransactionData,\n });\n\n if (signal.aborted) {\n log('Quote request aborted before building requests', { transactionId });\n return false;\n }\n\n const requests = buildQuoteRequests({\n atomic,\n from,\n isHyperliquidSource,\n isMaxAmount: isMaxAmount ?? false,\n isPolymarketDepositWallet,\n isPostQuote,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n });\n\n const supports7702 = accountSupports7702(messenger, from);\n\n const { batchTransactions, error, quotes } = await getQuotes(\n transaction,\n from,\n requests,\n paymentToken,\n isQuoteRequired ?? false,\n supports7702,\n getStrategies,\n messenger,\n fiatPayment?.selectedPaymentMethodId,\n signal,\n );\n\n if (signal.aborted) {\n log('Quote request aborted before persisting results', { transactionId });\n return false;\n }\n\n // No-op quotes mark direct routes. They have no fees or amounts and the\n // transaction is signed and submitted locally, so totals and transaction\n // sync must treat them as \"no quotes\".\n const executableQuotes = quotes.filter(\n (quote) => quote.strategy !== TransactionPayStrategy.None,\n );\n\n const totals = calculateTotals({\n fiatPaymentAmount: fiatPayment?.amountFiat,\n isMaxAmount,\n messenger,\n quotes: executableQuotes as TransactionPayQuote<unknown>[],\n tokens,\n transaction,\n });\n\n log('Calculated totals', { transactionId, totals });\n\n syncTransaction({\n batchTransactions,\n selectedFiatPayment: fiatPayment?.selectedPaymentMethodId,\n hasQuotes: executableQuotes.length > 0,\n isPostQuote,\n messenger: messenger as never,\n paymentToken,\n strategy: executableQuotes[0]?.strategy,\n totals,\n transactionId,\n });\n\n updateTransactionData(transactionId, (data) => {\n data.quotes = quotes as never;\n data.quoteError = quotes.length ? undefined : error;\n data.quotesLastUpdated = Date.now();\n data.totals = totals;\n });\n } catch (error) {\n if (signal.aborted) {\n log('Quote request aborted', { transactionId, reason: signal.reason });\n return false;\n }\n throw error;\n } finally {\n if (!signal.aborted) {\n updateTransactionData(transactionId, (data) => {\n data.isLoading = false;\n });\n }\n clearControllerIfCurrent(transactionId, controller);\n }\n\n return true;\n}\n\n/**\n * Sync batch transactions to the transaction meta.\n *\n * @param request - Request object.\n * @param request.batchTransactions - Batch transactions to sync.\n * @param request.hasQuotes - Whether MM Pay produced any quotes for this transaction.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.messenger - Messenger instance.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.selectedFiatPayment - Selected fiat payment method ID.\n * @param request.strategy - Strategy of the executable quotes.\n * @param request.totals - Calculated totals.\n * @param request.transactionId - ID of the transaction to sync.\n */\nfunction syncTransaction({\n batchTransactions,\n hasQuotes,\n isPostQuote,\n messenger,\n paymentToken,\n selectedFiatPayment,\n strategy,\n totals,\n transactionId,\n}: {\n batchTransactions: BatchTransaction[];\n selectedFiatPayment?: string;\n hasQuotes: boolean;\n isPostQuote?: boolean;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n strategy?: TransactionPayStrategy;\n totals: TransactionPayTotals;\n transactionId: string;\n}): void {\n if (!paymentToken && !selectedFiatPayment) {\n return;\n }\n\n updateTransaction(\n {\n transactionId,\n messenger: messenger as never,\n note: 'Update transaction pay data',\n },\n (tx: TransactionMeta) => {\n tx.batchTransactions = batchTransactions;\n tx.batchTransactionsOptions = {};\n\n // When MM Pay has produced quotes, it owns submission of this transaction\n // via its strategy publish hook, so the parent must be marked externally\n // signed to skip the local `KeyringController:signTransaction` call.\n // When there are no quotes (e.g. user selected the target token as the\n // payment token in a Predict flow), the transaction falls back to normal\n // local signing, so the flag is cleared to allow that.\n // If gas is sponsored, TC owns this field — it is set based on the\n // Sentinel simulation result and must not be cleared here. Same-token\n // flows (e.g. Monad mUSD withdrawal via a Money Account) produce no\n // quotes but still need external sign because the account cannot sign\n // locally.\n if (!tx.isGasFeeSponsored) {\n tx.isExternalSign = hasQuotes;\n }\n\n tx.metamaskPay = {\n bridgeFeeFiat: totals.fees.provider.usd,\n chainId: paymentToken?.chainId,\n isPostQuote,\n networkFeeFiat: totals.fees.sourceNetwork.estimate.usd,\n strategy,\n targetFiat: totals.targetAmount.usd,\n tokenAddress: paymentToken?.address,\n totalFiat: totals.total.usd,\n };\n },\n );\n}\n\n/**\n * Refresh quotes for all transactions if expired.\n *\n * @param messenger - Messenger instance.\n * @param updateTransactionData - Callback to update transaction data.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n */\nexport async function refreshQuotes(\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n): Promise<void> {\n const state = messenger.call('TransactionPayController:getState');\n const transactionIds = Object.keys(state.transactionData);\n\n for (const transactionId of transactionIds) {\n const transactionData = state.transactionData[transactionId];\n const { isLoading, quotes, quotesLastUpdated } = transactionData;\n\n if (isLoading || !quotes?.length) {\n continue;\n }\n\n // No-op quotes mark direct routes and have nothing to refresh. They are\n // regenerated whenever the transaction data changes.\n if (\n quotes.every((quote) => quote.strategy === TransactionPayStrategy.None)\n ) {\n continue;\n }\n\n const strategyName = quotes[0].strategy;\n const strategy = getStrategyByName(strategyName);\n\n const refreshInterval =\n (await strategy.getRefreshInterval?.({\n chainId: quotes[0].request.sourceChainId,\n messenger,\n })) ?? DEFAULT_REFRESH_INTERVAL;\n\n const isExpired = Date.now() - (quotesLastUpdated ?? 0) > refreshInterval;\n\n if (!isExpired) {\n continue;\n }\n\n const isUpdated = await updateQuotes({\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n });\n\n if (isUpdated) {\n log('Refreshed quotes', { transactionId, strategy: strategyName });\n }\n }\n}\n\nfunction abortPreviousAndCreateController(\n transactionId: string,\n): AbortController {\n const previous = inFlightQuoteRequests.get(transactionId);\n\n if (previous && !previous.signal.aborted) {\n log('Aborting previous quote request', { transactionId });\n previous.abort(new Error('Superseded by newer quote request'));\n }\n\n const controller = new AbortController();\n inFlightQuoteRequests.set(transactionId, controller);\n return controller;\n}\n\nfunction clearControllerIfCurrent(\n transactionId: string,\n controller: AbortController,\n): void {\n if (inFlightQuoteRequests.get(transactionId) === controller) {\n inFlightQuoteRequests.delete(transactionId);\n }\n}\n\n/**\n * Build quote requests required to retrieve quotes.\n *\n * @param request - Request parameters.\n * @param request.atomic - Whether the target transaction is executed atomically with the Relay quote.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction.\n * @param request.tokens - Required tokens for the transaction.\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests.\n */\nfunction buildQuoteRequests({\n atomic,\n from,\n isHyperliquidSource,\n isMaxAmount,\n isPolymarketDepositWallet,\n isPostQuote,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n}: {\n atomic?: boolean;\n from: Hex;\n isHyperliquidSource?: boolean;\n isMaxAmount: boolean;\n isPolymarketDepositWallet?: boolean;\n isPostQuote?: boolean;\n paymentOverride?: PaymentOverride;\n paymentToken: TransactionPaymentToken | undefined;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n tokens: TransactionPayRequiredToken[];\n transactionId: string;\n}): QuoteRequest[] {\n if (!paymentToken) {\n return [];\n }\n\n if (isPostQuote) {\n return buildPostQuoteRequests({\n atomic,\n destinationToken: paymentToken,\n from,\n isHyperliquidSource,\n isMaxAmount,\n isPolymarketDepositWallet,\n paymentOverride,\n refundTo,\n sourceAmounts,\n transactionId,\n });\n }\n\n // Standard flow: source = paymentToken, target = required tokens\n const requests = (sourceAmounts ?? []).map((sourceAmount) => {\n const token = tokens.find(\n (singleToken) => singleToken.address === sourceAmount.targetTokenAddress,\n ) as TransactionPayRequiredToken;\n\n return {\n atomic,\n from,\n isMaxAmount,\n paymentOverride,\n refundTo,\n sourceBalanceRaw: paymentToken.balanceRaw,\n sourceChainId: paymentToken.chainId,\n sourceTokenAddress: paymentToken.address,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n targetAmountMinimum: token.allowUnderMinimum ? '0' : token.amountRaw,\n targetChainId: token.chainId,\n targetTokenAddress: token.address,\n };\n });\n\n if (!requests.length) {\n log('No quote requests', { transactionId });\n }\n\n return requests;\n}\n\n/**\n * Build quote requests for post-quote flows.\n * In this flow, the source is the transaction's required token,\n * and the target is the user's selected destination token (paymentToken).\n *\n * @param request - Request parameters.\n * @param request.atomic - Whether the target transaction is executed atomically with the Relay quote.\n * @param request.destinationToken - Destination token (paymentToken in post-quote mode).\n * @param request.from - Address from which the transaction is sent.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction (includes source token info).\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests for post-quote flow.\n */\nfunction buildPostQuoteRequests({\n atomic,\n destinationToken,\n from,\n isHyperliquidSource,\n isMaxAmount,\n isPolymarketDepositWallet,\n paymentOverride,\n refundTo,\n sourceAmounts,\n transactionId,\n}: {\n atomic?: boolean;\n destinationToken: TransactionPaymentToken;\n from: Hex;\n isHyperliquidSource?: boolean;\n isMaxAmount: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n transactionId: string;\n}): QuoteRequest[] {\n // Find the source amount where targetTokenAddress matches the destination token\n const sourceAmount = sourceAmounts?.find(\n (amount) =>\n amount.targetTokenAddress.toLowerCase() ===\n destinationToken.address.toLowerCase(),\n );\n\n // Same-token-same-chain cases are already filtered in source-amounts.ts\n if (\n !sourceAmount?.sourceBalanceRaw ||\n !sourceAmount.sourceChainId ||\n !sourceAmount.sourceTokenAddress\n ) {\n log('No valid source amount found for post-quote request', {\n transactionId,\n });\n return [];\n }\n\n const request: QuoteRequest = {\n atomic,\n from,\n isHyperliquidSource,\n isMaxAmount,\n isPolymarketDepositWallet,\n isPostQuote: true,\n paymentOverride,\n refundTo,\n sourceBalanceRaw: sourceAmount.sourceBalanceRaw,\n sourceChainId: sourceAmount.sourceChainId,\n sourceTokenAddress: sourceAmount.sourceTokenAddress,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n targetAmountMinimum: '0',\n targetChainId: destinationToken.chainId,\n targetTokenAddress: destinationToken.address,\n };\n\n log('Post-quote request built', { transactionId, request });\n\n // Currently only single token post-quote flows are supported.\n // Multiple token support would require multiple quotes for each required token.\n return [request];\n}\n\nasync function refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken,\n signal,\n transactionId,\n updateTransactionData,\n}: {\n from: Hex;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n signal: AbortSignal;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n}): Promise<TransactionPaymentToken | undefined> {\n if (!paymentToken) {\n return undefined;\n }\n\n try {\n const fiatRates = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!fiatRates) {\n return paymentToken;\n }\n\n const liveBalance = await getLiveTokenBalance(\n messenger,\n from,\n paymentToken.chainId,\n paymentToken.address,\n );\n\n if (signal.aborted) {\n log('Payment token balance refresh aborted', { transactionId });\n return paymentToken;\n }\n\n const {\n raw: balanceRaw,\n human: balanceHuman,\n usd: balanceUsd,\n fiat: balanceFiat,\n } = computeTokenAmounts(liveBalance, paymentToken.decimals, fiatRates);\n\n const updatedToken = {\n ...paymentToken,\n balanceFiat,\n balanceHuman,\n balanceRaw,\n balanceUsd,\n };\n\n updateTransactionData(transactionId, (data) => {\n data.paymentToken = updatedToken;\n });\n\n log('Refreshed payment token balance', { transactionId, balanceRaw });\n\n return updatedToken;\n } catch (error) {\n log('Failed to refresh payment token balance', { transactionId, error });\n return paymentToken;\n }\n}\n\n/**\n * Retrieve quotes for a transaction.\n *\n * @param transaction - Transaction metadata.\n * @param from - Resolved wallet address (`accountOverride ?? txParams.from`).\n * @param requests - Quote requests.\n * @param paymentToken - Selected payment token, if any.\n * @param isQuoteRequired - Whether a quote is always required for the transaction.\n * @param isAccountEIP7702Compatible - Whether the account supports EIP-7702.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n * @param messenger - Controller messenger.\n * @param fiatPaymentMethod - Selected fiat payment method ID, if applicable.\n * @param signal - Signal that aborts when the quote request is superseded.\n * @returns An object containing batch transactions and quotes.\n */\nasync function getQuotes(\n transaction: TransactionMeta,\n from: Hex,\n requests: QuoteRequest[],\n paymentToken: TransactionPaymentToken | undefined,\n isQuoteRequired: boolean,\n isAccountEIP7702Compatible: boolean,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n messenger: TransactionPayControllerMessenger,\n fiatPaymentMethod?: string,\n signal?: AbortSignal,\n): Promise<{\n batchTransactions: BatchTransaction[];\n error?: QuoteErrorInfo;\n quotes: TransactionPayQuote<Json>[];\n}> {\n const { id: transactionId } = transaction;\n const strategies = getStrategiesByName(\n getStrategies(transaction),\n (strategyName) => {\n log('Skipping unknown strategy', {\n strategy: strategyName,\n transactionId,\n });\n },\n );\n\n if (!requests?.length && !fiatPaymentMethod) {\n // A selected payment token with no conversion requests means the route is\n // direct. Return an explicit no-op quote so clients and the publish hook\n // can distinguish \"no conversion needed\" from \"quote needed but missing\".\n // Not applicable when a quote is always required, as an empty requests\n // list then means the source amounts could not be calculated.\n const noOpQuote =\n paymentToken && !isQuoteRequired\n ? buildNoOpQuote(from, paymentToken)\n : undefined;\n\n if (noOpQuote) {\n log('Built no-op quote for direct route', { transactionId });\n }\n\n return {\n batchTransactions: [],\n quotes: noOpQuote ? [noOpQuote] : [],\n };\n }\n\n const request = {\n accountSupports7702: isAccountEIP7702Compatible,\n fiatPaymentMethod,\n from,\n messenger,\n requests,\n signal,\n transaction,\n };\n\n let error: QuoteErrorInfo | undefined;\n\n for (const { name, strategy } of strategies) {\n try {\n const support = await checkStrategySupport(strategy, request);\n\n if (!support) {\n log('Strategy does not support request', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n const quotes = (await strategy.getQuotes(\n request,\n )) as TransactionPayQuote<Json>[];\n\n if (!quotes.length) {\n log('Strategy returned no quotes', { strategy: name, transactionId });\n continue;\n }\n\n const isQuoteSupported = await checkStrategyQuoteSupport(strategy, {\n messenger,\n quotes,\n signal,\n transaction,\n });\n\n if (!isQuoteSupported) {\n log('Strategy does not support quotes', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n log('Updated', { transactionId, quotes });\n\n const batchTransactions = strategy.getBatchTransactions\n ? await strategy.getBatchTransactions({\n messenger,\n quotes,\n signal,\n })\n : [];\n\n log('Batch transactions', { transactionId, batchTransactions });\n\n return {\n batchTransactions,\n quotes,\n };\n } catch (caughtError) {\n if (signal?.aborted) {\n throw caughtError;\n }\n\n error ??= isQuoteError(caughtError)\n ? caughtError.info\n : { message: (caughtError as Error).message, reason: 'no-quotes' };\n\n log('Strategy failed, trying next', {\n error: caughtError,\n strategy: name,\n transactionId,\n });\n continue;\n }\n }\n\n log('No quotes available', { transactionId });\n\n return {\n batchTransactions: [],\n error,\n quotes: [],\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"quotes.d.cts","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAIxE,OAAO,EAAmB,sBAAsB,EAAE,yBAAwB;AAE1E,OAAO,KAAK,EAGV,eAAe,EACf,iCAAiC,EAMjC,6BAA6B,EAC9B,qBAAoB;AAwBrB,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,CAAC;IAC1E,SAAS,EAAE,iCAAiC,CAAC;IAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,6BAA6B,CAAC;CACtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAkJlB;AA4ED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
1
+ {"version":3,"file":"quotes.d.cts","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAIxE,OAAO,EAAmB,sBAAsB,EAAE,yBAAwB;AAE1E,OAAO,KAAK,EAGV,eAAe,EACf,iCAAiC,EAMjC,6BAA6B,EAC9B,qBAAoB;AAwBrB,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,CAAC;IAC1E,SAAS,EAAE,iCAAiC,CAAC;IAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,6BAA6B,CAAC;CACtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAqJlB;AAgFD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
@@ -1 +1 @@
1
- {"version":3,"file":"quotes.d.mts","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAIxE,OAAO,EAAmB,sBAAsB,EAAE,yBAAwB;AAE1E,OAAO,KAAK,EAGV,eAAe,EACf,iCAAiC,EAMjC,6BAA6B,EAC9B,qBAAoB;AAwBrB,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,CAAC;IAC1E,SAAS,EAAE,iCAAiC,CAAC;IAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,6BAA6B,CAAC;CACtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAkJlB;AA4ED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
1
+ {"version":3,"file":"quotes.d.mts","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAIxE,OAAO,EAAmB,sBAAsB,EAAE,yBAAwB;AAE1E,OAAO,KAAK,EAGV,eAAe,EACf,iCAAiC,EAMjC,6BAA6B,EAC9B,qBAAoB;AAwBrB,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,CAAC;IAC1E,SAAS,EAAE,iCAAiC,CAAC;IAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,6BAA6B,CAAC;CACtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAqJlB;AAgFD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,aAAa,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,sBAAsB,EAAE,GACxE,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
@@ -33,7 +33,7 @@ export async function updateQuotes(request) {
33
33
  return false;
34
34
  }
35
35
  log('Updating quotes', { transactionId });
36
- const { accountOverride, isMaxAmount, isPostQuote, isHyperliquidSource, isPolymarketDepositWallet, isQuoteRequired, paymentOverride, paymentToken: originalPaymentToken, fiatPayment, refundTo, sourceAmounts, tokens, } = transactionData;
36
+ const { accountOverride, atomic, fiatPayment, isHyperliquidSource, isMaxAmount, isPolymarketDepositWallet, isPostQuote, isQuoteRequired, paymentOverride, paymentToken: originalPaymentToken, refundTo, sourceAmounts, tokens, } = transactionData;
37
37
  const from = accountOverride ?? transaction.txParams.from;
38
38
  const controller = abortPreviousAndCreateController(transactionId);
39
39
  const { signal } = controller;
@@ -55,11 +55,12 @@ export async function updateQuotes(request) {
55
55
  return false;
56
56
  }
57
57
  const requests = buildQuoteRequests({
58
+ atomic,
58
59
  from,
59
- isMaxAmount: isMaxAmount ?? false,
60
- isPostQuote,
61
60
  isHyperliquidSource,
61
+ isMaxAmount: isMaxAmount ?? false,
62
62
  isPolymarketDepositWallet,
63
+ isPostQuote,
63
64
  paymentOverride,
64
65
  paymentToken,
65
66
  refundTo,
@@ -93,6 +94,7 @@ export async function updateQuotes(request) {
93
94
  isPostQuote,
94
95
  messenger: messenger,
95
96
  paymentToken,
97
+ strategy: executableQuotes[0]?.strategy,
96
98
  totals,
97
99
  transactionId,
98
100
  });
@@ -130,10 +132,11 @@ export async function updateQuotes(request) {
130
132
  * @param request.messenger - Messenger instance.
131
133
  * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).
132
134
  * @param request.selectedFiatPayment - Selected fiat payment method ID.
135
+ * @param request.strategy - Strategy of the executable quotes.
133
136
  * @param request.totals - Calculated totals.
134
137
  * @param request.transactionId - ID of the transaction to sync.
135
138
  */
136
- function syncTransaction({ batchTransactions, hasQuotes, isPostQuote, messenger, paymentToken, selectedFiatPayment, totals, transactionId, }) {
139
+ function syncTransaction({ batchTransactions, hasQuotes, isPostQuote, messenger, paymentToken, selectedFiatPayment, strategy, totals, transactionId, }) {
137
140
  if (!paymentToken && !selectedFiatPayment) {
138
141
  return;
139
142
  }
@@ -163,6 +166,7 @@ function syncTransaction({ batchTransactions, hasQuotes, isPostQuote, messenger,
163
166
  chainId: paymentToken?.chainId,
164
167
  isPostQuote,
165
168
  networkFeeFiat: totals.fees.sourceNetwork.estimate.usd,
169
+ strategy,
166
170
  targetFiat: totals.targetAmount.usd,
167
171
  tokenAddress: paymentToken?.address,
168
172
  totalFiat: totals.total.usd,
@@ -231,9 +235,10 @@ function clearControllerIfCurrent(transactionId, controller) {
231
235
  * Build quote requests required to retrieve quotes.
232
236
  *
233
237
  * @param request - Request parameters.
238
+ * @param request.atomic - Whether the target transaction is executed atomically with the Relay quote.
234
239
  * @param request.from - Address from which the transaction is sent.
235
- * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
236
240
  * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.
241
+ * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
237
242
  * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.
238
243
  * @param request.isPostQuote - Whether this is a post-quote flow.
239
244
  * @param request.paymentOverride - Optional payment override type for the transaction.
@@ -244,18 +249,19 @@ function clearControllerIfCurrent(transactionId, controller) {
244
249
  * @param request.transactionId - ID of the transaction.
245
250
  * @returns Array of quote requests.
246
251
  */
247
- function buildQuoteRequests({ from, isMaxAmount, isPostQuote, isHyperliquidSource, isPolymarketDepositWallet, paymentOverride, paymentToken, refundTo, sourceAmounts, tokens, transactionId, }) {
252
+ function buildQuoteRequests({ atomic, from, isHyperliquidSource, isMaxAmount, isPolymarketDepositWallet, isPostQuote, paymentOverride, paymentToken, refundTo, sourceAmounts, tokens, transactionId, }) {
248
253
  if (!paymentToken) {
249
254
  return [];
250
255
  }
251
256
  if (isPostQuote) {
252
257
  return buildPostQuoteRequests({
258
+ atomic,
259
+ destinationToken: paymentToken,
253
260
  from,
254
- isMaxAmount,
255
261
  isHyperliquidSource,
262
+ isMaxAmount,
256
263
  isPolymarketDepositWallet,
257
264
  paymentOverride,
258
- destinationToken: paymentToken,
259
265
  refundTo,
260
266
  sourceAmounts,
261
267
  transactionId,
@@ -265,13 +271,15 @@ function buildQuoteRequests({ from, isMaxAmount, isPostQuote, isHyperliquidSourc
265
271
  const requests = (sourceAmounts ?? []).map((sourceAmount) => {
266
272
  const token = tokens.find((singleToken) => singleToken.address === sourceAmount.targetTokenAddress);
267
273
  return {
274
+ atomic,
268
275
  from,
269
276
  isMaxAmount,
270
277
  paymentOverride,
278
+ refundTo,
271
279
  sourceBalanceRaw: paymentToken.balanceRaw,
272
- sourceTokenAmount: sourceAmount.sourceAmountRaw,
273
280
  sourceChainId: paymentToken.chainId,
274
281
  sourceTokenAddress: paymentToken.address,
282
+ sourceTokenAmount: sourceAmount.sourceAmountRaw,
275
283
  targetAmountMinimum: token.allowUnderMinimum ? '0' : token.amountRaw,
276
284
  targetChainId: token.chainId,
277
285
  targetTokenAddress: token.address,
@@ -288,18 +296,19 @@ function buildQuoteRequests({ from, isMaxAmount, isPostQuote, isHyperliquidSourc
288
296
  * and the target is the user's selected destination token (paymentToken).
289
297
  *
290
298
  * @param request - Request parameters.
299
+ * @param request.atomic - Whether the target transaction is executed atomically with the Relay quote.
300
+ * @param request.destinationToken - Destination token (paymentToken in post-quote mode).
291
301
  * @param request.from - Address from which the transaction is sent.
292
- * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
293
302
  * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.
303
+ * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.
294
304
  * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.
295
305
  * @param request.paymentOverride - Optional payment override type for the transaction.
296
- * @param request.destinationToken - Destination token (paymentToken in post-quote mode).
297
306
  * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.
298
307
  * @param request.sourceAmounts - Source amounts for the transaction (includes source token info).
299
308
  * @param request.transactionId - ID of the transaction.
300
309
  * @returns Array of quote requests for post-quote flow.
301
310
  */
302
- function buildPostQuoteRequests({ from, isMaxAmount, isHyperliquidSource, isPolymarketDepositWallet, paymentOverride, destinationToken, refundTo, sourceAmounts, transactionId, }) {
311
+ function buildPostQuoteRequests({ atomic, destinationToken, from, isHyperliquidSource, isMaxAmount, isPolymarketDepositWallet, paymentOverride, refundTo, sourceAmounts, transactionId, }) {
303
312
  // Find the source amount where targetTokenAddress matches the destination token
304
313
  const sourceAmount = sourceAmounts?.find((amount) => amount.targetTokenAddress.toLowerCase() ===
305
314
  destinationToken.address.toLowerCase());
@@ -313,17 +322,18 @@ function buildPostQuoteRequests({ from, isMaxAmount, isHyperliquidSource, isPoly
313
322
  return [];
314
323
  }
315
324
  const request = {
325
+ atomic,
316
326
  from,
317
- isMaxAmount,
318
- isPostQuote: true,
319
327
  isHyperliquidSource,
328
+ isMaxAmount,
320
329
  isPolymarketDepositWallet,
330
+ isPostQuote: true,
321
331
  paymentOverride,
322
332
  refundTo,
323
333
  sourceBalanceRaw: sourceAmount.sourceBalanceRaw,
324
- sourceTokenAmount: sourceAmount.sourceAmountRaw,
325
334
  sourceChainId: sourceAmount.sourceChainId,
326
335
  sourceTokenAddress: sourceAmount.sourceTokenAddress,
336
+ sourceTokenAmount: sourceAmount.sourceAmountRaw,
327
337
  targetAmountMinimum: '0',
328
338
  targetChainId: destinationToken.chainId,
329
339
  targetTokenAddress: destinationToken.address,