@metamask-previews/transaction-pay-controller 26.2.0-preview-2c1b43f24 → 26.2.2-preview-72a1eb691
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.
package/CHANGELOG.md
CHANGED
|
@@ -7,9 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [26.2.2]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Bump `@metamask/assets-controllers` from `^110.1.0` to `^110.1.1` ([#9779](https://github.com/MetaMask/core/pull/9779))
|
|
15
|
+
- Bump `@metamask/ramps-controller` from `^19.0.0` to `^20.0.0` ([#9779](https://github.com/MetaMask/core/pull/9779))
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Pass the quote's pre-signed `authorizationList` through `addTransactionBatch` for same-chain Relay submits when an account override is active, so Money Account vault upgrades are not dropped on the multi-step batch path ([#9765](https://github.com/MetaMask/core/pull/9765))
|
|
20
|
+
|
|
21
|
+
## [26.2.1]
|
|
22
|
+
|
|
10
23
|
### Changed
|
|
11
24
|
|
|
12
25
|
- Bump `@metamask/network-controller` from `^35.0.0` to `^35.0.1` ([#9758](https://github.com/MetaMask/core/pull/9758))
|
|
26
|
+
- Bump `@metamask/ramps-controller` from `^18.0.1` to `^19.0.0` ([#9778](https://github.com/MetaMask/core/pull/9778))
|
|
13
27
|
|
|
14
28
|
## [26.2.0]
|
|
15
29
|
|
|
@@ -1388,7 +1402,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1388
1402
|
|
|
1389
1403
|
- Initial release ([#6820](https://github.com/MetaMask/core/pull/6820))
|
|
1390
1404
|
|
|
1391
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.2.
|
|
1405
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.2.2...HEAD
|
|
1406
|
+
[26.2.2]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.2.1...@metamask/transaction-pay-controller@26.2.2
|
|
1407
|
+
[26.2.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.2.0...@metamask/transaction-pay-controller@26.2.1
|
|
1392
1408
|
[26.2.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.1.1...@metamask/transaction-pay-controller@26.2.0
|
|
1393
1409
|
[26.1.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.1.0...@metamask/transaction-pay-controller@26.1.1
|
|
1394
1410
|
[26.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@26.0.1...@metamask/transaction-pay-controller@26.1.0
|
|
@@ -574,12 +574,22 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
574
574
|
});
|
|
575
575
|
const isSameChain = quote.original.details.currencyIn.currency.chainId ===
|
|
576
576
|
quote.original.details.currencyOut.currency.chainId;
|
|
577
|
+
// Single-tx keeps address/chainId only — TransactionController re-signs with
|
|
578
|
+
// `from`. Batch may need a different signer (Money Account) than the batch
|
|
579
|
+
// payer (EOA account override), so preserve the full pre-signed list.
|
|
577
580
|
const authorizationList = isSameChain && quote.original.request.authorizationList?.length
|
|
578
581
|
? quote.original.request.authorizationList.map((a) => ({
|
|
579
582
|
address: a.address,
|
|
580
583
|
chainId: (0, controller_utils_1.toHex)(a.chainId),
|
|
581
584
|
}))
|
|
582
585
|
: undefined;
|
|
586
|
+
const hasAccountOverride = quote.request.from.toLowerCase() !==
|
|
587
|
+
transaction.txParams.from.toLowerCase();
|
|
588
|
+
const batchAuthorizationList = isSameChain &&
|
|
589
|
+
hasAccountOverride &&
|
|
590
|
+
quote.original.request.authorizationList?.length
|
|
591
|
+
? mapSignedQuoteAuthorizationList(quote.original.request.authorizationList)
|
|
592
|
+
: undefined;
|
|
583
593
|
const { metamask } = quote.original;
|
|
584
594
|
const { gasLimits } = metamask;
|
|
585
595
|
if (allParams.length === 1) {
|
|
@@ -601,6 +611,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
601
611
|
else {
|
|
602
612
|
await messenger.call('TransactionController:addTransactionBatch', buildRelayTransactionBatchRequest({
|
|
603
613
|
allParams,
|
|
614
|
+
authorizationList: batchAuthorizationList,
|
|
604
615
|
isGasFeeSponsored: isSourceGasFeeSponsored,
|
|
605
616
|
messenger,
|
|
606
617
|
normalizedParams,
|
|
@@ -625,7 +636,17 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
625
636
|
}
|
|
626
637
|
return hash;
|
|
627
638
|
}
|
|
628
|
-
function
|
|
639
|
+
function mapSignedQuoteAuthorizationList(authorizationList) {
|
|
640
|
+
return authorizationList.map((a) => ({
|
|
641
|
+
address: a.address,
|
|
642
|
+
chainId: (0, controller_utils_1.toHex)(a.chainId),
|
|
643
|
+
nonce: (0, controller_utils_1.toHex)(a.nonce),
|
|
644
|
+
r: a.r,
|
|
645
|
+
s: a.s,
|
|
646
|
+
yParity: (0, controller_utils_1.toHex)(a.yParity),
|
|
647
|
+
}));
|
|
648
|
+
}
|
|
649
|
+
function buildRelayTransactionBatchRequest({ allParams, authorizationList, isGasFeeSponsored, messenger, normalizedParams, quote, transaction, }) {
|
|
629
650
|
const { from, sourceChainId, sourceTokenAddress } = quote.request;
|
|
630
651
|
const { metamask } = quote.original;
|
|
631
652
|
const networkClientId = (0, provider_js_1.getNetworkClientId)(messenger, sourceChainId);
|
|
@@ -635,6 +656,7 @@ function buildRelayTransactionBatchRequest({ allParams, isGasFeeSponsored, messe
|
|
|
635
656
|
const gasLimit7702 = getGasLimit7702(quote);
|
|
636
657
|
return {
|
|
637
658
|
from,
|
|
659
|
+
...(authorizationList?.length ? { authorizationList } : {}),
|
|
638
660
|
disable7702: !gasLimit7702,
|
|
639
661
|
disableHook: Boolean(gasLimit7702),
|
|
640
662
|
disableSequential: Boolean(gasLimit7702),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n BatchTransactionParams,\n TransactionBatchRequest,\n TransactionBatchSingleRequest,\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 { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types.js';\nimport { prefixError } from '../../utils/error-prefix.js';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags.js';\nimport { submitMoneyAccountVaultDeposit } from '../../utils/ma-vault-deposit.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token.js';\nimport {\n collectTransactionIds,\n getTransaction,\n getTransferredAmountFromTxHash,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport {\n FALLBACK_HASH,\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants.js';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw.js';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw.js';\nimport { getRelayStatus } from './relay-api.js';\nimport { submitViaRelayExecute } from './relay-submit-execute.js';\nimport type {\n RelayCompletionOutcome,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\nconst RELAY_ERROR_PREFIX = 'Relay: ';\n\ntype RelaySubmitParams = {\n allParams: TransactionParams[];\n normalizedParams: TransactionParams[];\n};\n\nexport type RelaySubmitCalls = { calls: TransactionParams[] };\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n try {\n return await submitRelayQuotesInternal(request);\n } catch (error) {\n throw prefixError(error, RELAY_ERROR_PREFIX);\n }\n}\n\nexport async function getRelaySubmitCalls({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitCalls> {\n const { allParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n return { calls: allParams };\n}\n\nasync function submitRelayQuotesInternal(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n if (!quotes.length) {\n throw new Error('No quotes to submit');\n }\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n /* istanbul ignore if: concrete Relay submit paths return a hash/fallback or throw. */\n if (transactionHash === undefined) {\n throw new Error('Missing transaction hash');\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n let submittedSourceHash: Hex | undefined;\n\n // Shallow clone so the server-returned requestId can be written back (state is frozen by Immer).\n const mutableOriginal: RelayQuote = { ...quote.original };\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n submittedSourceHash = await submitTransactions(\n { ...quote, original: mutableOriginal },\n transaction,\n messenger,\n );\n }\n\n const completion = await waitForRelayCompletion(mutableOriginal, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n // Non-atomic flow: the quote bridged funds to `recipient` without embedding\n // the second leg. Now that Relay has settled, resolve the settled amount from\n // the on-chain Transfer log and submit the second-leg batch (approve + vault\n // deposit) sponsored from `recipient`.\n if (quote.request.atomic === false && completion.status === 'success') {\n const { transactionHash } = await submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n });\n\n return { transactionHash: transactionHash ?? completion.targetHash };\n }\n\n return { transactionHash: completion.targetHash };\n}\n\n/**\n * Runs the second leg of a non-atomic Relay quote. Resolves the settled amount\n * from the on-chain Transfer log, then submits the batch via\n * `submitMoneyAccountVaultDeposit`. Post-quote flows fetch pre-built calls via\n * the client `getPaymentOverrideData` callback; non-post-quote flows fall\n * through to the transaction's own nested calls re-encoded via\n * `getAmountData`. Funds settled on `quote.request.recipient`, derived at\n * quote time by `resolveNonAtomicRecipient`.\n *\n * @param options - Submit options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used to read the settled amount when Relay skips polling on\n * same-chain flows.\n * @param options.transaction - Original transaction meta.\n * @returns Hash of the final submitted child transaction, if available.\n */\nasync function submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n transaction: TransactionMeta;\n}): Promise<{ transactionHash?: Hex }> {\n const sourceAmountRaw = await resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n });\n\n const override = quote.request.isPostQuote\n ? await buildPostQuoteDepositCalls({\n messenger,\n sourceAmountRaw,\n transaction,\n quote,\n })\n : undefined;\n\n const recipient =\n override?.recipient ?? quote.request.recipient ?? quote.request.from;\n\n return submitMoneyAccountVaultDeposit({\n messenger,\n moneyAccountAddress: recipient,\n depositCalls: override?.calls,\n sourceAmountRaw,\n transaction,\n vaultDisabled: false,\n });\n}\n\n/**\n * Builds the post-completion batch for a post-quote flow whose parent\n * transaction carries no vault calls. Delegates to the client\n * `getPaymentOverrideData` callback with the settled amount.\n *\n * The callback MUST return a non-empty batch. Post-quote parent metas (e.g.\n * Perps/Predict withdraws) carry no vault-side nested calls, so falling back\n * to `getAmountData` in `resolveVaultDepositBatch` cannot recover the second\n * leg once Relay has already settled funds to the recipient. Throw eagerly so\n * the failure surfaces at the correct call site with an actionable message.\n *\n * The callback may also return the `recipient` that funds settled on, which the\n * caller prefers as the source of truth for the second-leg account.\n *\n * @param options - Build options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.sourceAmountRaw - Settled amount in raw units.\n * @param options.transaction - Original transaction meta.\n * @returns The batch calls and optional recipient.\n * @throws If the callback returns an empty batch.\n */\nasync function buildPostQuoteDepositCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n}): Promise<{ calls: BatchTransactionParams[]; recipient?: Hex }> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { decimals } = quote.original.details.currencyOut.currency;\n const amountHuman = new BigNumber(sourceAmountRaw)\n .shiftedBy(-decimals)\n .toFixed();\n\n const { calls, recipient } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: amountHuman,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (!calls.length) {\n throw new Error('Missing post-quote deposit calls');\n }\n\n return { calls, recipient };\n}\n\n/**\n * Resolves the actual amount that landed on the recipient after a Relay bridge.\n *\n * Cross-chain relays surface a real target-chain hash from polling; same-chain\n * relays skip polling (the `FALLBACK_HASH` placeholder) but the submitted\n * source transaction itself moved the funds, so its hash is read instead. In\n * both cases the exact settled amount comes from the on-chain Transfer log; a\n * read failure or missing amount throws rather than guessing, since using the\n * quote minimum would knowingly strand dust and defeat an EXACT_INPUT quote.\n *\n * Relay execute submissions return `FALLBACK_HASH` instead of a real source\n * hash, leaving nothing to read; only then is the quote's minimum output used\n * as the last available source.\n *\n * @param options - Resolution options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used when polling was skipped on same-chain flows.\n * @returns The raw (atomic) settled amount as a decimal string.\n */\nasync function resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n}): Promise<string> {\n const recipient = (quote.request.recipient ?? quote.request.from) as\n | Hex\n | undefined;\n\n const isSameChain =\n quote.request.sourceChainId === quote.request.targetChainId;\n\n const hasPolledTargetHash = Boolean(\n completion.targetHash && completion.targetHash !== FALLBACK_HASH,\n );\n\n let settlementHash: Hex | undefined;\n\n if (hasPolledTargetHash) {\n settlementHash = completion.targetHash as Hex;\n } else if (isSameChain && submittedSourceHash !== FALLBACK_HASH) {\n settlementHash = submittedSourceHash;\n }\n\n if (recipient && settlementHash) {\n const { amountRaw: onChainAmount } = await getTransferredAmountFromTxHash({\n messenger,\n txHash: settlementHash,\n chainId: quote.request.targetChainId,\n tokenAddress: quote.request.targetTokenAddress,\n walletAddress: recipient,\n });\n\n if (!onChainAmount) {\n throw new Error(\n 'Cannot resolve settled amount from on-chain transaction',\n );\n }\n\n log('Resolved settled amount from on-chain transaction', {\n settlementHash,\n onChainAmount,\n });\n\n return onChainAmount;\n }\n\n const fallback = quote.original.details.currencyOut.minimumAmount;\n\n if (!fallback) {\n throw new Error('Cannot resolve post-completion amount');\n }\n\n log('Resolved settled amount from quote minimum output', {\n fallback,\n targetHash: completion.targetHash,\n });\n\n return fallback;\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex | undefined) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Request failed with status: ${status.status}`);\n }\n throw new Error(`Unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas:\n params.maxFeePerGas === undefined\n ? undefined\n : toHex(params.maxFeePerGas),\n maxPriorityFeePerGas:\n params.maxPriorityFeePerGas === undefined\n ? undefined\n : toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote && !quote.request.paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const { allParams, normalizedParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\nfunction getRelayTransactionStepData(\n quote: TransactionPayQuote<RelayQuote>,\n): RelayTransactionStep['items'][0]['data'][] {\n const { steps } = quote.original;\n const supportedStepKinds = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !supportedStepKinds.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n\n return txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data)\n .filter((data): data is RelayTransactionStep['items'][0]['data'] =>\n isRelayTransactionStepData(data),\n );\n}\n\nasync function buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitParams> {\n const params = getRelayTransactionStepData(quote);\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n // Non-atomic flows are excluded from the paymentOverride prepend: their\n // second leg is submitted separately by `submitPostNonAtomic` after\n // Relay completion, so prepending here would double-embed the vault deposit.\n // Cross-chain atomic flows (e.g. `moneyAccountWithdraw` on Monad settling\n // USDC on Arbitrum for Perps) still need the source-side vault withdraw +\n // transfer prepended here so Relay has funds to bridge.\n const isNonAtomic = quote.request.atomic === false;\n\n let allParams = normalizedParams;\n\n if (quote.request.paymentOverride && !isNonAtomic) {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideTxs } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (overrideTxs.length > 0) {\n allParams = [\n ...(overrideTxs as TransactionParams[]),\n ...normalizedParams,\n ];\n }\n } else if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(\n transaction,\n messenger,\n normalizedParams[0],\n )\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n maxFeePerGas: normalizedParams[0]?.maxFeePerGas,\n maxPriorityFeePerGas: normalizedParams[0]?.maxPriorityFeePerGas,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n return { allParams, normalizedParams };\n}\n\nfunction isRelayTransactionStepData(\n data: RelayTransactionStep['items'][0]['data'],\n): data is RelayTransactionStep['items'][0]['data'] {\n const maybeStepData = data as { to?: unknown };\n return maybeStepData.to !== undefined;\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @param relayParams - Optional relay params to copy gas fee fields from.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n relayParams?: TransactionParams,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n maxFeePerGas: relayParams?.maxFeePerGas,\n maxPriorityFeePerGas: relayParams?.maxPriorityFeePerGas,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const isSourceGasFeeSponsored =\n transaction.isGasFeeSponsored &&\n quote.request.sourceChainId === transaction.chainId &&\n quote.request.targetChainId === transaction.chainId;\n\n const gasFeeToken =\n !isSourceGasFeeSponsored && quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n await messenger.call(\n 'TransactionController:addTransactionBatch',\n buildRelayTransactionBatchRequest({\n allParams,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n }),\n );\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (!transactionIds.length) {\n throw new Error('No transactions submitted');\n }\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\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 return hash as Hex;\n}\n\nfunction buildRelayTransactionBatchRequest({\n allParams,\n isGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n}: {\n allParams: TransactionParams[];\n isGasFeeSponsored: boolean | undefined;\n messenger: TransactionPayControllerMessenger;\n normalizedParams: TransactionParams[];\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): TransactionBatchRequest {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { metamask } = quote.original;\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n const gasFeeToken = quote.fees?.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n const gasLimit7702 = getGasLimit7702(quote);\n\n return {\n from,\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions: buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits: metamask.gasLimits,\n normalizedParams,\n transaction,\n }),\n };\n}\n\nfunction buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits,\n normalizedParams,\n transaction,\n}: {\n allParams: TransactionParams[];\n gasLimit7702?: Hex;\n gasLimits: number[];\n normalizedParams: TransactionParams[];\n transaction: TransactionMeta;\n}): TransactionBatchSingleRequest[] {\n const prependCount = allParams.length - normalizedParams.length;\n\n return allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n prependCount,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n}\n\nfunction getGasLimit7702(\n quote: TransactionPayQuote<RelayQuote>,\n): Hex | undefined {\n const { gasLimits, is7702 } = quote.original.metamask;\n const gasLimit = gasLimits[0];\n\n return is7702 && gasLimit !== undefined ? toHex(gasLimit) : undefined;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param prependCount - Number of non-relay txs prepended to the batch.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for prepended indices).\n * @param relayParamCount - Number of relay-only params (excludes prepended txs).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n prependCount: number,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n if (prependCount > 0 && index < prependCount) {\n return originalType;\n }\n\n const relayIndex = index - prependCount;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":";;;AAAA,iEAAoE;AACpE,6EAAmE;AAUnE,2CAAqD;AACrD,+CAAyC;AAEzC,gDAAgD;AAMhD,kEAA0D;AAC1D,oEAIsC;AACtC,0EAAiF;AACjF,0DAA6D;AAC7D,oDAI8B;AAC9B,gEAMoC;AACpC,kDAKwB;AACxB,wEAAsE;AACtE,2DAGkC;AAClC,kDAAgD;AAChD,wEAAkE;AASlE,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,yBAAa,EAAE,gBAAgB,CAAC,CAAC;AAChE,MAAM,kBAAkB,GAAG,SAAS,CAAC;AASrC;;;;;GAKG;AACI,KAAK,UAAU,iBAAiB,CACrC,OAA8C;IAE9C,IAAI,CAAC;QACH,OAAO,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAA,6BAAW,EAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AARD,8CAQC;AAEM,KAAK,UAAU,mBAAmB,CAAC,EACxC,SAAS,EACT,KAAK,EACL,WAAW,GAKZ;IACC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,sBAAsB,CAAC;QACjD,SAAS;QACT,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC;AAfD,kDAeC;AAED,KAAK,UAAU,yBAAyB,CACtC,OAA8C;IAE9C,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAEjC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEnD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,eAAgC,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,CAAC,EAAE,eAAe,EAAE,GAAG,MAAM,kBAAkB,CAC7C,KAAK,EACL,SAAS,EACT,WAAW,CACZ,CAAC,CAAC;IACL,CAAC;IAED,sFAAsF;IACtF,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,kBAAkB,CAC/B,KAAsC,EACtC,SAA4C,EAC5C,WAA4B;IAE5B,GAAG,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAErC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtE,IAAA,kCAAiB,EACf;QACE,aAAa,EAAE,WAAW,CAAC,EAAE;QAC7B,SAAS;QACT,IAAI,EAAE,uCAAuC;KAC9C,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IAChC,CAAC,CACF,CAAC;IAEF,IAAI,+BAA+B,GAAG,EAAE,CAAC;IACzC,IAAI,mBAAoC,CAAC;IAEzC,iGAAiG;IACjG,MAAM,eAAe,GAAe,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;IAE1D,IAAI,KAAK,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACtC,MAAM,IAAA,mDAAyB,EAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,MAAM,EAAE,UAAU,EAAE,qBAAqB,EAAE,GACzC,MAAM,IAAA,sCAAwB,EAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACvE,+BAA+B,GAAG,qBAAqB,CAAC;QACxD,kBAAkB,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,mBAAmB,GAAG,MAAM,kBAAkB,CAC5C,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,EACvC,WAAW,EACX,SAAS,CACV,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,sBAAsB,CAAC,eAAe,EAAE,SAAS,EAAE;QAC1E,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAClC,kBAAkB,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,eAAe,EAAE,YAAY;KAC9B,CAAC,CAAC;IAEH,GAAG,CAAC,yBAAyB,EAAE,UAAU,CAAC,CAAC;IAE3C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,IAAA,0CAA4B,EAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE;YAChE,WAAW,EAAE,UAAU,CAAC,MAAM;YAC9B,qBAAqB,EAAE,+BAA+B;SACvD,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,IAAA,kCAAiB,EACf;QACE,aAAa,EAAE,WAAW,CAAC,EAAE;QAC7B,SAAS;QACT,IAAI,EAAE,wCAAwC;KAC/C,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,4EAA4E;IAC5E,8EAA8E;IAC9E,6EAA6E;IAC7E,uCAAuC;IACvC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACtE,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,mBAAmB,CAAC;YACpD,UAAU;YACV,SAAS;YACT,KAAK;YACL,mBAAmB;YACnB,WAAW;SACZ,CAAC,CAAC;QAEH,OAAO,EAAE,eAAe,EAAE,eAAe,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;IACvE,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,KAAK,UAAU,mBAAmB,CAAC,EACjC,UAAU,EACV,SAAS,EACT,KAAK,EACL,mBAAmB,EACnB,WAAW,GAOZ;IACC,MAAM,eAAe,GAAG,MAAM,oBAAoB,CAAC;QACjD,UAAU;QACV,SAAS;QACT,KAAK;QACL,mBAAmB;KACpB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW;QACxC,CAAC,CAAC,MAAM,0BAA0B,CAAC;YAC/B,SAAS;YACT,eAAe;YACf,WAAW;YACX,KAAK;SACN,CAAC;QACJ,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,SAAS,GACb,QAAQ,EAAE,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IAEvE,OAAO,IAAA,oDAA8B,EAAC;QACpC,SAAS;QACT,mBAAmB,EAAE,SAAS;QAC9B,YAAY,EAAE,QAAQ,EAAE,KAAK;QAC7B,eAAe;QACf,WAAW;QACX,aAAa,EAAE,KAAK;KACrB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,KAAK,UAAU,0BAA0B,CAAC,EACxC,SAAS,EACT,KAAK,EACL,eAAe,EACf,WAAW,GAMZ;IACC,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC,IAAI,CACxC,mCAAmC,CACpC,CAAC;IAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC;IACjE,MAAM,WAAW,GAAG,IAAI,wBAAS,CAAC,eAAe,CAAC;SAC/C,SAAS,CAAC,CAAC,QAAQ,CAAC;SACpB,OAAO,EAAE,CAAC;IAEb,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CAC/C,iDAAiD,EACjD;QACE,MAAM,EAAE,WAAW;QACnB,WAAW;QACX,eAAe,EAAE,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;KACjD,CACF,CAAC;IAEF,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,KAAK,UAAU,oBAAoB,CAAC,EAClC,UAAU,EACV,SAAS,EACT,KAAK,EACL,mBAAmB,GAMpB;IACC,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAEnD,CAAC;IAEd,MAAM,WAAW,GACf,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;IAE9D,MAAM,mBAAmB,GAAG,OAAO,CACjC,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU,KAAK,4BAAa,CACjE,CAAC;IAEF,IAAI,cAA+B,CAAC;IAEpC,IAAI,mBAAmB,EAAE,CAAC;QACxB,cAAc,GAAG,UAAU,CAAC,UAAiB,CAAC;IAChD,CAAC;SAAM,IAAI,WAAW,IAAI,mBAAmB,KAAK,4BAAa,EAAE,CAAC;QAChE,cAAc,GAAG,mBAAmB,CAAC;IACvC,CAAC;IAED,IAAI,SAAS,IAAI,cAAc,EAAE,CAAC;QAChC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,IAAA,+CAA8B,EAAC;YACxE,SAAS;YACT,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa;YACpC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,kBAAkB;YAC9C,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QAED,GAAG,CAAC,mDAAmD,EAAE;YACvD,cAAc;YACd,aAAa;SACd,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC;IAElE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,GAAG,CAAC,mDAAmD,EAAE;QACvD,QAAQ;QACR,UAAU,EAAE,UAAU,CAAC,UAAU;KAClC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,kBAAkB,CACzB,WAA4B,EAC5B,SAA4C,EAC5C,UAAe;IAEf,IAAA,kCAAiB,EACf;QACE,aAAa,EAAE,WAAW,CAAC,EAAE;QAC7B,SAAS;QACT,IAAI,EAAE,mCAAmC;KAC1C,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,WAAW,KAAd,EAAE,CAAC,WAAW,GAAK,EAAE,EAAC;QACtB,EAAE,CAAC,WAAW,CAAC,UAAU,GAAG,UAAU,CAAC;IACzC,CAAC,CACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,KAAiB,EACjB,SAA4C,EAC5C,OAGC;IAED,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;IAElD,MAAM,WAAW,GACf,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO;QACzC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;IAE7C,MAAM,mBAAmB,GACvB,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC;IAE9D,IAAI,WAAW,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACxC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,4BAAa,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAErC,MAAM,eAAe,GAAG,IAAA,0CAAuB,EAAC,SAAS,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,IAAA,yCAAsB,EAAC,SAAS,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,cAAc,KAAK,SAAS,IAAI,cAAc,GAAG,CAAC,CAAC;IAEtE,GAAG,CAAC,gBAAgB,EAAE,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,UAAmC,CAAC;IAExC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAuC,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAA,6BAAc,EAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC5C,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;YAE3B,IAAI,CAAC,iBAAiB,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;gBACpD,iBAAiB,GAAG,IAAI,CAAC;gBACzB,YAAY,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAQ,CAAC,CAAC;YAC9C,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChC,MAAM,UAAU,GACb,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAqB,IAAI,4BAAa,CAAC;gBACtE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;YAC3C,CAAC;YAED,IAAI,CAAC,qCAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpD,IAAI,qCAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,IAAI,eAAe,EAAE,CAAC;wBACpB,GAAG,CAAC,2CAA2C,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;wBAChE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;oBACnC,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBAClE,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,IAAI,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,cAAc,EAAE,CAAC;YAC3D,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,kBAAkB,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,IAAI,eAAe,EAAE,CAAC;gBACpB,GAAG,CAAC,qCAAqC,EAAE,YAAY,CAAC,CAAC;gBACzD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAC/B,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,oBAAoB,YAAY,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,MAAgD,EAChD,SAA4C;IAE5C,MAAM,YAAY,GAAG,IAAA,kCAAe,EAAC,SAAS,CAAC,CAAC;IAEhD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,IAAA,wBAAK,EAAC,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC;QAC3D,YAAY,EACV,MAAM,CAAC,YAAY,KAAK,SAAS;YAC/B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAA,wBAAK,EAAC,MAAM,CAAC,YAAY,CAAC;QAChC,oBAAoB,EAClB,MAAM,CAAC,oBAAoB,KAAK,SAAS;YACvC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAA,wBAAK,EAAC,MAAM,CAAC,oBAAoB,CAAC;QACxC,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,KAAK,EAAE,IAAA,wBAAK,EAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC;KAClC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,qBAAqB,CAClC,KAAsC,EACtC,SAA4C;IAE5C,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAElE,MAAM,4BAA4B,GAAG,IAAA,gCAAqB,EACxD,kBAAkB,EAClB,aAAa,EACb,6BAAkB,CAAC,QAAQ,CAC5B,CAAC;IAEF,IAAI,cAAsB,CAAC;IAE3B,IAAI,CAAC;QACH,cAAc,GAAG,MAAM,IAAA,8BAAmB,EACxC,SAAS,EACT,IAAI,EACJ,aAAa,EACb,4BAA4B,CAC7B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,2CAA4C,KAAe,CAAC,OAAO,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC,CAAC;IAE9C,GAAG,CAAC,2BAA2B,EAAE;QAC/B,IAAI;QACJ,aAAa;QACb,kBAAkB;QAClB,cAAc;QACd,cAAc,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;KAC5C,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,uDAAuD;YACrD,aAAa,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI;YAC5C,cAAc,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CACvC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,kBAAkB,CAC/B,KAAsC,EACtC,WAA4B,EAC5B,SAA4C;IAE5C,6EAA6E;IAC7E,2EAA2E;IAC3E,kEAAkE;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QACjE,MAAM,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,MAAM,sBAAsB,CAAC;QACnE,SAAS;QACT,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACtC,OAAO,MAAM,IAAA,+CAAqB,EAChC,KAAK,EACL,WAAW,EACX,SAAS,EACT,SAAS,CACV,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,8BAA8B,CACzC,KAAK,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,SAAS,CACV,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAClC,KAAsC;IAEtC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IACjC,MAAM,kBAAkB,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAC5B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAClD,EAAE,IAAI,CAAC;IAER,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAC1B,CAAC,IAAI,EAAgC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CACpE,CAAC;IAEF,OAAO,OAAO;SACX,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;SAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACxB,MAAM,CAAC,CAAC,IAAI,EAAoD,EAAE,CACjE,0BAA0B,CAAC,IAAI,CAAC,CACjC,CAAC;AACN,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,EACpC,SAAS,EACT,KAAK,EACL,WAAW,GAKZ;IACC,MAAM,MAAM,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CACnD,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CACzC,CAAC;IAEF,oEAAoE;IACpE,wDAAwD;IACxD,sEAAsE;IACtE,4EAA4E;IAC5E,0EAA0E;IAC1E,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACtC,MAAM,kBAAkB,GACtB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE;QAC/B,WAAW,CAAC,QAAQ,CAAC,IAAY,CAAC,WAAW,EAAE,CAAC;IAEnD,wEAAwE;IACxE,oEAAoE;IACpE,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,wDAAwD;IACxD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC;IAEnD,IAAI,SAAS,GAAG,gBAAgB,CAAC;IAEjC,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC,IAAI,CACxC,mCAAmC,CACpC,CAAC;QAEF,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CACjD,iDAAiD,EACjD;YACE,MAAM,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK;YAChC,WAAW;YACX,eAAe,EAAE,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;SACjD,CACF,CAAC;QAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,SAAS,GAAG;gBACV,GAAI,WAAmC;gBACvC,GAAG,gBAAgB;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClD,MAAM,eAAe,GAAG,kBAAkB;YACxC,CAAC,CAAC,MAAM,4BAA4B,CAChC,WAAW,EACX,SAAS,EACT,gBAAgB,CAAC,CAAC,CAAC,CACpB;YACH,CAAC,CAAE;gBACC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAuB;gBAClD,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI;gBAC/B,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,YAAY;gBAC/C,oBAAoB,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,oBAAoB;gBAC/D,EAAE,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE;gBAC3B,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAwB;aAC/B,CAAC;QAE5B,SAAS,GAAG,CAAC,eAAe,EAAE,GAAG,gBAAgB,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;AACzC,CAAC;AAED,SAAS,0BAA0B,CACjC,IAA8C;IAE9C,MAAM,aAAa,GAAG,IAAwB,CAAC;IAC/C,OAAO,aAAa,CAAC,EAAE,KAAK,SAAS,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,4BAA4B,CACzC,WAA4B,EAC5B,SAA4C,EAC5C,WAA+B;IAE/B,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,IAAI,CACrC,mDAAmD,EACnD,EAAE,WAAW,EAAE,CAChB,CAAC;IAEF,GAAG,CAAC,6CAA6C,EAAE,UAAU,CAAC,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAW;QACtC,YAAY,EAAE,WAAW,EAAE,YAAY;QACvC,oBAAoB,EAAE,WAAW,EAAE,oBAAoB;QACvD,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,KAAK,EAAE,UAAU,CAAC,KAAK;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,8BAA8B,CAC3C,KAAsC,EACtC,WAA4B,EAC5B,SAA4C,EAC5C,gBAAqC,EACrC,SAA8B;IAE9B,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAClE,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAEtC,MAAM,eAAe,GAAG,IAAA,gCAAkB,EAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAErE,GAAG,CAAC,qBAAqB,EAAE;QACzB,gBAAgB,EAAE,SAAS;QAC3B,aAAa;QACb,IAAI;QACJ,eAAe;KAChB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,sCAAqB,EACnC,aAAa,EACb,IAAI,EACJ,SAAS,EACT,CAAC,aAAa,EAAE,EAAE;QAChB,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEnC,IAAA,kCAAiB,EACf;YACE,aAAa,EAAE,WAAW,CAAC,EAAE;YAC7B,SAAS;YACT,IAAI,EAAE,mDAAmD;SAC1D,EACD,CAAC,EAAE,EAAE,EAAE;YACL,EAAE,CAAC,sBAAsB,KAAzB,EAAE,CAAC,sBAAsB,GAAK,EAAE,EAAC;YACjC,EAAE,CAAC,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,CACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,IAAI,MAA+C,CAAC;IAEpD,MAAM,uBAAuB,GAC3B,WAAW,CAAC,iBAAiB;QAC7B,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,WAAW,CAAC,OAAO;QACnD,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,WAAW,CAAC,OAAO,CAAC;IAEtD,MAAM,WAAW,GACf,CAAC,uBAAuB,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB;QACxD,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,SAAS,CAAC;IAEhB,GAAG,CAAC,yBAAyB,EAAE;QAC7B,WAAW;QACX,WAAW;QACX,cAAc,EAAE,SAAS,CAAC,MAAM;KACjC,CAAC,CAAC;IAEH,MAAM,WAAW,GACf,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO;QAClD,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;IAEtD,6EAA6E;IAC7E,2EAA2E;IAC3E,sEAAsE;IACtE,MAAM,iBAAiB,GACrB,WAAW,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM;QAC7D,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,IAAA,wBAAK,EAAC,CAAC,CAAC,OAAO,CAAC;SAC1B,CAAC,CAAC;QACL,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,kBAAkB,GACtB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE;QAC/B,WAAW,CAAC,QAAQ,CAAC,IAAY,CAAC,WAAW,EAAE,CAAC;IAEnD,MAAM,sBAAsB,GAC1B,WAAW;QACX,kBAAkB;QAClB,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM;QAC9C,CAAC,CAAC,+BAA+B,CAC7B,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CACzC;QACH,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IACpC,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAE/B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,iBAAiB,GAAG;YACxB,GAAG,SAAS,CAAC,CAAC,CAAC;YACf,iBAAiB;YACjB,GAAG,EAAE,IAAA,wBAAK,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC;SACzB,CAAC;QAEF,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAC3B,sCAAsC,EACtC,iBAAiB,EACjB;YACE,WAAW;YACX,eAAe;YACf,MAAM,EAAE,kCAAe;YACvB,UAAU,EAAE,IAAI;YAChB,iBAAiB,EAAE,uBAAuB;YAC1C,eAAe,EAAE,KAAK;YACtB,IAAI,EAAE,mBAAmB,CAAC,2BAA2B,CAAC,WAAW,CAAC,CAAC;SACpE,CACF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,CAAC,IAAI,CAClB,2CAA2C,EAC3C,iCAAiC,CAAC;YAChC,SAAS;YACT,iBAAiB,EAAE,sBAAsB;YACzC,iBAAiB,EAAE,uBAAuB;YAC1C,SAAS;YACT,gBAAgB;YAChB,KAAK;YACL,WAAW;SACZ,CAAC,CACH,CAAC;IACJ,CAAC;IAED,GAAG,EAAE,CAAC;IAEN,GAAG,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;IAE1C,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CACf,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,4CAA2B,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAC3E,CAAC;IAEF,GAAG,CAAC,4BAA4B,EAAE,cAAc,CAAC,CAAC;IAElD,MAAM,IAAI,GAAG,IAAA,+BAAc,EAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC;IAE1E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,IAAW,CAAC;AACrB,CAAC;AAED,SAAS,+BAA+B,CACtC,iBAA0E;IAE1E,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,OAAO,EAAE,IAAA,wBAAK,EAAC,CAAC,CAAC,OAAO,CAAC;QACzB,KAAK,EAAE,IAAA,wBAAK,EAAC,CAAC,CAAC,KAAK,CAAC;QACrB,CAAC,EAAE,CAAC,CAAC,CAAC;QACN,CAAC,EAAE,CAAC,CAAC,CAAC;QACN,OAAO,EAAE,IAAA,wBAAK,EAAC,CAAC,CAAC,OAAO,CAAC;KAC1B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,iCAAiC,CAAC,EACzC,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,WAAW,GASZ;IACC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAClE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IACpC,MAAM,eAAe,GAAG,IAAA,gCAAkB,EAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,mBAAmB;QACjD,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAE5C,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,WAAW,EAAE,CAAC,YAAY;QAC1B,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC;QAClC,iBAAiB,EAAE,OAAO,CAAC,YAAY,CAAC;QACxC,WAAW;QACX,YAAY;QACZ,eAAe;QACf,MAAM,EAAE,kCAAe;QACvB,UAAU,EAAE,IAAI;QAChB,iBAAiB;QACjB,gBAAgB,EAAE,IAAI;QACtB,eAAe,EAAE,KAAK;QACtB,YAAY,EAAE,2BAA2B,CAAC;YACxC,SAAS;YACT,YAAY;YACZ,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,gBAAgB;YAChB,WAAW;SACZ,CAAC;KACH,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAAC,EACnC,SAAS,EACT,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,WAAW,GAOZ;IACC,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAEhE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE;QAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,GAAG,GACP,QAAQ,KAAK,SAAS,IAAI,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,wBAAK,EAAC,QAAQ,CAAC,CAAC;QAEvE,OAAO;YACL,MAAM,EAAE;gBACN,IAAI,EAAE,YAAY,CAAC,IAAW;gBAC9B,GAAG;gBACH,YAAY,EAAE,YAAY,CAAC,YAAmB;gBAC9C,oBAAoB,EAAE,YAAY,CAAC,oBAA2B;gBAC9D,EAAE,EAAE,YAAY,CAAC,EAAS;gBAC1B,KAAK,EAAE,YAAY,CAAC,KAAY;aACjC;YACD,IAAI,EAAE,kBAAkB,CACtB,YAAY,EACZ,KAAK,EACL,2BAA2B,CAAC,WAAW,CAAC,EACxC,gBAAgB,CAAC,MAAM,CACxB;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CACtB,KAAsC;IAEtC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACtD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAE9B,OAAO,MAAM,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAA,wBAAK,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxE,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CACzB,YAAoB,EACpB,KAAa,EACb,YAAqC,EACrC,eAAuB;IAEvB,IAAI,YAAY,GAAG,CAAC,IAAI,KAAK,GAAG,YAAY,EAAE,CAAC;QAC7C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,GAAG,YAAY,CAAC;IAExC,MAAM,WAAW,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAEtD,6DAA6D;IAC7D,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,wCAAe,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAC1B,YAAqC;IAErC,OAAO,CACL,CAAC,YAAY,IAAI,kCAAmB,CAAC,YAAY,CAAC,CAAC;QACnD,wCAAe,CAAC,YAAY,CAC7B,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,2BAA2B,CAClC,WAA4B;IAE5B,IAAI,WAAW,CAAC,IAAI,KAAK,wCAAe,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,kBAAkB,EAAE,IAAI,CACrD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,IAAI,kCAAmB,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,CAC9D,EAAE,IAAI,CAAC;IAER,OAAO,UAAU,IAAI,WAAW,CAAC,IAAI,CAAC;AACxC,CAAC","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n BatchTransactionParams,\n TransactionBatchRequest,\n TransactionBatchSingleRequest,\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 { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types.js';\nimport { prefixError } from '../../utils/error-prefix.js';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags.js';\nimport { submitMoneyAccountVaultDeposit } from '../../utils/ma-vault-deposit.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token.js';\nimport {\n collectTransactionIds,\n getTransaction,\n getTransferredAmountFromTxHash,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport {\n FALLBACK_HASH,\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants.js';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw.js';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw.js';\nimport { getRelayStatus } from './relay-api.js';\nimport { submitViaRelayExecute } from './relay-submit-execute.js';\nimport type {\n RelayCompletionOutcome,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\nconst RELAY_ERROR_PREFIX = 'Relay: ';\n\ntype RelaySubmitParams = {\n allParams: TransactionParams[];\n normalizedParams: TransactionParams[];\n};\n\nexport type RelaySubmitCalls = { calls: TransactionParams[] };\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n try {\n return await submitRelayQuotesInternal(request);\n } catch (error) {\n throw prefixError(error, RELAY_ERROR_PREFIX);\n }\n}\n\nexport async function getRelaySubmitCalls({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitCalls> {\n const { allParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n return { calls: allParams };\n}\n\nasync function submitRelayQuotesInternal(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n if (!quotes.length) {\n throw new Error('No quotes to submit');\n }\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n /* istanbul ignore if: concrete Relay submit paths return a hash/fallback or throw. */\n if (transactionHash === undefined) {\n throw new Error('Missing transaction hash');\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n let submittedSourceHash: Hex | undefined;\n\n // Shallow clone so the server-returned requestId can be written back (state is frozen by Immer).\n const mutableOriginal: RelayQuote = { ...quote.original };\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n submittedSourceHash = await submitTransactions(\n { ...quote, original: mutableOriginal },\n transaction,\n messenger,\n );\n }\n\n const completion = await waitForRelayCompletion(mutableOriginal, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n // Non-atomic flow: the quote bridged funds to `recipient` without embedding\n // the second leg. Now that Relay has settled, resolve the settled amount from\n // the on-chain Transfer log and submit the second-leg batch (approve + vault\n // deposit) sponsored from `recipient`.\n if (quote.request.atomic === false && completion.status === 'success') {\n const { transactionHash } = await submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n });\n\n return { transactionHash: transactionHash ?? completion.targetHash };\n }\n\n return { transactionHash: completion.targetHash };\n}\n\n/**\n * Runs the second leg of a non-atomic Relay quote. Resolves the settled amount\n * from the on-chain Transfer log, then submits the batch via\n * `submitMoneyAccountVaultDeposit`. Post-quote flows fetch pre-built calls via\n * the client `getPaymentOverrideData` callback; non-post-quote flows fall\n * through to the transaction's own nested calls re-encoded via\n * `getAmountData`. Funds settled on `quote.request.recipient`, derived at\n * quote time by `resolveNonAtomicRecipient`.\n *\n * @param options - Submit options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used to read the settled amount when Relay skips polling on\n * same-chain flows.\n * @param options.transaction - Original transaction meta.\n * @returns Hash of the final submitted child transaction, if available.\n */\nasync function submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n transaction: TransactionMeta;\n}): Promise<{ transactionHash?: Hex }> {\n const sourceAmountRaw = await resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n });\n\n const override = quote.request.isPostQuote\n ? await buildPostQuoteDepositCalls({\n messenger,\n sourceAmountRaw,\n transaction,\n quote,\n })\n : undefined;\n\n const recipient =\n override?.recipient ?? quote.request.recipient ?? quote.request.from;\n\n return submitMoneyAccountVaultDeposit({\n messenger,\n moneyAccountAddress: recipient,\n depositCalls: override?.calls,\n sourceAmountRaw,\n transaction,\n vaultDisabled: false,\n });\n}\n\n/**\n * Builds the post-completion batch for a post-quote flow whose parent\n * transaction carries no vault calls. Delegates to the client\n * `getPaymentOverrideData` callback with the settled amount.\n *\n * The callback MUST return a non-empty batch. Post-quote parent metas (e.g.\n * Perps/Predict withdraws) carry no vault-side nested calls, so falling back\n * to `getAmountData` in `resolveVaultDepositBatch` cannot recover the second\n * leg once Relay has already settled funds to the recipient. Throw eagerly so\n * the failure surfaces at the correct call site with an actionable message.\n *\n * The callback may also return the `recipient` that funds settled on, which the\n * caller prefers as the source of truth for the second-leg account.\n *\n * @param options - Build options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.sourceAmountRaw - Settled amount in raw units.\n * @param options.transaction - Original transaction meta.\n * @returns The batch calls and optional recipient.\n * @throws If the callback returns an empty batch.\n */\nasync function buildPostQuoteDepositCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n}): Promise<{ calls: BatchTransactionParams[]; recipient?: Hex }> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { decimals } = quote.original.details.currencyOut.currency;\n const amountHuman = new BigNumber(sourceAmountRaw)\n .shiftedBy(-decimals)\n .toFixed();\n\n const { calls, recipient } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: amountHuman,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (!calls.length) {\n throw new Error('Missing post-quote deposit calls');\n }\n\n return { calls, recipient };\n}\n\n/**\n * Resolves the actual amount that landed on the recipient after a Relay bridge.\n *\n * Cross-chain relays surface a real target-chain hash from polling; same-chain\n * relays skip polling (the `FALLBACK_HASH` placeholder) but the submitted\n * source transaction itself moved the funds, so its hash is read instead. In\n * both cases the exact settled amount comes from the on-chain Transfer log; a\n * read failure or missing amount throws rather than guessing, since using the\n * quote minimum would knowingly strand dust and defeat an EXACT_INPUT quote.\n *\n * Relay execute submissions return `FALLBACK_HASH` instead of a real source\n * hash, leaving nothing to read; only then is the quote's minimum output used\n * as the last available source.\n *\n * @param options - Resolution options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used when polling was skipped on same-chain flows.\n * @returns The raw (atomic) settled amount as a decimal string.\n */\nasync function resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n}): Promise<string> {\n const recipient = (quote.request.recipient ?? quote.request.from) as\n | Hex\n | undefined;\n\n const isSameChain =\n quote.request.sourceChainId === quote.request.targetChainId;\n\n const hasPolledTargetHash = Boolean(\n completion.targetHash && completion.targetHash !== FALLBACK_HASH,\n );\n\n let settlementHash: Hex | undefined;\n\n if (hasPolledTargetHash) {\n settlementHash = completion.targetHash as Hex;\n } else if (isSameChain && submittedSourceHash !== FALLBACK_HASH) {\n settlementHash = submittedSourceHash;\n }\n\n if (recipient && settlementHash) {\n const { amountRaw: onChainAmount } = await getTransferredAmountFromTxHash({\n messenger,\n txHash: settlementHash,\n chainId: quote.request.targetChainId,\n tokenAddress: quote.request.targetTokenAddress,\n walletAddress: recipient,\n });\n\n if (!onChainAmount) {\n throw new Error(\n 'Cannot resolve settled amount from on-chain transaction',\n );\n }\n\n log('Resolved settled amount from on-chain transaction', {\n settlementHash,\n onChainAmount,\n });\n\n return onChainAmount;\n }\n\n const fallback = quote.original.details.currencyOut.minimumAmount;\n\n if (!fallback) {\n throw new Error('Cannot resolve post-completion amount');\n }\n\n log('Resolved settled amount from quote minimum output', {\n fallback,\n targetHash: completion.targetHash,\n });\n\n return fallback;\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex | undefined) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Request failed with status: ${status.status}`);\n }\n throw new Error(`Unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas:\n params.maxFeePerGas === undefined\n ? undefined\n : toHex(params.maxFeePerGas),\n maxPriorityFeePerGas:\n params.maxPriorityFeePerGas === undefined\n ? undefined\n : toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote && !quote.request.paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const { allParams, normalizedParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\nfunction getRelayTransactionStepData(\n quote: TransactionPayQuote<RelayQuote>,\n): RelayTransactionStep['items'][0]['data'][] {\n const { steps } = quote.original;\n const supportedStepKinds = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !supportedStepKinds.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n\n return txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data)\n .filter((data): data is RelayTransactionStep['items'][0]['data'] =>\n isRelayTransactionStepData(data),\n );\n}\n\nasync function buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitParams> {\n const params = getRelayTransactionStepData(quote);\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n // Non-atomic flows are excluded from the paymentOverride prepend: their\n // second leg is submitted separately by `submitPostNonAtomic` after\n // Relay completion, so prepending here would double-embed the vault deposit.\n // Cross-chain atomic flows (e.g. `moneyAccountWithdraw` on Monad settling\n // USDC on Arbitrum for Perps) still need the source-side vault withdraw +\n // transfer prepended here so Relay has funds to bridge.\n const isNonAtomic = quote.request.atomic === false;\n\n let allParams = normalizedParams;\n\n if (quote.request.paymentOverride && !isNonAtomic) {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideTxs } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (overrideTxs.length > 0) {\n allParams = [\n ...(overrideTxs as TransactionParams[]),\n ...normalizedParams,\n ];\n }\n } else if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(\n transaction,\n messenger,\n normalizedParams[0],\n )\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n maxFeePerGas: normalizedParams[0]?.maxFeePerGas,\n maxPriorityFeePerGas: normalizedParams[0]?.maxPriorityFeePerGas,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n return { allParams, normalizedParams };\n}\n\nfunction isRelayTransactionStepData(\n data: RelayTransactionStep['items'][0]['data'],\n): data is RelayTransactionStep['items'][0]['data'] {\n const maybeStepData = data as { to?: unknown };\n return maybeStepData.to !== undefined;\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @param relayParams - Optional relay params to copy gas fee fields from.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n relayParams?: TransactionParams,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n maxFeePerGas: relayParams?.maxFeePerGas,\n maxPriorityFeePerGas: relayParams?.maxPriorityFeePerGas,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const isSourceGasFeeSponsored =\n transaction.isGasFeeSponsored &&\n quote.request.sourceChainId === transaction.chainId &&\n quote.request.targetChainId === transaction.chainId;\n\n const gasFeeToken =\n !isSourceGasFeeSponsored && quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n // Single-tx keeps address/chainId only — TransactionController re-signs with\n // `from`. Batch may need a different signer (Money Account) than the batch\n // payer (EOA account override), so preserve the full pre-signed list.\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n const batchAuthorizationList =\n isSameChain &&\n hasAccountOverride &&\n quote.original.request.authorizationList?.length\n ? mapSignedQuoteAuthorizationList(\n quote.original.request.authorizationList,\n )\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n await messenger.call(\n 'TransactionController:addTransactionBatch',\n buildRelayTransactionBatchRequest({\n allParams,\n authorizationList: batchAuthorizationList,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n }),\n );\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (!transactionIds.length) {\n throw new Error('No transactions submitted');\n }\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\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 return hash as Hex;\n}\n\nfunction mapSignedQuoteAuthorizationList(\n authorizationList: NonNullable<RelayQuote['request']['authorizationList']>,\n): AuthorizationList {\n return authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n nonce: toHex(a.nonce),\n r: a.r,\n s: a.s,\n yParity: toHex(a.yParity),\n }));\n}\n\nfunction buildRelayTransactionBatchRequest({\n allParams,\n authorizationList,\n isGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n}: {\n allParams: TransactionParams[];\n authorizationList?: AuthorizationList;\n isGasFeeSponsored: boolean | undefined;\n messenger: TransactionPayControllerMessenger;\n normalizedParams: TransactionParams[];\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): TransactionBatchRequest {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { metamask } = quote.original;\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n const gasFeeToken = quote.fees?.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n const gasLimit7702 = getGasLimit7702(quote);\n\n return {\n from,\n ...(authorizationList?.length ? { authorizationList } : {}),\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions: buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits: metamask.gasLimits,\n normalizedParams,\n transaction,\n }),\n };\n}\n\nfunction buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits,\n normalizedParams,\n transaction,\n}: {\n allParams: TransactionParams[];\n gasLimit7702?: Hex;\n gasLimits: number[];\n normalizedParams: TransactionParams[];\n transaction: TransactionMeta;\n}): TransactionBatchSingleRequest[] {\n const prependCount = allParams.length - normalizedParams.length;\n\n return allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n prependCount,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n}\n\nfunction getGasLimit7702(\n quote: TransactionPayQuote<RelayQuote>,\n): Hex | undefined {\n const { gasLimits, is7702 } = quote.original.metamask;\n const gasLimit = gasLimits[0];\n\n return is7702 && gasLimit !== undefined ? toHex(gasLimit) : undefined;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param prependCount - Number of non-relay txs prepended to the batch.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for prepended indices).\n * @param relayParamCount - Number of relay-only params (excludes prepended txs).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n prependCount: number,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n if (prependCount > 0 && index < prependCount) {\n return originalType;\n }\n\n const relayIndex = index - prependCount;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
|
@@ -569,12 +569,22 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
569
569
|
});
|
|
570
570
|
const isSameChain = quote.original.details.currencyIn.currency.chainId ===
|
|
571
571
|
quote.original.details.currencyOut.currency.chainId;
|
|
572
|
+
// Single-tx keeps address/chainId only — TransactionController re-signs with
|
|
573
|
+
// `from`. Batch may need a different signer (Money Account) than the batch
|
|
574
|
+
// payer (EOA account override), so preserve the full pre-signed list.
|
|
572
575
|
const authorizationList = isSameChain && quote.original.request.authorizationList?.length
|
|
573
576
|
? quote.original.request.authorizationList.map((a) => ({
|
|
574
577
|
address: a.address,
|
|
575
578
|
chainId: toHex(a.chainId),
|
|
576
579
|
}))
|
|
577
580
|
: undefined;
|
|
581
|
+
const hasAccountOverride = quote.request.from.toLowerCase() !==
|
|
582
|
+
transaction.txParams.from.toLowerCase();
|
|
583
|
+
const batchAuthorizationList = isSameChain &&
|
|
584
|
+
hasAccountOverride &&
|
|
585
|
+
quote.original.request.authorizationList?.length
|
|
586
|
+
? mapSignedQuoteAuthorizationList(quote.original.request.authorizationList)
|
|
587
|
+
: undefined;
|
|
578
588
|
const { metamask } = quote.original;
|
|
579
589
|
const { gasLimits } = metamask;
|
|
580
590
|
if (allParams.length === 1) {
|
|
@@ -596,6 +606,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
596
606
|
else {
|
|
597
607
|
await messenger.call('TransactionController:addTransactionBatch', buildRelayTransactionBatchRequest({
|
|
598
608
|
allParams,
|
|
609
|
+
authorizationList: batchAuthorizationList,
|
|
599
610
|
isGasFeeSponsored: isSourceGasFeeSponsored,
|
|
600
611
|
messenger,
|
|
601
612
|
normalizedParams,
|
|
@@ -620,7 +631,17 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
620
631
|
}
|
|
621
632
|
return hash;
|
|
622
633
|
}
|
|
623
|
-
function
|
|
634
|
+
function mapSignedQuoteAuthorizationList(authorizationList) {
|
|
635
|
+
return authorizationList.map((a) => ({
|
|
636
|
+
address: a.address,
|
|
637
|
+
chainId: toHex(a.chainId),
|
|
638
|
+
nonce: toHex(a.nonce),
|
|
639
|
+
r: a.r,
|
|
640
|
+
s: a.s,
|
|
641
|
+
yParity: toHex(a.yParity),
|
|
642
|
+
}));
|
|
643
|
+
}
|
|
644
|
+
function buildRelayTransactionBatchRequest({ allParams, authorizationList, isGasFeeSponsored, messenger, normalizedParams, quote, transaction, }) {
|
|
624
645
|
const { from, sourceChainId, sourceTokenAddress } = quote.request;
|
|
625
646
|
const { metamask } = quote.original;
|
|
626
647
|
const networkClientId = getNetworkClientId(messenger, sourceChainId);
|
|
@@ -630,6 +651,7 @@ function buildRelayTransactionBatchRequest({ allParams, isGasFeeSponsored, messe
|
|
|
630
651
|
const gasLimit7702 = getGasLimit7702(quote);
|
|
631
652
|
return {
|
|
632
653
|
from,
|
|
654
|
+
...(authorizationList?.length ? { authorizationList } : {}),
|
|
633
655
|
disable7702: !gasLimit7702,
|
|
634
656
|
disableHook: Boolean(gasLimit7702),
|
|
635
657
|
disableSequential: Boolean(gasLimit7702),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n BatchTransactionParams,\n TransactionBatchRequest,\n TransactionBatchSingleRequest,\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 { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types.js';\nimport { prefixError } from '../../utils/error-prefix.js';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags.js';\nimport { submitMoneyAccountVaultDeposit } from '../../utils/ma-vault-deposit.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token.js';\nimport {\n collectTransactionIds,\n getTransaction,\n getTransferredAmountFromTxHash,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport {\n FALLBACK_HASH,\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants.js';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw.js';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw.js';\nimport { getRelayStatus } from './relay-api.js';\nimport { submitViaRelayExecute } from './relay-submit-execute.js';\nimport type {\n RelayCompletionOutcome,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\nconst RELAY_ERROR_PREFIX = 'Relay: ';\n\ntype RelaySubmitParams = {\n allParams: TransactionParams[];\n normalizedParams: TransactionParams[];\n};\n\nexport type RelaySubmitCalls = { calls: TransactionParams[] };\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n try {\n return await submitRelayQuotesInternal(request);\n } catch (error) {\n throw prefixError(error, RELAY_ERROR_PREFIX);\n }\n}\n\nexport async function getRelaySubmitCalls({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitCalls> {\n const { allParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n return { calls: allParams };\n}\n\nasync function submitRelayQuotesInternal(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n if (!quotes.length) {\n throw new Error('No quotes to submit');\n }\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n /* istanbul ignore if: concrete Relay submit paths return a hash/fallback or throw. */\n if (transactionHash === undefined) {\n throw new Error('Missing transaction hash');\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n let submittedSourceHash: Hex | undefined;\n\n // Shallow clone so the server-returned requestId can be written back (state is frozen by Immer).\n const mutableOriginal: RelayQuote = { ...quote.original };\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n submittedSourceHash = await submitTransactions(\n { ...quote, original: mutableOriginal },\n transaction,\n messenger,\n );\n }\n\n const completion = await waitForRelayCompletion(mutableOriginal, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n // Non-atomic flow: the quote bridged funds to `recipient` without embedding\n // the second leg. Now that Relay has settled, resolve the settled amount from\n // the on-chain Transfer log and submit the second-leg batch (approve + vault\n // deposit) sponsored from `recipient`.\n if (quote.request.atomic === false && completion.status === 'success') {\n const { transactionHash } = await submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n });\n\n return { transactionHash: transactionHash ?? completion.targetHash };\n }\n\n return { transactionHash: completion.targetHash };\n}\n\n/**\n * Runs the second leg of a non-atomic Relay quote. Resolves the settled amount\n * from the on-chain Transfer log, then submits the batch via\n * `submitMoneyAccountVaultDeposit`. Post-quote flows fetch pre-built calls via\n * the client `getPaymentOverrideData` callback; non-post-quote flows fall\n * through to the transaction's own nested calls re-encoded via\n * `getAmountData`. Funds settled on `quote.request.recipient`, derived at\n * quote time by `resolveNonAtomicRecipient`.\n *\n * @param options - Submit options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used to read the settled amount when Relay skips polling on\n * same-chain flows.\n * @param options.transaction - Original transaction meta.\n * @returns Hash of the final submitted child transaction, if available.\n */\nasync function submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n transaction: TransactionMeta;\n}): Promise<{ transactionHash?: Hex }> {\n const sourceAmountRaw = await resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n });\n\n const override = quote.request.isPostQuote\n ? await buildPostQuoteDepositCalls({\n messenger,\n sourceAmountRaw,\n transaction,\n quote,\n })\n : undefined;\n\n const recipient =\n override?.recipient ?? quote.request.recipient ?? quote.request.from;\n\n return submitMoneyAccountVaultDeposit({\n messenger,\n moneyAccountAddress: recipient,\n depositCalls: override?.calls,\n sourceAmountRaw,\n transaction,\n vaultDisabled: false,\n });\n}\n\n/**\n * Builds the post-completion batch for a post-quote flow whose parent\n * transaction carries no vault calls. Delegates to the client\n * `getPaymentOverrideData` callback with the settled amount.\n *\n * The callback MUST return a non-empty batch. Post-quote parent metas (e.g.\n * Perps/Predict withdraws) carry no vault-side nested calls, so falling back\n * to `getAmountData` in `resolveVaultDepositBatch` cannot recover the second\n * leg once Relay has already settled funds to the recipient. Throw eagerly so\n * the failure surfaces at the correct call site with an actionable message.\n *\n * The callback may also return the `recipient` that funds settled on, which the\n * caller prefers as the source of truth for the second-leg account.\n *\n * @param options - Build options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.sourceAmountRaw - Settled amount in raw units.\n * @param options.transaction - Original transaction meta.\n * @returns The batch calls and optional recipient.\n * @throws If the callback returns an empty batch.\n */\nasync function buildPostQuoteDepositCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n}): Promise<{ calls: BatchTransactionParams[]; recipient?: Hex }> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { decimals } = quote.original.details.currencyOut.currency;\n const amountHuman = new BigNumber(sourceAmountRaw)\n .shiftedBy(-decimals)\n .toFixed();\n\n const { calls, recipient } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: amountHuman,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (!calls.length) {\n throw new Error('Missing post-quote deposit calls');\n }\n\n return { calls, recipient };\n}\n\n/**\n * Resolves the actual amount that landed on the recipient after a Relay bridge.\n *\n * Cross-chain relays surface a real target-chain hash from polling; same-chain\n * relays skip polling (the `FALLBACK_HASH` placeholder) but the submitted\n * source transaction itself moved the funds, so its hash is read instead. In\n * both cases the exact settled amount comes from the on-chain Transfer log; a\n * read failure or missing amount throws rather than guessing, since using the\n * quote minimum would knowingly strand dust and defeat an EXACT_INPUT quote.\n *\n * Relay execute submissions return `FALLBACK_HASH` instead of a real source\n * hash, leaving nothing to read; only then is the quote's minimum output used\n * as the last available source.\n *\n * @param options - Resolution options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used when polling was skipped on same-chain flows.\n * @returns The raw (atomic) settled amount as a decimal string.\n */\nasync function resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n}): Promise<string> {\n const recipient = (quote.request.recipient ?? quote.request.from) as\n | Hex\n | undefined;\n\n const isSameChain =\n quote.request.sourceChainId === quote.request.targetChainId;\n\n const hasPolledTargetHash = Boolean(\n completion.targetHash && completion.targetHash !== FALLBACK_HASH,\n );\n\n let settlementHash: Hex | undefined;\n\n if (hasPolledTargetHash) {\n settlementHash = completion.targetHash as Hex;\n } else if (isSameChain && submittedSourceHash !== FALLBACK_HASH) {\n settlementHash = submittedSourceHash;\n }\n\n if (recipient && settlementHash) {\n const { amountRaw: onChainAmount } = await getTransferredAmountFromTxHash({\n messenger,\n txHash: settlementHash,\n chainId: quote.request.targetChainId,\n tokenAddress: quote.request.targetTokenAddress,\n walletAddress: recipient,\n });\n\n if (!onChainAmount) {\n throw new Error(\n 'Cannot resolve settled amount from on-chain transaction',\n );\n }\n\n log('Resolved settled amount from on-chain transaction', {\n settlementHash,\n onChainAmount,\n });\n\n return onChainAmount;\n }\n\n const fallback = quote.original.details.currencyOut.minimumAmount;\n\n if (!fallback) {\n throw new Error('Cannot resolve post-completion amount');\n }\n\n log('Resolved settled amount from quote minimum output', {\n fallback,\n targetHash: completion.targetHash,\n });\n\n return fallback;\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex | undefined) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Request failed with status: ${status.status}`);\n }\n throw new Error(`Unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas:\n params.maxFeePerGas === undefined\n ? undefined\n : toHex(params.maxFeePerGas),\n maxPriorityFeePerGas:\n params.maxPriorityFeePerGas === undefined\n ? undefined\n : toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote && !quote.request.paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const { allParams, normalizedParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\nfunction getRelayTransactionStepData(\n quote: TransactionPayQuote<RelayQuote>,\n): RelayTransactionStep['items'][0]['data'][] {\n const { steps } = quote.original;\n const supportedStepKinds = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !supportedStepKinds.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n\n return txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data)\n .filter((data): data is RelayTransactionStep['items'][0]['data'] =>\n isRelayTransactionStepData(data),\n );\n}\n\nasync function buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitParams> {\n const params = getRelayTransactionStepData(quote);\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n // Non-atomic flows are excluded from the paymentOverride prepend: their\n // second leg is submitted separately by `submitPostNonAtomic` after\n // Relay completion, so prepending here would double-embed the vault deposit.\n // Cross-chain atomic flows (e.g. `moneyAccountWithdraw` on Monad settling\n // USDC on Arbitrum for Perps) still need the source-side vault withdraw +\n // transfer prepended here so Relay has funds to bridge.\n const isNonAtomic = quote.request.atomic === false;\n\n let allParams = normalizedParams;\n\n if (quote.request.paymentOverride && !isNonAtomic) {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideTxs } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (overrideTxs.length > 0) {\n allParams = [\n ...(overrideTxs as TransactionParams[]),\n ...normalizedParams,\n ];\n }\n } else if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(\n transaction,\n messenger,\n normalizedParams[0],\n )\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n maxFeePerGas: normalizedParams[0]?.maxFeePerGas,\n maxPriorityFeePerGas: normalizedParams[0]?.maxPriorityFeePerGas,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n return { allParams, normalizedParams };\n}\n\nfunction isRelayTransactionStepData(\n data: RelayTransactionStep['items'][0]['data'],\n): data is RelayTransactionStep['items'][0]['data'] {\n const maybeStepData = data as { to?: unknown };\n return maybeStepData.to !== undefined;\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @param relayParams - Optional relay params to copy gas fee fields from.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n relayParams?: TransactionParams,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n maxFeePerGas: relayParams?.maxFeePerGas,\n maxPriorityFeePerGas: relayParams?.maxPriorityFeePerGas,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const isSourceGasFeeSponsored =\n transaction.isGasFeeSponsored &&\n quote.request.sourceChainId === transaction.chainId &&\n quote.request.targetChainId === transaction.chainId;\n\n const gasFeeToken =\n !isSourceGasFeeSponsored && quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n await messenger.call(\n 'TransactionController:addTransactionBatch',\n buildRelayTransactionBatchRequest({\n allParams,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n }),\n );\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (!transactionIds.length) {\n throw new Error('No transactions submitted');\n }\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\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 return hash as Hex;\n}\n\nfunction buildRelayTransactionBatchRequest({\n allParams,\n isGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n}: {\n allParams: TransactionParams[];\n isGasFeeSponsored: boolean | undefined;\n messenger: TransactionPayControllerMessenger;\n normalizedParams: TransactionParams[];\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): TransactionBatchRequest {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { metamask } = quote.original;\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n const gasFeeToken = quote.fees?.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n const gasLimit7702 = getGasLimit7702(quote);\n\n return {\n from,\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions: buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits: metamask.gasLimits,\n normalizedParams,\n transaction,\n }),\n };\n}\n\nfunction buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits,\n normalizedParams,\n transaction,\n}: {\n allParams: TransactionParams[];\n gasLimit7702?: Hex;\n gasLimits: number[];\n normalizedParams: TransactionParams[];\n transaction: TransactionMeta;\n}): TransactionBatchSingleRequest[] {\n const prependCount = allParams.length - normalizedParams.length;\n\n return allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n prependCount,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n}\n\nfunction getGasLimit7702(\n quote: TransactionPayQuote<RelayQuote>,\n): Hex | undefined {\n const { gasLimits, is7702 } = quote.original.metamask;\n const gasLimit = gasLimits[0];\n\n return is7702 && gasLimit !== undefined ? toHex(gasLimit) : undefined;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param prependCount - Number of non-relay txs prepended to the batch.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for prepended indices).\n * @param relayParamCount - Number of relay-only params (excludes prepended txs).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n prependCount: number,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n if (prependCount > 0 && index < prependCount) {\n return originalType;\n }\n\n const relayIndex = index - prependCount;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n BatchTransactionParams,\n TransactionBatchRequest,\n TransactionBatchSingleRequest,\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 { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types.js';\nimport { prefixError } from '../../utils/error-prefix.js';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags.js';\nimport { submitMoneyAccountVaultDeposit } from '../../utils/ma-vault-deposit.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token.js';\nimport {\n collectTransactionIds,\n getTransaction,\n getTransferredAmountFromTxHash,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport {\n FALLBACK_HASH,\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants.js';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw.js';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw.js';\nimport { getRelayStatus } from './relay-api.js';\nimport { submitViaRelayExecute } from './relay-submit-execute.js';\nimport type {\n RelayCompletionOutcome,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\nconst RELAY_ERROR_PREFIX = 'Relay: ';\n\ntype RelaySubmitParams = {\n allParams: TransactionParams[];\n normalizedParams: TransactionParams[];\n};\n\nexport type RelaySubmitCalls = { calls: TransactionParams[] };\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n try {\n return await submitRelayQuotesInternal(request);\n } catch (error) {\n throw prefixError(error, RELAY_ERROR_PREFIX);\n }\n}\n\nexport async function getRelaySubmitCalls({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitCalls> {\n const { allParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n return { calls: allParams };\n}\n\nasync function submitRelayQuotesInternal(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n if (!quotes.length) {\n throw new Error('No quotes to submit');\n }\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n /* istanbul ignore if: concrete Relay submit paths return a hash/fallback or throw. */\n if (transactionHash === undefined) {\n throw new Error('Missing transaction hash');\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n let submittedSourceHash: Hex | undefined;\n\n // Shallow clone so the server-returned requestId can be written back (state is frozen by Immer).\n const mutableOriginal: RelayQuote = { ...quote.original };\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n submittedSourceHash = await submitTransactions(\n { ...quote, original: mutableOriginal },\n transaction,\n messenger,\n );\n }\n\n const completion = await waitForRelayCompletion(mutableOriginal, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n // Non-atomic flow: the quote bridged funds to `recipient` without embedding\n // the second leg. Now that Relay has settled, resolve the settled amount from\n // the on-chain Transfer log and submit the second-leg batch (approve + vault\n // deposit) sponsored from `recipient`.\n if (quote.request.atomic === false && completion.status === 'success') {\n const { transactionHash } = await submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n });\n\n return { transactionHash: transactionHash ?? completion.targetHash };\n }\n\n return { transactionHash: completion.targetHash };\n}\n\n/**\n * Runs the second leg of a non-atomic Relay quote. Resolves the settled amount\n * from the on-chain Transfer log, then submits the batch via\n * `submitMoneyAccountVaultDeposit`. Post-quote flows fetch pre-built calls via\n * the client `getPaymentOverrideData` callback; non-post-quote flows fall\n * through to the transaction's own nested calls re-encoded via\n * `getAmountData`. Funds settled on `quote.request.recipient`, derived at\n * quote time by `resolveNonAtomicRecipient`.\n *\n * @param options - Submit options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used to read the settled amount when Relay skips polling on\n * same-chain flows.\n * @param options.transaction - Original transaction meta.\n * @returns Hash of the final submitted child transaction, if available.\n */\nasync function submitPostNonAtomic({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n transaction,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n transaction: TransactionMeta;\n}): Promise<{ transactionHash?: Hex }> {\n const sourceAmountRaw = await resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n });\n\n const override = quote.request.isPostQuote\n ? await buildPostQuoteDepositCalls({\n messenger,\n sourceAmountRaw,\n transaction,\n quote,\n })\n : undefined;\n\n const recipient =\n override?.recipient ?? quote.request.recipient ?? quote.request.from;\n\n return submitMoneyAccountVaultDeposit({\n messenger,\n moneyAccountAddress: recipient,\n depositCalls: override?.calls,\n sourceAmountRaw,\n transaction,\n vaultDisabled: false,\n });\n}\n\n/**\n * Builds the post-completion batch for a post-quote flow whose parent\n * transaction carries no vault calls. Delegates to the client\n * `getPaymentOverrideData` callback with the settled amount.\n *\n * The callback MUST return a non-empty batch. Post-quote parent metas (e.g.\n * Perps/Predict withdraws) carry no vault-side nested calls, so falling back\n * to `getAmountData` in `resolveVaultDepositBatch` cannot recover the second\n * leg once Relay has already settled funds to the recipient. Throw eagerly so\n * the failure surfaces at the correct call site with an actionable message.\n *\n * The callback may also return the `recipient` that funds settled on, which the\n * caller prefers as the source of truth for the second-leg account.\n *\n * @param options - Build options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.sourceAmountRaw - Settled amount in raw units.\n * @param options.transaction - Original transaction meta.\n * @returns The batch calls and optional recipient.\n * @throws If the callback returns an empty batch.\n */\nasync function buildPostQuoteDepositCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n}): Promise<{ calls: BatchTransactionParams[]; recipient?: Hex }> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { decimals } = quote.original.details.currencyOut.currency;\n const amountHuman = new BigNumber(sourceAmountRaw)\n .shiftedBy(-decimals)\n .toFixed();\n\n const { calls, recipient } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: amountHuman,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (!calls.length) {\n throw new Error('Missing post-quote deposit calls');\n }\n\n return { calls, recipient };\n}\n\n/**\n * Resolves the actual amount that landed on the recipient after a Relay bridge.\n *\n * Cross-chain relays surface a real target-chain hash from polling; same-chain\n * relays skip polling (the `FALLBACK_HASH` placeholder) but the submitted\n * source transaction itself moved the funds, so its hash is read instead. In\n * both cases the exact settled amount comes from the on-chain Transfer log; a\n * read failure or missing amount throws rather than guessing, since using the\n * quote minimum would knowingly strand dust and defeat an EXACT_INPUT quote.\n *\n * Relay execute submissions return `FALLBACK_HASH` instead of a real source\n * hash, leaving nothing to read; only then is the quote's minimum output used\n * as the last available source.\n *\n * @param options - Resolution options.\n * @param options.completion - Outcome of `waitForRelayCompletion`.\n * @param options.messenger - Controller messenger.\n * @param options.quote - The Relay quote that was submitted.\n * @param options.submittedSourceHash - Hash of the submitted source\n * transaction, used when polling was skipped on same-chain flows.\n * @returns The raw (atomic) settled amount as a decimal string.\n */\nasync function resolveSettledAmount({\n completion,\n messenger,\n quote,\n submittedSourceHash,\n}: {\n completion: RelayCompletionOutcome;\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n submittedSourceHash?: Hex;\n}): Promise<string> {\n const recipient = (quote.request.recipient ?? quote.request.from) as\n | Hex\n | undefined;\n\n const isSameChain =\n quote.request.sourceChainId === quote.request.targetChainId;\n\n const hasPolledTargetHash = Boolean(\n completion.targetHash && completion.targetHash !== FALLBACK_HASH,\n );\n\n let settlementHash: Hex | undefined;\n\n if (hasPolledTargetHash) {\n settlementHash = completion.targetHash as Hex;\n } else if (isSameChain && submittedSourceHash !== FALLBACK_HASH) {\n settlementHash = submittedSourceHash;\n }\n\n if (recipient && settlementHash) {\n const { amountRaw: onChainAmount } = await getTransferredAmountFromTxHash({\n messenger,\n txHash: settlementHash,\n chainId: quote.request.targetChainId,\n tokenAddress: quote.request.targetTokenAddress,\n walletAddress: recipient,\n });\n\n if (!onChainAmount) {\n throw new Error(\n 'Cannot resolve settled amount from on-chain transaction',\n );\n }\n\n log('Resolved settled amount from on-chain transaction', {\n settlementHash,\n onChainAmount,\n });\n\n return onChainAmount;\n }\n\n const fallback = quote.original.details.currencyOut.minimumAmount;\n\n if (!fallback) {\n throw new Error('Cannot resolve post-completion amount');\n }\n\n log('Resolved settled amount from quote minimum output', {\n fallback,\n targetHash: completion.targetHash,\n });\n\n return fallback;\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex | undefined) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Request failed with status: ${status.status}`);\n }\n throw new Error(`Unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas:\n params.maxFeePerGas === undefined\n ? undefined\n : toHex(params.maxFeePerGas),\n maxPriorityFeePerGas:\n params.maxPriorityFeePerGas === undefined\n ? undefined\n : toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote && !quote.request.paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const { allParams, normalizedParams } = await buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n });\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\nfunction getRelayTransactionStepData(\n quote: TransactionPayQuote<RelayQuote>,\n): RelayTransactionStep['items'][0]['data'][] {\n const { steps } = quote.original;\n const supportedStepKinds = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !supportedStepKinds.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n\n return txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data)\n .filter((data): data is RelayTransactionStep['items'][0]['data'] =>\n isRelayTransactionStepData(data),\n );\n}\n\nasync function buildRelaySubmitParams({\n messenger,\n quote,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): Promise<RelaySubmitParams> {\n const params = getRelayTransactionStepData(quote);\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n // Non-atomic flows are excluded from the paymentOverride prepend: their\n // second leg is submitted separately by `submitPostNonAtomic` after\n // Relay completion, so prepending here would double-embed the vault deposit.\n // Cross-chain atomic flows (e.g. `moneyAccountWithdraw` on Monad settling\n // USDC on Arbitrum for Perps) still need the source-side vault withdraw +\n // transfer prepended here so Relay has funds to bridge.\n const isNonAtomic = quote.request.atomic === false;\n\n let allParams = normalizedParams;\n\n if (quote.request.paymentOverride && !isNonAtomic) {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideTxs } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (overrideTxs.length > 0) {\n allParams = [\n ...(overrideTxs as TransactionParams[]),\n ...normalizedParams,\n ];\n }\n } else if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(\n transaction,\n messenger,\n normalizedParams[0],\n )\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n maxFeePerGas: normalizedParams[0]?.maxFeePerGas,\n maxPriorityFeePerGas: normalizedParams[0]?.maxPriorityFeePerGas,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n return { allParams, normalizedParams };\n}\n\nfunction isRelayTransactionStepData(\n data: RelayTransactionStep['items'][0]['data'],\n): data is RelayTransactionStep['items'][0]['data'] {\n const maybeStepData = data as { to?: unknown };\n return maybeStepData.to !== undefined;\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @param relayParams - Optional relay params to copy gas fee fields from.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n relayParams?: TransactionParams,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n maxFeePerGas: relayParams?.maxFeePerGas,\n maxPriorityFeePerGas: relayParams?.maxPriorityFeePerGas,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const isSourceGasFeeSponsored =\n transaction.isGasFeeSponsored &&\n quote.request.sourceChainId === transaction.chainId &&\n quote.request.targetChainId === transaction.chainId;\n\n const gasFeeToken =\n !isSourceGasFeeSponsored && quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n // Single-tx keeps address/chainId only — TransactionController re-signs with\n // `from`. Batch may need a different signer (Money Account) than the batch\n // payer (EOA account override), so preserve the full pre-signed list.\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n const batchAuthorizationList =\n isSameChain &&\n hasAccountOverride &&\n quote.original.request.authorizationList?.length\n ? mapSignedQuoteAuthorizationList(\n quote.original.request.authorizationList,\n )\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n await messenger.call(\n 'TransactionController:addTransactionBatch',\n buildRelayTransactionBatchRequest({\n allParams,\n authorizationList: batchAuthorizationList,\n isGasFeeSponsored: isSourceGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n }),\n );\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (!transactionIds.length) {\n throw new Error('No transactions submitted');\n }\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\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 return hash as Hex;\n}\n\nfunction mapSignedQuoteAuthorizationList(\n authorizationList: NonNullable<RelayQuote['request']['authorizationList']>,\n): AuthorizationList {\n return authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n nonce: toHex(a.nonce),\n r: a.r,\n s: a.s,\n yParity: toHex(a.yParity),\n }));\n}\n\nfunction buildRelayTransactionBatchRequest({\n allParams,\n authorizationList,\n isGasFeeSponsored,\n messenger,\n normalizedParams,\n quote,\n transaction,\n}: {\n allParams: TransactionParams[];\n authorizationList?: AuthorizationList;\n isGasFeeSponsored: boolean | undefined;\n messenger: TransactionPayControllerMessenger;\n normalizedParams: TransactionParams[];\n quote: TransactionPayQuote<RelayQuote>;\n transaction: TransactionMeta;\n}): TransactionBatchRequest {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { metamask } = quote.original;\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n const gasFeeToken = quote.fees?.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n const gasLimit7702 = getGasLimit7702(quote);\n\n return {\n from,\n ...(authorizationList?.length ? { authorizationList } : {}),\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n isGasFeeSponsored,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions: buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits: metamask.gasLimits,\n normalizedParams,\n transaction,\n }),\n };\n}\n\nfunction buildRelayBatchTransactions({\n allParams,\n gasLimit7702,\n gasLimits,\n normalizedParams,\n transaction,\n}: {\n allParams: TransactionParams[];\n gasLimit7702?: Hex;\n gasLimits: number[];\n normalizedParams: TransactionParams[];\n transaction: TransactionMeta;\n}): TransactionBatchSingleRequest[] {\n const prependCount = allParams.length - normalizedParams.length;\n\n return allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n prependCount,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n}\n\nfunction getGasLimit7702(\n quote: TransactionPayQuote<RelayQuote>,\n): Hex | undefined {\n const { gasLimits, is7702 } = quote.original.metamask;\n const gasLimit = gasLimits[0];\n\n return is7702 && gasLimit !== undefined ? toHex(gasLimit) : undefined;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param prependCount - Number of non-relay txs prepended to the batch.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for prepended indices).\n * @param relayParamCount - Number of relay-only params (excludes prepended txs).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n prependCount: number,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n if (prependCount > 0 && index < prependCount) {\n return originalType;\n }\n\n const relayIndex = index - prependCount;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/transaction-pay-controller",
|
|
3
|
-
"version": "26.2.
|
|
3
|
+
"version": "26.2.2-preview-72a1eb691",
|
|
4
4
|
"description": "Manages alternate payment strategies to provide required funds for transactions in MetaMask",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@ethersproject/contracts": "^5.7.0",
|
|
61
61
|
"@ethersproject/providers": "^5.7.0",
|
|
62
62
|
"@metamask/assets-controller": "^13.1.0",
|
|
63
|
-
"@metamask/assets-controllers": "^110.1.
|
|
63
|
+
"@metamask/assets-controllers": "^110.1.1",
|
|
64
64
|
"@metamask/base-controller": "^9.1.0",
|
|
65
65
|
"@metamask/controller-utils": "^12.3.0",
|
|
66
66
|
"@metamask/gas-fee-controller": "^26.3.1",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@metamask/messenger": "^2.0.0",
|
|
69
69
|
"@metamask/metamask-eth-abis": "^3.1.1",
|
|
70
70
|
"@metamask/network-controller": "^35.0.1",
|
|
71
|
-
"@metamask/ramps-controller": "^
|
|
71
|
+
"@metamask/ramps-controller": "^20.0.0",
|
|
72
72
|
"@metamask/remote-feature-flag-controller": "^5.0.0",
|
|
73
73
|
"@metamask/sentinel-api-service": "^1.0.0",
|
|
74
74
|
"@metamask/transaction-controller": "^69.4.0",
|