@metamask-previews/transaction-pay-controller 30.2.0-preview-601bac5ab → 30.3.0-preview-56cdd31f1
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 +15 -1
- package/dist/strategy/across/across-submit.js +7 -1
- package/dist/strategy/across/across-submit.js.map +1 -1
- package/dist/strategy/server/server-submit.js +6 -2
- package/dist/strategy/server/server-submit.js.map +1 -1
- package/dist/utils/quote-gas.d.ts +1 -1
- package/dist/utils/quote-gas.js +10 -6
- package/dist/utils/quote-gas.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [30.3.0]
|
|
11
|
+
|
|
10
12
|
### Added
|
|
11
13
|
|
|
12
14
|
- Add support for Node.js 26 ([#10981](https://github.com/MetaMask/core/pull/10981))
|
|
13
15
|
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Read `mode` from the `TransactionController:estimateGasBatch` result to detect a combined EIP-7702 gas limit, instead of inferring it from the number of gas limits, falling back to the number of gas limits if `mode` is missing ([#10790](https://github.com/MetaMask/core/pull/10790))
|
|
19
|
+
- Bump `@metamask/ramps-controller` from `^27.1.0` to `^27.2.0` ([#11092](https://github.com/MetaMask/core/pull/11092))
|
|
20
|
+
- Bump `@metamask/utils` from `^12.0.0` to `^12.0.1` ([#11107](https://github.com/MetaMask/core/pull/11107))
|
|
21
|
+
- Bump `@metamask/assets-controller` from `^19.1.0` to `^20.0.0` ([#11115](https://github.com/MetaMask/core/pull/11115))
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Stop copying the outer EIP-7702 gas limit into the `gas` of each nested transaction when submitting a Server quote as an EIP-7702 batch, as nested gas is not supported in EIP-7702 batches ([#10790](https://github.com/MetaMask/core/pull/10790))
|
|
26
|
+
|
|
14
27
|
## [30.2.0]
|
|
15
28
|
|
|
16
29
|
### Added
|
|
@@ -1735,7 +1748,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1735
1748
|
|
|
1736
1749
|
- Initial release ([#6820](https://github.com/MetaMask/core/pull/6820))
|
|
1737
1750
|
|
|
1738
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@30.
|
|
1751
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@30.3.0...HEAD
|
|
1752
|
+
[30.3.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@30.2.0...@metamask/transaction-pay-controller@30.3.0
|
|
1739
1753
|
[30.2.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@30.1.0...@metamask/transaction-pay-controller@30.2.0
|
|
1740
1754
|
[30.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@30.0.3...@metamask/transaction-pay-controller@30.1.0
|
|
1741
1755
|
[30.0.3]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@30.0.2...@metamask/transaction-pay-controller@30.0.3
|
|
@@ -328,7 +328,13 @@ async function estimateSubmitBatchGasLimit7702({ chainId, from, messenger, order
|
|
|
328
328
|
from,
|
|
329
329
|
transactions: transactions.map(({ params }) => toBatchTransactionParams(params)),
|
|
330
330
|
});
|
|
331
|
-
|
|
331
|
+
// Older TransactionController versions return no `mode`, so detect a
|
|
332
|
+
// combined EIP-7702 gas limit from the number of gas limits instead.
|
|
333
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
334
|
+
const is7702Result = result.mode === undefined
|
|
335
|
+
? result.gasLimits.length === 1
|
|
336
|
+
: result.mode === 'eip7702';
|
|
337
|
+
if (!is7702Result) {
|
|
332
338
|
return undefined;
|
|
333
339
|
}
|
|
334
340
|
const gasLimit = Math.ceil(result.gasLimits[0] * getGasBuffer(messenger, chainId));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"across-submit.js","sourceRoot":"","sources":["../../../src/strategy/across/across-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ORIGIN_METAMASK,\n successfulFetch,\n toHex,\n} from '@metamask/controller-utils';\nimport {\n TransactionType,\n hasTransactionType,\n} from '@metamask/transaction-controller';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n TransactionParams,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types.js';\nimport { accountSupports7702 } from '../../utils/7702.js';\nimport { getPayStrategiesConfig } from '../../utils/feature-flags.js';\nimport { getGasBuffer } from '../../utils/feature-flags.js';\nimport {\n GasPaymentMode,\n logGasPaymentOutcome,\n resolveGasPayment,\n} from '../../utils/gas-payment.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport {\n getAcrossOrderedTransactions,\n getOriginalTransactionGas,\n} from './transactions.js';\nimport type { AcrossQuote } from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\nconst ACROSS_STATUS_POLL_INTERVAL = 1000;\n\ntype PreparedAcrossTransaction = {\n params: TransactionParams;\n type: TransactionMeta['type'];\n};\n\n/**\n * Submit Across quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitAcrossQuotes(\n request: PayStrategyExecuteRequest<AcrossQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\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 return { transactionHash };\n}\n\nasync function executeSingleQuote(\n quote: TransactionPayQuote<AcrossQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\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 const acrossDepositType = getAcrossDepositType(transaction);\n const transactionHash = await submitTransactions(\n quote,\n transaction,\n acrossDepositType,\n messenger,\n );\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Across submission',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash };\n}\n\n/**\n * Submit transactions for an Across quote.\n *\n * @param quote - Across quote.\n * @param parentTransaction - Parent transaction.\n * @param acrossDepositType - Transaction type used for the swap/deposit step.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction, if available.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<AcrossQuote>,\n parentTransaction: TransactionMeta,\n acrossDepositType: TransactionType,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex | undefined> {\n const { swapTx } = quote.original.quote;\n const { gasLimits: quoteGasLimits, is7702 } = quote.original.metamask;\n const { from, sourceTokenAddress } = quote.request;\n const chainId = toHex(swapTx.chainId);\n\n // Across has no relayer-paid delegation flow and is never sponsored, so the\n // only lift available is the gas station collecting gas in the source token.\n const gasPayment = resolveGasPayment({\n isSourceGasFeeToken: quote.fees.isSourceGasFeeToken,\n sourceTokenAddress,\n });\n const isGasFeeTokenPayment = gasPayment.mode === GasPaymentMode.GasFeeToken;\n\n const orderedTransactions = getAcrossOrderedTransactions({\n quote: quote.original.quote,\n swapType: acrossDepositType,\n });\n const shouldPrependOriginalTransaction =\n quote.request.isPostQuote === true &&\n parentTransaction.txParams.to !== undefined;\n const hasPrependedOriginalGasLimit =\n shouldPrependOriginalTransaction &&\n !is7702 &&\n quoteGasLimits.length > orderedTransactions.length;\n const gasLimitOffset = hasPrependedOriginalGasLimit ? 1 : 0;\n const transactionCount =\n orderedTransactions.length + (shouldPrependOriginalTransaction ? 1 : 0);\n\n const networkClientId = getNetworkClientId(messenger, chainId);\n\n const is7702Batch = is7702 && transactionCount > 1;\n const canUseQuotedBatchGasLimit =\n is7702Batch &&\n (!shouldPrependOriginalTransaction ||\n hasOriginalTransactionGas(parentTransaction));\n const batchGasLimit = canUseQuotedBatchGasLimit\n ? quoteGasLimits[0]?.max\n : undefined;\n\n if (canUseQuotedBatchGasLimit && batchGasLimit === undefined) {\n throw new Error('Missing quote gas limit for Across 7702 batch');\n }\n\n const quotedGasLimit7702 =\n batchGasLimit === undefined ? undefined : toHex(batchGasLimit);\n const parentHasAuthorizationList = Boolean(\n parentTransaction.txParams.authorizationList?.length,\n );\n\n const shouldUseGasFeeToken7702Submit = shouldEstimate7702SubmitBatch({\n isGasFeeTokenPayment,\n parentTransaction,\n quote,\n })\n ? accountSupports7702(messenger, from)\n : false;\n const shouldUse7702Submit = [\n Boolean(quotedGasLimit7702),\n is7702Batch,\n parentHasAuthorizationList,\n shouldUseGasFeeToken7702Submit,\n ].some(Boolean);\n\n const shouldEstimateGasLimit7702 = !quotedGasLimit7702 && shouldUse7702Submit;\n\n const estimatedGasLimit7702 = shouldEstimateGasLimit7702\n ? await estimateSubmitBatchGasLimit7702({\n chainId,\n from,\n messenger,\n orderedTransactions,\n parentTransaction,\n shouldPrependOriginalTransaction,\n })\n : undefined;\n\n const gasLimit7702 = quotedGasLimit7702 ?? estimatedGasLimit7702;\n const submitAs7702 = shouldUse7702Submit || Boolean(gasLimit7702);\n\n const acrossTransactions: PreparedAcrossTransaction[] =\n orderedTransactions.map((transaction, index) => {\n const gasLimit = submitAs7702\n ? undefined\n : quoteGasLimits[index + gasLimitOffset]?.max;\n\n if (gasLimit === undefined && !submitAs7702) {\n const quoteGasIndex = index + gasLimitOffset;\n const errorMessage =\n transaction.kind === 'approval'\n ? `Missing quote gas limit for Across approval transaction at index ${quoteGasIndex}`\n : 'Missing quote gas limit for Across swap transaction';\n\n throw new Error(errorMessage);\n }\n\n return {\n params: buildTransactionParams(from, {\n chainId: transaction.chainId,\n data: transaction.data,\n gasLimit,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n to: transaction.to,\n value: transaction.value,\n }),\n type: transaction.type ?? acrossDepositType,\n };\n });\n const originalTransaction = shouldPrependOriginalTransaction\n ? [\n buildOriginalTransaction(\n parentTransaction,\n submitAs7702 || !hasPrependedOriginalGasLimit\n ? undefined\n : quoteGasLimits[0]?.max,\n ),\n ]\n : [];\n const transactions = [...originalTransaction, ...acrossTransactions];\n\n const transactionIds: string[] = [];\n\n const { end } = collectTransactionIds(\n chainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: parentTransaction.id,\n messenger,\n note: 'Add required transaction ID from Across 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 const { excludeNativeTokenForFee, gasFeeToken } = gasPayment;\n\n try {\n if (transactions.length === 1) {\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactions[0].params,\n {\n excludeNativeTokenForFee,\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n type: transactions[0].type,\n },\n );\n } else {\n const batchTransactions = transactions.map(({ params, type }) => ({\n params: toBatchTransactionParams(params),\n type,\n }));\n\n await messenger.call('TransactionController:addTransactionBatch', {\n disable7702: !submitAs7702,\n disableHook: submitAs7702,\n disableSequential: submitAs7702,\n excludeNativeTokenForFee,\n from,\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n transactions: batchTransactions,\n });\n }\n } finally {\n end();\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 logGasPaymentOutcome(\n gasPayment,\n transactionIds.map((txId) => getTransaction(txId, messenger)),\n );\n\n const hash = transactionIds.length\n ? getTransaction(transactionIds.slice(-1)[0], messenger)?.hash\n : undefined;\n\n return await waitForAcrossCompletion(hash as Hex | undefined, messenger);\n}\n\ntype AcrossStatusResponse = {\n depositId?: number | string;\n depositTxnRef?: Hex;\n status?: string;\n destinationTxHash?: Hex;\n fillTxnRef?: Hex;\n fillTxHash?: Hex;\n txHash?: Hex;\n};\n\n/**\n * Poll Across until a submitted deposit reaches a terminal status.\n *\n * @param transactionHash - Source-chain deposit transaction hash.\n * @param messenger - Controller messenger.\n * @returns Destination/fill transaction hash when available, otherwise the source hash.\n */\nasync function waitForAcrossCompletion(\n transactionHash: Hex | undefined,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex | undefined> {\n if (!transactionHash) {\n return transactionHash;\n }\n\n const config = getPayStrategiesConfig(messenger);\n const params = new URLSearchParams({\n depositTxnRef: transactionHash,\n });\n const url = `${config.across.apiBase}/deposit/status?${params.toString()}`;\n\n let attempt = 0;\n\n while (true) {\n attempt += 1;\n let status: AcrossStatusResponse;\n\n try {\n const response = await successfulFetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n });\n status = (await response.json()) as AcrossStatusResponse;\n } catch (error) {\n log('Across status polling request failed', {\n attempt,\n error: String(error),\n transactionHash,\n });\n\n await new Promise((resolve) =>\n setTimeout(resolve, ACROSS_STATUS_POLL_INTERVAL),\n );\n continue;\n }\n\n const normalizedStatus = status.status?.toLowerCase();\n\n log('Polled Across status', {\n attempt,\n status: normalizedStatus,\n transactionHash,\n });\n\n if (\n normalizedStatus &&\n ['completed', 'filled', 'success'].includes(normalizedStatus)\n ) {\n return (\n status.destinationTxHash ??\n status.fillTxnRef ??\n status.fillTxHash ??\n status.txHash ??\n transactionHash\n );\n }\n\n if (\n normalizedStatus &&\n ['error', 'failed', 'refund', 'refunded'].includes(normalizedStatus)\n ) {\n throw new Error(`Across request failed with status: ${normalizedStatus}`);\n }\n\n await new Promise((resolve) =>\n setTimeout(resolve, ACROSS_STATUS_POLL_INTERVAL),\n );\n }\n}\n\n/**\n * Check whether submit should estimate a 7702 batch gas limit.\n *\n * This is needed for Predict withdraw post-quote flows that pay source-chain\n * gas with the source token, because the final submit batch can differ from the\n * batch shape that Across quoted.\n *\n * @param args - Check arguments.\n * @param args.isGasFeeTokenPayment - Whether source-chain gas is paid with a gas fee token.\n * @param args.parentTransaction - Original transaction metadata.\n * @param args.quote - Across quote selected for execution.\n * @returns Whether submit should try to estimate the final 7702 batch gas.\n */\nfunction shouldEstimate7702SubmitBatch({\n isGasFeeTokenPayment,\n parentTransaction,\n quote,\n}: {\n isGasFeeTokenPayment: boolean;\n parentTransaction: TransactionMeta;\n quote: TransactionPayQuote<AcrossQuote>;\n}): boolean {\n return (\n hasTransactionType(parentTransaction, [TransactionType.predictWithdraw]) &&\n quote.request.isPostQuote === true &&\n isGasFeeTokenPayment\n );\n}\n\n/**\n * Estimate the 7702 batch gas limit for the actual submit payload.\n *\n * Quotes can contain a combined 7702 gas limit that only covered the Across\n * approval/swap legs. When submit prepends the original transaction, estimate\n * the final batch shape so the gas limit covers every submitted leg.\n *\n * @param args - Estimation arguments.\n * @param args.chainId - Source chain ID.\n * @param args.from - Sender address.\n * @param args.messenger - Controller messenger.\n * @param args.orderedTransactions - Across approval/swap legs in submission order.\n * @param args.parentTransaction - Original transaction that may be prepended.\n * @param args.shouldPrependOriginalTransaction - Whether to include the original transaction in the estimate.\n * @returns Hex gas limit, or `undefined` when estimation is unavailable.\n */\nasync function estimateSubmitBatchGasLimit7702({\n chainId,\n from,\n messenger,\n orderedTransactions,\n parentTransaction,\n shouldPrependOriginalTransaction,\n}: {\n chainId: Hex;\n from: Hex;\n messenger: TransactionPayControllerMessenger;\n orderedTransactions: ReturnType<typeof getAcrossOrderedTransactions>;\n parentTransaction: TransactionMeta;\n shouldPrependOriginalTransaction: boolean;\n}): Promise<Hex | undefined> {\n if (!accountSupports7702(messenger, from)) {\n return undefined;\n }\n\n const originalTransaction = shouldPrependOriginalTransaction\n ? [buildOriginalTransaction(parentTransaction)]\n : [];\n\n const acrossTransactions = orderedTransactions.map((transaction) => ({\n params: buildTransactionParams(from, {\n chainId: transaction.chainId,\n data: transaction.data,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n to: transaction.to,\n value: transaction.value,\n }),\n type: transaction.type,\n }));\n\n const transactions = [...originalTransaction, ...acrossTransactions];\n\n try {\n const result = await messenger.call(\n 'TransactionController:estimateGasBatch',\n {\n chainId,\n from,\n transactions: transactions.map(({ params }) =>\n toBatchTransactionParams(params),\n ),\n },\n );\n\n if (result.gasLimits.length !== 1) {\n return undefined;\n }\n\n const gasLimit = Math.ceil(\n result.gasLimits[0] * getGasBuffer(messenger, chainId),\n );\n\n return toHex(gasLimit);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build the original parent transaction as a prepared batch leg.\n *\n * @param transaction - Original transaction metadata.\n * @param gasLimit - Optional gas limit to pin on the original leg.\n * @returns Prepared transaction params and transaction type for the original leg.\n */\nfunction buildOriginalTransaction(\n transaction: TransactionMeta,\n gasLimit?: number,\n): PreparedAcrossTransaction {\n return {\n params: {\n data: transaction.txParams.data,\n from: transaction.txParams.from,\n gas: gasLimit === undefined ? undefined : toHex(gasLimit),\n to: transaction.txParams.to,\n value: transaction.txParams.value,\n },\n type: getOriginalTransactionType(transaction),\n };\n}\n\n/**\n * Get the transaction type to use for the original batch leg.\n *\n * @param transaction - Original transaction metadata.\n * @returns `predictWithdraw` for Predict withdrawals; otherwise the original type.\n */\nfunction getOriginalTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (hasTransactionType(transaction, [TransactionType.predictWithdraw])) {\n return TransactionType.predictWithdraw;\n }\n\n return transaction.type;\n}\n\n/**\n * Check whether the original transaction already has a usable gas limit.\n *\n * @param transaction - Original transaction metadata.\n * @returns Whether the original or nested transaction gas is a positive integer.\n */\nfunction hasOriginalTransactionGas(transaction: TransactionMeta): boolean {\n return getOriginalTransactionGas(transaction) !== undefined;\n}\n\n/**\n * Get the transaction type for the Across bridge/deposit leg.\n *\n * @param transaction - Original parent transaction.\n * @returns Across-specific transaction type for known flows, or the original type.\n */\nfunction getAcrossDepositType(transaction: TransactionMeta): TransactionType {\n if (hasTransactionType(transaction, [TransactionType.predictWithdraw])) {\n return TransactionType.predictAcrossWithdraw;\n }\n\n switch (transaction.type) {\n case TransactionType.perpsDeposit:\n return TransactionType.perpsAcrossDeposit;\n case TransactionType.predictDeposit:\n return TransactionType.predictAcrossDeposit;\n case undefined:\n return TransactionType.perpsAcrossDeposit;\n default:\n return transaction.type;\n }\n}\n\n/**\n * Build TransactionController params for an Across approval or swap leg.\n *\n * @param from - Sender address.\n * @param params - Across transaction fields.\n * @param params.chainId - Source chain ID.\n * @param params.data - Transaction calldata.\n * @param params.gasLimit - Optional gas limit.\n * @param params.to - Recipient contract address.\n * @param params.value - Optional native value.\n * @param params.maxFeePerGas - Optional EIP-1559 max fee.\n * @param params.maxPriorityFeePerGas - Optional EIP-1559 priority fee.\n * @returns TransactionController params.\n */\nfunction buildTransactionParams(\n from: Hex,\n params: {\n chainId: number;\n data: Hex;\n gasLimit?: number;\n to: Hex;\n value?: Hex;\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n },\n): TransactionParams {\n const value = toHex(params.value ?? '0x0');\n\n return {\n data: params.data,\n from,\n gas: params.gasLimit === undefined ? undefined : toHex(params.gasLimit),\n maxFeePerGas: normalizeOptionalHex(params.maxFeePerGas),\n maxPriorityFeePerGas: normalizeOptionalHex(params.maxPriorityFeePerGas),\n to: params.to,\n value,\n };\n}\n\n/**\n * Normalize an optional numeric string or hex string into a hex value.\n *\n * @param value - Optional value to normalize.\n * @returns Hex value, or `undefined` when no value is provided.\n */\nfunction normalizeOptionalHex(value?: string): Hex | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return toHex(value);\n}\n\n/**\n * Convert full TransactionController params into batch transaction params.\n *\n * @param params - Transaction params.\n * @returns Batch-compatible transaction params.\n */\nfunction toBatchTransactionParams(\n params: TransactionParams,\n): BatchTransactionParams {\n return {\n data: params.data as Hex | undefined,\n gas: params.gas as Hex | undefined,\n maxFeePerGas: params.maxFeePerGas as Hex | undefined,\n maxPriorityFeePerGas: params.maxPriorityFeePerGas as Hex | undefined,\n to: params.to as Hex | undefined,\n value: params.value as Hex | undefined,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"across-submit.js","sourceRoot":"","sources":["../../../src/strategy/across/across-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ORIGIN_METAMASK,\n successfulFetch,\n toHex,\n} from '@metamask/controller-utils';\nimport {\n TransactionType,\n hasTransactionType,\n} from '@metamask/transaction-controller';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n TransactionParams,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types.js';\nimport { accountSupports7702 } from '../../utils/7702.js';\nimport { getPayStrategiesConfig } from '../../utils/feature-flags.js';\nimport { getGasBuffer } from '../../utils/feature-flags.js';\nimport {\n GasPaymentMode,\n logGasPaymentOutcome,\n resolveGasPayment,\n} from '../../utils/gas-payment.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport {\n getAcrossOrderedTransactions,\n getOriginalTransactionGas,\n} from './transactions.js';\nimport type { AcrossQuote } from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'across-strategy');\nconst ACROSS_STATUS_POLL_INTERVAL = 1000;\n\ntype PreparedAcrossTransaction = {\n params: TransactionParams;\n type: TransactionMeta['type'];\n};\n\n/**\n * Submit Across quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitAcrossQuotes(\n request: PayStrategyExecuteRequest<AcrossQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\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 return { transactionHash };\n}\n\nasync function executeSingleQuote(\n quote: TransactionPayQuote<AcrossQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\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 const acrossDepositType = getAcrossDepositType(transaction);\n const transactionHash = await submitTransactions(\n quote,\n transaction,\n acrossDepositType,\n messenger,\n );\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Across submission',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash };\n}\n\n/**\n * Submit transactions for an Across quote.\n *\n * @param quote - Across quote.\n * @param parentTransaction - Parent transaction.\n * @param acrossDepositType - Transaction type used for the swap/deposit step.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction, if available.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<AcrossQuote>,\n parentTransaction: TransactionMeta,\n acrossDepositType: TransactionType,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex | undefined> {\n const { swapTx } = quote.original.quote;\n const { gasLimits: quoteGasLimits, is7702 } = quote.original.metamask;\n const { from, sourceTokenAddress } = quote.request;\n const chainId = toHex(swapTx.chainId);\n\n // Across has no relayer-paid delegation flow and is never sponsored, so the\n // only lift available is the gas station collecting gas in the source token.\n const gasPayment = resolveGasPayment({\n isSourceGasFeeToken: quote.fees.isSourceGasFeeToken,\n sourceTokenAddress,\n });\n const isGasFeeTokenPayment = gasPayment.mode === GasPaymentMode.GasFeeToken;\n\n const orderedTransactions = getAcrossOrderedTransactions({\n quote: quote.original.quote,\n swapType: acrossDepositType,\n });\n const shouldPrependOriginalTransaction =\n quote.request.isPostQuote === true &&\n parentTransaction.txParams.to !== undefined;\n const hasPrependedOriginalGasLimit =\n shouldPrependOriginalTransaction &&\n !is7702 &&\n quoteGasLimits.length > orderedTransactions.length;\n const gasLimitOffset = hasPrependedOriginalGasLimit ? 1 : 0;\n const transactionCount =\n orderedTransactions.length + (shouldPrependOriginalTransaction ? 1 : 0);\n\n const networkClientId = getNetworkClientId(messenger, chainId);\n\n const is7702Batch = is7702 && transactionCount > 1;\n const canUseQuotedBatchGasLimit =\n is7702Batch &&\n (!shouldPrependOriginalTransaction ||\n hasOriginalTransactionGas(parentTransaction));\n const batchGasLimit = canUseQuotedBatchGasLimit\n ? quoteGasLimits[0]?.max\n : undefined;\n\n if (canUseQuotedBatchGasLimit && batchGasLimit === undefined) {\n throw new Error('Missing quote gas limit for Across 7702 batch');\n }\n\n const quotedGasLimit7702 =\n batchGasLimit === undefined ? undefined : toHex(batchGasLimit);\n const parentHasAuthorizationList = Boolean(\n parentTransaction.txParams.authorizationList?.length,\n );\n\n const shouldUseGasFeeToken7702Submit = shouldEstimate7702SubmitBatch({\n isGasFeeTokenPayment,\n parentTransaction,\n quote,\n })\n ? accountSupports7702(messenger, from)\n : false;\n const shouldUse7702Submit = [\n Boolean(quotedGasLimit7702),\n is7702Batch,\n parentHasAuthorizationList,\n shouldUseGasFeeToken7702Submit,\n ].some(Boolean);\n\n const shouldEstimateGasLimit7702 = !quotedGasLimit7702 && shouldUse7702Submit;\n\n const estimatedGasLimit7702 = shouldEstimateGasLimit7702\n ? await estimateSubmitBatchGasLimit7702({\n chainId,\n from,\n messenger,\n orderedTransactions,\n parentTransaction,\n shouldPrependOriginalTransaction,\n })\n : undefined;\n\n const gasLimit7702 = quotedGasLimit7702 ?? estimatedGasLimit7702;\n const submitAs7702 = shouldUse7702Submit || Boolean(gasLimit7702);\n\n const acrossTransactions: PreparedAcrossTransaction[] =\n orderedTransactions.map((transaction, index) => {\n const gasLimit = submitAs7702\n ? undefined\n : quoteGasLimits[index + gasLimitOffset]?.max;\n\n if (gasLimit === undefined && !submitAs7702) {\n const quoteGasIndex = index + gasLimitOffset;\n const errorMessage =\n transaction.kind === 'approval'\n ? `Missing quote gas limit for Across approval transaction at index ${quoteGasIndex}`\n : 'Missing quote gas limit for Across swap transaction';\n\n throw new Error(errorMessage);\n }\n\n return {\n params: buildTransactionParams(from, {\n chainId: transaction.chainId,\n data: transaction.data,\n gasLimit,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n to: transaction.to,\n value: transaction.value,\n }),\n type: transaction.type ?? acrossDepositType,\n };\n });\n const originalTransaction = shouldPrependOriginalTransaction\n ? [\n buildOriginalTransaction(\n parentTransaction,\n submitAs7702 || !hasPrependedOriginalGasLimit\n ? undefined\n : quoteGasLimits[0]?.max,\n ),\n ]\n : [];\n const transactions = [...originalTransaction, ...acrossTransactions];\n\n const transactionIds: string[] = [];\n\n const { end } = collectTransactionIds(\n chainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: parentTransaction.id,\n messenger,\n note: 'Add required transaction ID from Across 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 const { excludeNativeTokenForFee, gasFeeToken } = gasPayment;\n\n try {\n if (transactions.length === 1) {\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactions[0].params,\n {\n excludeNativeTokenForFee,\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n type: transactions[0].type,\n },\n );\n } else {\n const batchTransactions = transactions.map(({ params, type }) => ({\n params: toBatchTransactionParams(params),\n type,\n }));\n\n await messenger.call('TransactionController:addTransactionBatch', {\n disable7702: !submitAs7702,\n disableHook: submitAs7702,\n disableSequential: submitAs7702,\n excludeNativeTokenForFee,\n from,\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n transactions: batchTransactions,\n });\n }\n } finally {\n end();\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 logGasPaymentOutcome(\n gasPayment,\n transactionIds.map((txId) => getTransaction(txId, messenger)),\n );\n\n const hash = transactionIds.length\n ? getTransaction(transactionIds.slice(-1)[0], messenger)?.hash\n : undefined;\n\n return await waitForAcrossCompletion(hash as Hex | undefined, messenger);\n}\n\ntype AcrossStatusResponse = {\n depositId?: number | string;\n depositTxnRef?: Hex;\n status?: string;\n destinationTxHash?: Hex;\n fillTxnRef?: Hex;\n fillTxHash?: Hex;\n txHash?: Hex;\n};\n\n/**\n * Poll Across until a submitted deposit reaches a terminal status.\n *\n * @param transactionHash - Source-chain deposit transaction hash.\n * @param messenger - Controller messenger.\n * @returns Destination/fill transaction hash when available, otherwise the source hash.\n */\nasync function waitForAcrossCompletion(\n transactionHash: Hex | undefined,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex | undefined> {\n if (!transactionHash) {\n return transactionHash;\n }\n\n const config = getPayStrategiesConfig(messenger);\n const params = new URLSearchParams({\n depositTxnRef: transactionHash,\n });\n const url = `${config.across.apiBase}/deposit/status?${params.toString()}`;\n\n let attempt = 0;\n\n while (true) {\n attempt += 1;\n let status: AcrossStatusResponse;\n\n try {\n const response = await successfulFetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n });\n status = (await response.json()) as AcrossStatusResponse;\n } catch (error) {\n log('Across status polling request failed', {\n attempt,\n error: String(error),\n transactionHash,\n });\n\n await new Promise((resolve) =>\n setTimeout(resolve, ACROSS_STATUS_POLL_INTERVAL),\n );\n continue;\n }\n\n const normalizedStatus = status.status?.toLowerCase();\n\n log('Polled Across status', {\n attempt,\n status: normalizedStatus,\n transactionHash,\n });\n\n if (\n normalizedStatus &&\n ['completed', 'filled', 'success'].includes(normalizedStatus)\n ) {\n return (\n status.destinationTxHash ??\n status.fillTxnRef ??\n status.fillTxHash ??\n status.txHash ??\n transactionHash\n );\n }\n\n if (\n normalizedStatus &&\n ['error', 'failed', 'refund', 'refunded'].includes(normalizedStatus)\n ) {\n throw new Error(`Across request failed with status: ${normalizedStatus}`);\n }\n\n await new Promise((resolve) =>\n setTimeout(resolve, ACROSS_STATUS_POLL_INTERVAL),\n );\n }\n}\n\n/**\n * Check whether submit should estimate a 7702 batch gas limit.\n *\n * This is needed for Predict withdraw post-quote flows that pay source-chain\n * gas with the source token, because the final submit batch can differ from the\n * batch shape that Across quoted.\n *\n * @param args - Check arguments.\n * @param args.isGasFeeTokenPayment - Whether source-chain gas is paid with a gas fee token.\n * @param args.parentTransaction - Original transaction metadata.\n * @param args.quote - Across quote selected for execution.\n * @returns Whether submit should try to estimate the final 7702 batch gas.\n */\nfunction shouldEstimate7702SubmitBatch({\n isGasFeeTokenPayment,\n parentTransaction,\n quote,\n}: {\n isGasFeeTokenPayment: boolean;\n parentTransaction: TransactionMeta;\n quote: TransactionPayQuote<AcrossQuote>;\n}): boolean {\n return (\n hasTransactionType(parentTransaction, [TransactionType.predictWithdraw]) &&\n quote.request.isPostQuote === true &&\n isGasFeeTokenPayment\n );\n}\n\n/**\n * Estimate the 7702 batch gas limit for the actual submit payload.\n *\n * Quotes can contain a combined 7702 gas limit that only covered the Across\n * approval/swap legs. When submit prepends the original transaction, estimate\n * the final batch shape so the gas limit covers every submitted leg.\n *\n * @param args - Estimation arguments.\n * @param args.chainId - Source chain ID.\n * @param args.from - Sender address.\n * @param args.messenger - Controller messenger.\n * @param args.orderedTransactions - Across approval/swap legs in submission order.\n * @param args.parentTransaction - Original transaction that may be prepended.\n * @param args.shouldPrependOriginalTransaction - Whether to include the original transaction in the estimate.\n * @returns Hex gas limit, or `undefined` when estimation is unavailable.\n */\nasync function estimateSubmitBatchGasLimit7702({\n chainId,\n from,\n messenger,\n orderedTransactions,\n parentTransaction,\n shouldPrependOriginalTransaction,\n}: {\n chainId: Hex;\n from: Hex;\n messenger: TransactionPayControllerMessenger;\n orderedTransactions: ReturnType<typeof getAcrossOrderedTransactions>;\n parentTransaction: TransactionMeta;\n shouldPrependOriginalTransaction: boolean;\n}): Promise<Hex | undefined> {\n if (!accountSupports7702(messenger, from)) {\n return undefined;\n }\n\n const originalTransaction = shouldPrependOriginalTransaction\n ? [buildOriginalTransaction(parentTransaction)]\n : [];\n\n const acrossTransactions = orderedTransactions.map((transaction) => ({\n params: buildTransactionParams(from, {\n chainId: transaction.chainId,\n data: transaction.data,\n maxFeePerGas: transaction.maxFeePerGas,\n maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,\n to: transaction.to,\n value: transaction.value,\n }),\n type: transaction.type,\n }));\n\n const transactions = [...originalTransaction, ...acrossTransactions];\n\n try {\n const result = await messenger.call(\n 'TransactionController:estimateGasBatch',\n {\n chainId,\n from,\n transactions: transactions.map(({ params }) =>\n toBatchTransactionParams(params),\n ),\n },\n );\n\n // Older TransactionController versions return no `mode`, so detect a\n // combined EIP-7702 gas limit from the number of gas limits instead.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const is7702Result =\n result.mode === undefined\n ? result.gasLimits.length === 1\n : result.mode === 'eip7702';\n\n if (!is7702Result) {\n return undefined;\n }\n\n const gasLimit = Math.ceil(\n result.gasLimits[0] * getGasBuffer(messenger, chainId),\n );\n\n return toHex(gasLimit);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build the original parent transaction as a prepared batch leg.\n *\n * @param transaction - Original transaction metadata.\n * @param gasLimit - Optional gas limit to pin on the original leg.\n * @returns Prepared transaction params and transaction type for the original leg.\n */\nfunction buildOriginalTransaction(\n transaction: TransactionMeta,\n gasLimit?: number,\n): PreparedAcrossTransaction {\n return {\n params: {\n data: transaction.txParams.data,\n from: transaction.txParams.from,\n gas: gasLimit === undefined ? undefined : toHex(gasLimit),\n to: transaction.txParams.to,\n value: transaction.txParams.value,\n },\n type: getOriginalTransactionType(transaction),\n };\n}\n\n/**\n * Get the transaction type to use for the original batch leg.\n *\n * @param transaction - Original transaction metadata.\n * @returns `predictWithdraw` for Predict withdrawals; otherwise the original type.\n */\nfunction getOriginalTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (hasTransactionType(transaction, [TransactionType.predictWithdraw])) {\n return TransactionType.predictWithdraw;\n }\n\n return transaction.type;\n}\n\n/**\n * Check whether the original transaction already has a usable gas limit.\n *\n * @param transaction - Original transaction metadata.\n * @returns Whether the original or nested transaction gas is a positive integer.\n */\nfunction hasOriginalTransactionGas(transaction: TransactionMeta): boolean {\n return getOriginalTransactionGas(transaction) !== undefined;\n}\n\n/**\n * Get the transaction type for the Across bridge/deposit leg.\n *\n * @param transaction - Original parent transaction.\n * @returns Across-specific transaction type for known flows, or the original type.\n */\nfunction getAcrossDepositType(transaction: TransactionMeta): TransactionType {\n if (hasTransactionType(transaction, [TransactionType.predictWithdraw])) {\n return TransactionType.predictAcrossWithdraw;\n }\n\n switch (transaction.type) {\n case TransactionType.perpsDeposit:\n return TransactionType.perpsAcrossDeposit;\n case TransactionType.predictDeposit:\n return TransactionType.predictAcrossDeposit;\n case undefined:\n return TransactionType.perpsAcrossDeposit;\n default:\n return transaction.type;\n }\n}\n\n/**\n * Build TransactionController params for an Across approval or swap leg.\n *\n * @param from - Sender address.\n * @param params - Across transaction fields.\n * @param params.chainId - Source chain ID.\n * @param params.data - Transaction calldata.\n * @param params.gasLimit - Optional gas limit.\n * @param params.to - Recipient contract address.\n * @param params.value - Optional native value.\n * @param params.maxFeePerGas - Optional EIP-1559 max fee.\n * @param params.maxPriorityFeePerGas - Optional EIP-1559 priority fee.\n * @returns TransactionController params.\n */\nfunction buildTransactionParams(\n from: Hex,\n params: {\n chainId: number;\n data: Hex;\n gasLimit?: number;\n to: Hex;\n value?: Hex;\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n },\n): TransactionParams {\n const value = toHex(params.value ?? '0x0');\n\n return {\n data: params.data,\n from,\n gas: params.gasLimit === undefined ? undefined : toHex(params.gasLimit),\n maxFeePerGas: normalizeOptionalHex(params.maxFeePerGas),\n maxPriorityFeePerGas: normalizeOptionalHex(params.maxPriorityFeePerGas),\n to: params.to,\n value,\n };\n}\n\n/**\n * Normalize an optional numeric string or hex string into a hex value.\n *\n * @param value - Optional value to normalize.\n * @returns Hex value, or `undefined` when no value is provided.\n */\nfunction normalizeOptionalHex(value?: string): Hex | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return toHex(value);\n}\n\n/**\n * Convert full TransactionController params into batch transaction params.\n *\n * @param params - Transaction params.\n * @returns Batch-compatible transaction params.\n */\nfunction toBatchTransactionParams(\n params: TransactionParams,\n): BatchTransactionParams {\n return {\n data: params.data as Hex | undefined,\n gas: params.gas as Hex | undefined,\n maxFeePerGas: params.maxFeePerGas as Hex | undefined,\n maxPriorityFeePerGas: params.maxPriorityFeePerGas as Hex | undefined,\n to: params.to as Hex | undefined,\n value: params.value as Hex | undefined,\n };\n}\n"]}
|
|
@@ -592,8 +592,12 @@ async function submitViaTransactionController(quote, stepTransactions, messenger
|
|
|
592
592
|
// params.gas was already resolved correctly by buildStepTransaction
|
|
593
593
|
// (indexed by quote-step position), so use it directly. Indexing
|
|
594
594
|
// the step position into gasLimits would be wrong when payment-
|
|
595
|
-
// override or post-quote transactions are prepended.
|
|
596
|
-
|
|
595
|
+
// override or post-quote transactions are prepended. In an EIP-7702
|
|
596
|
+
// batch, the outer limit is passed as gasLimit7702 and nested gas is
|
|
597
|
+
// not supported, so it is omitted.
|
|
598
|
+
const gas = gasLimit7702 === undefined
|
|
599
|
+
? params.gas
|
|
600
|
+
: undefined;
|
|
597
601
|
return {
|
|
598
602
|
params: {
|
|
599
603
|
data: params.data,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-submit.js","sourceRoot":"","sources":["../../../src/strategy/server/server-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ORIGIN_METAMASK,\n successfulFetch,\n toHex,\n} from '@metamask/controller-utils';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n TransactionParams,\n TransactionType,\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 { accountSupports7702 } from '../../utils/7702.js';\nimport {\n getServerPollingInterval,\n getServerPollingTimeout,\n} from '../../utils/feature-flags.js';\nimport type { GasPayment } from '../../utils/gas-payment.js';\nimport {\n GasPaymentMode,\n logGasPaymentOutcome,\n resolveGasPayment,\n} from '../../utils/gas-payment.js';\nimport {\n submitPolymarketWithdraw,\n sweepPolymarketDepositWallet,\n} from '../../utils/polymarket/withdraw.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport { submitSecondLeg } from '../../utils/second-leg.js';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token.js';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport { RELAY_DEPOSIT_TYPES } from '../relay/constants.js';\nimport { getServerDepositData } from './deposit-step.js';\nimport { getServerStatus, submitServerIntent } from './server-api.js';\nimport type {\n ServerQuote,\n ServerSignatureStep,\n ServerTransactionStep,\n ServerStatusResponse,\n ServerSubmitRequest,\n} from './types.js';\nimport { ServerStatus } from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'server-strategy');\n\n/**\n * Placeholder returned when an intent confirms without reporting a\n * target-chain transaction hash, so there is no settlement to read amounts\n * from.\n */\nconst MISSING_TARGET_HASH = '0x' as Hex;\n\nconst DOMAIN_FIELD_MAP: Record<string, { name: string; type: string }> = {\n name: { name: 'name', type: 'string' },\n version: { name: 'version', type: 'string' },\n chainId: { name: 'chainId', type: 'uint256' },\n verifyingContract: { name: 'verifyingContract', type: 'address' },\n salt: { name: 'salt', type: 'bytes32' },\n};\n\n/**\n * A transaction to submit for a single quote step.\n *\n * The semantic transaction type is held alongside `params` rather than within\n * it, since `TransactionParams.type` is the EVM envelope type (`0x0` - `0x4`)\n * and is rejected by the transaction controller if given anything else.\n */\ntype StepTransaction = {\n params: TransactionParams;\n type?: TransactionType;\n};\n\n/** Terminal outcome of a server intent. */\ntype ServerCompletion = {\n status: ServerStatus.Confirmed | ServerStatus.Failed | ServerStatus.Refunded;\n targetHash?: Hex;\n};\n\nfunction isSignatureStep(\n step: ServerQuote['steps'][number],\n): step is ServerSignatureStep {\n return step.type === 'signature';\n}\n\nfunction isTransactionStep(\n step: ServerQuote['steps'][number],\n): step is ServerTransactionStep {\n return step.type === 'transaction';\n}\n\n/**\n * Submits server intent quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitServerQuotes(\n request: PayStrategyExecuteRequest<ServerQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing server quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleServerQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n return { transactionHash };\n}\n\nasync function executeSingleServerQuote(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single server quote', quote);\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 const isDepositWallet = Boolean(quote.request.isPolymarketDepositWallet);\n\n // Phase 1: off-chain signature steps (e.g. Relay authorize, HyperLiquid deposit).\n // Use quote.request.from (resolved accountOverride) not transaction.txParams.from.\n const signatureSteps = quote.original.steps.filter(isSignatureStep);\n\n for (const step of signatureSteps) {\n await submitSignatureStep(step, quote.request.from, messenger);\n }\n\n // Phase 2: on-chain transaction steps (if any). A deposit wallet withdraw\n // replaces them with an unwrap straight to the provider deposit address.\n let preSubmitUsdceBalance: bigint | undefined;\n\n if (isDepositWallet) {\n preSubmitUsdceBalance = await submitDepositWalletWithdraw(\n quote,\n messenger,\n transaction,\n );\n } else {\n await submitTransactionSteps(quote, messenger, transaction);\n }\n\n // Phase 3: poll until the intent settles on the target chain.\n const completion = await waitForServerCompletion(\n quote.original,\n messenger,\n transaction.id,\n );\n\n log('Server request completed', completion);\n\n // A deposit wallet sweeps leftover USDC.e back into pUSD whatever the\n // outcome, so a refund is restored before the failure is reported.\n if (preSubmitUsdceBalance !== undefined) {\n await sweepPolymarketDepositWallet({\n from: quote.request.from,\n isRefund: completion.status === ServerStatus.Refunded,\n messenger,\n preSubmitUsdceBalance,\n });\n }\n\n if (completion.status !== ServerStatus.Confirmed) {\n throw new Error(`Server intent ${completion.status.toLowerCase()}`);\n }\n\n const targetHash = completion.targetHash ?? MISSING_TARGET_HASH;\n\n // Phase 4: submit the calls the quote could not execute itself, now that the\n // funds have settled on the target chain.\n const secondLegHash = quote.requiresSecondLeg\n ? await submitServerSecondLeg(quote, messenger, transaction, targetHash)\n : undefined;\n\n // Only complete once every leg has landed, so a failed second leg does not\n // leave the parent transaction flagged as achieved.\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Server completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash: secondLegHash ?? targetHash };\n}\n\n/**\n * Submit the calls a server quote could not execute itself, from the account\n * the funds settled on.\n *\n * @param quote - Server quote.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @param targetHash - Hash of the settlement on the target chain.\n * @returns Hash of the second-leg transaction, if available.\n */\nasync function submitServerSecondLeg(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n targetHash: Hex | undefined,\n): Promise<Hex | undefined> {\n const { from, isPostQuote, recipient, targetChainId, targetTokenAddress } =\n quote.request;\n\n const { transactionHash } = await submitSecondLeg({\n chainId: targetChainId,\n from: recipient ?? from,\n // Post-quote flows carry no calls of their own, so the payment override\n // builds the batch for the settled amount.\n getCalls: isPostQuote\n ? async (sourceAmountRaw): Promise<BatchTransactionParams[]> =>\n await buildPaymentOverrideCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n })\n : undefined,\n messenger,\n settlementHash: targetHash === MISSING_TARGET_HASH ? undefined : targetHash,\n tokenAddress: targetTokenAddress,\n transaction,\n });\n\n return transactionHash;\n}\n\n/**\n * Build the second-leg batch from the payment override for the settled amount.\n *\n * @param options - Build options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - Server quote that settled.\n * @param options.sourceAmountRaw - Settled amount in raw units.\n * @param options.transaction - Original transaction meta.\n * @returns The batch calls.\n */\nasync function buildPaymentOverrideCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<ServerQuote>;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n}): Promise<BatchTransactionParams[]> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const amount = new BigNumber(sourceAmountRaw)\n .shiftedBy(-quote.original.output.decimals)\n .toFixed();\n\n const { calls } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n return calls;\n}\n\n/**\n * Unwrap the deposit wallet's pUSD straight to the provider deposit address.\n *\n * @param quote - Server quote.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns The deposit wallet's USDC.e balance before submission, so the sweep\n * can detect a refund.\n */\nasync function submitDepositWalletWithdraw(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<bigint> {\n const { preSubmitUsdceBalance, sourceHash } = await submitPolymarketWithdraw({\n depositData: getServerDepositData(quote.original),\n from: quote.request.from,\n messenger,\n sourceAmountRaw: quote.sourceAmount.raw,\n });\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from deposit wallet withdraw',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n\n return preSubmitUsdceBalance;\n}\n\n/**\n * Submit the on-chain transaction steps for a server quote.\n *\n * Validates the source balance, builds the complete set of transactions (including\n * any post-quote or payment-override prepends), then dispatches to the\n * gasless execute path or TransactionController depending on the quote.\n *\n * No-ops when the quote has no transaction steps (signature-only flows).\n *\n * @param quote - Server quote.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n */\nasync function submitTransactionSteps(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<void> {\n const transactionSteps = quote.original.steps.filter(isTransactionStep);\n\n if (transactionSteps.length === 0) {\n // Signature-only quotes (all steps are signature steps, no transaction\n // steps) have nothing to submit on-chain even when gasless is false.\n const hasSignatureSteps = quote.original.steps.some(isSignatureStep);\n if (!quote.original.gasless && !hasSignatureSteps) {\n throw new Error('Server quote has no steps to submit');\n }\n return;\n }\n\n const { isHyperliquidSource, isPostQuote, paymentOverride } = quote.request;\n\n // Skip balance check for HyperLiquid source flows (no on-chain debit),\n // post-quote flows (funds come from the Safe after the original tx executes),\n // and payment-override flows (funds are supplied by the override account).\n if (!isHyperliquidSource && !isPostQuote && !paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const stepTransactions = await buildStepTransactions(\n quote,\n transactionSteps,\n transaction,\n messenger,\n );\n\n const gasPayment = resolveGasPayment({\n isDelegated: quote.original.gasless,\n isSourceGasFeeToken: quote.fees.isSourceGasFeeToken,\n sourceTokenAddress: quote.request.sourceTokenAddress,\n sponsorship: {\n accountSupports7702: accountSupports7702(messenger, quote.request.from),\n request: quote.request,\n transaction,\n },\n });\n\n if (gasPayment.mode === GasPaymentMode.Delegation) {\n await submitViaServerExecute(\n quote,\n stepTransactions,\n messenger,\n transaction,\n );\n } else {\n await submitViaTransactionController(\n quote,\n stepTransactions,\n messenger,\n transaction,\n gasPayment,\n );\n }\n}\n\n/**\n * Build the complete flat array of transactions for on-chain submission.\n *\n * Converts server transaction steps to transactions, then prepends any\n * additional calls required by the payment override or post-quote flow. The\n * returned array is ready to pass directly to submitViaServerExecute or\n * submitViaTransactionController.\n *\n * @param quote - Server quote.\n * @param transactionSteps - Transaction steps from the quote (pre-filtered).\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Complete ordered array of transactions for submission.\n */\nasync function buildStepTransactions(\n quote: TransactionPayQuote<ServerQuote>,\n transactionSteps: ServerTransactionStep[],\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<StepTransaction[]> {\n const { atomic, from, isPostQuote, paymentOverride } = quote.request;\n const { gasLimits, maxFeePerGas, maxPriorityFeePerGas } =\n quote.original.client;\n const originalType = getEffectiveTransactionType(transaction);\n\n // Client gas limits are estimated in submission order, so any prepended\n // transactions come first and the quote steps take the trailing limits.\n const stepGasLimits = gasLimits.slice(\n Math.max(gasLimits.length - transactionSteps.length, 0),\n );\n\n const quoteStepTransactions = transactionSteps.map((step, i) =>\n buildStepTransaction(\n step,\n i,\n transactionSteps.length,\n from,\n stepGasLimits,\n maxFeePerGas,\n maxPriorityFeePerGas,\n originalType,\n ),\n );\n\n // Non-atomic flows run the override calls as a second leg once the funds\n // settle, so prepending them here would run them twice.\n if (paymentOverride && atomic !== false) {\n return prependPaymentOverrideTransactions(\n quoteStepTransactions,\n quote,\n transaction,\n messenger,\n );\n }\n\n if (isPostQuote && transaction.txParams.to) {\n return prependPostQuoteTransactions(\n quoteStepTransactions,\n quote,\n transaction,\n messenger,\n );\n }\n\n return quoteStepTransactions;\n}\n\n/**\n * Converts a single server transaction step to a transaction.\n *\n * @param step - The transaction step.\n * @param index - Zero-based position within the transaction steps array.\n * @param totalSteps - Total number of transaction steps (for type mapping).\n * @param from - Sender address.\n * @param gasLimits - Per-step gas limits from client-side estimation.\n * @param clientMaxFeePerGas - Client-side max fee per gas fallback.\n * @param clientMaxPriorityFeePerGas - Client-side max priority fee per gas fallback.\n * @param originalType - Effective type of the parent transaction.\n * @returns Normalized transaction for this step.\n */\nfunction buildStepTransaction(\n step: ServerTransactionStep,\n index: number,\n totalSteps: number,\n from: Hex,\n gasLimits: number[],\n clientMaxFeePerGas: string | undefined,\n clientMaxPriorityFeePerGas: string | undefined,\n originalType: TransactionMeta['type'],\n): StepTransaction {\n let gas: Hex | undefined;\n const gasLimit = gasLimits[index];\n\n if (gasLimit) {\n gas = toHex(gasLimit);\n } else if (step.gasLimit) {\n gas = toHex(step.gasLimit);\n }\n\n const resolvedMaxFeePerGas = step.maxFeePerGas ?? clientMaxFeePerGas;\n const resolvedMaxPriorityFeePerGas =\n step.maxPriorityFeePerGas ?? clientMaxPriorityFeePerGas;\n\n const params: TransactionParams = {\n data: step.data,\n from,\n gas,\n maxFeePerGas: resolvedMaxFeePerGas\n ? toHex(resolvedMaxFeePerGas)\n : undefined,\n maxPriorityFeePerGas: resolvedMaxPriorityFeePerGas\n ? toHex(resolvedMaxPriorityFeePerGas)\n : undefined,\n to: step.to,\n value: toHex(step.value),\n };\n\n const type = getTransactionType(index, totalSteps, originalType);\n\n log('Built transaction for step', {\n index,\n step: {\n gasLimit: step.gasLimit,\n maxFeePerGas: step.maxFeePerGas,\n maxPriorityFeePerGas: step.maxPriorityFeePerGas,\n value: step.value,\n },\n params: {\n gas: params.gas,\n maxFeePerGas: params.maxFeePerGas,\n maxPriorityFeePerGas: params.maxPriorityFeePerGas,\n type,\n value: params.value,\n },\n });\n\n return { params, type };\n}\n\n/**\n * Determine the relay deposit transaction type for a step at the given index.\n *\n * Single-step quotes always use the deposit type. In multi-step quotes the\n * first step is an approval and subsequent steps are deposits — matching the\n * Relay strategy's convention.\n *\n * @param index - Zero-based index of the step within the transaction step array.\n * @param totalSteps - Total number of transaction steps.\n * @param originalType - Effective type of the parent transaction.\n * @returns The mapped TransactionType for this step.\n */\nfunction getTransactionType(\n index: number,\n totalSteps: number,\n originalType: TransactionMeta['type'],\n): TransactionType {\n const depositType = getRelayDepositType(originalType);\n\n if (totalSteps === 1) {\n return depositType;\n }\n\n return index === 0 ? ('tokenMethodApprove' as TransactionType) : 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 ('relayDeposit' as TransactionType)\n );\n}\n\n/**\n * Get the effective transaction type, resolving through batch-type parent\n * transactions to find the nested perps/predict type.\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 !== ('batch' as TransactionType)) {\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\n/**\n * Prepend payment override calls before the quote transaction steps.\n *\n * For money-account payment override flows the override account supplies\n * the source funds. The override transactions must be batched ahead of the\n * deposit steps.\n *\n * @param quoteStepTransactions - Transactions already built from the quote steps.\n * @param quote - Server quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Combined transactions with override calls prepended.\n */\nasync function prependPaymentOverrideTransactions(\n quoteStepTransactions: StepTransaction[],\n quote: TransactionPayQuote<ServerQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<StepTransaction[]> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideCalls } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (!overrideCalls.length) {\n log('No payment override calls to prepend');\n return quoteStepTransactions;\n }\n\n log('Prepending payment override calls', { count: overrideCalls.length });\n\n const overrideTransactions = (overrideCalls as TransactionParams[]).map(\n (params) => ({\n params,\n }),\n );\n\n return [...overrideTransactions, ...quoteStepTransactions];\n}\n\n/**\n * Prepend the original transaction (or a delegation-wrapped version) before\n * the deposit steps for post-quote flows.\n *\n * In post-quote flows the source tokens are held in the Safe and only become\n * available after the original transaction executes as part of the batch.\n * When an accountOverride is active the override account cannot directly\n * execute the original call, so it is wrapped in a delegation transaction.\n *\n * @param quoteStepTransactions - Transactions already built from the quote steps.\n * @param quote - Server quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Combined transactions with the original tx prepended.\n */\nasync function prependPostQuoteTransactions(\n quoteStepTransactions: StepTransaction[],\n quote: TransactionPayQuote<ServerQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<StepTransaction[]> {\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n const { gasLimits, maxFeePerGas, maxPriorityFeePerGas } =\n quote.original.client;\n\n let prependedParams: TransactionParams;\n\n if (hasAccountOverride) {\n prependedParams = await buildDelegatedOriginalParams(\n transaction,\n messenger,\n );\n } else {\n prependedParams = {\n data: transaction.txParams.data,\n from: transaction.txParams.from,\n to: transaction.txParams.to,\n value: transaction.txParams.value,\n };\n }\n\n // Ensure the prepended tx carries the same fee caps as the quote steps so\n // it isn't submitted with undefined maxFeePerGas in a non-7702 batch.\n prependedParams.maxFeePerGas = maxFeePerGas ? toHex(maxFeePerGas) : undefined;\n prependedParams.maxPriorityFeePerGas = maxPriorityFeePerGas\n ? toHex(maxPriorityFeePerGas)\n : undefined;\n\n // The original transaction is estimated ahead of the quote steps, so it owns\n // the leading limit when each transaction has its own.\n if (gasLimits.length > quoteStepTransactions.length) {\n prependedParams.gas = toHex(gasLimits[0]);\n }\n\n log('Prepending post-quote original tx', { hasAccountOverride });\n\n return [{ params: prependedParams }, ...quoteStepTransactions];\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for post-quote original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Validate that the user's source token balance covers the quote's required\n * source amount before submitting on-chain.\n *\n * Reads the live balance via RPC rather than the cached state so it reflects\n * any concurrent spends. Throws fast with a clear error instead of letting\n * the on-chain transaction revert.\n *\n * @param quote - Server quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<ServerQuote>,\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 server deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\nasync function submitViaServerExecute(\n quote: TransactionPayQuote<ServerQuote>,\n stepTransactions: StepTransaction[],\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<void> {\n const { from, sourceChainId } = quote.request;\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n const nestedTransactions = stepTransactions.map(({ params }) => ({\n data: (params.data ?? '0x') as Hex,\n to: params.to as Hex,\n value: (params.value ?? '0x0') as Hex,\n }));\n\n const sourceCallTransaction = {\n ...transaction,\n chainId: sourceChainId,\n networkClientId,\n nestedTransactions,\n txParams: {\n ...transaction.txParams,\n from,\n },\n } as TransactionMeta;\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction: sourceCallTransaction },\n );\n\n log('Delegation result for server source calls', delegation);\n\n const submitBody: ServerSubmitRequest = {\n provider: quote.original.provider,\n id: quote.original.id,\n chainId: Number(sourceChainId),\n to: delegation.to,\n data: delegation.data,\n value: new BigNumber(delegation.value).toFixed(),\n ...(delegation.authorizationList?.length\n ? {\n authorizationList: delegation.authorizationList.map((auth) => ({\n chainId: Number(auth.chainId),\n address: auth.address,\n nonce: Number(auth.nonce),\n yParity: Number(auth.yParity),\n r: auth.r as Hex,\n s: auth.s as Hex,\n })),\n }\n : {}),\n };\n\n const submitResponse = await submitServerIntent(messenger, submitBody);\n\n if (!submitResponse.success) {\n throw new Error(\n `Server submit failed: ${submitResponse.error ?? 'unknown'}`,\n );\n }\n}\n\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<ServerQuote>,\n stepTransactions: StepTransaction[],\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n gasPayment: GasPayment,\n): Promise<void> {\n const { from, sourceChainId } = quote.request;\n const { gasLimits, is7702 } = quote.original.client;\n const { excludeNativeTokenForFee, gasFeeToken } = gasPayment;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Submitting via TransactionController', {\n from,\n gasFeeToken,\n is7702,\n networkClientId,\n transactionCount: stepTransactions.length,\n sourceChainId,\n });\n\n const transactionIds: string[] = [];\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from server submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n try {\n if (stepTransactions.length === 1) {\n const { params, type } = stepTransactions[0];\n\n const addTransactionOptions = {\n excludeNativeTokenForFee,\n gasFeeToken,\n isGasFeeSponsored: gasPayment.isGasFeeSponsored,\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n requireApproval: false,\n type,\n };\n\n log('Calling addTransaction', {\n params,\n options: addTransactionOptions,\n });\n\n await messenger.call(\n 'TransactionController:addTransaction',\n params,\n addTransactionOptions,\n );\n } else {\n const gasLimit7702 = is7702 ? toHex(gasLimits[0]) : undefined;\n\n const batchTransactions = stepTransactions.map(({ params, type }) => {\n // params.gas was already resolved correctly by buildStepTransaction\n // (indexed by quote-step position), so use it directly. Indexing\n // the step position into gasLimits would be wrong when payment-\n // override or post-quote transactions are prepended.\n const gas = (gasLimit7702 ?? params.gas) as Hex | undefined;\n\n return {\n params: {\n data: params.data as Hex,\n gas,\n maxFeePerGas: params.maxFeePerGas as Hex,\n maxPriorityFeePerGas: params.maxPriorityFeePerGas as Hex,\n to: params.to as Hex,\n value: params.value as Hex,\n },\n type,\n };\n });\n\n const addTransactionBatchOptions = {\n from,\n ...(gasLimit7702 === undefined\n ? { disable7702: true }\n : {\n disable7702: false,\n disableHook: true,\n disableSequential: true,\n gasLimit7702,\n }),\n excludeNativeTokenForFee,\n gasFeeToken,\n isGasFeeSponsored: gasPayment.isGasFeeSponsored,\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions: batchTransactions,\n };\n\n log('Calling addTransactionBatch', addTransactionBatchOptions);\n\n await messenger.call(\n 'TransactionController:addTransactionBatch',\n addTransactionBatchOptions,\n );\n }\n } finally {\n end();\n }\n\n log('Server transactions added', transactionIds);\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('Server transactions confirmed', transactionIds);\n\n logGasPaymentOutcome(\n gasPayment,\n transactionIds.map((txId) => getTransaction(txId, messenger)),\n );\n\n const lastId = transactionIds.at(-1);\n const sourceHash = lastId\n ? getTransaction(lastId, messenger)?.hash\n : undefined;\n\n if (sourceHash) {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from server transaction submission',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash as Hex;\n },\n );\n }\n}\n\nasync function submitSignatureStep(\n step: ServerSignatureStep,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { sign, post } = step;\n\n const typedData = {\n domain: sign.domain,\n types: {\n ...sign.types,\n EIP712Domain: deriveEIP712DomainType(sign.domain),\n },\n primaryType: sign.primaryType,\n message: sign.value,\n };\n\n log('Signing typed data for signature step', {\n primaryType: sign.primaryType,\n });\n\n const signature = await messenger.call(\n 'KeyringController:signTypedMessage',\n { from, data: JSON.stringify(typedData) },\n SignTypedDataVersion.V4,\n );\n\n await postSignatureStepResult(\n post.endpoint,\n post.method,\n post.body,\n signature,\n post.signatureFormat,\n );\n}\n\nasync function postSignatureStepResult(\n endpoint: string,\n method: string,\n body: Record<string, unknown>,\n signature: string,\n signatureFormat: 'queryParam' | 'rsv',\n): Promise<void> {\n let url = endpoint;\n let postBody: Record<string, unknown>;\n\n if (signatureFormat === 'queryParam') {\n url = `${endpoint}?signature=${signature}`;\n postBody = body;\n } else {\n // eslint-disable-next-line id-length\n const r = signature.slice(0, 66);\n // eslint-disable-next-line id-length\n const s = `0x${signature.slice(66, 130)}`;\n // eslint-disable-next-line id-length\n const v = parseInt(signature.slice(130, 132), 16);\n postBody = { ...body, signature: { r, s, v } };\n }\n\n log('Posting signature step result', { url, signatureFormat });\n\n let result: unknown;\n\n try {\n const response = await successfulFetch(url, {\n method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(postBody),\n });\n\n result = await response.json();\n } catch (error) {\n throw new Error(`Signature step POST failed: ${(error as Error).message}`);\n }\n\n log('Signature step POST response', result);\n\n // For rsv-format steps (HyperLiquid exchange endpoint) the response body\n // carries an explicit status field. Validate it here so a failed deposit\n // throws immediately rather than silently proceeding to the polling phase.\n if (signatureFormat === 'rsv') {\n const status = (result as { status?: string })?.status;\n\n if (status !== 'ok') {\n throw new Error(\n `Signature step rejected by server: ${JSON.stringify(result)}`,\n );\n }\n }\n}\n\nfunction deriveEIP712DomainType(\n domain: Record<string, unknown>,\n): { name: string; type: string }[] {\n return Object.keys(DOMAIN_FIELD_MAP)\n .filter((key) => Object.prototype.hasOwnProperty.call(domain, key))\n .map((key) => DOMAIN_FIELD_MAP[key]);\n}\n\n/**\n * Poll the server until the intent reaches a terminal status.\n *\n * Failures are returned rather than thrown so callers can clean up first, such\n * as sweeping a deposit wallet refund. Timeouts still throw.\n *\n * @param quote - Server quote being polled.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the parent transaction.\n * @returns The terminal status and the target-chain hash when reported.\n */\nasync function waitForServerCompletion(\n quote: ServerQuote,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n): Promise<ServerCompletion> {\n const pollingInterval = getServerPollingInterval(messenger);\n const pollingTimeout = getServerPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Server polling config', { pollingInterval, pollingTimeout });\n\n const startTime = Date.now();\n\n let lastStatus: string | undefined;\n let sourceHashEmitted = false;\n\n while (true) {\n let statusResponse: ServerStatusResponse | undefined;\n\n try {\n const tx = getTransaction(transactionId, messenger);\n\n statusResponse = await getServerStatus(messenger, {\n provider: quote.provider,\n id: quote.id,\n hash: tx?.metamaskPay?.sourceHash ?? tx?.hash,\n });\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (statusResponse) {\n lastStatus = statusResponse.status;\n log('Polled status', statusResponse.status, statusResponse);\n\n if (!sourceHashEmitted && statusResponse.sourceHash) {\n sourceHashEmitted = true;\n const { sourceHash } = statusResponse;\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Add source hash from server status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n }\n\n const { status, targetHash } = statusResponse;\n\n if (\n status === ServerStatus.Confirmed ||\n status === ServerStatus.Failed ||\n status === ServerStatus.Refunded\n ) {\n return { status, targetHash };\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n throw new Error(`Server polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server-submit.js","sourceRoot":"","sources":["../../../src/strategy/server/server-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ORIGIN_METAMASK,\n successfulFetch,\n toHex,\n} from '@metamask/controller-utils';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n TransactionParams,\n TransactionType,\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 { accountSupports7702 } from '../../utils/7702.js';\nimport {\n getServerPollingInterval,\n getServerPollingTimeout,\n} from '../../utils/feature-flags.js';\nimport type { GasPayment } from '../../utils/gas-payment.js';\nimport {\n GasPaymentMode,\n logGasPaymentOutcome,\n resolveGasPayment,\n} from '../../utils/gas-payment.js';\nimport {\n submitPolymarketWithdraw,\n sweepPolymarketDepositWallet,\n} from '../../utils/polymarket/withdraw.js';\nimport { getNetworkClientId } from '../../utils/provider.js';\nimport { submitSecondLeg } from '../../utils/second-leg.js';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token.js';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction.js';\nimport { RELAY_DEPOSIT_TYPES } from '../relay/constants.js';\nimport { getServerDepositData } from './deposit-step.js';\nimport { getServerStatus, submitServerIntent } from './server-api.js';\nimport type {\n ServerQuote,\n ServerSignatureStep,\n ServerTransactionStep,\n ServerStatusResponse,\n ServerSubmitRequest,\n} from './types.js';\nimport { ServerStatus } from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'server-strategy');\n\n/**\n * Placeholder returned when an intent confirms without reporting a\n * target-chain transaction hash, so there is no settlement to read amounts\n * from.\n */\nconst MISSING_TARGET_HASH = '0x' as Hex;\n\nconst DOMAIN_FIELD_MAP: Record<string, { name: string; type: string }> = {\n name: { name: 'name', type: 'string' },\n version: { name: 'version', type: 'string' },\n chainId: { name: 'chainId', type: 'uint256' },\n verifyingContract: { name: 'verifyingContract', type: 'address' },\n salt: { name: 'salt', type: 'bytes32' },\n};\n\n/**\n * A transaction to submit for a single quote step.\n *\n * The semantic transaction type is held alongside `params` rather than within\n * it, since `TransactionParams.type` is the EVM envelope type (`0x0` - `0x4`)\n * and is rejected by the transaction controller if given anything else.\n */\ntype StepTransaction = {\n params: TransactionParams;\n type?: TransactionType;\n};\n\n/** Terminal outcome of a server intent. */\ntype ServerCompletion = {\n status: ServerStatus.Confirmed | ServerStatus.Failed | ServerStatus.Refunded;\n targetHash?: Hex;\n};\n\nfunction isSignatureStep(\n step: ServerQuote['steps'][number],\n): step is ServerSignatureStep {\n return step.type === 'signature';\n}\n\nfunction isTransactionStep(\n step: ServerQuote['steps'][number],\n): step is ServerTransactionStep {\n return step.type === 'transaction';\n}\n\n/**\n * Submits server intent quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitServerQuotes(\n request: PayStrategyExecuteRequest<ServerQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing server quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleServerQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n return { transactionHash };\n}\n\nasync function executeSingleServerQuote(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single server quote', quote);\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 const isDepositWallet = Boolean(quote.request.isPolymarketDepositWallet);\n\n // Phase 1: off-chain signature steps (e.g. Relay authorize, HyperLiquid deposit).\n // Use quote.request.from (resolved accountOverride) not transaction.txParams.from.\n const signatureSteps = quote.original.steps.filter(isSignatureStep);\n\n for (const step of signatureSteps) {\n await submitSignatureStep(step, quote.request.from, messenger);\n }\n\n // Phase 2: on-chain transaction steps (if any). A deposit wallet withdraw\n // replaces them with an unwrap straight to the provider deposit address.\n let preSubmitUsdceBalance: bigint | undefined;\n\n if (isDepositWallet) {\n preSubmitUsdceBalance = await submitDepositWalletWithdraw(\n quote,\n messenger,\n transaction,\n );\n } else {\n await submitTransactionSteps(quote, messenger, transaction);\n }\n\n // Phase 3: poll until the intent settles on the target chain.\n const completion = await waitForServerCompletion(\n quote.original,\n messenger,\n transaction.id,\n );\n\n log('Server request completed', completion);\n\n // A deposit wallet sweeps leftover USDC.e back into pUSD whatever the\n // outcome, so a refund is restored before the failure is reported.\n if (preSubmitUsdceBalance !== undefined) {\n await sweepPolymarketDepositWallet({\n from: quote.request.from,\n isRefund: completion.status === ServerStatus.Refunded,\n messenger,\n preSubmitUsdceBalance,\n });\n }\n\n if (completion.status !== ServerStatus.Confirmed) {\n throw new Error(`Server intent ${completion.status.toLowerCase()}`);\n }\n\n const targetHash = completion.targetHash ?? MISSING_TARGET_HASH;\n\n // Phase 4: submit the calls the quote could not execute itself, now that the\n // funds have settled on the target chain.\n const secondLegHash = quote.requiresSecondLeg\n ? await submitServerSecondLeg(quote, messenger, transaction, targetHash)\n : undefined;\n\n // Only complete once every leg has landed, so a failed second leg does not\n // leave the parent transaction flagged as achieved.\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Server completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash: secondLegHash ?? targetHash };\n}\n\n/**\n * Submit the calls a server quote could not execute itself, from the account\n * the funds settled on.\n *\n * @param quote - Server quote.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @param targetHash - Hash of the settlement on the target chain.\n * @returns Hash of the second-leg transaction, if available.\n */\nasync function submitServerSecondLeg(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n targetHash: Hex | undefined,\n): Promise<Hex | undefined> {\n const { from, isPostQuote, recipient, targetChainId, targetTokenAddress } =\n quote.request;\n\n const { transactionHash } = await submitSecondLeg({\n chainId: targetChainId,\n from: recipient ?? from,\n // Post-quote flows carry no calls of their own, so the payment override\n // builds the batch for the settled amount.\n getCalls: isPostQuote\n ? async (sourceAmountRaw): Promise<BatchTransactionParams[]> =>\n await buildPaymentOverrideCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n })\n : undefined,\n messenger,\n settlementHash: targetHash === MISSING_TARGET_HASH ? undefined : targetHash,\n tokenAddress: targetTokenAddress,\n transaction,\n });\n\n return transactionHash;\n}\n\n/**\n * Build the second-leg batch from the payment override for the settled amount.\n *\n * @param options - Build options.\n * @param options.messenger - Controller messenger.\n * @param options.quote - Server quote that settled.\n * @param options.sourceAmountRaw - Settled amount in raw units.\n * @param options.transaction - Original transaction meta.\n * @returns The batch calls.\n */\nasync function buildPaymentOverrideCalls({\n messenger,\n quote,\n sourceAmountRaw,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n quote: TransactionPayQuote<ServerQuote>;\n sourceAmountRaw: string;\n transaction: TransactionMeta;\n}): Promise<BatchTransactionParams[]> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const amount = new BigNumber(sourceAmountRaw)\n .shiftedBy(-quote.original.output.decimals)\n .toFixed();\n\n const { calls } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n return calls;\n}\n\n/**\n * Unwrap the deposit wallet's pUSD straight to the provider deposit address.\n *\n * @param quote - Server quote.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns The deposit wallet's USDC.e balance before submission, so the sweep\n * can detect a refund.\n */\nasync function submitDepositWalletWithdraw(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<bigint> {\n const { preSubmitUsdceBalance, sourceHash } = await submitPolymarketWithdraw({\n depositData: getServerDepositData(quote.original),\n from: quote.request.from,\n messenger,\n sourceAmountRaw: quote.sourceAmount.raw,\n });\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from deposit wallet withdraw',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n\n return preSubmitUsdceBalance;\n}\n\n/**\n * Submit the on-chain transaction steps for a server quote.\n *\n * Validates the source balance, builds the complete set of transactions (including\n * any post-quote or payment-override prepends), then dispatches to the\n * gasless execute path or TransactionController depending on the quote.\n *\n * No-ops when the quote has no transaction steps (signature-only flows).\n *\n * @param quote - Server quote.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n */\nasync function submitTransactionSteps(\n quote: TransactionPayQuote<ServerQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<void> {\n const transactionSteps = quote.original.steps.filter(isTransactionStep);\n\n if (transactionSteps.length === 0) {\n // Signature-only quotes (all steps are signature steps, no transaction\n // steps) have nothing to submit on-chain even when gasless is false.\n const hasSignatureSteps = quote.original.steps.some(isSignatureStep);\n if (!quote.original.gasless && !hasSignatureSteps) {\n throw new Error('Server quote has no steps to submit');\n }\n return;\n }\n\n const { isHyperliquidSource, isPostQuote, paymentOverride } = quote.request;\n\n // Skip balance check for HyperLiquid source flows (no on-chain debit),\n // post-quote flows (funds come from the Safe after the original tx executes),\n // and payment-override flows (funds are supplied by the override account).\n if (!isHyperliquidSource && !isPostQuote && !paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const stepTransactions = await buildStepTransactions(\n quote,\n transactionSteps,\n transaction,\n messenger,\n );\n\n const gasPayment = resolveGasPayment({\n isDelegated: quote.original.gasless,\n isSourceGasFeeToken: quote.fees.isSourceGasFeeToken,\n sourceTokenAddress: quote.request.sourceTokenAddress,\n sponsorship: {\n accountSupports7702: accountSupports7702(messenger, quote.request.from),\n request: quote.request,\n transaction,\n },\n });\n\n if (gasPayment.mode === GasPaymentMode.Delegation) {\n await submitViaServerExecute(\n quote,\n stepTransactions,\n messenger,\n transaction,\n );\n } else {\n await submitViaTransactionController(\n quote,\n stepTransactions,\n messenger,\n transaction,\n gasPayment,\n );\n }\n}\n\n/**\n * Build the complete flat array of transactions for on-chain submission.\n *\n * Converts server transaction steps to transactions, then prepends any\n * additional calls required by the payment override or post-quote flow. The\n * returned array is ready to pass directly to submitViaServerExecute or\n * submitViaTransactionController.\n *\n * @param quote - Server quote.\n * @param transactionSteps - Transaction steps from the quote (pre-filtered).\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Complete ordered array of transactions for submission.\n */\nasync function buildStepTransactions(\n quote: TransactionPayQuote<ServerQuote>,\n transactionSteps: ServerTransactionStep[],\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<StepTransaction[]> {\n const { atomic, from, isPostQuote, paymentOverride } = quote.request;\n const { gasLimits, maxFeePerGas, maxPriorityFeePerGas } =\n quote.original.client;\n const originalType = getEffectiveTransactionType(transaction);\n\n // Client gas limits are estimated in submission order, so any prepended\n // transactions come first and the quote steps take the trailing limits.\n const stepGasLimits = gasLimits.slice(\n Math.max(gasLimits.length - transactionSteps.length, 0),\n );\n\n const quoteStepTransactions = transactionSteps.map((step, i) =>\n buildStepTransaction(\n step,\n i,\n transactionSteps.length,\n from,\n stepGasLimits,\n maxFeePerGas,\n maxPriorityFeePerGas,\n originalType,\n ),\n );\n\n // Non-atomic flows run the override calls as a second leg once the funds\n // settle, so prepending them here would run them twice.\n if (paymentOverride && atomic !== false) {\n return prependPaymentOverrideTransactions(\n quoteStepTransactions,\n quote,\n transaction,\n messenger,\n );\n }\n\n if (isPostQuote && transaction.txParams.to) {\n return prependPostQuoteTransactions(\n quoteStepTransactions,\n quote,\n transaction,\n messenger,\n );\n }\n\n return quoteStepTransactions;\n}\n\n/**\n * Converts a single server transaction step to a transaction.\n *\n * @param step - The transaction step.\n * @param index - Zero-based position within the transaction steps array.\n * @param totalSteps - Total number of transaction steps (for type mapping).\n * @param from - Sender address.\n * @param gasLimits - Per-step gas limits from client-side estimation.\n * @param clientMaxFeePerGas - Client-side max fee per gas fallback.\n * @param clientMaxPriorityFeePerGas - Client-side max priority fee per gas fallback.\n * @param originalType - Effective type of the parent transaction.\n * @returns Normalized transaction for this step.\n */\nfunction buildStepTransaction(\n step: ServerTransactionStep,\n index: number,\n totalSteps: number,\n from: Hex,\n gasLimits: number[],\n clientMaxFeePerGas: string | undefined,\n clientMaxPriorityFeePerGas: string | undefined,\n originalType: TransactionMeta['type'],\n): StepTransaction {\n let gas: Hex | undefined;\n const gasLimit = gasLimits[index];\n\n if (gasLimit) {\n gas = toHex(gasLimit);\n } else if (step.gasLimit) {\n gas = toHex(step.gasLimit);\n }\n\n const resolvedMaxFeePerGas = step.maxFeePerGas ?? clientMaxFeePerGas;\n const resolvedMaxPriorityFeePerGas =\n step.maxPriorityFeePerGas ?? clientMaxPriorityFeePerGas;\n\n const params: TransactionParams = {\n data: step.data,\n from,\n gas,\n maxFeePerGas: resolvedMaxFeePerGas\n ? toHex(resolvedMaxFeePerGas)\n : undefined,\n maxPriorityFeePerGas: resolvedMaxPriorityFeePerGas\n ? toHex(resolvedMaxPriorityFeePerGas)\n : undefined,\n to: step.to,\n value: toHex(step.value),\n };\n\n const type = getTransactionType(index, totalSteps, originalType);\n\n log('Built transaction for step', {\n index,\n step: {\n gasLimit: step.gasLimit,\n maxFeePerGas: step.maxFeePerGas,\n maxPriorityFeePerGas: step.maxPriorityFeePerGas,\n value: step.value,\n },\n params: {\n gas: params.gas,\n maxFeePerGas: params.maxFeePerGas,\n maxPriorityFeePerGas: params.maxPriorityFeePerGas,\n type,\n value: params.value,\n },\n });\n\n return { params, type };\n}\n\n/**\n * Determine the relay deposit transaction type for a step at the given index.\n *\n * Single-step quotes always use the deposit type. In multi-step quotes the\n * first step is an approval and subsequent steps are deposits — matching the\n * Relay strategy's convention.\n *\n * @param index - Zero-based index of the step within the transaction step array.\n * @param totalSteps - Total number of transaction steps.\n * @param originalType - Effective type of the parent transaction.\n * @returns The mapped TransactionType for this step.\n */\nfunction getTransactionType(\n index: number,\n totalSteps: number,\n originalType: TransactionMeta['type'],\n): TransactionType {\n const depositType = getRelayDepositType(originalType);\n\n if (totalSteps === 1) {\n return depositType;\n }\n\n return index === 0 ? ('tokenMethodApprove' as TransactionType) : 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 ('relayDeposit' as TransactionType)\n );\n}\n\n/**\n * Get the effective transaction type, resolving through batch-type parent\n * transactions to find the nested perps/predict type.\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 !== ('batch' as TransactionType)) {\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\n/**\n * Prepend payment override calls before the quote transaction steps.\n *\n * For money-account payment override flows the override account supplies\n * the source funds. The override transactions must be batched ahead of the\n * deposit steps.\n *\n * @param quoteStepTransactions - Transactions already built from the quote steps.\n * @param quote - Server quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Combined transactions with override calls prepended.\n */\nasync function prependPaymentOverrideTransactions(\n quoteStepTransactions: StepTransaction[],\n quote: TransactionPayQuote<ServerQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<StepTransaction[]> {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideCalls } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (!overrideCalls.length) {\n log('No payment override calls to prepend');\n return quoteStepTransactions;\n }\n\n log('Prepending payment override calls', { count: overrideCalls.length });\n\n const overrideTransactions = (overrideCalls as TransactionParams[]).map(\n (params) => ({\n params,\n }),\n );\n\n return [...overrideTransactions, ...quoteStepTransactions];\n}\n\n/**\n * Prepend the original transaction (or a delegation-wrapped version) before\n * the deposit steps for post-quote flows.\n *\n * In post-quote flows the source tokens are held in the Safe and only become\n * available after the original transaction executes as part of the batch.\n * When an accountOverride is active the override account cannot directly\n * execute the original call, so it is wrapped in a delegation transaction.\n *\n * @param quoteStepTransactions - Transactions already built from the quote steps.\n * @param quote - Server quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Combined transactions with the original tx prepended.\n */\nasync function prependPostQuoteTransactions(\n quoteStepTransactions: StepTransaction[],\n quote: TransactionPayQuote<ServerQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<StepTransaction[]> {\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n const { gasLimits, maxFeePerGas, maxPriorityFeePerGas } =\n quote.original.client;\n\n let prependedParams: TransactionParams;\n\n if (hasAccountOverride) {\n prependedParams = await buildDelegatedOriginalParams(\n transaction,\n messenger,\n );\n } else {\n prependedParams = {\n data: transaction.txParams.data,\n from: transaction.txParams.from,\n to: transaction.txParams.to,\n value: transaction.txParams.value,\n };\n }\n\n // Ensure the prepended tx carries the same fee caps as the quote steps so\n // it isn't submitted with undefined maxFeePerGas in a non-7702 batch.\n prependedParams.maxFeePerGas = maxFeePerGas ? toHex(maxFeePerGas) : undefined;\n prependedParams.maxPriorityFeePerGas = maxPriorityFeePerGas\n ? toHex(maxPriorityFeePerGas)\n : undefined;\n\n // The original transaction is estimated ahead of the quote steps, so it owns\n // the leading limit when each transaction has its own.\n if (gasLimits.length > quoteStepTransactions.length) {\n prependedParams.gas = toHex(gasLimits[0]);\n }\n\n log('Prepending post-quote original tx', { hasAccountOverride });\n\n return [{ params: prependedParams }, ...quoteStepTransactions];\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for post-quote original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Validate that the user's source token balance covers the quote's required\n * source amount before submitting on-chain.\n *\n * Reads the live balance via RPC rather than the cached state so it reflects\n * any concurrent spends. Throws fast with a clear error instead of letting\n * the on-chain transaction revert.\n *\n * @param quote - Server quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<ServerQuote>,\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 server deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\nasync function submitViaServerExecute(\n quote: TransactionPayQuote<ServerQuote>,\n stepTransactions: StepTransaction[],\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<void> {\n const { from, sourceChainId } = quote.request;\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n const nestedTransactions = stepTransactions.map(({ params }) => ({\n data: (params.data ?? '0x') as Hex,\n to: params.to as Hex,\n value: (params.value ?? '0x0') as Hex,\n }));\n\n const sourceCallTransaction = {\n ...transaction,\n chainId: sourceChainId,\n networkClientId,\n nestedTransactions,\n txParams: {\n ...transaction.txParams,\n from,\n },\n } as TransactionMeta;\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction: sourceCallTransaction },\n );\n\n log('Delegation result for server source calls', delegation);\n\n const submitBody: ServerSubmitRequest = {\n provider: quote.original.provider,\n id: quote.original.id,\n chainId: Number(sourceChainId),\n to: delegation.to,\n data: delegation.data,\n value: new BigNumber(delegation.value).toFixed(),\n ...(delegation.authorizationList?.length\n ? {\n authorizationList: delegation.authorizationList.map((auth) => ({\n chainId: Number(auth.chainId),\n address: auth.address,\n nonce: Number(auth.nonce),\n yParity: Number(auth.yParity),\n r: auth.r as Hex,\n s: auth.s as Hex,\n })),\n }\n : {}),\n };\n\n const submitResponse = await submitServerIntent(messenger, submitBody);\n\n if (!submitResponse.success) {\n throw new Error(\n `Server submit failed: ${submitResponse.error ?? 'unknown'}`,\n );\n }\n}\n\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<ServerQuote>,\n stepTransactions: StepTransaction[],\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n gasPayment: GasPayment,\n): Promise<void> {\n const { from, sourceChainId } = quote.request;\n const { gasLimits, is7702 } = quote.original.client;\n const { excludeNativeTokenForFee, gasFeeToken } = gasPayment;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Submitting via TransactionController', {\n from,\n gasFeeToken,\n is7702,\n networkClientId,\n transactionCount: stepTransactions.length,\n sourceChainId,\n });\n\n const transactionIds: string[] = [];\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from server submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n try {\n if (stepTransactions.length === 1) {\n const { params, type } = stepTransactions[0];\n\n const addTransactionOptions = {\n excludeNativeTokenForFee,\n gasFeeToken,\n isGasFeeSponsored: gasPayment.isGasFeeSponsored,\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n requireApproval: false,\n type,\n };\n\n log('Calling addTransaction', {\n params,\n options: addTransactionOptions,\n });\n\n await messenger.call(\n 'TransactionController:addTransaction',\n params,\n addTransactionOptions,\n );\n } else {\n const gasLimit7702 = is7702 ? toHex(gasLimits[0]) : undefined;\n\n const batchTransactions = stepTransactions.map(({ params, type }) => {\n // params.gas was already resolved correctly by buildStepTransaction\n // (indexed by quote-step position), so use it directly. Indexing\n // the step position into gasLimits would be wrong when payment-\n // override or post-quote transactions are prepended. In an EIP-7702\n // batch, the outer limit is passed as gasLimit7702 and nested gas is\n // not supported, so it is omitted.\n const gas =\n gasLimit7702 === undefined\n ? (params.gas as Hex | undefined)\n : undefined;\n\n return {\n params: {\n data: params.data as Hex,\n gas,\n maxFeePerGas: params.maxFeePerGas as Hex,\n maxPriorityFeePerGas: params.maxPriorityFeePerGas as Hex,\n to: params.to as Hex,\n value: params.value as Hex,\n },\n type,\n };\n });\n\n const addTransactionBatchOptions = {\n from,\n ...(gasLimit7702 === undefined\n ? { disable7702: true }\n : {\n disable7702: false,\n disableHook: true,\n disableSequential: true,\n gasLimit7702,\n }),\n excludeNativeTokenForFee,\n gasFeeToken,\n isGasFeeSponsored: gasPayment.isGasFeeSponsored,\n isInternal: true,\n networkClientId,\n origin: ORIGIN_METAMASK,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions: batchTransactions,\n };\n\n log('Calling addTransactionBatch', addTransactionBatchOptions);\n\n await messenger.call(\n 'TransactionController:addTransactionBatch',\n addTransactionBatchOptions,\n );\n }\n } finally {\n end();\n }\n\n log('Server transactions added', transactionIds);\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('Server transactions confirmed', transactionIds);\n\n logGasPaymentOutcome(\n gasPayment,\n transactionIds.map((txId) => getTransaction(txId, messenger)),\n );\n\n const lastId = transactionIds.at(-1);\n const sourceHash = lastId\n ? getTransaction(lastId, messenger)?.hash\n : undefined;\n\n if (sourceHash) {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from server transaction submission',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash as Hex;\n },\n );\n }\n}\n\nasync function submitSignatureStep(\n step: ServerSignatureStep,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { sign, post } = step;\n\n const typedData = {\n domain: sign.domain,\n types: {\n ...sign.types,\n EIP712Domain: deriveEIP712DomainType(sign.domain),\n },\n primaryType: sign.primaryType,\n message: sign.value,\n };\n\n log('Signing typed data for signature step', {\n primaryType: sign.primaryType,\n });\n\n const signature = await messenger.call(\n 'KeyringController:signTypedMessage',\n { from, data: JSON.stringify(typedData) },\n SignTypedDataVersion.V4,\n );\n\n await postSignatureStepResult(\n post.endpoint,\n post.method,\n post.body,\n signature,\n post.signatureFormat,\n );\n}\n\nasync function postSignatureStepResult(\n endpoint: string,\n method: string,\n body: Record<string, unknown>,\n signature: string,\n signatureFormat: 'queryParam' | 'rsv',\n): Promise<void> {\n let url = endpoint;\n let postBody: Record<string, unknown>;\n\n if (signatureFormat === 'queryParam') {\n url = `${endpoint}?signature=${signature}`;\n postBody = body;\n } else {\n // eslint-disable-next-line id-length\n const r = signature.slice(0, 66);\n // eslint-disable-next-line id-length\n const s = `0x${signature.slice(66, 130)}`;\n // eslint-disable-next-line id-length\n const v = parseInt(signature.slice(130, 132), 16);\n postBody = { ...body, signature: { r, s, v } };\n }\n\n log('Posting signature step result', { url, signatureFormat });\n\n let result: unknown;\n\n try {\n const response = await successfulFetch(url, {\n method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(postBody),\n });\n\n result = await response.json();\n } catch (error) {\n throw new Error(`Signature step POST failed: ${(error as Error).message}`);\n }\n\n log('Signature step POST response', result);\n\n // For rsv-format steps (HyperLiquid exchange endpoint) the response body\n // carries an explicit status field. Validate it here so a failed deposit\n // throws immediately rather than silently proceeding to the polling phase.\n if (signatureFormat === 'rsv') {\n const status = (result as { status?: string })?.status;\n\n if (status !== 'ok') {\n throw new Error(\n `Signature step rejected by server: ${JSON.stringify(result)}`,\n );\n }\n }\n}\n\nfunction deriveEIP712DomainType(\n domain: Record<string, unknown>,\n): { name: string; type: string }[] {\n return Object.keys(DOMAIN_FIELD_MAP)\n .filter((key) => Object.prototype.hasOwnProperty.call(domain, key))\n .map((key) => DOMAIN_FIELD_MAP[key]);\n}\n\n/**\n * Poll the server until the intent reaches a terminal status.\n *\n * Failures are returned rather than thrown so callers can clean up first, such\n * as sweeping a deposit wallet refund. Timeouts still throw.\n *\n * @param quote - Server quote being polled.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the parent transaction.\n * @returns The terminal status and the target-chain hash when reported.\n */\nasync function waitForServerCompletion(\n quote: ServerQuote,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n): Promise<ServerCompletion> {\n const pollingInterval = getServerPollingInterval(messenger);\n const pollingTimeout = getServerPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Server polling config', { pollingInterval, pollingTimeout });\n\n const startTime = Date.now();\n\n let lastStatus: string | undefined;\n let sourceHashEmitted = false;\n\n while (true) {\n let statusResponse: ServerStatusResponse | undefined;\n\n try {\n const tx = getTransaction(transactionId, messenger);\n\n statusResponse = await getServerStatus(messenger, {\n provider: quote.provider,\n id: quote.id,\n hash: tx?.metamaskPay?.sourceHash ?? tx?.hash,\n });\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (statusResponse) {\n lastStatus = statusResponse.status;\n log('Polled status', statusResponse.status, statusResponse);\n\n if (!sourceHashEmitted && statusResponse.sourceHash) {\n sourceHashEmitted = true;\n const { sourceHash } = statusResponse;\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Add source hash from server status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n }\n\n const { status, targetHash } = statusResponse;\n\n if (\n status === ServerStatus.Confirmed ||\n status === ServerStatus.Failed ||\n status === ServerStatus.Refunded\n ) {\n return { status, targetHash };\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n throw new Error(`Server polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n"]}
|
|
@@ -56,7 +56,7 @@ export declare function estimateQuoteGasLimits({ fallbackGas, fallbackOnSimulati
|
|
|
56
56
|
* @param options.request - Quote request.
|
|
57
57
|
* @param options.transaction - Original transaction metadata.
|
|
58
58
|
* @param options.transactions - Quote transactions to estimate.
|
|
59
|
-
* @returns Source gas, with
|
|
59
|
+
* @returns Source gas, with separate limits in submission order.
|
|
60
60
|
*/
|
|
61
61
|
export declare function estimateSourceGas({ fromOverride, messenger, request, transaction, transactions, }: {
|
|
62
62
|
fromOverride?: Hex;
|
package/dist/utils/quote-gas.js
CHANGED
|
@@ -47,7 +47,7 @@ export async function estimateQuoteGasLimits({ fallbackGas, fallbackOnSimulation
|
|
|
47
47
|
* @param options.request - Quote request.
|
|
48
48
|
* @param options.transaction - Original transaction metadata.
|
|
49
49
|
* @param options.transactions - Quote transactions to estimate.
|
|
50
|
-
* @returns Source gas, with
|
|
50
|
+
* @returns Source gas, with separate limits in submission order.
|
|
51
51
|
*/
|
|
52
52
|
export async function estimateSourceGas({ fromOverride, messenger, request, transaction, transactions, }) {
|
|
53
53
|
const originalTransaction = getOriginalTransactionGas(request, transaction);
|
|
@@ -72,12 +72,17 @@ async function estimateQuoteGasLimitsBatch(transactions, messenger) {
|
|
|
72
72
|
const [firstTransaction] = transactions;
|
|
73
73
|
const gasBuffer = getGasBuffer(messenger, firstTransaction.chainId);
|
|
74
74
|
const paramGasLimits = transactions.map((transaction) => parseGasLimit(transaction.gas));
|
|
75
|
-
const { gasLimits, requiresAuthorizationList } = await messenger.call('TransactionController:estimateGasBatch', {
|
|
75
|
+
const { gasLimits, mode, requiresAuthorizationList } = await messenger.call('TransactionController:estimateGasBatch', {
|
|
76
76
|
chainId: firstTransaction.chainId,
|
|
77
77
|
from: firstTransaction.from,
|
|
78
78
|
transactions: transactions.map(toBatchTransactionParams),
|
|
79
79
|
});
|
|
80
|
-
|
|
80
|
+
// Older TransactionController versions return no `mode`, so detect a
|
|
81
|
+
// combined EIP-7702 gas limit from the number of gas limits instead.
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
83
|
+
const is7702 = mode === undefined ? gasLimits.length === 1 : mode === 'eip7702';
|
|
84
|
+
const expectedGasLimitCount = is7702 ? 1 : transactions.length;
|
|
85
|
+
if (gasLimits.length !== expectedGasLimitCount) {
|
|
81
86
|
throw new Error('Unexpected batch gas limit count');
|
|
82
87
|
}
|
|
83
88
|
const bufferedGasLimits = gasLimits.map((gasLimit, index) => {
|
|
@@ -86,9 +91,9 @@ async function estimateQuoteGasLimitsBatch(transactions, messenger) {
|
|
|
86
91
|
// Per-entry batch results currently preserve validated input gas values
|
|
87
92
|
// for transactions that already provided gas. If that contract changes
|
|
88
93
|
// and batch estimation returns a different value, treat it as a fresh
|
|
89
|
-
// estimate and apply the buffer. A
|
|
94
|
+
// estimate and apply the buffer. A combined 7702 result is always
|
|
90
95
|
// buffered because it is a fresh batch estimate.
|
|
91
|
-
const useBuffer =
|
|
96
|
+
const useBuffer = is7702 || !providedGasWasPreserved;
|
|
92
97
|
const bufferedGas = Math.ceil(gasLimit * (useBuffer ? gasBuffer : 1));
|
|
93
98
|
return {
|
|
94
99
|
estimate: bufferedGas,
|
|
@@ -96,7 +101,6 @@ async function estimateQuoteGasLimitsBatch(transactions, messenger) {
|
|
|
96
101
|
};
|
|
97
102
|
});
|
|
98
103
|
const totalGasLimit = bufferedGasLimits.reduce((acc, gasLimit) => acc + gasLimit.max, 0);
|
|
99
|
-
const is7702 = bufferedGasLimits.length === 1;
|
|
100
104
|
const batchGasLimit = is7702 ? bufferedGasLimits[0] : undefined;
|
|
101
105
|
return {
|
|
102
106
|
...(batchGasLimit ? { batchGasLimit } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quote-gas.js","sourceRoot":"","sources":["../../src/utils/quote-gas.ts"],"names":[],"mappings":"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","sourcesContent":["import { toHex } from '@metamask/controller-utils';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type { TransactionPayControllerMessenger } from '../index.js';\nimport { projectLogger } from '../logger.js';\nimport type { QuoteRequest } from '../types.js';\nimport { getFeatureFlags, getGasBuffer } from './feature-flags.js';\nimport { estimateGasLimit } from './gas.js';\n\nconst log = createModuleLogger(projectLogger, 'quote-gas');\n\n// Hardcoded gas allowance for the prepended payment override transaction(s).\nconst PAYMENT_OVERRIDE_GAS = 75_000;\n\nexport type QuoteGasTransaction = {\n chainId: Hex;\n data: Hex;\n from: Hex;\n gas?: number | string;\n to: Hex;\n value?: number | string | Hex;\n};\n\nexport type QuoteGasLimit = {\n estimate: number;\n max: number;\n};\n\n/** Gas required on the source chain, including any prepended transactions. */\nexport type SourceGas = {\n gasLimits: number[];\n is7702: boolean;\n totalGasEstimate: number;\n totalGasLimit: number;\n};\n\nexport async function estimateQuoteGasLimits({\n fallbackGas,\n fallbackOnSimulationFailure = false,\n messenger,\n transactions,\n}: {\n fallbackGas?: {\n estimate: number;\n max: number;\n };\n fallbackOnSimulationFailure?: boolean;\n messenger: TransactionPayControllerMessenger;\n transactions: QuoteGasTransaction[];\n}): Promise<{\n batchGasLimit?: QuoteGasLimit;\n gasLimits: QuoteGasLimit[];\n is7702: boolean;\n requiresAuthorizationList?: true;\n totalGasEstimate: number;\n totalGasLimit: number;\n usedBatch: boolean;\n}> {\n if (transactions.length === 0) {\n throw new Error('Quote gas estimation requires at least one transaction');\n }\n\n const useBatch = transactions.length > 1;\n\n if (useBatch) {\n return {\n ...(await estimateQuoteGasLimitsBatch(transactions, messenger)),\n usedBatch: true,\n };\n }\n\n return {\n ...(await estimateQuoteGasLimitSingle({\n fallbackGas,\n fallbackOnSimulationFailure,\n messenger,\n transaction: transactions[0],\n })),\n is7702: false,\n usedBatch: false,\n };\n}\n\n/**\n * Estimate the source-chain gas for a quote's transactions, including the\n * transactions prepended at submit time.\n *\n * Post-quote flows prepend the original transaction, so it is estimated with\n * the quote transactions to let batch estimation detect EIP-7702 support.\n * Without it a single quote step is estimated alone, gets `is7702: false`, and\n * the batch falls back to separate transactions that each need native gas.\n * When the original transaction cannot be estimated, fixed allowances for the\n * prepended transactions are added instead.\n *\n * @param options - Options bag.\n * @param options.fromOverride - Address to estimate from instead of each\n * transaction's own `from`, such as the Predict Safe holding the source token.\n * @param options.messenger - Controller messenger.\n * @param options.request - Quote request.\n * @param options.transaction - Original transaction metadata.\n * @param options.transactions - Quote transactions to estimate.\n * @returns Source gas, with per-transaction limits in submission order.\n */\nexport async function estimateSourceGas({\n fromOverride,\n messenger,\n request,\n transaction,\n transactions,\n}: {\n fromOverride?: Hex;\n messenger: TransactionPayControllerMessenger;\n request: QuoteRequest;\n transaction: TransactionMeta;\n transactions: QuoteGasTransaction[];\n}): Promise<SourceGas> {\n const originalTransaction = getOriginalTransactionGas(request, transaction);\n\n const allTransactions = (\n originalTransaction ? [originalTransaction, ...transactions] : transactions\n ).map((singleTransaction) =>\n fromOverride\n ? { ...singleTransaction, from: fromOverride, gas: undefined }\n : singleTransaction,\n );\n\n const result = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions: allTransactions,\n });\n\n const gas = {\n gasLimits: result.gasLimits.map((gasLimit) => gasLimit.max),\n is7702: result.is7702,\n totalGasEstimate: result.totalGasEstimate,\n totalGasLimit: result.totalGasLimit,\n };\n\n return originalTransaction ? gas : addPrependedGas(gas, request, transaction);\n}\n\nasync function estimateQuoteGasLimitsBatch(\n transactions: QuoteGasTransaction[],\n messenger: TransactionPayControllerMessenger,\n): Promise<{\n batchGasLimit?: QuoteGasLimit;\n gasLimits: QuoteGasLimit[];\n is7702: boolean;\n requiresAuthorizationList?: true;\n totalGasEstimate: number;\n totalGasLimit: number;\n}> {\n const [firstTransaction] = transactions;\n const gasBuffer = getGasBuffer(messenger, firstTransaction.chainId);\n\n const paramGasLimits = transactions.map((transaction) =>\n parseGasLimit(transaction.gas),\n );\n\n const { gasLimits, requiresAuthorizationList } = await messenger.call(\n 'TransactionController:estimateGasBatch',\n {\n chainId: firstTransaction.chainId,\n from: firstTransaction.from,\n transactions: transactions.map(toBatchTransactionParams),\n },\n );\n\n if (gasLimits.length !== 1 && gasLimits.length !== transactions.length) {\n throw new Error('Unexpected batch gas limit count');\n }\n\n const bufferedGasLimits = gasLimits.map((gasLimit, index) => {\n const providedGasLimit = paramGasLimits[index];\n const providedGasWasPreserved =\n providedGasLimit !== undefined && providedGasLimit === gasLimit;\n\n // Per-entry batch results currently preserve validated input gas values\n // for transactions that already provided gas. If that contract changes\n // and batch estimation returns a different value, treat it as a fresh\n // estimate and apply the buffer. A single combined 7702 result is always\n // buffered because it is a fresh batch estimate.\n const useBuffer = gasLimits.length === 1 || !providedGasWasPreserved;\n const bufferedGas = Math.ceil(gasLimit * (useBuffer ? gasBuffer : 1));\n\n return {\n estimate: bufferedGas,\n max: bufferedGas,\n };\n });\n\n const totalGasLimit = bufferedGasLimits.reduce(\n (acc, gasLimit) => acc + gasLimit.max,\n 0,\n );\n const is7702 = bufferedGasLimits.length === 1;\n const batchGasLimit = is7702 ? bufferedGasLimits[0] : undefined;\n\n return {\n ...(batchGasLimit ? { batchGasLimit } : {}),\n gasLimits: bufferedGasLimits,\n is7702,\n ...(requiresAuthorizationList ? { requiresAuthorizationList } : {}),\n totalGasEstimate: totalGasLimit,\n totalGasLimit,\n };\n}\n\nasync function estimateQuoteGasLimitSingle({\n fallbackGas,\n fallbackOnSimulationFailure,\n messenger,\n transaction,\n}: {\n fallbackGas?: {\n estimate: number;\n max: number;\n };\n fallbackOnSimulationFailure: boolean;\n messenger: TransactionPayControllerMessenger;\n transaction: QuoteGasTransaction;\n}): Promise<{\n gasLimits: QuoteGasLimit[];\n totalGasEstimate: number;\n totalGasLimit: number;\n}> {\n const providedGasLimit = parseGasLimit(transaction.gas);\n\n if (providedGasLimit !== undefined) {\n log('Using provided gas limit', {\n chainId: transaction.chainId,\n gas: providedGasLimit,\n index: 0,\n to: transaction.to,\n });\n\n return {\n gasLimits: [\n {\n estimate: providedGasLimit,\n max: providedGasLimit,\n },\n ],\n totalGasEstimate: providedGasLimit,\n totalGasLimit: providedGasLimit,\n };\n }\n\n const gasLimitResult = await estimateGasLimit({\n chainId: transaction.chainId,\n data: transaction.data,\n fallbackGas,\n fallbackOnSimulationFailure,\n from: transaction.from,\n messenger,\n to: transaction.to,\n value: toHex(transaction.value ?? '0'),\n });\n\n if (gasLimitResult.usedFallback) {\n log('Gas estimate failed, using fallback', {\n chainId: transaction.chainId,\n error: gasLimitResult.error,\n index: 0,\n to: transaction.to,\n });\n }\n\n const gasLimit = {\n estimate: gasLimitResult.estimate,\n max: gasLimitResult.max,\n };\n\n return {\n gasLimits: [gasLimit],\n totalGasEstimate: gasLimit.estimate,\n totalGasLimit: gasLimit.max,\n };\n}\n\nfunction toBatchTransactionParams(\n transaction: QuoteGasTransaction,\n): BatchTransactionParams {\n return {\n data: transaction.data,\n gas: transaction.gas === undefined ? undefined : toHex(transaction.gas),\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n to: transaction.to,\n value: toHex(transaction.value ?? '0'),\n };\n}\n\nfunction parseGasLimit(gas?: number | string): number | undefined {\n if (gas === undefined) {\n return undefined;\n }\n\n const parsedGas = new BigNumber(gas);\n\n if (\n !parsedGas.isFinite() ||\n parsedGas.isNaN() ||\n !parsedGas.isInteger() ||\n parsedGas.lte(0)\n ) {\n return undefined;\n }\n\n return parsedGas.toNumber();\n}\n\nfunction getOriginalTransactionGas(\n request: QuoteRequest,\n transaction: TransactionMeta,\n): QuoteGasTransaction | undefined {\n const { txParams } = transaction;\n const to = txParams.to as Hex | undefined;\n\n if (!request.isPostQuote || !to || hasAccountOverride(request, transaction)) {\n return undefined;\n }\n\n const gas = getOriginalGas(transaction);\n\n return {\n chainId: transaction.chainId,\n data: (txParams.data as Hex) ?? '0x',\n from: txParams.from as Hex,\n gas: gas ? String(gas) : undefined,\n to,\n value: txParams.value ?? '0',\n };\n}\n\nfunction addPrependedGas(\n gas: SourceGas,\n request: QuoteRequest,\n transaction: TransactionMeta,\n): SourceGas {\n const originalGas = request.isPostQuote\n ? getOriginalGas(transaction)\n : undefined;\n\n const withOriginal = originalGas\n ? prependGas(gas, new BigNumber(originalGas).toNumber())\n : gas;\n\n return request.paymentOverride\n ? prependGas(withOriginal, PAYMENT_OVERRIDE_GAS)\n : withOriginal;\n}\n\nfunction prependGas(gas: SourceGas, prependedGas: number): SourceGas {\n // A combined 7702 limit stays a single limit, otherwise the prepended\n // transaction gets its own limit ahead of the quote transactions.\n const gasLimits = gas.is7702\n ? [gas.gasLimits[0] + prependedGas]\n : [prependedGas, ...gas.gasLimits];\n\n log('Added prepended transaction gas', { gasLimits, prependedGas });\n\n return {\n gasLimits,\n is7702: gas.is7702,\n totalGasEstimate: gas.totalGasEstimate + prependedGas,\n totalGasLimit: gas.totalGasLimit + prependedGas,\n };\n}\n\n// Prefer the caller-provided nested gas, since the transaction controller may\n// re-estimate `txParams.gas` during batch creation.\nfunction getOriginalGas(transaction: TransactionMeta): string | undefined {\n return (\n transaction.nestedTransactions?.find((nested) => nested.gas)?.gas ??\n transaction.txParams.gas\n );\n}\n\nfunction hasAccountOverride(\n request: QuoteRequest,\n transaction: TransactionMeta,\n): boolean {\n return (\n request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase()\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"quote-gas.js","sourceRoot":"","sources":["../../src/utils/quote-gas.ts"],"names":[],"mappings":"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","sourcesContent":["import { toHex } from '@metamask/controller-utils';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type { TransactionPayControllerMessenger } from '../index.js';\nimport { projectLogger } from '../logger.js';\nimport type { QuoteRequest } from '../types.js';\nimport { getFeatureFlags, getGasBuffer } from './feature-flags.js';\nimport { estimateGasLimit } from './gas.js';\n\nconst log = createModuleLogger(projectLogger, 'quote-gas');\n\n// Hardcoded gas allowance for the prepended payment override transaction(s).\nconst PAYMENT_OVERRIDE_GAS = 75_000;\n\nexport type QuoteGasTransaction = {\n chainId: Hex;\n data: Hex;\n from: Hex;\n gas?: number | string;\n to: Hex;\n value?: number | string | Hex;\n};\n\nexport type QuoteGasLimit = {\n estimate: number;\n max: number;\n};\n\n/** Gas required on the source chain, including any prepended transactions. */\nexport type SourceGas = {\n gasLimits: number[];\n is7702: boolean;\n totalGasEstimate: number;\n totalGasLimit: number;\n};\n\nexport async function estimateQuoteGasLimits({\n fallbackGas,\n fallbackOnSimulationFailure = false,\n messenger,\n transactions,\n}: {\n fallbackGas?: {\n estimate: number;\n max: number;\n };\n fallbackOnSimulationFailure?: boolean;\n messenger: TransactionPayControllerMessenger;\n transactions: QuoteGasTransaction[];\n}): Promise<{\n batchGasLimit?: QuoteGasLimit;\n gasLimits: QuoteGasLimit[];\n is7702: boolean;\n requiresAuthorizationList?: true;\n totalGasEstimate: number;\n totalGasLimit: number;\n usedBatch: boolean;\n}> {\n if (transactions.length === 0) {\n throw new Error('Quote gas estimation requires at least one transaction');\n }\n\n const useBatch = transactions.length > 1;\n\n if (useBatch) {\n return {\n ...(await estimateQuoteGasLimitsBatch(transactions, messenger)),\n usedBatch: true,\n };\n }\n\n return {\n ...(await estimateQuoteGasLimitSingle({\n fallbackGas,\n fallbackOnSimulationFailure,\n messenger,\n transaction: transactions[0],\n })),\n is7702: false,\n usedBatch: false,\n };\n}\n\n/**\n * Estimate the source-chain gas for a quote's transactions, including the\n * transactions prepended at submit time.\n *\n * Post-quote flows prepend the original transaction, so it is estimated with\n * the quote transactions to let batch estimation detect EIP-7702 support.\n * Without it a single quote step is estimated alone, gets `is7702: false`, and\n * the batch falls back to separate transactions that each need native gas.\n * When the original transaction cannot be estimated, fixed allowances for the\n * prepended transactions are added instead.\n *\n * @param options - Options bag.\n * @param options.fromOverride - Address to estimate from instead of each\n * transaction's own `from`, such as the Predict Safe holding the source token.\n * @param options.messenger - Controller messenger.\n * @param options.request - Quote request.\n * @param options.transaction - Original transaction metadata.\n * @param options.transactions - Quote transactions to estimate.\n * @returns Source gas, with separate limits in submission order.\n */\nexport async function estimateSourceGas({\n fromOverride,\n messenger,\n request,\n transaction,\n transactions,\n}: {\n fromOverride?: Hex;\n messenger: TransactionPayControllerMessenger;\n request: QuoteRequest;\n transaction: TransactionMeta;\n transactions: QuoteGasTransaction[];\n}): Promise<SourceGas> {\n const originalTransaction = getOriginalTransactionGas(request, transaction);\n\n const allTransactions = (\n originalTransaction ? [originalTransaction, ...transactions] : transactions\n ).map((singleTransaction) =>\n fromOverride\n ? { ...singleTransaction, from: fromOverride, gas: undefined }\n : singleTransaction,\n );\n\n const result = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions: allTransactions,\n });\n\n const gas = {\n gasLimits: result.gasLimits.map((gasLimit) => gasLimit.max),\n is7702: result.is7702,\n totalGasEstimate: result.totalGasEstimate,\n totalGasLimit: result.totalGasLimit,\n };\n\n return originalTransaction ? gas : addPrependedGas(gas, request, transaction);\n}\n\nasync function estimateQuoteGasLimitsBatch(\n transactions: QuoteGasTransaction[],\n messenger: TransactionPayControllerMessenger,\n): Promise<{\n batchGasLimit?: QuoteGasLimit;\n gasLimits: QuoteGasLimit[];\n is7702: boolean;\n requiresAuthorizationList?: true;\n totalGasEstimate: number;\n totalGasLimit: number;\n}> {\n const [firstTransaction] = transactions;\n const gasBuffer = getGasBuffer(messenger, firstTransaction.chainId);\n\n const paramGasLimits = transactions.map((transaction) =>\n parseGasLimit(transaction.gas),\n );\n\n const { gasLimits, mode, requiresAuthorizationList } = await messenger.call(\n 'TransactionController:estimateGasBatch',\n {\n chainId: firstTransaction.chainId,\n from: firstTransaction.from,\n transactions: transactions.map(toBatchTransactionParams),\n },\n );\n\n // Older TransactionController versions return no `mode`, so detect a\n // combined EIP-7702 gas limit from the number of gas limits instead.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const is7702 =\n mode === undefined ? gasLimits.length === 1 : mode === 'eip7702';\n\n const expectedGasLimitCount = is7702 ? 1 : transactions.length;\n\n if (gasLimits.length !== expectedGasLimitCount) {\n throw new Error('Unexpected batch gas limit count');\n }\n\n const bufferedGasLimits = gasLimits.map((gasLimit, index) => {\n const providedGasLimit = paramGasLimits[index];\n const providedGasWasPreserved =\n providedGasLimit !== undefined && providedGasLimit === gasLimit;\n\n // Per-entry batch results currently preserve validated input gas values\n // for transactions that already provided gas. If that contract changes\n // and batch estimation returns a different value, treat it as a fresh\n // estimate and apply the buffer. A combined 7702 result is always\n // buffered because it is a fresh batch estimate.\n const useBuffer = is7702 || !providedGasWasPreserved;\n const bufferedGas = Math.ceil(gasLimit * (useBuffer ? gasBuffer : 1));\n\n return {\n estimate: bufferedGas,\n max: bufferedGas,\n };\n });\n\n const totalGasLimit = bufferedGasLimits.reduce(\n (acc, gasLimit) => acc + gasLimit.max,\n 0,\n );\n const batchGasLimit = is7702 ? bufferedGasLimits[0] : undefined;\n\n return {\n ...(batchGasLimit ? { batchGasLimit } : {}),\n gasLimits: bufferedGasLimits,\n is7702,\n ...(requiresAuthorizationList ? { requiresAuthorizationList } : {}),\n totalGasEstimate: totalGasLimit,\n totalGasLimit,\n };\n}\n\nasync function estimateQuoteGasLimitSingle({\n fallbackGas,\n fallbackOnSimulationFailure,\n messenger,\n transaction,\n}: {\n fallbackGas?: {\n estimate: number;\n max: number;\n };\n fallbackOnSimulationFailure: boolean;\n messenger: TransactionPayControllerMessenger;\n transaction: QuoteGasTransaction;\n}): Promise<{\n gasLimits: QuoteGasLimit[];\n totalGasEstimate: number;\n totalGasLimit: number;\n}> {\n const providedGasLimit = parseGasLimit(transaction.gas);\n\n if (providedGasLimit !== undefined) {\n log('Using provided gas limit', {\n chainId: transaction.chainId,\n gas: providedGasLimit,\n index: 0,\n to: transaction.to,\n });\n\n return {\n gasLimits: [\n {\n estimate: providedGasLimit,\n max: providedGasLimit,\n },\n ],\n totalGasEstimate: providedGasLimit,\n totalGasLimit: providedGasLimit,\n };\n }\n\n const gasLimitResult = await estimateGasLimit({\n chainId: transaction.chainId,\n data: transaction.data,\n fallbackGas,\n fallbackOnSimulationFailure,\n from: transaction.from,\n messenger,\n to: transaction.to,\n value: toHex(transaction.value ?? '0'),\n });\n\n if (gasLimitResult.usedFallback) {\n log('Gas estimate failed, using fallback', {\n chainId: transaction.chainId,\n error: gasLimitResult.error,\n index: 0,\n to: transaction.to,\n });\n }\n\n const gasLimit = {\n estimate: gasLimitResult.estimate,\n max: gasLimitResult.max,\n };\n\n return {\n gasLimits: [gasLimit],\n totalGasEstimate: gasLimit.estimate,\n totalGasLimit: gasLimit.max,\n };\n}\n\nfunction toBatchTransactionParams(\n transaction: QuoteGasTransaction,\n): BatchTransactionParams {\n return {\n data: transaction.data,\n gas: transaction.gas === undefined ? undefined : toHex(transaction.gas),\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n to: transaction.to,\n value: toHex(transaction.value ?? '0'),\n };\n}\n\nfunction parseGasLimit(gas?: number | string): number | undefined {\n if (gas === undefined) {\n return undefined;\n }\n\n const parsedGas = new BigNumber(gas);\n\n if (\n !parsedGas.isFinite() ||\n parsedGas.isNaN() ||\n !parsedGas.isInteger() ||\n parsedGas.lte(0)\n ) {\n return undefined;\n }\n\n return parsedGas.toNumber();\n}\n\nfunction getOriginalTransactionGas(\n request: QuoteRequest,\n transaction: TransactionMeta,\n): QuoteGasTransaction | undefined {\n const { txParams } = transaction;\n const to = txParams.to as Hex | undefined;\n\n if (!request.isPostQuote || !to || hasAccountOverride(request, transaction)) {\n return undefined;\n }\n\n const gas = getOriginalGas(transaction);\n\n return {\n chainId: transaction.chainId,\n data: (txParams.data as Hex) ?? '0x',\n from: txParams.from as Hex,\n gas: gas ? String(gas) : undefined,\n to,\n value: txParams.value ?? '0',\n };\n}\n\nfunction addPrependedGas(\n gas: SourceGas,\n request: QuoteRequest,\n transaction: TransactionMeta,\n): SourceGas {\n const originalGas = request.isPostQuote\n ? getOriginalGas(transaction)\n : undefined;\n\n const withOriginal = originalGas\n ? prependGas(gas, new BigNumber(originalGas).toNumber())\n : gas;\n\n return request.paymentOverride\n ? prependGas(withOriginal, PAYMENT_OVERRIDE_GAS)\n : withOriginal;\n}\n\nfunction prependGas(gas: SourceGas, prependedGas: number): SourceGas {\n // A combined 7702 limit stays a single limit, otherwise the prepended\n // transaction gets its own limit ahead of the quote transactions.\n const gasLimits = gas.is7702\n ? [gas.gasLimits[0] + prependedGas]\n : [prependedGas, ...gas.gasLimits];\n\n log('Added prepended transaction gas', { gasLimits, prependedGas });\n\n return {\n gasLimits,\n is7702: gas.is7702,\n totalGasEstimate: gas.totalGasEstimate + prependedGas,\n totalGasLimit: gas.totalGasLimit + prependedGas,\n };\n}\n\n// Prefer the caller-provided nested gas, since the transaction controller may\n// re-estimate `txParams.gas` during batch creation.\nfunction getOriginalGas(transaction: TransactionMeta): string | undefined {\n return (\n transaction.nestedTransactions?.find((nested) => nested.gas)?.gas ??\n transaction.txParams.gas\n );\n}\n\nfunction hasAccountOverride(\n request: QuoteRequest,\n transaction: TransactionMeta,\n): boolean {\n return (\n request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase()\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/transaction-pay-controller",
|
|
3
|
-
"version": "30.
|
|
3
|
+
"version": "30.3.0-preview-56cdd31f1",
|
|
4
4
|
"description": "Manages alternate payment strategies to provide required funds for transactions in MetaMask",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@ethersproject/contracts": "^5.7.0",
|
|
56
56
|
"@ethersproject/providers": "^5.8.0",
|
|
57
57
|
"@metamask/accounts-controller": "^40.1.0",
|
|
58
|
-
"@metamask/assets-controller": "^
|
|
58
|
+
"@metamask/assets-controller": "^20.0.0",
|
|
59
59
|
"@metamask/base-controller": "^10.1.0",
|
|
60
60
|
"@metamask/controller-utils": "^13.0.0",
|
|
61
61
|
"@metamask/gas-fee-controller": "^27.0.0",
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"@metamask/messenger": "^3.0.0",
|
|
64
64
|
"@metamask/metamask-eth-abis": "^3.1.1",
|
|
65
65
|
"@metamask/network-controller": "^37.1.1",
|
|
66
|
-
"@metamask/ramps-controller": "^27.
|
|
66
|
+
"@metamask/ramps-controller": "^27.2.0",
|
|
67
67
|
"@metamask/remote-feature-flag-controller": "^7.0.0",
|
|
68
68
|
"@metamask/sentinel-api-service": "^2.1.0",
|
|
69
69
|
"@metamask/transaction-controller": "^72.2.1",
|
|
70
|
-
"@metamask/utils": "^12.0.
|
|
70
|
+
"@metamask/utils": "^12.0.1",
|
|
71
71
|
"bignumber.js": "^9.1.2",
|
|
72
72
|
"bn.js": "^5.2.5",
|
|
73
73
|
"immer": "^11.1.18",
|