@metamask/transaction-pay-controller 21.0.0 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -1
- package/dist/TransactionPayController.cjs +30 -3
- package/dist/TransactionPayController.cjs.map +1 -1
- package/dist/TransactionPayController.d.cts.map +1 -1
- package/dist/TransactionPayController.d.mts.map +1 -1
- package/dist/TransactionPayController.mjs +31 -4
- package/dist/TransactionPayController.mjs.map +1 -1
- package/dist/strategy/fiat/fiat-submit.cjs +264 -5
- package/dist/strategy/fiat/fiat-submit.cjs.map +1 -1
- package/dist/strategy/fiat/fiat-submit.d.cts +9 -4
- package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -1
- package/dist/strategy/fiat/fiat-submit.d.mts +9 -4
- package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -1
- package/dist/strategy/fiat/fiat-submit.mjs +264 -5
- package/dist/strategy/fiat/fiat-submit.mjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.cjs +7 -4
- package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.cts.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.mts.map +1 -1
- package/dist/strategy/relay/relay-quotes.mjs +7 -4
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/tests/messenger-mock.d.cts +1 -1
- package/dist/tests/messenger-mock.d.mts +1 -1
- package/dist/types.cjs +2 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +10 -7
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +10 -7
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +6 -1
- package/dist/utils/feature-flags.cjs.map +1 -1
- package/dist/utils/feature-flags.d.cts +2 -1
- package/dist/utils/feature-flags.d.cts.map +1 -1
- package/dist/utils/feature-flags.d.mts +2 -1
- package/dist/utils/feature-flags.d.mts.map +1 -1
- package/dist/utils/feature-flags.mjs +6 -1
- package/dist/utils/feature-flags.mjs.map +1 -1
- package/dist/utils/quotes.cjs +1 -1
- package/dist/utils/quotes.cjs.map +1 -1
- package/dist/utils/quotes.mjs +1 -1
- package/dist/utils/quotes.mjs.map +1 -1
- package/dist/utils/required-tokens.cjs +24 -2
- package/dist/utils/required-tokens.cjs.map +1 -1
- package/dist/utils/required-tokens.d.cts.map +1 -1
- package/dist/utils/required-tokens.d.mts.map +1 -1
- package/dist/utils/required-tokens.mjs +24 -2
- package/dist/utils/required-tokens.mjs.map +1 -1
- package/dist/utils/transaction.cjs +37 -4
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +12 -3
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +12 -3
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +34 -2
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fiat-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA8C;IAE9C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC","sourcesContent":["import type { PayStrategy, PayStrategyExecuteRequest } from '../../types';\nimport type { FiatQuote } from './types';\n\n/**\n * Submit Fiat quotes.\n *\n * @param _request - Strategy execute request.\n * @returns Empty transaction hash until fiat submit implementation is added.\n */\nexport async function submitFiatQuotes(\n _request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n return { transactionHash: undefined };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fiat-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport { submitRelayQuotes } from '../relay/relay-submit';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment } from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\n\nconst ORDER_POLL_INTERVAL_MS = 1000;\nconst ORDER_POLL_TIMEOUT_MS = 10 * 60 * 1000;\nconst MAX_SLIPPAGE_PERCENT = 5;\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const walletAddress = transaction.txParams.from as Hex | undefined;\n\n if (!walletAddress) {\n throw new Error('Missing wallet address for fiat submission');\n }\n\n const state = messenger.call('TransactionPayController:getState');\n const orderId = state.transactionData[transactionId]?.fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID for fiat submission');\n }\n\n const parsedOrder = parseOrderId(orderId);\n\n if (!parsedOrder) {\n throw new Error(`Invalid order ID format: ${orderId}`);\n }\n\n log('Starting fiat order polling', {\n orderId,\n providerCode: parsedOrder.providerCode,\n transactionId,\n });\n\n const order = await waitForOrderCompletion({\n messenger,\n orderCode: parsedOrder.orderCode,\n providerCode: parsedOrder.providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n return await submitRelayAfterFiatCompletion({ order, request });\n}\n\n/**\n * Parses a normalized order ID string into its provider and order components.\n *\n * @param orderId - Order ID in `/providers/{providerCode}/orders/{orderCode}` format.\n * @returns The parsed provider and order codes, or `null` if the format is invalid.\n */\nfunction parseOrderId(\n orderId: string,\n): { orderCode: string; providerCode: string } | null {\n const parts = orderId.split('/').filter(Boolean);\n\n if (parts.length < 4 || parts[0] !== 'providers' || parts[2] !== 'orders') {\n return null;\n }\n\n return { orderCode: parts[3], providerCode: parts[1] };\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nfunction getRawSourceAmountFromOrder({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = expectedAsset.caipAssetId.toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Fiat order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Fiat order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Validates that the re-quoted relay target output hasn't drifted beyond the\n * acceptable slippage threshold compared to the original quote shown to the user.\n *\n * @param options - The validation options.\n * @param options.originalTargetRaw - Raw target amount from the original relay quote.\n * @param options.reQuotedTargetRaw - Raw target amount from the re-quoted relay.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateRelaySlippage({\n originalTargetRaw,\n reQuotedTargetRaw,\n transactionId,\n}: {\n originalTargetRaw: string;\n reQuotedTargetRaw: string;\n transactionId: string;\n}): void {\n const original = new BigNumber(originalTargetRaw);\n const reQuoted = new BigNumber(reQuotedTargetRaw);\n\n if (!original.gt(0) || !reQuoted.gt(0)) {\n return;\n }\n\n const slippagePercent = original\n .minus(reQuoted)\n .dividedBy(original)\n .multipliedBy(100);\n\n log('Relay slippage check', {\n originalTargetRaw,\n reQuotedTargetRaw,\n slippagePercent: slippagePercent.toFixed(2),\n transactionId,\n });\n\n if (slippagePercent.gt(MAX_SLIPPAGE_PERCENT)) {\n throw new Error(\n `Relay re-quote slippage too high for transaction ` +\n `${slippagePercent.toFixed(2)}% exceeds ${MAX_SLIPPAGE_PERCENT}% max`,\n );\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= ORDER_POLL_TIMEOUT_MS) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, ORDER_POLL_INTERVAL_MS));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (!quotes.length) {\n throw new Error('Missing fiat quote for relay submission');\n }\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction);\n if (!fiatAsset) {\n throw new Error(\n `Missing fiat asset mapping for transaction type: ${String(transaction.type)}`,\n );\n }\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const sourceAmountRaw = getRawSourceAmountFromOrder({\n cryptoAmount: order.cryptoAmount,\n decimals: fiatAsset.decimals,\n });\n\n const baseRequest = quotes[0].request;\n const relayRequest: QuoteRequest = {\n ...baseRequest,\n isMaxAmount: true,\n isPostQuote: false,\n sourceBalanceRaw: sourceAmountRaw,\n sourceTokenAmount: sourceAmountRaw,\n };\n\n log('Re-quoting relay from completed fiat order', {\n completedOrderAmount: order.cryptoAmount,\n relayRequest,\n sourceAmountRaw,\n transactionId,\n });\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702: request.accountSupports7702,\n messenger,\n requests: [relayRequest],\n transaction,\n });\n\n if (!relayQuotes.length) {\n throw new Error('No relay quotes returned for completed fiat order');\n }\n\n const originalRelayQuote = quotes[0].original.relayQuote;\n validateRelaySlippage({\n originalTargetRaw: originalRelayQuote.details.currencyOut.amount,\n reQuotedTargetRaw: relayQuotes[0].original.details.currencyOut.amount,\n transactionId,\n });\n\n log('Received relay quotes for completed fiat order', {\n relayQuoteCount: relayQuotes.length,\n transactionId,\n });\n\n const relaySubmitRequest: PayStrategyExecuteRequest<RelayQuote> = {\n accountSupports7702: request.accountSupports7702,\n isSmartTransaction: request.isSmartTransaction,\n messenger,\n quotes: relayQuotes,\n transaction,\n };\n\n const relayResult = await submitRelayQuotes(relaySubmitRequest);\n\n log('Relay submission completed after fiat order', {\n relayResult,\n transactionId,\n });\n\n return relayResult;\n}\n"]}
|
|
@@ -31,10 +31,13 @@ async function getRelayQuotes(request) {
|
|
|
31
31
|
log('Fetching quotes', requests);
|
|
32
32
|
try {
|
|
33
33
|
const normalizedRequests = requests
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
singleRequest.
|
|
34
|
+
.filter((singleRequest) => {
|
|
35
|
+
const hasTargetMinimum = singleRequest.targetAmountMinimum !== '0';
|
|
36
|
+
const isPostQuote = Boolean(singleRequest.isPostQuote);
|
|
37
|
+
const isExactInputRequest = Boolean(singleRequest.isMaxAmount) &&
|
|
38
|
+
new bignumber_js_1.BigNumber(singleRequest.sourceTokenAmount).gt(0);
|
|
39
|
+
return hasTargetMinimum || isPostQuote || isExactInputRequest;
|
|
40
|
+
})
|
|
38
41
|
.map((singleRequest) => normalizeRequest(singleRequest));
|
|
39
42
|
log('Normalized requests', normalizedRequests);
|
|
40
43
|
return await Promise.all(normalizedRequests.map((singleRequest) => getQuoteWithMaxAmountHandling(singleRequest, request)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":";AAAA,2CAA2C;;;AAE3C,4CAA+C;AAC/C,iEAAmD;AAGnD,2CAAqD;AACrD,+CAAyC;AAEzC,uCAA+C;AAC/C,mDAUyB;AACzB,6CAA6C;AAS7C,qDAA0D;AAC1D,iEAMmC;AACnC,6CAAmD;AACnD,6DAGiC;AACjC,yDAA+D;AAE/D,iDAM2B;AAC3B,6DAAuE;AACvE,+CAAuD;AACvD,+CAA8C;AAC9C,uEAAqE;AAQrE,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,gBAAgB,CAAC,CAAC;AAEhE;;;;;GAKG;AACI,KAAK,UAAU,cAAc,CAClC,OAAoC;IAEpC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7B,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,kBAAkB,GAAG,QAAQ;YACjC,wEAAwE;YACxE,gEAAgE;aAC/D,MAAM,CACL,CAAC,aAAa,EAAE,EAAE,CAChB,aAAa,CAAC,mBAAmB,KAAK,GAAG;YACzC,aAAa,CAAC,WAAW,CAC5B;aACA,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;QAE3D,GAAG,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,CAAC;QAE/C,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,kBAAkB,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACvC,6BAA6B,CAAC,aAAa,EAAE,OAAO,CAAC,CACtD,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AA7BD,wCA6BC;AAED,KAAK,UAAU,6BAA6B,CAC1C,OAAqB,EACrB,WAAwC;IAExC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEhC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,gCAAgC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,IAAA,kDAA0B,EAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,gCAAgC,CAC7C,OAAqB,EACrB,WAAwC;IAExC,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAE/D,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAClE,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;IAE1D,MAAM,oBAAoB,GAAG,IAAI,wBAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC;SAClE,KAAK,CAAC,UAAU,CAAC;SACjB,YAAY,CAAC,wBAAS,CAAC,UAAU,CAAC,CAAC;IAEtC,GAAG,CAAC,qDAAqD,EAAE;QACzD,oBAAoB,EAAE,OAAO,CAAC,iBAAiB;QAC/C,UAAU;QACV,oBAAoB,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;KACxD,CAAC,CAAC;IAEH,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CACD,0EAA0E,CAC3E,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,cAAc,CACtC;YACE,GAAG,OAAO;YACV,iBAAiB,EAAE,oBAAoB,CAAC,OAAO,CAC7C,CAAC,EACD,wBAAS,CAAC,UAAU,CACrB;SACF,EACD,WAAW,CACZ,CAAC;QAEF,IACE,WAAW,CAAC,IAAI,CAAC,mBAAmB;YACpC,CAAC,WAAW,CAAC,IAAI,CAAC,mBAAmB,EACrC,CAAC;YACD,GAAG,CAAC,iEAAiE,CAAC,CAAC;YACvE,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,+CAA+C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,cAAc,CAC3B,OAAqB,EACrB,WAAwC;IAExC,MAAM,EACJ,mBAAmB,EAAE,YAAY,EACjC,SAAS,EACT,MAAM,EACN,WAAW,GACZ,GAAG,WAAW,CAAC;IAEhB,MAAM,EACJ,IAAI,EACJ,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,GAAG,OAAO,CAAC;IAEZ,MAAM,eAAe,GAAG,IAAA,2BAAW,EACjC,SAAS,EACT,aAAa,EACb,kBAAkB,CACnB,CAAC;IAEF,MAAM,iBAAiB,GAAG,IAAI,wBAAS,CAAC,eAAe,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAC1E,CAAC,CACF,CAAC;IAEF,IAAI,CAAC;QACH,yFAAyF;QACzF,wDAAwD;QACxD,+DAA+D;QAC/D,wEAAwE;QACxE,MAAM,aAAa,GAAG,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;QAEzD,MAAM,UAAU,GACd,YAAY;YACZ,IAAA,qCAAqB,EAAC,SAAS,CAAC;YAChC,IAAA,8BAAc,EAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAsB;YAC9B,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB;YAC/D,kBAAkB,EAAE,MAAM,CAAC,aAAa,CAAC;YACzC,mBAAmB,EAAE,kBAAkB;YACvC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;YACpC,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,UAAU;gBACZ,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAA,yCAAyB,EAAC,SAAS,CAAC,EAAE;gBAC7D,CAAC,CAAC,EAAE,CAAC;YACP,SAAS,EAAE,IAAI;YACf,iBAAiB;YACjB,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB;YAC5D,IAAI,EAAE,IAAI;SACX,CAAC;QAEF,8EAA8E;QAC9E,qEAAqE;QACrE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,mBAAmB,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC5B,2EAA2E;YAC3E,4EAA4E;YAC5E,iDAAiD;YACjD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACnC,CAAC;QAED,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QAE1B,MAAM,KAAK,GAAG,MAAM,IAAA,2BAAe,EAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAE7D,GAAG,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAElC,OAAO,MAAM,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,mBAAmB,CAChC,WAA4B,EAC5B,OAAqB,EACrB,WAA8B,EAC9B,SAA4C;IAE5C,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC;IACrD,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAC/C,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAuB,CAAC;IAE/C,MAAM,UAAU,GACd,kBAAkB,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,MAAM,WAAW,GAAG,aAAa,KAAK,8BAAkB,CAAC;IAEzD,MAAM,eAAe,GACnB,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,oCAAwB,CAAC,CAAC,CAAC;IAE5E,IAAI,eAAe,EAAE,CAAC;QACpB,WAAW,CAAC,SAAS,GAAG,oBAAoB,CAAC,UAAiB,CAAC,CAAC;QAEhE,GAAG,CAAC,sCAAsC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,CAAC;IAClE,MAAM,cAAc,GAAG,SAAS,IAAI,eAAe,IAAI,WAAW,CAAC;IAEnE,IAAI,cAAc,EAAE,CAAC;QACnB,GAAG,CAAC,4DAA4D,CAAC,CAAC;QAClE,OAAO;IACT,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,IAAI,CACrC,mDAAmD,EACnD,EAAE,WAAW,EAAE,CAChB,CAAC;IAEF,MAAM,2BAA2B,GAAG,UAAU,CAAC,iBAAiB,EAAE,GAAG,CACnE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACN,GAAG,CAAC;QACJ,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACtB,CAAC,EAAE,CAAC,CAAC,CAAQ;QACb,CAAC,EAAE,CAAC,CAAC,CAAQ;QACb,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;KAC3B,CAAC,CACH,CAAC;IAEF,WAAW,CAAC,iBAAiB,GAAG,2BAA2B,CAAC;IAC5D,WAAW,CAAC,SAAS,GAAG,cAAc,CAAC;IAEvC,MAAM,iBAAiB,GAAG,kBAAkB,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,oCAAwB,CAAC,CACpD,EAAE,IAAI,CAAC;IAER,qEAAqE;IACrE,oFAAoF;IACpF,IAAI,iBAAiB,EAAE,CAAC;QACtB,WAAW,CAAC,SAAS,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QAChE,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,GAAG,GAAG;QAChB;YACE,EAAE,EAAE,OAAO,CAAC,kBAAkB;YAC9B,IAAI,EAAE,sBAAsB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,mBAAmB,CAAC;YACvE,KAAK,EAAE,KAAK;SACb;QACD;YACE,EAAE,EAAE,UAAU,CAAC,EAAE;YACjB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,KAAK,EAAE,UAAU,CAAC,KAAK;SACxB;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,OAAqB;IAC7C,MAAM,UAAU,GAAG;QACjB,GAAG,OAAO;KACX,CAAC;IAEF,MAAM,oBAAoB,GACxB,CAAC,OAAO,CAAC,WAAW;QACpB,OAAO,CAAC,aAAa,KAAK,6BAAiB;QAC3C,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE;YACtC,iCAAqB,CAAC,WAAW,EAAE,CAAC;IAExC,UAAU,CAAC,kBAAkB,GAAG,IAAA,6BAAqB,EACnD,UAAU,CAAC,kBAAkB,EAC7B,UAAU,CAAC,aAAa,EACxB,0BAAkB,CAAC,KAAK,CACzB,CAAC;IACF,UAAU,CAAC,kBAAkB,GAAG,IAAA,6BAAqB,EACnD,UAAU,CAAC,kBAAkB,EAC7B,UAAU,CAAC,aAAa,EACxB,0BAAkB,CAAC,KAAK,CACzB,CAAC;IAEF,IAAI,oBAAoB,EAAE,CAAC;QACzB,UAAU,CAAC,aAAa,GAAG,8BAAkB,CAAC;QAC9C,UAAU,CAAC,kBAAkB,GAAG,kCAAsB,CAAC;QACvD,UAAU,CAAC,mBAAmB,GAAG,IAAI,wBAAS,CAAC,OAAO,CAAC,mBAAmB,CAAC;aACxE,SAAS,CAAC,mCAAuB,GAAG,yBAAa,CAAC;aAClD,QAAQ,CAAC,EAAE,CAAC,CAAC;QAEhB,GAAG,CAAC,2DAA2D,EAAE;YAC/D,eAAe,EAAE,OAAO;YACxB,iBAAiB,EAAE,UAAU;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAChC,UAAU,CAAC,aAAa,GAAG,8BAAkB,CAAC;QAC9C,UAAU,CAAC,kBAAkB,GAAG,kCAAsB,CAAC;QAEvD,IAAI,UAAU,CAAC,iBAAiB,EAAE,CAAC;YACjC,UAAU,CAAC,iBAAiB,GAAG,IAAI,wBAAS,CAAC,UAAU,CAAC,iBAAiB,CAAC;iBACvE,SAAS,CAAC,mCAAuB,GAAG,yBAAa,CAAC;iBAClD,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,cAAc,CAC3B,KAAiB,EACjB,OAAqB,EACrB,WAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC;IAClC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC1B,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE5C,MAAM,EAAE,aAAa,EAAE,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE3D,MAAM,IAAI,GAAG,IAAA,6BAAmB,EAC9B,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,EAChC,aAAa,CACd,CAAC;IAEF,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,IAAA,6BAAmB,EAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAElE,+EAA+E;IAC/E,MAAM,cAAc,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE;QACzB,CAAC,CAAC,IAAA,6BAAmB,EAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAEvD,MAAM,EACJ,SAAS,EACT,MAAM,EACN,aAAa,EAAE,mBAAmB,EAClC,GAAG,aAAa,EACjB,GAAG,MAAM,0BAA0B,CAClC,KAAK,EACL,SAAS,EACT,OAAO,EACP,WAAW,CAAC,WAAW,CACxB,CAAC;IAEF,MAAM,aAAa,GAAG;QACpB,GAAG,EAAE,GAAG;QACR,IAAI,EAAE,GAAG;KACV,CAAC;IAEF,MAAM,YAAY,GAAW;QAC3B,KAAK,EAAE,UAAU,CAAC,eAAe;QACjC,GAAG,EAAE,UAAU,CAAC,MAAM;QACtB,GAAG,IAAA,6BAAmB,EAAC,IAAI,wBAAS,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;KAC3E,CAAC;IAEF,MAAM,kBAAkB,GAAG,YAAY,CACrC,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,kBAAkB,CAC3B,CAAC;IAEF,MAAM,eAAe,GAAG,kBAAkB;QACxC,CAAC,CAAC,IAAI,wBAAS,CAAC,WAAW,CAAC,eAAe,CAAC;QAC5C,CAAC,CAAC,IAAI,wBAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAEzC,MAAM,YAAY,GAAG,IAAA,6BAAmB,EAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IAEzE,MAAM,QAAQ,GAAuB;QACnC,GAAG,KAAK,CAAC,QAAQ;QACjB,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC9C,MAAM;KACP,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,iBAAiB,EAAE,OAAO,CAAC,YAAY;QACvC,IAAI,EAAE;YACJ,mBAAmB;YACnB,QAAQ,EAAE,WAAW;YACrB,QAAQ;YACR,aAAa;YACb,aAAa;SACd;QACD,QAAQ,EAAE;YACR,GAAG,KAAK;YACR,QAAQ;SACT;QACD,OAAO;QACP,YAAY;QACZ,YAAY;QACZ,QAAQ,EAAE,0BAAsB,CAAC,KAAK;KACvC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,KAAiB,EAAE,OAAqB;IAChE,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACtC,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC;IAClE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;IAE1D,MAAM,aAAa,GAAG,IAAI,wBAAS,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAE1E,MAAM,OAAO,GAAG,IAAI,wBAAS,CAAC,aAAa,CAAC,CAAC,KAAK,CAChD,OAAO,CAAC,mBAAmB,CAC5B,CAAC;IAEF,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CACnB,SAA4C,EAC5C,OAAqB;IAKrB,8EAA8E;IAC9E,2EAA2E;IAC3E,iBAAiB;IACjB,MAAM,aAAa,GAAG,OAAO,CAAC,mBAAmB;QAC/C,CAAC,CAAC,6BAAiB;QACnB,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC1B,MAAM,kBAAkB,GAAG,OAAO,CAAC,mBAAmB;QACpD,CAAC,CAAC,iCAAqB;QACvB,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAE/B,MAAM,uBAAuB,GAC3B,aAAa,KAAK,4BAAgB;QAClC,kBAAkB,KAAK,gCAAoB;QACzC,CAAC,CAAC,IAAA,sBAAc,EAAC,aAAa,CAAC;QAC/B,CAAC,CAAC,kBAAkB,CAAC;IAEzB,MAAM,cAAc,GAAG,IAAA,wBAAgB,EACrC,SAAS,EACT,uBAAuB,EACvB,aAAa,CACd,CAAC;IAEF,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CACpE,cAAc,CAAC,OAAO,CACvB,CAAC;IAEF,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,KAAK,UAAU,0BAA0B,CACvC,KAAiB,EACjB,SAA4C,EAC5C,OAAqB,EACrB,WAA4B;IAQ5B,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAE5D,IAAI,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;QAC9B,GAAG,CAAC,uCAAuC,CAAC,CAAC;QAE7C,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QAEjE,OAAO;YACL,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,UAAU;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,KAAK;SACd,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,gEAAgE;IAChE,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAChC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QAEjE,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QAEjE,OAAO;YACL,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,UAAU;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,KAAK;SACd,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAChC,CAAC,IAAI,EAAgC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CACpE,CAAC;IACF,MAAM,WAAW,GAAG,OAAO;SACxB,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;SAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE5B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,oBAAoB,EAAE,EAAE,EAAE,KAAK,EAAE,GACpE,WAAW,CAAC,CAAC,CAAC,CAAC;IAEjB,MAAM,iBAAiB,GACrB,OAAO,CAAC,WAAW,IAAI,IAAA,0CAA4B,EAAC,WAAW,CAAC,CAAC;IAEnE,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAEtE,MAAM,YAAY,GAAG,MAAM,8BAA8B,CACvD,WAAW,EACX,SAAS,EACT,YAAY,CACb,CAAC;IAEF,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,GAC1D,OAAO,CAAC,WAAW;QACjB,CAAC,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC;QAChD,CAAC,CAAC,YAAY,CAAC;IAEnB,GAAG,CAAC,WAAW,EAAE;QACf,MAAM;QACN,gBAAgB;QAChB,aAAa;QACb,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAA,sBAAgB,EAAC;QAChC,OAAO;QACP,GAAG,EAAE,gBAAgB;QACrB,YAAY;QACZ,oBAAoB;QACpB,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAA,sBAAgB,EAAC;QAC3B,OAAO;QACP,GAAG,EAAE,aAAa;QAClB,YAAY;QACZ,oBAAoB;QACpB,SAAS;QACT,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,IAAA,uBAAe,EACnC,SAAS,EACT,IAAI,EACJ,aAAa,EACb,IAAA,sBAAc,EAAC,aAAa,CAAC,CAC9B,CAAC;IAEF,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpD,IAAI,IAAI,wBAAS,CAAC,aAAa,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACjE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,qBAAqB,GAAG,IAAA,sCAAwB,EACpD,SAAS,EACT,aAAa,CACd,CAAC;IAEF,IAAI,qBAAqB,CAAC,eAAe,EAAE,CAAC;QAC1C,GAAG,CAAC,wCAAwC,EAAE;YAC5C,aAAa;SACd,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,qBAAqB,CAAC,uBAAuB,EAAE,CAAC;QACnD,GAAG,CAAC,yDAAyD,EAAE;YAC7D,aAAa;SACd,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,wDAAwD,EAAE;QAC5D,aAAa;QACb,GAAG,EAAE,GAAG,CAAC,GAAG;KACb,CAAC,CAAC;IAEH,IAAI,iBAAiB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC1C,GAAG,CAAC,iEAAiE,EAAE;YACrE,YAAY,EAAE,OAAO,CAAC,QAAQ;YAC9B,kBAAkB;YAClB,gBAAgB;SACjB,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,MAAM,IAAA,+CAAiC,EAAC;YAC9D,aAAa,EAAE;gBACb,IAAI;gBACJ,EAAE;gBACF,KAAK;aACN;YACD,SAAS;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,aAAa;gBACb,kBAAkB;aACnB;YACD,gBAAgB;YAChB,cAAc,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC;SACvC,CAAC,CAAC;QAEH,IAAI,eAAe,EAAE,CAAC;YACpB,GAAG,CAAC,yDAAyD,EAAE;gBAC7D,eAAe;aAChB,CAAC,CAAC;YAEH,OAAO;gBACL,aAAa,EAAE,IAAI;gBACnB,QAAQ,EAAE,eAAe;gBACzB,GAAG,EAAE,eAAe;gBACpB,SAAS;gBACT,MAAM;aACP,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,IAAA,+CAAiC,EAAC;QAC9D,aAAa,EAAE;YACb,IAAI;YACJ,EAAE;YACF,KAAK;SACN;QACD,SAAS;QACT,OAAO,EAAE;YACP,IAAI;YACJ,aAAa;YACb,kBAAkB;SACnB;QACD,gBAAgB;QAChB,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;KAC/D,CAAC,CAAC;IAEH,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,wCAAwC,EAAE;QAC5C,eAAe;KAChB,CAAC,CAAC;IAEH,OAAO;QACL,aAAa,EAAE,IAAI;QACnB,QAAQ,EAAE,eAAe;QACzB,GAAG,EAAE,eAAe;QACpB,SAAS;QACT,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,8BAA8B,CAC3C,MAAkD,EAClD,SAA4C,EAC5C,YAAkB;IAOlB,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAC/C,0BAA0B,CAAC,YAAY,EAAE,YAAY,CAAC,CACvD,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,IAAA,kCAAsB,EAAC;QAClD,WAAW,EAAE,IAAA,+BAAe,EAAC,SAAS,CAAC,CAAC,gBAAgB;QACxD,2BAA2B,EAAE,IAAI;QACjC,SAAS;QACT,YAAY;KACb,CAAC,CAAC;IAEH,OAAO;QACL,SAAS,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnE,MAAM,EAAE,cAAc,CAAC,MAAM;QAC7B,gBAAgB,EAAE,cAAc,CAAC,gBAAgB;QACjD,aAAa,EAAE,cAAc,CAAC,aAAa;KAC5C,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,YAAsD,EACtD,YAAkB;IAElB,OAAO;QACL,OAAO,EAAE,IAAA,wBAAK,EAAC,YAAY,CAAC,OAAO,CAAC;QACpC,IAAI,EAAE,YAAY,CAAC,IAAI;QACvB,IAAI,EAAE,YAAY,IAAI,YAAY,CAAC,IAAI;QACvC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG;QAChD,EAAE,EAAE,YAAY,CAAC,EAAE;QACnB,KAAK,EAAE,YAAY,CAAC,KAAK,IAAI,GAAG;KACjC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,mBAAmB,CAC1B,QAKC,EACD,WAA4B;IAO5B,MAAM,SAAS,GAAG,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IAC5E,MAAM,MAAM,GAAG,SAAS,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;IACrD,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAE5E,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAE7B,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,iEAAiE;QACjE,mCAAmC;QACnC,SAAS,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,+DAA+D;QAC/D,8DAA8D;QAC9D,SAAS,GAAG,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,GAAG,aAAa,CAAC;IACnE,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;IAE7D,GAAG,CAAC,yCAAyC,EAAE;QAC7C,aAAa;QACb,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,SAAS;QACT,aAAa;KACd,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,aAAa;QACb,SAAS;QACT,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,KAAiB;IAC7C,OAAO,IAAI,wBAAS,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,SAAc,EAAE,SAAiB;IAC/D,OAAO,IAAI,eAAS,CAAC;QACnB,+CAA+C;KAChD,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAQ,CAAC;AACnE,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,IAAS;IACrC,OAAO,IAAI,eAAS,CAAC,CAAC,+CAA+C,CAAC,CAAC;SACpE,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC;SACpC,EAAE,CAAC,WAAW,EAAE,CAAC;AACtB,CAAC;AACD,SAAS,yBAAyB,CAAC,KAAiB;IAClD,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,aAAa,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC;IACjE,MAAM,eAAe,GAAG,IAAI,wBAAS,CAAC,aAAa,EAAE,eAAe,IAAI,GAAG,CAAC,CAAC;IAE7E,IAAI,CAAC,aAAa,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,OAAO,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,sBAAsB,GAAG,YAAY,CACzC,IAAA,wBAAK,EAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EACrC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAC/B,CAAC;IAEF,OAAO,sBAAsB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9D,CAAC;AAED,SAAS,YAAY,CAAC,OAAe,EAAE,YAAoB;IACzD,OAAO,OAAO,CACZ,uBAAW,CAAC,OAAc,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC,WAAW,EAAS,CAAC,CACzE,CAAC;AACJ,CAAC","sourcesContent":["/* eslint-disable require-atomic-updates */\n\nimport { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TransactionPayStrategy } from '../..';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n CHAIN_ID_POLYGON,\n HYPERCORE_USDC_ADDRESS,\n HYPERCORE_USDC_DECIMALS,\n NATIVE_TOKEN_ADDRESS,\n USDC_DECIMALS,\n STABLECOINS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd } from '../../utils/amounts';\nimport {\n getFeatureFlags,\n getRelayOriginGasOverhead,\n getSlippage,\n isEIP7702Chain,\n isRelayExecuteEnabled,\n} from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport {\n getGasStationCostInSourceTokenRaw,\n getGasStationEligibility,\n} from '../../utils/gas-station';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport { isPredictWithdrawTransaction } from '../../utils/transaction';\nimport { TOKEN_TRANSFER_FOUR_BYTE } from './constants';\nimport { fetchRelayQuote } from './relay-api';\nimport { getRelayMaxGasStationQuote } from './relay-max-gas-station';\nimport type {\n RelayQuote,\n RelayQuoteMetamask,\n RelayQuoteRequest,\n RelayTransactionStep,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Fetches Relay quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getRelayQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests\n // Ignore gas fee token requests (which have both target=0 and source=0)\n // but keep post-quote requests (identified by isPostQuote flag)\n .filter(\n (singleRequest) =>\n singleRequest.targetAmountMinimum !== '0' ||\n singleRequest.isPostQuote,\n )\n .map((singleRequest) => normalizeRequest(singleRequest));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getQuoteWithMaxAmountHandling(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\n }\n}\n\nasync function getQuoteWithMaxAmountHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { isMaxAmount } = request;\n\n if (!isMaxAmount) {\n return getQuoteWithPostQuoteGasHandling(request, fullRequest);\n }\n\n return getRelayMaxGasStationQuote(request, fullRequest, getSingleQuote);\n}\n\n/**\n * For post-quote flows, fetch an initial quote to compute gas cost in source\n * token, then re-quote with the source amount reduced by the gas cost.\n * This ensures Relay reserves enough for the gas fee token payment.\n *\n * For non-post-quote flows, just returns a single quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full request context.\n * @returns The final quote (phase 2 for post-quote, or phase 1 for normal).\n */\nasync function getQuoteWithPostQuoteGasHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const phase1Quote = await getSingleQuote(request, fullRequest);\n\n if (!request.isPostQuote || !phase1Quote.fees.isSourceGasFeeToken) {\n return phase1Quote;\n }\n\n const gasCostRaw = phase1Quote.fees.sourceNetwork.max.raw;\n\n const adjustedSourceAmount = new BigNumber(request.sourceTokenAmount)\n .minus(gasCostRaw)\n .integerValue(BigNumber.ROUND_DOWN);\n\n log('Subtracting gas from source for post-quote two-call', {\n originalSourceAmount: request.sourceTokenAmount,\n gasCostRaw,\n adjustedSourceAmount: adjustedSourceAmount.toString(10),\n });\n\n if (!adjustedSourceAmount.isGreaterThan(0)) {\n log(\n 'Insufficient balance after gas subtraction for post-quote, using phase 1',\n );\n return phase1Quote;\n }\n\n try {\n const phase2Quote = await getSingleQuote(\n {\n ...request,\n sourceTokenAmount: adjustedSourceAmount.toFixed(\n 0,\n BigNumber.ROUND_DOWN,\n ),\n },\n fullRequest,\n );\n\n if (\n phase1Quote.fees.isSourceGasFeeToken &&\n !phase2Quote.fees.isSourceGasFeeToken\n ) {\n log('Phase 2 lost gas fee token eligibility, falling back to phase 1');\n return phase1Quote;\n }\n\n return phase2Quote;\n } catch (error) {\n log('Phase 2 quote failed, falling back to phase 1', { error });\n return phase1Quote;\n }\n}\n\n/**\n * Fetches a single Relay quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full quotes request.\n * @returns Single quote.\n */\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const {\n accountSupports7702: supports7702,\n messenger,\n signal,\n transaction,\n } = fullRequest;\n\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const slippageTolerance = new BigNumber(slippageDecimal * 100 * 100).toFixed(\n 0,\n );\n\n try {\n // For post-quote or max amount flows, use EXACT_INPUT - user specifies how much to send,\n // and we show them how much they'll receive after fees.\n // For regular flows with a target amount, use EXPECTED_OUTPUT.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n const useExactInput = isMaxAmount || request.isPostQuote;\n\n const useExecute =\n supports7702 &&\n isRelayExecuteEnabled(messenger) &&\n isEIP7702Chain(messenger, sourceChainId);\n\n const body: RelayQuoteRequest = {\n amount: useExactInput ? sourceTokenAmount : targetAmountMinimum,\n destinationChainId: Number(targetChainId),\n destinationCurrency: targetTokenAddress,\n originChainId: Number(sourceChainId),\n originCurrency: sourceTokenAddress,\n ...(useExecute\n ? { originGasOverhead: getRelayOriginGasOverhead(messenger) }\n : {}),\n recipient: from,\n slippageTolerance,\n tradeType: useExactInput ? 'EXACT_INPUT' : 'EXPECTED_OUTPUT',\n user: from,\n };\n\n // Skip transaction processing for post-quote flows - the original transaction\n // will be included in the batch separately, not as part of the quote\n if (!request.isPostQuote) {\n await processTransactions(transaction, request, body, messenger);\n } else if (request.refundTo) {\n // For post-quote flows, honour the caller-specified refund address so that\n // failed Relay transactions refund to the correct account (e.g. the Predict\n // Safe proxy) rather than defaulting to the EOA.\n body.refundTo = request.refundTo;\n }\n\n log('Request body', body);\n\n const quote = await fetchRelayQuote(messenger, body, signal);\n\n log('Fetched relay quote', quote);\n\n return await normalizeQuote(quote, request, fullRequest);\n } catch (error) {\n log('Error fetching relay quote', error);\n throw error;\n }\n}\n\n/**\n * Add tranasction data to request body if needed.\n *\n * @param transaction - Transaction metadata.\n * @param request - Quote request.\n * @param requestBody - Request body to populate.\n * @param messenger - Controller messenger.\n */\nasync function processTransactions(\n transaction: TransactionMeta,\n request: QuoteRequest,\n requestBody: RelayQuoteRequest,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { nestedTransactions, txParams } = transaction;\n const { isMaxAmount, targetChainId } = request;\n const data = txParams?.data as Hex | undefined;\n\n const singleData =\n nestedTransactions?.length === 1 ? nestedTransactions[0].data : data;\n\n const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;\n\n const isTokenTransfer =\n !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));\n\n if (isTokenTransfer) {\n requestBody.recipient = getTransferRecipient(singleData as Hex);\n\n log('Updating recipient as token transfer', requestBody.recipient);\n }\n\n const hasNoData = singleData === undefined || singleData === '0x';\n const skipDelegation = hasNoData || isTokenTransfer || isHypercore;\n\n if (skipDelegation) {\n log('Skipping delegation as token transfer or Hypercore deposit');\n return;\n }\n\n if (isMaxAmount) {\n throw new Error('Max amount quotes do not support included transactions');\n }\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n const normalizedAuthorizationList = delegation.authorizationList?.map(\n (a) => ({\n ...a,\n chainId: Number(a.chainId),\n nonce: Number(a.nonce),\n r: a.r as Hex,\n s: a.s as Hex,\n yParity: Number(a.yParity),\n }),\n );\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n const tokenTransferData = nestedTransactions?.find((nestedTx) =>\n nestedTx.data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE),\n )?.data;\n\n // If the transactions include a token transfer, change the recipient\n // so any extra dust is also sent to the same address, rather than back to the user.\n if (tokenTransferData) {\n requestBody.recipient = getTransferRecipient(tokenTransferData);\n requestBody.refundTo = request.from;\n }\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: buildTokenTransferData(request.from, request.targetAmountMinimum),\n value: '0x0',\n },\n {\n to: delegation.to,\n data: delegation.data,\n value: delegation.value,\n },\n ];\n}\n\n/**\n * Normalizes requests for Relay.\n *\n * @param request - Quote request to normalize.\n * @returns Normalized request.\n */\nfunction normalizeRequest(request: QuoteRequest): QuoteRequest {\n const newRequest = {\n ...request,\n };\n\n const isHyperliquidDeposit =\n !request.isPostQuote &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n newRequest.sourceTokenAddress = normalizeTokenAddress(\n newRequest.sourceTokenAddress,\n newRequest.sourceChainId,\n TokenAddressTarget.Relay,\n );\n newRequest.targetTokenAddress = normalizeTokenAddress(\n newRequest.targetTokenAddress,\n newRequest.targetChainId,\n TokenAddressTarget.Relay,\n );\n\n if (isHyperliquidDeposit) {\n newRequest.targetChainId = CHAIN_ID_HYPERCORE;\n newRequest.targetTokenAddress = HYPERCORE_USDC_ADDRESS;\n newRequest.targetAmountMinimum = new BigNumber(request.targetAmountMinimum)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: newRequest,\n });\n }\n\n // HyperLiquid withdrawal: source is HyperCore Perps USDC, not Arbitrum.\n if (request.isHyperliquidSource) {\n newRequest.sourceChainId = CHAIN_ID_HYPERCORE;\n newRequest.sourceTokenAddress = HYPERCORE_USDC_ADDRESS;\n\n if (newRequest.sourceTokenAmount) {\n newRequest.sourceTokenAmount = new BigNumber(newRequest.sourceTokenAmount)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n }\n }\n\n return newRequest;\n}\n\n/**\n * Normalizes a Relay quote into a TransactionPayQuote.\n *\n * @param quote - Relay quote.\n * @param request - Original quote request.\n * @param fullRequest - Full quotes request.\n * @returns Normalized quote.\n */\nasync function normalizeQuote(\n quote: RelayQuote,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { messenger } = fullRequest;\n const { details } = quote;\n const { currencyIn, currencyOut } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const subsidizedFeeUsd = getSubsidizedFeeAmountUsd(quote);\n\n const appFeeUsd = new BigNumber(quote.fees?.app?.amountUsd ?? '0');\n const metaMaskFee = getFiatValueFromUsd(appFeeUsd, usdToFiatRate);\n\n // Subtract app fee from provider fee since totalImpact.usd already includes it\n const providerFeeUsd = calculateProviderFee(quote).minus(appFeeUsd);\n const provider = subsidizedFeeUsd.gt(0)\n ? { usd: '0', fiat: '0' }\n : getFiatValueFromUsd(providerFeeUsd, usdToFiatRate);\n\n const {\n gasLimits,\n is7702,\n isGasFeeToken: isSourceGasFeeToken,\n ...sourceNetwork\n } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n fullRequest.transaction,\n );\n\n const targetNetwork = {\n usd: '0',\n fiat: '0',\n };\n\n const sourceAmount: Amount = {\n human: currencyIn.amountFormatted,\n raw: currencyIn.amount,\n ...getFiatValueFromUsd(new BigNumber(currencyIn.amountUsd), usdToFiatRate),\n };\n\n const isTargetStablecoin = isStablecoin(\n request.targetChainId,\n request.targetTokenAddress,\n );\n\n const targetAmountUsd = isTargetStablecoin\n ? new BigNumber(currencyOut.amountFormatted)\n : new BigNumber(currencyOut.amountUsd);\n\n const targetAmount = getFiatValueFromUsd(targetAmountUsd, usdToFiatRate);\n\n const metamask: RelayQuoteMetamask = {\n ...quote.metamask,\n gasLimits: is7702 ? [gasLimits[0]] : gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n isSourceGasFeeToken,\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...quote,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Relay,\n };\n}\n\n/**\n * Calculate dust USD value.\n *\n * @param quote - Relay quote.\n * @param request - Quote request.\n * @returns Dust value in USD and fiat.\n */\nfunction calculateDustUsd(quote: RelayQuote, request: QuoteRequest): BigNumber {\n const { currencyOut } = quote.details;\n const { amountUsd, amountFormatted, minimumAmount } = currencyOut;\n const { decimals: targetDecimals } = currencyOut.currency;\n\n const targetUsdRate = new BigNumber(amountUsd).dividedBy(amountFormatted);\n\n const dustRaw = new BigNumber(minimumAmount).minus(\n request.targetAmountMinimum,\n );\n\n return dustRaw.shiftedBy(-targetDecimals).multipliedBy(targetUsdRate);\n}\n\n/**\n * Calculates USD to fiat rate.\n *\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @returns USD to fiat rate.\n */\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): {\n sourceFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n // For HyperLiquid source, the normalized chain/token (HyperCore + Perps USDC)\n // won't have a fiat rate entry. Use Arbitrum USDC instead since Perps USDC\n // is pegged 1:1.\n const sourceChainId = request.isHyperliquidSource\n ? CHAIN_ID_ARBITRUM\n : request.sourceChainId;\n const sourceTokenAddress = request.isHyperliquidSource\n ? ARBITRUM_USDC_ADDRESS\n : request.sourceTokenAddress;\n\n const finalSourceTokenAddress =\n sourceChainId === CHAIN_ID_POLYGON &&\n sourceTokenAddress === NATIVE_TOKEN_ADDRESS\n ? getNativeToken(sourceChainId)\n : sourceTokenAddress;\n\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n finalSourceTokenAddress,\n sourceChainId,\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, usdToFiatRate };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * For post-quote flows (e.g. predictWithdraw), the cost also includes the\n * original transaction's gas (the user's Polygon USDC.e transfer) in addition\n * to the Relay deposit transaction gas, by appending the original\n * transaction's params so that gas estimation and gas-fee-token logic handle\n * both transactions together.\n *\n * When the execute flow is active (indicated by `quote.metamask.isExecute`),\n * network fees are zeroed because the relayer covers them.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @param transaction - Original transaction metadata.\n * @returns Total source network cost in USD and fiat.\n */\nasync function calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n transaction: TransactionMeta,\n): Promise<\n TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] & {\n gasLimits: number[];\n isGasFeeToken?: boolean;\n is7702: boolean;\n }\n> {\n const { from, sourceChainId, sourceTokenAddress } = request;\n\n if (quote.metamask?.isExecute) {\n log('Zeroing network fees for execute flow');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n // HyperLiquid withdrawals are gasless -- the \"deposit\" step is an HL\n // sendAsset (off-chain signature), not an on-chain transaction.\n if (request.isHyperliquidSource) {\n log('Zeroing network fees for HyperLiquid withdrawal (gasless)');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n const txSteps = quote.steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const relayParams = txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data);\n\n const { chainId, data, maxFeePerGas, maxPriorityFeePerGas, to, value } =\n relayParams[0];\n\n const isPredictWithdraw =\n request.isPostQuote && isPredictWithdrawTransaction(transaction);\n\n const fromOverride = isPredictWithdraw ? request.refundTo : undefined;\n\n const relayOnlyGas = await calculateSourceNetworkGasLimit(\n relayParams,\n messenger,\n fromOverride,\n );\n\n const { gasLimits, is7702, totalGasEstimate, totalGasLimit } =\n request.isPostQuote\n ? combinePostQuoteGas(relayOnlyGas, transaction)\n : relayOnlyGas;\n\n log('Gas limit', {\n is7702,\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n });\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasEstimate,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n isMax: true,\n });\n\n const nativeBalance = getTokenBalance(\n messenger,\n from,\n sourceChainId,\n getNativeToken(sourceChainId),\n );\n\n const result = { estimate, max, gasLimits, is7702 };\n\n if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {\n return result;\n }\n\n const gasStationEligibility = getGasStationEligibility(\n messenger,\n sourceChainId,\n );\n\n if (gasStationEligibility.isDisabledChain) {\n log('Skipping gas station as disabled chain', {\n sourceChainId,\n });\n\n return result;\n }\n\n if (!gasStationEligibility.chainSupportsGasStation) {\n log('Skipping gas station as chain does not support EIP-7702', {\n sourceChainId,\n });\n\n return result;\n }\n\n log('Checking gas fee tokens as insufficient native balance', {\n nativeBalance,\n max: max.raw,\n });\n\n if (isPredictWithdraw && request.refundTo) {\n log('Using proxy address for predict withdraw gas station simulation', {\n proxyAddress: request.refundTo,\n sourceTokenAddress,\n totalGasEstimate,\n });\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from: request.refundTo,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: relayParams.length + 1,\n });\n\n if (gasFeeTokenCost) {\n log('Using predict withdraw gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n }\n\n return result;\n }\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: Math.max(relayParams.length, gasLimits.length),\n });\n\n if (!gasFeeTokenCost) {\n return result;\n }\n\n log('Using gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n}\n\n/**\n * Calculate the total gas limit for the source network.\n *\n * @param params - Array of relay transaction parameters.\n * @param messenger - Controller messenger.\n * @param fromOverride - Optional address to use as `from` in gas estimation\n * instead of the address in the relay params. Used in predict withdraw flows\n * to estimate with the proxy/Safe address that holds the source token balance.\n * @returns Total gas estimates and per-transaction gas limits.\n */\nasync function calculateSourceNetworkGasLimit(\n params: RelayTransactionStep['items'][0]['data'][],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n}> {\n const transactions = params.map((singleParams) =>\n toRelayQuoteGasTransaction(singleParams, fromOverride),\n );\n\n const relayGasResult = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions,\n });\n\n return {\n gasLimits: relayGasResult.gasLimits.map((gasLimit) => gasLimit.max),\n is7702: relayGasResult.is7702,\n totalGasEstimate: relayGasResult.totalGasEstimate,\n totalGasLimit: relayGasResult.totalGasLimit,\n };\n}\n\nfunction toRelayQuoteGasTransaction(\n singleParams: RelayTransactionStep['items'][0]['data'],\n fromOverride?: Hex,\n): QuoteGasTransaction {\n return {\n chainId: toHex(singleParams.chainId),\n data: singleParams.data,\n from: fromOverride ?? singleParams.from,\n gas: fromOverride ? undefined : singleParams.gas,\n to: singleParams.to,\n value: singleParams.value ?? '0',\n };\n}\n\n/**\n * Combine the original transaction's gas with relay gas for post-quote flows.\n *\n * Prefers gas from `nestedTransactions` (preserves the caller-provided value)\n * since TransactionController may re-estimate `txParams.gas` during batch\n * creation.\n *\n * @param relayGas - Gas estimates from relay transactions.\n * @param relayGas.totalGasEstimate - Estimated gas total.\n * @param relayGas.totalGasLimit - Maximum gas total.\n * @param relayGas.gasLimits - Per-transaction gas limits.\n * @param relayGas.is7702 - Whether the relay gas came from a combined 7702 batch estimate.\n * @param transaction - Original transaction metadata.\n * @returns Combined gas estimates including the original transaction.\n */\nfunction combinePostQuoteGas(\n relayGas: {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n },\n transaction: TransactionMeta,\n): {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n} {\n const nestedGas = transaction.nestedTransactions?.find((tx) => tx.gas)?.gas;\n const rawGas = nestedGas ?? transaction.txParams.gas;\n const originalTxGas = rawGas ? new BigNumber(rawGas).toNumber() : undefined;\n\n if (originalTxGas === undefined) {\n return relayGas;\n }\n\n let { gasLimits } = relayGas;\n\n if (relayGas.is7702) {\n // Combined 7702 gas limit — add the original tx gas so the batch\n // keeps using a single 7702 limit.\n gasLimits = [gasLimits[0] + originalTxGas];\n } else {\n // Multiple individual gas limits — prepend the original tx gas\n // so the list order matches relay-submit's transaction order.\n gasLimits = [originalTxGas, ...gasLimits];\n }\n\n const totalGasEstimate = relayGas.totalGasEstimate + originalTxGas;\n const totalGasLimit = relayGas.totalGasLimit + originalTxGas;\n\n log('Combined original tx gas with relay gas', {\n originalTxGas,\n is7702: relayGas.is7702,\n gasLimits,\n totalGasLimit,\n });\n\n return {\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n is7702: relayGas.is7702,\n };\n}\n\n/**\n * Calculate the provider fee for a Relay quote.\n *\n * @param quote - Relay quote.\n * @returns - Provider fee in USD.\n */\nfunction calculateProviderFee(quote: RelayQuote): BigNumber {\n return new BigNumber(quote.details.totalImpact.usd).abs();\n}\n\n/**\n * Build token transfer data.\n *\n * @param recipient - Recipient address.\n * @param amountRaw - Amount in raw format.\n * @returns Token transfer data.\n */\nfunction buildTokenTransferData(recipient: Hex, amountRaw: string): Hex {\n return new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [recipient, amountRaw]) as Hex;\n}\n\n/**\n * Get transfer recipient from token transfer data.\n *\n * @param data - Token transfer data.\n * @returns Transfer recipient.\n */\nfunction getTransferRecipient(data: Hex): Hex {\n return new Interface(['function transfer(address to, uint256 amount)'])\n .decodeFunctionData('transfer', data)\n .to.toLowerCase();\n}\nfunction getSubsidizedFeeAmountUsd(quote: RelayQuote): BigNumber {\n const subsidizedFee = quote.fees?.subsidized;\n const amountUsd = new BigNumber(subsidizedFee?.amountUsd ?? '0');\n const amountFormatted = new BigNumber(subsidizedFee?.amountFormatted ?? '0');\n\n if (!subsidizedFee || amountUsd.isZero()) {\n return new BigNumber(0);\n }\n\n const isSubsidizedStablecoin = isStablecoin(\n toHex(subsidizedFee.currency.chainId),\n subsidizedFee.currency.address,\n );\n\n return isSubsidizedStablecoin ? amountFormatted : amountUsd;\n}\n\nfunction isStablecoin(chainId: string, tokenAddress: string): boolean {\n return Boolean(\n STABLECOINS[chainId as Hex]?.includes(tokenAddress.toLowerCase() as Hex),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable require-atomic-updates */\n\nimport { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TransactionPayStrategy } from '../..';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n CHAIN_ID_POLYGON,\n HYPERCORE_USDC_ADDRESS,\n HYPERCORE_USDC_DECIMALS,\n NATIVE_TOKEN_ADDRESS,\n USDC_DECIMALS,\n STABLECOINS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd } from '../../utils/amounts';\nimport {\n getFeatureFlags,\n getRelayOriginGasOverhead,\n getSlippage,\n isEIP7702Chain,\n isRelayExecuteEnabled,\n} from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport {\n getGasStationCostInSourceTokenRaw,\n getGasStationEligibility,\n} from '../../utils/gas-station';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport { isPredictWithdrawTransaction } from '../../utils/transaction';\nimport { TOKEN_TRANSFER_FOUR_BYTE } from './constants';\nimport { fetchRelayQuote } from './relay-api';\nimport { getRelayMaxGasStationQuote } from './relay-max-gas-station';\nimport type {\n RelayQuote,\n RelayQuoteMetamask,\n RelayQuoteRequest,\n RelayTransactionStep,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Fetches Relay quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getRelayQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests\n .filter((singleRequest) => {\n const hasTargetMinimum = singleRequest.targetAmountMinimum !== '0';\n const isPostQuote = Boolean(singleRequest.isPostQuote);\n const isExactInputRequest =\n Boolean(singleRequest.isMaxAmount) &&\n new BigNumber(singleRequest.sourceTokenAmount).gt(0);\n\n return hasTargetMinimum || isPostQuote || isExactInputRequest;\n })\n .map((singleRequest) => normalizeRequest(singleRequest));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getQuoteWithMaxAmountHandling(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\n }\n}\n\nasync function getQuoteWithMaxAmountHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { isMaxAmount } = request;\n\n if (!isMaxAmount) {\n return getQuoteWithPostQuoteGasHandling(request, fullRequest);\n }\n\n return getRelayMaxGasStationQuote(request, fullRequest, getSingleQuote);\n}\n\n/**\n * For post-quote flows, fetch an initial quote to compute gas cost in source\n * token, then re-quote with the source amount reduced by the gas cost.\n * This ensures Relay reserves enough for the gas fee token payment.\n *\n * For non-post-quote flows, just returns a single quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full request context.\n * @returns The final quote (phase 2 for post-quote, or phase 1 for normal).\n */\nasync function getQuoteWithPostQuoteGasHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const phase1Quote = await getSingleQuote(request, fullRequest);\n\n if (!request.isPostQuote || !phase1Quote.fees.isSourceGasFeeToken) {\n return phase1Quote;\n }\n\n const gasCostRaw = phase1Quote.fees.sourceNetwork.max.raw;\n\n const adjustedSourceAmount = new BigNumber(request.sourceTokenAmount)\n .minus(gasCostRaw)\n .integerValue(BigNumber.ROUND_DOWN);\n\n log('Subtracting gas from source for post-quote two-call', {\n originalSourceAmount: request.sourceTokenAmount,\n gasCostRaw,\n adjustedSourceAmount: adjustedSourceAmount.toString(10),\n });\n\n if (!adjustedSourceAmount.isGreaterThan(0)) {\n log(\n 'Insufficient balance after gas subtraction for post-quote, using phase 1',\n );\n return phase1Quote;\n }\n\n try {\n const phase2Quote = await getSingleQuote(\n {\n ...request,\n sourceTokenAmount: adjustedSourceAmount.toFixed(\n 0,\n BigNumber.ROUND_DOWN,\n ),\n },\n fullRequest,\n );\n\n if (\n phase1Quote.fees.isSourceGasFeeToken &&\n !phase2Quote.fees.isSourceGasFeeToken\n ) {\n log('Phase 2 lost gas fee token eligibility, falling back to phase 1');\n return phase1Quote;\n }\n\n return phase2Quote;\n } catch (error) {\n log('Phase 2 quote failed, falling back to phase 1', { error });\n return phase1Quote;\n }\n}\n\n/**\n * Fetches a single Relay quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full quotes request.\n * @returns Single quote.\n */\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const {\n accountSupports7702: supports7702,\n messenger,\n signal,\n transaction,\n } = fullRequest;\n\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const slippageTolerance = new BigNumber(slippageDecimal * 100 * 100).toFixed(\n 0,\n );\n\n try {\n // For post-quote or max amount flows, use EXACT_INPUT - user specifies how much to send,\n // and we show them how much they'll receive after fees.\n // For regular flows with a target amount, use EXPECTED_OUTPUT.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n const useExactInput = isMaxAmount || request.isPostQuote;\n\n const useExecute =\n supports7702 &&\n isRelayExecuteEnabled(messenger) &&\n isEIP7702Chain(messenger, sourceChainId);\n\n const body: RelayQuoteRequest = {\n amount: useExactInput ? sourceTokenAmount : targetAmountMinimum,\n destinationChainId: Number(targetChainId),\n destinationCurrency: targetTokenAddress,\n originChainId: Number(sourceChainId),\n originCurrency: sourceTokenAddress,\n ...(useExecute\n ? { originGasOverhead: getRelayOriginGasOverhead(messenger) }\n : {}),\n recipient: from,\n slippageTolerance,\n tradeType: useExactInput ? 'EXACT_INPUT' : 'EXPECTED_OUTPUT',\n user: from,\n };\n\n // Skip transaction processing for post-quote flows - the original transaction\n // will be included in the batch separately, not as part of the quote\n if (!request.isPostQuote) {\n await processTransactions(transaction, request, body, messenger);\n } else if (request.refundTo) {\n // For post-quote flows, honour the caller-specified refund address so that\n // failed Relay transactions refund to the correct account (e.g. the Predict\n // Safe proxy) rather than defaulting to the EOA.\n body.refundTo = request.refundTo;\n }\n\n log('Request body', body);\n\n const quote = await fetchRelayQuote(messenger, body, signal);\n\n log('Fetched relay quote', quote);\n\n return await normalizeQuote(quote, request, fullRequest);\n } catch (error) {\n log('Error fetching relay quote', error);\n throw error;\n }\n}\n\n/**\n * Add tranasction data to request body if needed.\n *\n * @param transaction - Transaction metadata.\n * @param request - Quote request.\n * @param requestBody - Request body to populate.\n * @param messenger - Controller messenger.\n */\nasync function processTransactions(\n transaction: TransactionMeta,\n request: QuoteRequest,\n requestBody: RelayQuoteRequest,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { nestedTransactions, txParams } = transaction;\n const { isMaxAmount, targetChainId } = request;\n const data = txParams?.data as Hex | undefined;\n\n const singleData =\n nestedTransactions?.length === 1 ? nestedTransactions[0].data : data;\n\n const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;\n\n const isTokenTransfer =\n !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));\n\n if (isTokenTransfer) {\n requestBody.recipient = getTransferRecipient(singleData as Hex);\n\n log('Updating recipient as token transfer', requestBody.recipient);\n }\n\n const hasNoData = singleData === undefined || singleData === '0x';\n const skipDelegation = hasNoData || isTokenTransfer || isHypercore;\n\n if (skipDelegation) {\n log('Skipping delegation as token transfer or Hypercore deposit');\n return;\n }\n\n if (isMaxAmount) {\n throw new Error('Max amount quotes do not support included transactions');\n }\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n const normalizedAuthorizationList = delegation.authorizationList?.map(\n (a) => ({\n ...a,\n chainId: Number(a.chainId),\n nonce: Number(a.nonce),\n r: a.r as Hex,\n s: a.s as Hex,\n yParity: Number(a.yParity),\n }),\n );\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n const tokenTransferData = nestedTransactions?.find((nestedTx) =>\n nestedTx.data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE),\n )?.data;\n\n // If the transactions include a token transfer, change the recipient\n // so any extra dust is also sent to the same address, rather than back to the user.\n if (tokenTransferData) {\n requestBody.recipient = getTransferRecipient(tokenTransferData);\n requestBody.refundTo = request.from;\n }\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: buildTokenTransferData(request.from, request.targetAmountMinimum),\n value: '0x0',\n },\n {\n to: delegation.to,\n data: delegation.data,\n value: delegation.value,\n },\n ];\n}\n\n/**\n * Normalizes requests for Relay.\n *\n * @param request - Quote request to normalize.\n * @returns Normalized request.\n */\nfunction normalizeRequest(request: QuoteRequest): QuoteRequest {\n const newRequest = {\n ...request,\n };\n\n const isHyperliquidDeposit =\n !request.isPostQuote &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n newRequest.sourceTokenAddress = normalizeTokenAddress(\n newRequest.sourceTokenAddress,\n newRequest.sourceChainId,\n TokenAddressTarget.Relay,\n );\n newRequest.targetTokenAddress = normalizeTokenAddress(\n newRequest.targetTokenAddress,\n newRequest.targetChainId,\n TokenAddressTarget.Relay,\n );\n\n if (isHyperliquidDeposit) {\n newRequest.targetChainId = CHAIN_ID_HYPERCORE;\n newRequest.targetTokenAddress = HYPERCORE_USDC_ADDRESS;\n newRequest.targetAmountMinimum = new BigNumber(request.targetAmountMinimum)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: newRequest,\n });\n }\n\n // HyperLiquid withdrawal: source is HyperCore Perps USDC, not Arbitrum.\n if (request.isHyperliquidSource) {\n newRequest.sourceChainId = CHAIN_ID_HYPERCORE;\n newRequest.sourceTokenAddress = HYPERCORE_USDC_ADDRESS;\n\n if (newRequest.sourceTokenAmount) {\n newRequest.sourceTokenAmount = new BigNumber(newRequest.sourceTokenAmount)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n }\n }\n\n return newRequest;\n}\n\n/**\n * Normalizes a Relay quote into a TransactionPayQuote.\n *\n * @param quote - Relay quote.\n * @param request - Original quote request.\n * @param fullRequest - Full quotes request.\n * @returns Normalized quote.\n */\nasync function normalizeQuote(\n quote: RelayQuote,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { messenger } = fullRequest;\n const { details } = quote;\n const { currencyIn, currencyOut } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const subsidizedFeeUsd = getSubsidizedFeeAmountUsd(quote);\n\n const appFeeUsd = new BigNumber(quote.fees?.app?.amountUsd ?? '0');\n const metaMaskFee = getFiatValueFromUsd(appFeeUsd, usdToFiatRate);\n\n // Subtract app fee from provider fee since totalImpact.usd already includes it\n const providerFeeUsd = calculateProviderFee(quote).minus(appFeeUsd);\n const provider = subsidizedFeeUsd.gt(0)\n ? { usd: '0', fiat: '0' }\n : getFiatValueFromUsd(providerFeeUsd, usdToFiatRate);\n\n const {\n gasLimits,\n is7702,\n isGasFeeToken: isSourceGasFeeToken,\n ...sourceNetwork\n } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n fullRequest.transaction,\n );\n\n const targetNetwork = {\n usd: '0',\n fiat: '0',\n };\n\n const sourceAmount: Amount = {\n human: currencyIn.amountFormatted,\n raw: currencyIn.amount,\n ...getFiatValueFromUsd(new BigNumber(currencyIn.amountUsd), usdToFiatRate),\n };\n\n const isTargetStablecoin = isStablecoin(\n request.targetChainId,\n request.targetTokenAddress,\n );\n\n const targetAmountUsd = isTargetStablecoin\n ? new BigNumber(currencyOut.amountFormatted)\n : new BigNumber(currencyOut.amountUsd);\n\n const targetAmount = getFiatValueFromUsd(targetAmountUsd, usdToFiatRate);\n\n const metamask: RelayQuoteMetamask = {\n ...quote.metamask,\n gasLimits: is7702 ? [gasLimits[0]] : gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n isSourceGasFeeToken,\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...quote,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Relay,\n };\n}\n\n/**\n * Calculate dust USD value.\n *\n * @param quote - Relay quote.\n * @param request - Quote request.\n * @returns Dust value in USD and fiat.\n */\nfunction calculateDustUsd(quote: RelayQuote, request: QuoteRequest): BigNumber {\n const { currencyOut } = quote.details;\n const { amountUsd, amountFormatted, minimumAmount } = currencyOut;\n const { decimals: targetDecimals } = currencyOut.currency;\n\n const targetUsdRate = new BigNumber(amountUsd).dividedBy(amountFormatted);\n\n const dustRaw = new BigNumber(minimumAmount).minus(\n request.targetAmountMinimum,\n );\n\n return dustRaw.shiftedBy(-targetDecimals).multipliedBy(targetUsdRate);\n}\n\n/**\n * Calculates USD to fiat rate.\n *\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @returns USD to fiat rate.\n */\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): {\n sourceFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n // For HyperLiquid source, the normalized chain/token (HyperCore + Perps USDC)\n // won't have a fiat rate entry. Use Arbitrum USDC instead since Perps USDC\n // is pegged 1:1.\n const sourceChainId = request.isHyperliquidSource\n ? CHAIN_ID_ARBITRUM\n : request.sourceChainId;\n const sourceTokenAddress = request.isHyperliquidSource\n ? ARBITRUM_USDC_ADDRESS\n : request.sourceTokenAddress;\n\n const finalSourceTokenAddress =\n sourceChainId === CHAIN_ID_POLYGON &&\n sourceTokenAddress === NATIVE_TOKEN_ADDRESS\n ? getNativeToken(sourceChainId)\n : sourceTokenAddress;\n\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n finalSourceTokenAddress,\n sourceChainId,\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, usdToFiatRate };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * For post-quote flows (e.g. predictWithdraw), the cost also includes the\n * original transaction's gas (the user's Polygon USDC.e transfer) in addition\n * to the Relay deposit transaction gas, by appending the original\n * transaction's params so that gas estimation and gas-fee-token logic handle\n * both transactions together.\n *\n * When the execute flow is active (indicated by `quote.metamask.isExecute`),\n * network fees are zeroed because the relayer covers them.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @param transaction - Original transaction metadata.\n * @returns Total source network cost in USD and fiat.\n */\nasync function calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n transaction: TransactionMeta,\n): Promise<\n TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] & {\n gasLimits: number[];\n isGasFeeToken?: boolean;\n is7702: boolean;\n }\n> {\n const { from, sourceChainId, sourceTokenAddress } = request;\n\n if (quote.metamask?.isExecute) {\n log('Zeroing network fees for execute flow');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n // HyperLiquid withdrawals are gasless -- the \"deposit\" step is an HL\n // sendAsset (off-chain signature), not an on-chain transaction.\n if (request.isHyperliquidSource) {\n log('Zeroing network fees for HyperLiquid withdrawal (gasless)');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n const txSteps = quote.steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const relayParams = txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data);\n\n const { chainId, data, maxFeePerGas, maxPriorityFeePerGas, to, value } =\n relayParams[0];\n\n const isPredictWithdraw =\n request.isPostQuote && isPredictWithdrawTransaction(transaction);\n\n const fromOverride = isPredictWithdraw ? request.refundTo : undefined;\n\n const relayOnlyGas = await calculateSourceNetworkGasLimit(\n relayParams,\n messenger,\n fromOverride,\n );\n\n const { gasLimits, is7702, totalGasEstimate, totalGasLimit } =\n request.isPostQuote\n ? combinePostQuoteGas(relayOnlyGas, transaction)\n : relayOnlyGas;\n\n log('Gas limit', {\n is7702,\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n });\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasEstimate,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n isMax: true,\n });\n\n const nativeBalance = getTokenBalance(\n messenger,\n from,\n sourceChainId,\n getNativeToken(sourceChainId),\n );\n\n const result = { estimate, max, gasLimits, is7702 };\n\n if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {\n return result;\n }\n\n const gasStationEligibility = getGasStationEligibility(\n messenger,\n sourceChainId,\n );\n\n if (gasStationEligibility.isDisabledChain) {\n log('Skipping gas station as disabled chain', {\n sourceChainId,\n });\n\n return result;\n }\n\n if (!gasStationEligibility.chainSupportsGasStation) {\n log('Skipping gas station as chain does not support EIP-7702', {\n sourceChainId,\n });\n\n return result;\n }\n\n log('Checking gas fee tokens as insufficient native balance', {\n nativeBalance,\n max: max.raw,\n });\n\n if (isPredictWithdraw && request.refundTo) {\n log('Using proxy address for predict withdraw gas station simulation', {\n proxyAddress: request.refundTo,\n sourceTokenAddress,\n totalGasEstimate,\n });\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from: request.refundTo,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: relayParams.length + 1,\n });\n\n if (gasFeeTokenCost) {\n log('Using predict withdraw gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n }\n\n return result;\n }\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: Math.max(relayParams.length, gasLimits.length),\n });\n\n if (!gasFeeTokenCost) {\n return result;\n }\n\n log('Using gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n}\n\n/**\n * Calculate the total gas limit for the source network.\n *\n * @param params - Array of relay transaction parameters.\n * @param messenger - Controller messenger.\n * @param fromOverride - Optional address to use as `from` in gas estimation\n * instead of the address in the relay params. Used in predict withdraw flows\n * to estimate with the proxy/Safe address that holds the source token balance.\n * @returns Total gas estimates and per-transaction gas limits.\n */\nasync function calculateSourceNetworkGasLimit(\n params: RelayTransactionStep['items'][0]['data'][],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n}> {\n const transactions = params.map((singleParams) =>\n toRelayQuoteGasTransaction(singleParams, fromOverride),\n );\n\n const relayGasResult = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions,\n });\n\n return {\n gasLimits: relayGasResult.gasLimits.map((gasLimit) => gasLimit.max),\n is7702: relayGasResult.is7702,\n totalGasEstimate: relayGasResult.totalGasEstimate,\n totalGasLimit: relayGasResult.totalGasLimit,\n };\n}\n\nfunction toRelayQuoteGasTransaction(\n singleParams: RelayTransactionStep['items'][0]['data'],\n fromOverride?: Hex,\n): QuoteGasTransaction {\n return {\n chainId: toHex(singleParams.chainId),\n data: singleParams.data,\n from: fromOverride ?? singleParams.from,\n gas: fromOverride ? undefined : singleParams.gas,\n to: singleParams.to,\n value: singleParams.value ?? '0',\n };\n}\n\n/**\n * Combine the original transaction's gas with relay gas for post-quote flows.\n *\n * Prefers gas from `nestedTransactions` (preserves the caller-provided value)\n * since TransactionController may re-estimate `txParams.gas` during batch\n * creation.\n *\n * @param relayGas - Gas estimates from relay transactions.\n * @param relayGas.totalGasEstimate - Estimated gas total.\n * @param relayGas.totalGasLimit - Maximum gas total.\n * @param relayGas.gasLimits - Per-transaction gas limits.\n * @param relayGas.is7702 - Whether the relay gas came from a combined 7702 batch estimate.\n * @param transaction - Original transaction metadata.\n * @returns Combined gas estimates including the original transaction.\n */\nfunction combinePostQuoteGas(\n relayGas: {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n },\n transaction: TransactionMeta,\n): {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n} {\n const nestedGas = transaction.nestedTransactions?.find((tx) => tx.gas)?.gas;\n const rawGas = nestedGas ?? transaction.txParams.gas;\n const originalTxGas = rawGas ? new BigNumber(rawGas).toNumber() : undefined;\n\n if (originalTxGas === undefined) {\n return relayGas;\n }\n\n let { gasLimits } = relayGas;\n\n if (relayGas.is7702) {\n // Combined 7702 gas limit — add the original tx gas so the batch\n // keeps using a single 7702 limit.\n gasLimits = [gasLimits[0] + originalTxGas];\n } else {\n // Multiple individual gas limits — prepend the original tx gas\n // so the list order matches relay-submit's transaction order.\n gasLimits = [originalTxGas, ...gasLimits];\n }\n\n const totalGasEstimate = relayGas.totalGasEstimate + originalTxGas;\n const totalGasLimit = relayGas.totalGasLimit + originalTxGas;\n\n log('Combined original tx gas with relay gas', {\n originalTxGas,\n is7702: relayGas.is7702,\n gasLimits,\n totalGasLimit,\n });\n\n return {\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n is7702: relayGas.is7702,\n };\n}\n\n/**\n * Calculate the provider fee for a Relay quote.\n *\n * @param quote - Relay quote.\n * @returns - Provider fee in USD.\n */\nfunction calculateProviderFee(quote: RelayQuote): BigNumber {\n return new BigNumber(quote.details.totalImpact.usd).abs();\n}\n\n/**\n * Build token transfer data.\n *\n * @param recipient - Recipient address.\n * @param amountRaw - Amount in raw format.\n * @returns Token transfer data.\n */\nfunction buildTokenTransferData(recipient: Hex, amountRaw: string): Hex {\n return new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [recipient, amountRaw]) as Hex;\n}\n\n/**\n * Get transfer recipient from token transfer data.\n *\n * @param data - Token transfer data.\n * @returns Transfer recipient.\n */\nfunction getTransferRecipient(data: Hex): Hex {\n return new Interface(['function transfer(address to, uint256 amount)'])\n .decodeFunctionData('transfer', data)\n .to.toLowerCase();\n}\nfunction getSubsidizedFeeAmountUsd(quote: RelayQuote): BigNumber {\n const subsidizedFee = quote.fees?.subsidized;\n const amountUsd = new BigNumber(subsidizedFee?.amountUsd ?? '0');\n const amountFormatted = new BigNumber(subsidizedFee?.amountFormatted ?? '0');\n\n if (!subsidizedFee || amountUsd.isZero()) {\n return new BigNumber(0);\n }\n\n const isSubsidizedStablecoin = isStablecoin(\n toHex(subsidizedFee.currency.chainId),\n subsidizedFee.currency.address,\n );\n\n return isSubsidizedStablecoin ? amountFormatted : amountUsd;\n}\n\nfunction isStablecoin(chainId: string, tokenAddress: string): boolean {\n return Boolean(\n STABLECOINS[chainId as Hex]?.includes(tokenAddress.toLowerCase() as Hex),\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AA2BrB,OAAO,KAAK,EACV,UAAU,EAIX,oBAAgB;AAIjB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"relay-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AA2BrB,OAAO,KAAK,EACV,UAAU,EAIX,oBAAgB;AAIjB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CA6B5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AA2BrB,OAAO,KAAK,EACV,UAAU,EAIX,oBAAgB;AAIjB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"relay-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AA2BrB,OAAO,KAAK,EACV,UAAU,EAIX,oBAAgB;AAIjB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CA6B5C"}
|
|
@@ -28,10 +28,13 @@ export async function getRelayQuotes(request) {
|
|
|
28
28
|
log('Fetching quotes', requests);
|
|
29
29
|
try {
|
|
30
30
|
const normalizedRequests = requests
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
singleRequest.
|
|
31
|
+
.filter((singleRequest) => {
|
|
32
|
+
const hasTargetMinimum = singleRequest.targetAmountMinimum !== '0';
|
|
33
|
+
const isPostQuote = Boolean(singleRequest.isPostQuote);
|
|
34
|
+
const isExactInputRequest = Boolean(singleRequest.isMaxAmount) &&
|
|
35
|
+
new BigNumber(singleRequest.sourceTokenAmount).gt(0);
|
|
36
|
+
return hasTargetMinimum || isPostQuote || isExactInputRequest;
|
|
37
|
+
})
|
|
35
38
|
.map((singleRequest) => normalizeRequest(singleRequest));
|
|
36
39
|
log('Normalized requests', normalizedRequests);
|
|
37
40
|
return await Promise.all(normalizedRequests.map((singleRequest) => getQuoteWithMaxAmountHandling(singleRequest, request)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable require-atomic-updates */\n\nimport { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TransactionPayStrategy } from '../..';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n CHAIN_ID_POLYGON,\n HYPERCORE_USDC_ADDRESS,\n HYPERCORE_USDC_DECIMALS,\n NATIVE_TOKEN_ADDRESS,\n USDC_DECIMALS,\n STABLECOINS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd } from '../../utils/amounts';\nimport {\n getFeatureFlags,\n getRelayOriginGasOverhead,\n getSlippage,\n isEIP7702Chain,\n isRelayExecuteEnabled,\n} from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport {\n getGasStationCostInSourceTokenRaw,\n getGasStationEligibility,\n} from '../../utils/gas-station';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport { isPredictWithdrawTransaction } from '../../utils/transaction';\nimport { TOKEN_TRANSFER_FOUR_BYTE } from './constants';\nimport { fetchRelayQuote } from './relay-api';\nimport { getRelayMaxGasStationQuote } from './relay-max-gas-station';\nimport type {\n RelayQuote,\n RelayQuoteMetamask,\n RelayQuoteRequest,\n RelayTransactionStep,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Fetches Relay quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getRelayQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests\n // Ignore gas fee token requests (which have both target=0 and source=0)\n // but keep post-quote requests (identified by isPostQuote flag)\n .filter(\n (singleRequest) =>\n singleRequest.targetAmountMinimum !== '0' ||\n singleRequest.isPostQuote,\n )\n .map((singleRequest) => normalizeRequest(singleRequest));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getQuoteWithMaxAmountHandling(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\n }\n}\n\nasync function getQuoteWithMaxAmountHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { isMaxAmount } = request;\n\n if (!isMaxAmount) {\n return getQuoteWithPostQuoteGasHandling(request, fullRequest);\n }\n\n return getRelayMaxGasStationQuote(request, fullRequest, getSingleQuote);\n}\n\n/**\n * For post-quote flows, fetch an initial quote to compute gas cost in source\n * token, then re-quote with the source amount reduced by the gas cost.\n * This ensures Relay reserves enough for the gas fee token payment.\n *\n * For non-post-quote flows, just returns a single quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full request context.\n * @returns The final quote (phase 2 for post-quote, or phase 1 for normal).\n */\nasync function getQuoteWithPostQuoteGasHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const phase1Quote = await getSingleQuote(request, fullRequest);\n\n if (!request.isPostQuote || !phase1Quote.fees.isSourceGasFeeToken) {\n return phase1Quote;\n }\n\n const gasCostRaw = phase1Quote.fees.sourceNetwork.max.raw;\n\n const adjustedSourceAmount = new BigNumber(request.sourceTokenAmount)\n .minus(gasCostRaw)\n .integerValue(BigNumber.ROUND_DOWN);\n\n log('Subtracting gas from source for post-quote two-call', {\n originalSourceAmount: request.sourceTokenAmount,\n gasCostRaw,\n adjustedSourceAmount: adjustedSourceAmount.toString(10),\n });\n\n if (!adjustedSourceAmount.isGreaterThan(0)) {\n log(\n 'Insufficient balance after gas subtraction for post-quote, using phase 1',\n );\n return phase1Quote;\n }\n\n try {\n const phase2Quote = await getSingleQuote(\n {\n ...request,\n sourceTokenAmount: adjustedSourceAmount.toFixed(\n 0,\n BigNumber.ROUND_DOWN,\n ),\n },\n fullRequest,\n );\n\n if (\n phase1Quote.fees.isSourceGasFeeToken &&\n !phase2Quote.fees.isSourceGasFeeToken\n ) {\n log('Phase 2 lost gas fee token eligibility, falling back to phase 1');\n return phase1Quote;\n }\n\n return phase2Quote;\n } catch (error) {\n log('Phase 2 quote failed, falling back to phase 1', { error });\n return phase1Quote;\n }\n}\n\n/**\n * Fetches a single Relay quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full quotes request.\n * @returns Single quote.\n */\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const {\n accountSupports7702: supports7702,\n messenger,\n signal,\n transaction,\n } = fullRequest;\n\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const slippageTolerance = new BigNumber(slippageDecimal * 100 * 100).toFixed(\n 0,\n );\n\n try {\n // For post-quote or max amount flows, use EXACT_INPUT - user specifies how much to send,\n // and we show them how much they'll receive after fees.\n // For regular flows with a target amount, use EXPECTED_OUTPUT.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n const useExactInput = isMaxAmount || request.isPostQuote;\n\n const useExecute =\n supports7702 &&\n isRelayExecuteEnabled(messenger) &&\n isEIP7702Chain(messenger, sourceChainId);\n\n const body: RelayQuoteRequest = {\n amount: useExactInput ? sourceTokenAmount : targetAmountMinimum,\n destinationChainId: Number(targetChainId),\n destinationCurrency: targetTokenAddress,\n originChainId: Number(sourceChainId),\n originCurrency: sourceTokenAddress,\n ...(useExecute\n ? { originGasOverhead: getRelayOriginGasOverhead(messenger) }\n : {}),\n recipient: from,\n slippageTolerance,\n tradeType: useExactInput ? 'EXACT_INPUT' : 'EXPECTED_OUTPUT',\n user: from,\n };\n\n // Skip transaction processing for post-quote flows - the original transaction\n // will be included in the batch separately, not as part of the quote\n if (!request.isPostQuote) {\n await processTransactions(transaction, request, body, messenger);\n } else if (request.refundTo) {\n // For post-quote flows, honour the caller-specified refund address so that\n // failed Relay transactions refund to the correct account (e.g. the Predict\n // Safe proxy) rather than defaulting to the EOA.\n body.refundTo = request.refundTo;\n }\n\n log('Request body', body);\n\n const quote = await fetchRelayQuote(messenger, body, signal);\n\n log('Fetched relay quote', quote);\n\n return await normalizeQuote(quote, request, fullRequest);\n } catch (error) {\n log('Error fetching relay quote', error);\n throw error;\n }\n}\n\n/**\n * Add tranasction data to request body if needed.\n *\n * @param transaction - Transaction metadata.\n * @param request - Quote request.\n * @param requestBody - Request body to populate.\n * @param messenger - Controller messenger.\n */\nasync function processTransactions(\n transaction: TransactionMeta,\n request: QuoteRequest,\n requestBody: RelayQuoteRequest,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { nestedTransactions, txParams } = transaction;\n const { isMaxAmount, targetChainId } = request;\n const data = txParams?.data as Hex | undefined;\n\n const singleData =\n nestedTransactions?.length === 1 ? nestedTransactions[0].data : data;\n\n const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;\n\n const isTokenTransfer =\n !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));\n\n if (isTokenTransfer) {\n requestBody.recipient = getTransferRecipient(singleData as Hex);\n\n log('Updating recipient as token transfer', requestBody.recipient);\n }\n\n const hasNoData = singleData === undefined || singleData === '0x';\n const skipDelegation = hasNoData || isTokenTransfer || isHypercore;\n\n if (skipDelegation) {\n log('Skipping delegation as token transfer or Hypercore deposit');\n return;\n }\n\n if (isMaxAmount) {\n throw new Error('Max amount quotes do not support included transactions');\n }\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n const normalizedAuthorizationList = delegation.authorizationList?.map(\n (a) => ({\n ...a,\n chainId: Number(a.chainId),\n nonce: Number(a.nonce),\n r: a.r as Hex,\n s: a.s as Hex,\n yParity: Number(a.yParity),\n }),\n );\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n const tokenTransferData = nestedTransactions?.find((nestedTx) =>\n nestedTx.data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE),\n )?.data;\n\n // If the transactions include a token transfer, change the recipient\n // so any extra dust is also sent to the same address, rather than back to the user.\n if (tokenTransferData) {\n requestBody.recipient = getTransferRecipient(tokenTransferData);\n requestBody.refundTo = request.from;\n }\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: buildTokenTransferData(request.from, request.targetAmountMinimum),\n value: '0x0',\n },\n {\n to: delegation.to,\n data: delegation.data,\n value: delegation.value,\n },\n ];\n}\n\n/**\n * Normalizes requests for Relay.\n *\n * @param request - Quote request to normalize.\n * @returns Normalized request.\n */\nfunction normalizeRequest(request: QuoteRequest): QuoteRequest {\n const newRequest = {\n ...request,\n };\n\n const isHyperliquidDeposit =\n !request.isPostQuote &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n newRequest.sourceTokenAddress = normalizeTokenAddress(\n newRequest.sourceTokenAddress,\n newRequest.sourceChainId,\n TokenAddressTarget.Relay,\n );\n newRequest.targetTokenAddress = normalizeTokenAddress(\n newRequest.targetTokenAddress,\n newRequest.targetChainId,\n TokenAddressTarget.Relay,\n );\n\n if (isHyperliquidDeposit) {\n newRequest.targetChainId = CHAIN_ID_HYPERCORE;\n newRequest.targetTokenAddress = HYPERCORE_USDC_ADDRESS;\n newRequest.targetAmountMinimum = new BigNumber(request.targetAmountMinimum)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: newRequest,\n });\n }\n\n // HyperLiquid withdrawal: source is HyperCore Perps USDC, not Arbitrum.\n if (request.isHyperliquidSource) {\n newRequest.sourceChainId = CHAIN_ID_HYPERCORE;\n newRequest.sourceTokenAddress = HYPERCORE_USDC_ADDRESS;\n\n if (newRequest.sourceTokenAmount) {\n newRequest.sourceTokenAmount = new BigNumber(newRequest.sourceTokenAmount)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n }\n }\n\n return newRequest;\n}\n\n/**\n * Normalizes a Relay quote into a TransactionPayQuote.\n *\n * @param quote - Relay quote.\n * @param request - Original quote request.\n * @param fullRequest - Full quotes request.\n * @returns Normalized quote.\n */\nasync function normalizeQuote(\n quote: RelayQuote,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { messenger } = fullRequest;\n const { details } = quote;\n const { currencyIn, currencyOut } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const subsidizedFeeUsd = getSubsidizedFeeAmountUsd(quote);\n\n const appFeeUsd = new BigNumber(quote.fees?.app?.amountUsd ?? '0');\n const metaMaskFee = getFiatValueFromUsd(appFeeUsd, usdToFiatRate);\n\n // Subtract app fee from provider fee since totalImpact.usd already includes it\n const providerFeeUsd = calculateProviderFee(quote).minus(appFeeUsd);\n const provider = subsidizedFeeUsd.gt(0)\n ? { usd: '0', fiat: '0' }\n : getFiatValueFromUsd(providerFeeUsd, usdToFiatRate);\n\n const {\n gasLimits,\n is7702,\n isGasFeeToken: isSourceGasFeeToken,\n ...sourceNetwork\n } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n fullRequest.transaction,\n );\n\n const targetNetwork = {\n usd: '0',\n fiat: '0',\n };\n\n const sourceAmount: Amount = {\n human: currencyIn.amountFormatted,\n raw: currencyIn.amount,\n ...getFiatValueFromUsd(new BigNumber(currencyIn.amountUsd), usdToFiatRate),\n };\n\n const isTargetStablecoin = isStablecoin(\n request.targetChainId,\n request.targetTokenAddress,\n );\n\n const targetAmountUsd = isTargetStablecoin\n ? new BigNumber(currencyOut.amountFormatted)\n : new BigNumber(currencyOut.amountUsd);\n\n const targetAmount = getFiatValueFromUsd(targetAmountUsd, usdToFiatRate);\n\n const metamask: RelayQuoteMetamask = {\n ...quote.metamask,\n gasLimits: is7702 ? [gasLimits[0]] : gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n isSourceGasFeeToken,\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...quote,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Relay,\n };\n}\n\n/**\n * Calculate dust USD value.\n *\n * @param quote - Relay quote.\n * @param request - Quote request.\n * @returns Dust value in USD and fiat.\n */\nfunction calculateDustUsd(quote: RelayQuote, request: QuoteRequest): BigNumber {\n const { currencyOut } = quote.details;\n const { amountUsd, amountFormatted, minimumAmount } = currencyOut;\n const { decimals: targetDecimals } = currencyOut.currency;\n\n const targetUsdRate = new BigNumber(amountUsd).dividedBy(amountFormatted);\n\n const dustRaw = new BigNumber(minimumAmount).minus(\n request.targetAmountMinimum,\n );\n\n return dustRaw.shiftedBy(-targetDecimals).multipliedBy(targetUsdRate);\n}\n\n/**\n * Calculates USD to fiat rate.\n *\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @returns USD to fiat rate.\n */\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): {\n sourceFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n // For HyperLiquid source, the normalized chain/token (HyperCore + Perps USDC)\n // won't have a fiat rate entry. Use Arbitrum USDC instead since Perps USDC\n // is pegged 1:1.\n const sourceChainId = request.isHyperliquidSource\n ? CHAIN_ID_ARBITRUM\n : request.sourceChainId;\n const sourceTokenAddress = request.isHyperliquidSource\n ? ARBITRUM_USDC_ADDRESS\n : request.sourceTokenAddress;\n\n const finalSourceTokenAddress =\n sourceChainId === CHAIN_ID_POLYGON &&\n sourceTokenAddress === NATIVE_TOKEN_ADDRESS\n ? getNativeToken(sourceChainId)\n : sourceTokenAddress;\n\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n finalSourceTokenAddress,\n sourceChainId,\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, usdToFiatRate };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * For post-quote flows (e.g. predictWithdraw), the cost also includes the\n * original transaction's gas (the user's Polygon USDC.e transfer) in addition\n * to the Relay deposit transaction gas, by appending the original\n * transaction's params so that gas estimation and gas-fee-token logic handle\n * both transactions together.\n *\n * When the execute flow is active (indicated by `quote.metamask.isExecute`),\n * network fees are zeroed because the relayer covers them.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @param transaction - Original transaction metadata.\n * @returns Total source network cost in USD and fiat.\n */\nasync function calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n transaction: TransactionMeta,\n): Promise<\n TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] & {\n gasLimits: number[];\n isGasFeeToken?: boolean;\n is7702: boolean;\n }\n> {\n const { from, sourceChainId, sourceTokenAddress } = request;\n\n if (quote.metamask?.isExecute) {\n log('Zeroing network fees for execute flow');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n // HyperLiquid withdrawals are gasless -- the \"deposit\" step is an HL\n // sendAsset (off-chain signature), not an on-chain transaction.\n if (request.isHyperliquidSource) {\n log('Zeroing network fees for HyperLiquid withdrawal (gasless)');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n const txSteps = quote.steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const relayParams = txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data);\n\n const { chainId, data, maxFeePerGas, maxPriorityFeePerGas, to, value } =\n relayParams[0];\n\n const isPredictWithdraw =\n request.isPostQuote && isPredictWithdrawTransaction(transaction);\n\n const fromOverride = isPredictWithdraw ? request.refundTo : undefined;\n\n const relayOnlyGas = await calculateSourceNetworkGasLimit(\n relayParams,\n messenger,\n fromOverride,\n );\n\n const { gasLimits, is7702, totalGasEstimate, totalGasLimit } =\n request.isPostQuote\n ? combinePostQuoteGas(relayOnlyGas, transaction)\n : relayOnlyGas;\n\n log('Gas limit', {\n is7702,\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n });\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasEstimate,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n isMax: true,\n });\n\n const nativeBalance = getTokenBalance(\n messenger,\n from,\n sourceChainId,\n getNativeToken(sourceChainId),\n );\n\n const result = { estimate, max, gasLimits, is7702 };\n\n if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {\n return result;\n }\n\n const gasStationEligibility = getGasStationEligibility(\n messenger,\n sourceChainId,\n );\n\n if (gasStationEligibility.isDisabledChain) {\n log('Skipping gas station as disabled chain', {\n sourceChainId,\n });\n\n return result;\n }\n\n if (!gasStationEligibility.chainSupportsGasStation) {\n log('Skipping gas station as chain does not support EIP-7702', {\n sourceChainId,\n });\n\n return result;\n }\n\n log('Checking gas fee tokens as insufficient native balance', {\n nativeBalance,\n max: max.raw,\n });\n\n if (isPredictWithdraw && request.refundTo) {\n log('Using proxy address for predict withdraw gas station simulation', {\n proxyAddress: request.refundTo,\n sourceTokenAddress,\n totalGasEstimate,\n });\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from: request.refundTo,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: relayParams.length + 1,\n });\n\n if (gasFeeTokenCost) {\n log('Using predict withdraw gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n }\n\n return result;\n }\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: Math.max(relayParams.length, gasLimits.length),\n });\n\n if (!gasFeeTokenCost) {\n return result;\n }\n\n log('Using gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n}\n\n/**\n * Calculate the total gas limit for the source network.\n *\n * @param params - Array of relay transaction parameters.\n * @param messenger - Controller messenger.\n * @param fromOverride - Optional address to use as `from` in gas estimation\n * instead of the address in the relay params. Used in predict withdraw flows\n * to estimate with the proxy/Safe address that holds the source token balance.\n * @returns Total gas estimates and per-transaction gas limits.\n */\nasync function calculateSourceNetworkGasLimit(\n params: RelayTransactionStep['items'][0]['data'][],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n}> {\n const transactions = params.map((singleParams) =>\n toRelayQuoteGasTransaction(singleParams, fromOverride),\n );\n\n const relayGasResult = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions,\n });\n\n return {\n gasLimits: relayGasResult.gasLimits.map((gasLimit) => gasLimit.max),\n is7702: relayGasResult.is7702,\n totalGasEstimate: relayGasResult.totalGasEstimate,\n totalGasLimit: relayGasResult.totalGasLimit,\n };\n}\n\nfunction toRelayQuoteGasTransaction(\n singleParams: RelayTransactionStep['items'][0]['data'],\n fromOverride?: Hex,\n): QuoteGasTransaction {\n return {\n chainId: toHex(singleParams.chainId),\n data: singleParams.data,\n from: fromOverride ?? singleParams.from,\n gas: fromOverride ? undefined : singleParams.gas,\n to: singleParams.to,\n value: singleParams.value ?? '0',\n };\n}\n\n/**\n * Combine the original transaction's gas with relay gas for post-quote flows.\n *\n * Prefers gas from `nestedTransactions` (preserves the caller-provided value)\n * since TransactionController may re-estimate `txParams.gas` during batch\n * creation.\n *\n * @param relayGas - Gas estimates from relay transactions.\n * @param relayGas.totalGasEstimate - Estimated gas total.\n * @param relayGas.totalGasLimit - Maximum gas total.\n * @param relayGas.gasLimits - Per-transaction gas limits.\n * @param relayGas.is7702 - Whether the relay gas came from a combined 7702 batch estimate.\n * @param transaction - Original transaction metadata.\n * @returns Combined gas estimates including the original transaction.\n */\nfunction combinePostQuoteGas(\n relayGas: {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n },\n transaction: TransactionMeta,\n): {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n} {\n const nestedGas = transaction.nestedTransactions?.find((tx) => tx.gas)?.gas;\n const rawGas = nestedGas ?? transaction.txParams.gas;\n const originalTxGas = rawGas ? new BigNumber(rawGas).toNumber() : undefined;\n\n if (originalTxGas === undefined) {\n return relayGas;\n }\n\n let { gasLimits } = relayGas;\n\n if (relayGas.is7702) {\n // Combined 7702 gas limit — add the original tx gas so the batch\n // keeps using a single 7702 limit.\n gasLimits = [gasLimits[0] + originalTxGas];\n } else {\n // Multiple individual gas limits — prepend the original tx gas\n // so the list order matches relay-submit's transaction order.\n gasLimits = [originalTxGas, ...gasLimits];\n }\n\n const totalGasEstimate = relayGas.totalGasEstimate + originalTxGas;\n const totalGasLimit = relayGas.totalGasLimit + originalTxGas;\n\n log('Combined original tx gas with relay gas', {\n originalTxGas,\n is7702: relayGas.is7702,\n gasLimits,\n totalGasLimit,\n });\n\n return {\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n is7702: relayGas.is7702,\n };\n}\n\n/**\n * Calculate the provider fee for a Relay quote.\n *\n * @param quote - Relay quote.\n * @returns - Provider fee in USD.\n */\nfunction calculateProviderFee(quote: RelayQuote): BigNumber {\n return new BigNumber(quote.details.totalImpact.usd).abs();\n}\n\n/**\n * Build token transfer data.\n *\n * @param recipient - Recipient address.\n * @param amountRaw - Amount in raw format.\n * @returns Token transfer data.\n */\nfunction buildTokenTransferData(recipient: Hex, amountRaw: string): Hex {\n return new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [recipient, amountRaw]) as Hex;\n}\n\n/**\n * Get transfer recipient from token transfer data.\n *\n * @param data - Token transfer data.\n * @returns Transfer recipient.\n */\nfunction getTransferRecipient(data: Hex): Hex {\n return new Interface(['function transfer(address to, uint256 amount)'])\n .decodeFunctionData('transfer', data)\n .to.toLowerCase();\n}\nfunction getSubsidizedFeeAmountUsd(quote: RelayQuote): BigNumber {\n const subsidizedFee = quote.fees?.subsidized;\n const amountUsd = new BigNumber(subsidizedFee?.amountUsd ?? '0');\n const amountFormatted = new BigNumber(subsidizedFee?.amountFormatted ?? '0');\n\n if (!subsidizedFee || amountUsd.isZero()) {\n return new BigNumber(0);\n }\n\n const isSubsidizedStablecoin = isStablecoin(\n toHex(subsidizedFee.currency.chainId),\n subsidizedFee.currency.address,\n );\n\n return isSubsidizedStablecoin ? amountFormatted : amountUsd;\n}\n\nfunction isStablecoin(chainId: string, tokenAddress: string): boolean {\n return Boolean(\n STABLECOINS[chainId as Hex]?.includes(tokenAddress.toLowerCase() as Hex),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-quotes.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable require-atomic-updates */\n\nimport { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TransactionPayStrategy } from '../..';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n CHAIN_ID_POLYGON,\n HYPERCORE_USDC_ADDRESS,\n HYPERCORE_USDC_DECIMALS,\n NATIVE_TOKEN_ADDRESS,\n USDC_DECIMALS,\n STABLECOINS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatRates,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { getFiatValueFromUsd } from '../../utils/amounts';\nimport {\n getFeatureFlags,\n getRelayOriginGasOverhead,\n getSlippage,\n isEIP7702Chain,\n isRelayExecuteEnabled,\n} from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport {\n getGasStationCostInSourceTokenRaw,\n getGasStationEligibility,\n} from '../../utils/gas-station';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport { isPredictWithdrawTransaction } from '../../utils/transaction';\nimport { TOKEN_TRANSFER_FOUR_BYTE } from './constants';\nimport { fetchRelayQuote } from './relay-api';\nimport { getRelayMaxGasStationQuote } from './relay-max-gas-station';\nimport type {\n RelayQuote,\n RelayQuoteMetamask,\n RelayQuoteRequest,\n RelayTransactionStep,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Fetches Relay quotes.\n *\n * @param request - Request object.\n * @returns Array of quotes.\n */\nexport async function getRelayQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>[]> {\n const { requests } = request;\n\n log('Fetching quotes', requests);\n\n try {\n const normalizedRequests = requests\n .filter((singleRequest) => {\n const hasTargetMinimum = singleRequest.targetAmountMinimum !== '0';\n const isPostQuote = Boolean(singleRequest.isPostQuote);\n const isExactInputRequest =\n Boolean(singleRequest.isMaxAmount) &&\n new BigNumber(singleRequest.sourceTokenAmount).gt(0);\n\n return hasTargetMinimum || isPostQuote || isExactInputRequest;\n })\n .map((singleRequest) => normalizeRequest(singleRequest));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((singleRequest) =>\n getQuoteWithMaxAmountHandling(singleRequest, request),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\n }\n}\n\nasync function getQuoteWithMaxAmountHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { isMaxAmount } = request;\n\n if (!isMaxAmount) {\n return getQuoteWithPostQuoteGasHandling(request, fullRequest);\n }\n\n return getRelayMaxGasStationQuote(request, fullRequest, getSingleQuote);\n}\n\n/**\n * For post-quote flows, fetch an initial quote to compute gas cost in source\n * token, then re-quote with the source amount reduced by the gas cost.\n * This ensures Relay reserves enough for the gas fee token payment.\n *\n * For non-post-quote flows, just returns a single quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full request context.\n * @returns The final quote (phase 2 for post-quote, or phase 1 for normal).\n */\nasync function getQuoteWithPostQuoteGasHandling(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const phase1Quote = await getSingleQuote(request, fullRequest);\n\n if (!request.isPostQuote || !phase1Quote.fees.isSourceGasFeeToken) {\n return phase1Quote;\n }\n\n const gasCostRaw = phase1Quote.fees.sourceNetwork.max.raw;\n\n const adjustedSourceAmount = new BigNumber(request.sourceTokenAmount)\n .minus(gasCostRaw)\n .integerValue(BigNumber.ROUND_DOWN);\n\n log('Subtracting gas from source for post-quote two-call', {\n originalSourceAmount: request.sourceTokenAmount,\n gasCostRaw,\n adjustedSourceAmount: adjustedSourceAmount.toString(10),\n });\n\n if (!adjustedSourceAmount.isGreaterThan(0)) {\n log(\n 'Insufficient balance after gas subtraction for post-quote, using phase 1',\n );\n return phase1Quote;\n }\n\n try {\n const phase2Quote = await getSingleQuote(\n {\n ...request,\n sourceTokenAmount: adjustedSourceAmount.toFixed(\n 0,\n BigNumber.ROUND_DOWN,\n ),\n },\n fullRequest,\n );\n\n if (\n phase1Quote.fees.isSourceGasFeeToken &&\n !phase2Quote.fees.isSourceGasFeeToken\n ) {\n log('Phase 2 lost gas fee token eligibility, falling back to phase 1');\n return phase1Quote;\n }\n\n return phase2Quote;\n } catch (error) {\n log('Phase 2 quote failed, falling back to phase 1', { error });\n return phase1Quote;\n }\n}\n\n/**\n * Fetches a single Relay quote.\n *\n * @param request - Quote request.\n * @param fullRequest - Full quotes request.\n * @returns Single quote.\n */\nasync function getSingleQuote(\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const {\n accountSupports7702: supports7702,\n messenger,\n signal,\n transaction,\n } = fullRequest;\n\n const {\n from,\n isMaxAmount,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = request;\n\n const slippageDecimal = getSlippage(\n messenger,\n sourceChainId,\n sourceTokenAddress,\n );\n\n const slippageTolerance = new BigNumber(slippageDecimal * 100 * 100).toFixed(\n 0,\n );\n\n try {\n // For post-quote or max amount flows, use EXACT_INPUT - user specifies how much to send,\n // and we show them how much they'll receive after fees.\n // For regular flows with a target amount, use EXPECTED_OUTPUT.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n const useExactInput = isMaxAmount || request.isPostQuote;\n\n const useExecute =\n supports7702 &&\n isRelayExecuteEnabled(messenger) &&\n isEIP7702Chain(messenger, sourceChainId);\n\n const body: RelayQuoteRequest = {\n amount: useExactInput ? sourceTokenAmount : targetAmountMinimum,\n destinationChainId: Number(targetChainId),\n destinationCurrency: targetTokenAddress,\n originChainId: Number(sourceChainId),\n originCurrency: sourceTokenAddress,\n ...(useExecute\n ? { originGasOverhead: getRelayOriginGasOverhead(messenger) }\n : {}),\n recipient: from,\n slippageTolerance,\n tradeType: useExactInput ? 'EXACT_INPUT' : 'EXPECTED_OUTPUT',\n user: from,\n };\n\n // Skip transaction processing for post-quote flows - the original transaction\n // will be included in the batch separately, not as part of the quote\n if (!request.isPostQuote) {\n await processTransactions(transaction, request, body, messenger);\n } else if (request.refundTo) {\n // For post-quote flows, honour the caller-specified refund address so that\n // failed Relay transactions refund to the correct account (e.g. the Predict\n // Safe proxy) rather than defaulting to the EOA.\n body.refundTo = request.refundTo;\n }\n\n log('Request body', body);\n\n const quote = await fetchRelayQuote(messenger, body, signal);\n\n log('Fetched relay quote', quote);\n\n return await normalizeQuote(quote, request, fullRequest);\n } catch (error) {\n log('Error fetching relay quote', error);\n throw error;\n }\n}\n\n/**\n * Add tranasction data to request body if needed.\n *\n * @param transaction - Transaction metadata.\n * @param request - Quote request.\n * @param requestBody - Request body to populate.\n * @param messenger - Controller messenger.\n */\nasync function processTransactions(\n transaction: TransactionMeta,\n request: QuoteRequest,\n requestBody: RelayQuoteRequest,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { nestedTransactions, txParams } = transaction;\n const { isMaxAmount, targetChainId } = request;\n const data = txParams?.data as Hex | undefined;\n\n const singleData =\n nestedTransactions?.length === 1 ? nestedTransactions[0].data : data;\n\n const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;\n\n const isTokenTransfer =\n !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));\n\n if (isTokenTransfer) {\n requestBody.recipient = getTransferRecipient(singleData as Hex);\n\n log('Updating recipient as token transfer', requestBody.recipient);\n }\n\n const hasNoData = singleData === undefined || singleData === '0x';\n const skipDelegation = hasNoData || isTokenTransfer || isHypercore;\n\n if (skipDelegation) {\n log('Skipping delegation as token transfer or Hypercore deposit');\n return;\n }\n\n if (isMaxAmount) {\n throw new Error('Max amount quotes do not support included transactions');\n }\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n const normalizedAuthorizationList = delegation.authorizationList?.map(\n (a) => ({\n ...a,\n chainId: Number(a.chainId),\n nonce: Number(a.nonce),\n r: a.r as Hex,\n s: a.s as Hex,\n yParity: Number(a.yParity),\n }),\n );\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n const tokenTransferData = nestedTransactions?.find((nestedTx) =>\n nestedTx.data?.startsWith(TOKEN_TRANSFER_FOUR_BYTE),\n )?.data;\n\n // If the transactions include a token transfer, change the recipient\n // so any extra dust is also sent to the same address, rather than back to the user.\n if (tokenTransferData) {\n requestBody.recipient = getTransferRecipient(tokenTransferData);\n requestBody.refundTo = request.from;\n }\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: buildTokenTransferData(request.from, request.targetAmountMinimum),\n value: '0x0',\n },\n {\n to: delegation.to,\n data: delegation.data,\n value: delegation.value,\n },\n ];\n}\n\n/**\n * Normalizes requests for Relay.\n *\n * @param request - Quote request to normalize.\n * @returns Normalized request.\n */\nfunction normalizeRequest(request: QuoteRequest): QuoteRequest {\n const newRequest = {\n ...request,\n };\n\n const isHyperliquidDeposit =\n !request.isPostQuote &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n newRequest.sourceTokenAddress = normalizeTokenAddress(\n newRequest.sourceTokenAddress,\n newRequest.sourceChainId,\n TokenAddressTarget.Relay,\n );\n newRequest.targetTokenAddress = normalizeTokenAddress(\n newRequest.targetTokenAddress,\n newRequest.targetChainId,\n TokenAddressTarget.Relay,\n );\n\n if (isHyperliquidDeposit) {\n newRequest.targetChainId = CHAIN_ID_HYPERCORE;\n newRequest.targetTokenAddress = HYPERCORE_USDC_ADDRESS;\n newRequest.targetAmountMinimum = new BigNumber(request.targetAmountMinimum)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: newRequest,\n });\n }\n\n // HyperLiquid withdrawal: source is HyperCore Perps USDC, not Arbitrum.\n if (request.isHyperliquidSource) {\n newRequest.sourceChainId = CHAIN_ID_HYPERCORE;\n newRequest.sourceTokenAddress = HYPERCORE_USDC_ADDRESS;\n\n if (newRequest.sourceTokenAmount) {\n newRequest.sourceTokenAmount = new BigNumber(newRequest.sourceTokenAmount)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toString(10);\n }\n }\n\n return newRequest;\n}\n\n/**\n * Normalizes a Relay quote into a TransactionPayQuote.\n *\n * @param quote - Relay quote.\n * @param request - Original quote request.\n * @param fullRequest - Full quotes request.\n * @returns Normalized quote.\n */\nasync function normalizeQuote(\n quote: RelayQuote,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<RelayQuote>> {\n const { messenger } = fullRequest;\n const { details } = quote;\n const { currencyIn, currencyOut } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const subsidizedFeeUsd = getSubsidizedFeeAmountUsd(quote);\n\n const appFeeUsd = new BigNumber(quote.fees?.app?.amountUsd ?? '0');\n const metaMaskFee = getFiatValueFromUsd(appFeeUsd, usdToFiatRate);\n\n // Subtract app fee from provider fee since totalImpact.usd already includes it\n const providerFeeUsd = calculateProviderFee(quote).minus(appFeeUsd);\n const provider = subsidizedFeeUsd.gt(0)\n ? { usd: '0', fiat: '0' }\n : getFiatValueFromUsd(providerFeeUsd, usdToFiatRate);\n\n const {\n gasLimits,\n is7702,\n isGasFeeToken: isSourceGasFeeToken,\n ...sourceNetwork\n } = await calculateSourceNetworkCost(\n quote,\n messenger,\n request,\n fullRequest.transaction,\n );\n\n const targetNetwork = {\n usd: '0',\n fiat: '0',\n };\n\n const sourceAmount: Amount = {\n human: currencyIn.amountFormatted,\n raw: currencyIn.amount,\n ...getFiatValueFromUsd(new BigNumber(currencyIn.amountUsd), usdToFiatRate),\n };\n\n const isTargetStablecoin = isStablecoin(\n request.targetChainId,\n request.targetTokenAddress,\n );\n\n const targetAmountUsd = isTargetStablecoin\n ? new BigNumber(currencyOut.amountFormatted)\n : new BigNumber(currencyOut.amountUsd);\n\n const targetAmount = getFiatValueFromUsd(targetAmountUsd, usdToFiatRate);\n\n const metamask: RelayQuoteMetamask = {\n ...quote.metamask,\n gasLimits: is7702 ? [gasLimits[0]] : gasLimits,\n is7702,\n };\n\n return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n isSourceGasFeeToken,\n metaMask: metaMaskFee,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: {\n ...quote,\n metamask,\n },\n request,\n sourceAmount,\n targetAmount,\n strategy: TransactionPayStrategy.Relay,\n };\n}\n\n/**\n * Calculate dust USD value.\n *\n * @param quote - Relay quote.\n * @param request - Quote request.\n * @returns Dust value in USD and fiat.\n */\nfunction calculateDustUsd(quote: RelayQuote, request: QuoteRequest): BigNumber {\n const { currencyOut } = quote.details;\n const { amountUsd, amountFormatted, minimumAmount } = currencyOut;\n const { decimals: targetDecimals } = currencyOut.currency;\n\n const targetUsdRate = new BigNumber(amountUsd).dividedBy(amountFormatted);\n\n const dustRaw = new BigNumber(minimumAmount).minus(\n request.targetAmountMinimum,\n );\n\n return dustRaw.shiftedBy(-targetDecimals).multipliedBy(targetUsdRate);\n}\n\n/**\n * Calculates USD to fiat rate.\n *\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @returns USD to fiat rate.\n */\nfunction getFiatRates(\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): {\n sourceFiatRate: FiatRates;\n usdToFiatRate: BigNumber;\n} {\n // For HyperLiquid source, the normalized chain/token (HyperCore + Perps USDC)\n // won't have a fiat rate entry. Use Arbitrum USDC instead since Perps USDC\n // is pegged 1:1.\n const sourceChainId = request.isHyperliquidSource\n ? CHAIN_ID_ARBITRUM\n : request.sourceChainId;\n const sourceTokenAddress = request.isHyperliquidSource\n ? ARBITRUM_USDC_ADDRESS\n : request.sourceTokenAddress;\n\n const finalSourceTokenAddress =\n sourceChainId === CHAIN_ID_POLYGON &&\n sourceTokenAddress === NATIVE_TOKEN_ADDRESS\n ? getNativeToken(sourceChainId)\n : sourceTokenAddress;\n\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n finalSourceTokenAddress,\n sourceChainId,\n );\n\n if (!sourceFiatRate) {\n throw new Error('Source token fiat rate not found');\n }\n\n const usdToFiatRate = new BigNumber(sourceFiatRate.fiatRate).dividedBy(\n sourceFiatRate.usdRate,\n );\n\n return { sourceFiatRate, usdToFiatRate };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * For post-quote flows (e.g. predictWithdraw), the cost also includes the\n * original transaction's gas (the user's Polygon USDC.e transfer) in addition\n * to the Relay deposit transaction gas, by appending the original\n * transaction's params so that gas estimation and gas-fee-token logic handle\n * both transactions together.\n *\n * When the execute flow is active (indicated by `quote.metamask.isExecute`),\n * network fees are zeroed because the relayer covers them.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @param transaction - Original transaction metadata.\n * @returns Total source network cost in USD and fiat.\n */\nasync function calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n transaction: TransactionMeta,\n): Promise<\n TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] & {\n gasLimits: number[];\n isGasFeeToken?: boolean;\n is7702: boolean;\n }\n> {\n const { from, sourceChainId, sourceTokenAddress } = request;\n\n if (quote.metamask?.isExecute) {\n log('Zeroing network fees for execute flow');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n // HyperLiquid withdrawals are gasless -- the \"deposit\" step is an HL\n // sendAsset (off-chain signature), not an on-chain transaction.\n if (request.isHyperliquidSource) {\n log('Zeroing network fees for HyperLiquid withdrawal (gasless)');\n\n const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };\n\n return {\n estimate: zeroAmount,\n max: zeroAmount,\n gasLimits: [],\n is7702: false,\n };\n }\n\n const txSteps = quote.steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const relayParams = txSteps\n .flatMap((step) => step.items)\n .map((item) => item.data);\n\n const { chainId, data, maxFeePerGas, maxPriorityFeePerGas, to, value } =\n relayParams[0];\n\n const isPredictWithdraw =\n request.isPostQuote && isPredictWithdrawTransaction(transaction);\n\n const fromOverride = isPredictWithdraw ? request.refundTo : undefined;\n\n const relayOnlyGas = await calculateSourceNetworkGasLimit(\n relayParams,\n messenger,\n fromOverride,\n );\n\n const { gasLimits, is7702, totalGasEstimate, totalGasLimit } =\n request.isPostQuote\n ? combinePostQuoteGas(relayOnlyGas, transaction)\n : relayOnlyGas;\n\n log('Gas limit', {\n is7702,\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n });\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasEstimate,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n messenger,\n isMax: true,\n });\n\n const nativeBalance = getTokenBalance(\n messenger,\n from,\n sourceChainId,\n getNativeToken(sourceChainId),\n );\n\n const result = { estimate, max, gasLimits, is7702 };\n\n if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {\n return result;\n }\n\n const gasStationEligibility = getGasStationEligibility(\n messenger,\n sourceChainId,\n );\n\n if (gasStationEligibility.isDisabledChain) {\n log('Skipping gas station as disabled chain', {\n sourceChainId,\n });\n\n return result;\n }\n\n if (!gasStationEligibility.chainSupportsGasStation) {\n log('Skipping gas station as chain does not support EIP-7702', {\n sourceChainId,\n });\n\n return result;\n }\n\n log('Checking gas fee tokens as insufficient native balance', {\n nativeBalance,\n max: max.raw,\n });\n\n if (isPredictWithdraw && request.refundTo) {\n log('Using proxy address for predict withdraw gas station simulation', {\n proxyAddress: request.refundTo,\n sourceTokenAddress,\n totalGasEstimate,\n });\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from: request.refundTo,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: relayParams.length + 1,\n });\n\n if (gasFeeTokenCost) {\n log('Using predict withdraw gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n }\n\n return result;\n }\n\n const gasFeeTokenCost = await getGasStationCostInSourceTokenRaw({\n firstStepData: {\n data,\n to,\n value,\n },\n messenger,\n request: {\n from,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: Math.max(relayParams.length, gasLimits.length),\n });\n\n if (!gasFeeTokenCost) {\n return result;\n }\n\n log('Using gas fee token for source network', {\n gasFeeTokenCost,\n });\n\n return {\n isGasFeeToken: true,\n estimate: gasFeeTokenCost,\n max: gasFeeTokenCost,\n gasLimits,\n is7702,\n };\n}\n\n/**\n * Calculate the total gas limit for the source network.\n *\n * @param params - Array of relay transaction parameters.\n * @param messenger - Controller messenger.\n * @param fromOverride - Optional address to use as `from` in gas estimation\n * instead of the address in the relay params. Used in predict withdraw flows\n * to estimate with the proxy/Safe address that holds the source token balance.\n * @returns Total gas estimates and per-transaction gas limits.\n */\nasync function calculateSourceNetworkGasLimit(\n params: RelayTransactionStep['items'][0]['data'][],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n}> {\n const transactions = params.map((singleParams) =>\n toRelayQuoteGasTransaction(singleParams, fromOverride),\n );\n\n const relayGasResult = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions,\n });\n\n return {\n gasLimits: relayGasResult.gasLimits.map((gasLimit) => gasLimit.max),\n is7702: relayGasResult.is7702,\n totalGasEstimate: relayGasResult.totalGasEstimate,\n totalGasLimit: relayGasResult.totalGasLimit,\n };\n}\n\nfunction toRelayQuoteGasTransaction(\n singleParams: RelayTransactionStep['items'][0]['data'],\n fromOverride?: Hex,\n): QuoteGasTransaction {\n return {\n chainId: toHex(singleParams.chainId),\n data: singleParams.data,\n from: fromOverride ?? singleParams.from,\n gas: fromOverride ? undefined : singleParams.gas,\n to: singleParams.to,\n value: singleParams.value ?? '0',\n };\n}\n\n/**\n * Combine the original transaction's gas with relay gas for post-quote flows.\n *\n * Prefers gas from `nestedTransactions` (preserves the caller-provided value)\n * since TransactionController may re-estimate `txParams.gas` during batch\n * creation.\n *\n * @param relayGas - Gas estimates from relay transactions.\n * @param relayGas.totalGasEstimate - Estimated gas total.\n * @param relayGas.totalGasLimit - Maximum gas total.\n * @param relayGas.gasLimits - Per-transaction gas limits.\n * @param relayGas.is7702 - Whether the relay gas came from a combined 7702 batch estimate.\n * @param transaction - Original transaction metadata.\n * @returns Combined gas estimates including the original transaction.\n */\nfunction combinePostQuoteGas(\n relayGas: {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n },\n transaction: TransactionMeta,\n): {\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n is7702: boolean;\n} {\n const nestedGas = transaction.nestedTransactions?.find((tx) => tx.gas)?.gas;\n const rawGas = nestedGas ?? transaction.txParams.gas;\n const originalTxGas = rawGas ? new BigNumber(rawGas).toNumber() : undefined;\n\n if (originalTxGas === undefined) {\n return relayGas;\n }\n\n let { gasLimits } = relayGas;\n\n if (relayGas.is7702) {\n // Combined 7702 gas limit — add the original tx gas so the batch\n // keeps using a single 7702 limit.\n gasLimits = [gasLimits[0] + originalTxGas];\n } else {\n // Multiple individual gas limits — prepend the original tx gas\n // so the list order matches relay-submit's transaction order.\n gasLimits = [originalTxGas, ...gasLimits];\n }\n\n const totalGasEstimate = relayGas.totalGasEstimate + originalTxGas;\n const totalGasLimit = relayGas.totalGasLimit + originalTxGas;\n\n log('Combined original tx gas with relay gas', {\n originalTxGas,\n is7702: relayGas.is7702,\n gasLimits,\n totalGasLimit,\n });\n\n return {\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n is7702: relayGas.is7702,\n };\n}\n\n/**\n * Calculate the provider fee for a Relay quote.\n *\n * @param quote - Relay quote.\n * @returns - Provider fee in USD.\n */\nfunction calculateProviderFee(quote: RelayQuote): BigNumber {\n return new BigNumber(quote.details.totalImpact.usd).abs();\n}\n\n/**\n * Build token transfer data.\n *\n * @param recipient - Recipient address.\n * @param amountRaw - Amount in raw format.\n * @returns Token transfer data.\n */\nfunction buildTokenTransferData(recipient: Hex, amountRaw: string): Hex {\n return new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [recipient, amountRaw]) as Hex;\n}\n\n/**\n * Get transfer recipient from token transfer data.\n *\n * @param data - Token transfer data.\n * @returns Transfer recipient.\n */\nfunction getTransferRecipient(data: Hex): Hex {\n return new Interface(['function transfer(address to, uint256 amount)'])\n .decodeFunctionData('transfer', data)\n .to.toLowerCase();\n}\nfunction getSubsidizedFeeAmountUsd(quote: RelayQuote): BigNumber {\n const subsidizedFee = quote.fees?.subsidized;\n const amountUsd = new BigNumber(subsidizedFee?.amountUsd ?? '0');\n const amountFormatted = new BigNumber(subsidizedFee?.amountFormatted ?? '0');\n\n if (!subsidizedFee || amountUsd.isZero()) {\n return new BigNumber(0);\n }\n\n const isSubsidizedStablecoin = isStablecoin(\n toHex(subsidizedFee.currency.chainId),\n subsidizedFee.currency.address,\n );\n\n return isSubsidizedStablecoin ? amountFormatted : amountUsd;\n}\n\nfunction isStablecoin(chainId: string, tokenAddress: string): boolean {\n return Boolean(\n STABLECOINS[chainId as Hex]?.includes(tokenAddress.toLowerCase() as Hex),\n );\n}\n"]}
|
|
@@ -59,7 +59,7 @@ export declare function getMessengerMock({ skipRegister, }?: {
|
|
|
59
59
|
getTokensControllerStateMock: jest.MockedFn<() => import("@metamask/assets-controllers").TokensControllerState>;
|
|
60
60
|
getTransactionControllerStateMock: jest.MockedFn<() => import("@metamask/transaction-controller").TransactionControllerState>;
|
|
61
61
|
messenger: TransactionPayControllerMessenger;
|
|
62
|
-
publish: <EventType extends "BridgeStatusController:stateChange" | "TransactionController:stateChange" | "TransactionController:unapprovedTransactionAdded" | "TransactionPayController:stateChange">(eventType: EventType & `${string}:${string}`, ...payload: import("@metamask/messenger").ExtractEventPayload<import("@metamask/bridge-status-controller").BridgeStatusControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerUnapprovedTransactionAddedEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("../index.cjs").TransactionPayControllerStateChangeEvent, EventType>) => void;
|
|
62
|
+
publish: <EventType extends "AssetsController:stateChange" | "BridgeStatusController:stateChange" | "CurrencyRateController:stateChange" | "TokenRatesController:stateChange" | "TokensController:stateChange" | "TransactionController:stateChange" | "TransactionController:unapprovedTransactionAdded" | "TransactionPayController:stateChange">(eventType: EventType & `${string}:${string}`, ...payload: import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controller").AssetsControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/bridge-status-controller").BridgeStatusControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controllers").CurrencyRateStateChange, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controllers").TokenRatesControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controllers").TokensControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerUnapprovedTransactionAddedEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("../index.cjs").TransactionPayControllerStateChangeEvent, EventType>) => void;
|
|
63
63
|
submitTransactionMock: jest.MockedFunction<(accountAddress: string, quoteResponse: {
|
|
64
64
|
quote: {
|
|
65
65
|
srcChainId: number;
|
|
@@ -59,7 +59,7 @@ export declare function getMessengerMock({ skipRegister, }?: {
|
|
|
59
59
|
getTokensControllerStateMock: jest.MockedFn<() => import("@metamask/assets-controllers").TokensControllerState>;
|
|
60
60
|
getTransactionControllerStateMock: jest.MockedFn<() => import("@metamask/transaction-controller").TransactionControllerState>;
|
|
61
61
|
messenger: TransactionPayControllerMessenger;
|
|
62
|
-
publish: <EventType extends "BridgeStatusController:stateChange" | "TransactionController:stateChange" | "TransactionController:unapprovedTransactionAdded" | "TransactionPayController:stateChange">(eventType: EventType & `${string}:${string}`, ...payload: import("@metamask/messenger").ExtractEventPayload<import("@metamask/bridge-status-controller").BridgeStatusControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerUnapprovedTransactionAddedEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("../index.mjs").TransactionPayControllerStateChangeEvent, EventType>) => void;
|
|
62
|
+
publish: <EventType extends "AssetsController:stateChange" | "BridgeStatusController:stateChange" | "CurrencyRateController:stateChange" | "TokenRatesController:stateChange" | "TokensController:stateChange" | "TransactionController:stateChange" | "TransactionController:unapprovedTransactionAdded" | "TransactionPayController:stateChange">(eventType: EventType & `${string}:${string}`, ...payload: import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controller").AssetsControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/bridge-status-controller").BridgeStatusControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controllers").CurrencyRateStateChange, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controllers").TokenRatesControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/assets-controllers").TokensControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerStateChangeEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("@metamask/transaction-controller").TransactionControllerUnapprovedTransactionAddedEvent, EventType> | import("@metamask/messenger").ExtractEventPayload<import("../index.mjs").TransactionPayControllerStateChangeEvent, EventType>) => void;
|
|
63
63
|
submitTransactionMock: jest.MockedFunction<(accountAddress: string, quoteResponse: {
|
|
64
64
|
quote: {
|
|
65
65
|
srcChainId: number;
|
package/dist/types.cjs
CHANGED
|
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.KEYRING_TYPES_SUPPORTING_7702 = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Keyring types that support EIP-7702 authorization signing.
|
|
6
|
-
* Hardware wallets, snap keyrings, and
|
|
6
|
+
* Hardware wallets, snap keyrings, and custody keyrings are excluded.
|
|
7
7
|
*/
|
|
8
8
|
exports.KEYRING_TYPES_SUPPORTING_7702 = [
|
|
9
9
|
'HD Key Tree',
|
|
10
10
|
'Simple Key Pair',
|
|
11
|
+
'Money Keyring',
|
|
11
12
|
];
|
|
12
13
|
//# sourceMappingURL=types.cjs.map
|