@metamask/transaction-pay-controller 17.1.0 → 18.1.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 +26 -1
- package/dist/TransactionPayController-method-action-types.cjs +1 -1
- package/dist/TransactionPayController-method-action-types.cjs.map +1 -1
- package/dist/TransactionPayController-method-action-types.d.cts +1 -1
- package/dist/TransactionPayController-method-action-types.d.mts +1 -1
- package/dist/TransactionPayController-method-action-types.mjs +1 -1
- package/dist/TransactionPayController-method-action-types.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/strategy/across/across-actions.cjs +185 -0
- package/dist/strategy/across/across-actions.cjs.map +1 -0
- package/dist/strategy/across/across-actions.d.cts +21 -0
- package/dist/strategy/across/across-actions.d.cts.map +1 -0
- package/dist/strategy/across/across-actions.d.mts +21 -0
- package/dist/strategy/across/across-actions.d.mts.map +1 -0
- package/dist/strategy/across/across-actions.mjs +178 -0
- package/dist/strategy/across/across-actions.mjs.map +1 -0
- package/dist/strategy/across/across-quotes.cjs +66 -165
- package/dist/strategy/across/across-quotes.cjs.map +1 -1
- package/dist/strategy/across/across-quotes.d.cts.map +1 -1
- package/dist/strategy/across/across-quotes.d.mts.map +1 -1
- package/dist/strategy/across/across-quotes.mjs +66 -165
- package/dist/strategy/across/across-quotes.mjs.map +1 -1
- package/dist/strategy/across/across-submit.cjs +38 -37
- package/dist/strategy/across/across-submit.cjs.map +1 -1
- package/dist/strategy/across/across-submit.d.cts.map +1 -1
- package/dist/strategy/across/across-submit.d.mts.map +1 -1
- package/dist/strategy/across/across-submit.mjs +38 -37
- package/dist/strategy/across/across-submit.mjs.map +1 -1
- package/dist/strategy/across/transactions.cjs +23 -0
- package/dist/strategy/across/transactions.cjs.map +1 -0
- package/dist/strategy/across/transactions.d.cts +18 -0
- package/dist/strategy/across/transactions.d.cts.map +1 -0
- package/dist/strategy/across/transactions.d.mts +18 -0
- package/dist/strategy/across/transactions.d.mts.map +1 -0
- package/dist/strategy/across/transactions.mjs +19 -0
- package/dist/strategy/across/transactions.mjs.map +1 -0
- package/dist/strategy/across/types.cjs.map +1 -1
- package/dist/strategy/across/types.d.cts +6 -10
- package/dist/strategy/across/types.d.cts.map +1 -1
- package/dist/strategy/across/types.d.mts +6 -10
- package/dist/strategy/across/types.d.mts.map +1 -1
- package/dist/strategy/across/types.mjs.map +1 -1
- package/dist/strategy/fiat/FiatStrategy.cjs +15 -0
- package/dist/strategy/fiat/FiatStrategy.cjs.map +1 -0
- package/dist/strategy/fiat/FiatStrategy.d.cts +7 -0
- package/dist/strategy/fiat/FiatStrategy.d.cts.map +1 -0
- package/dist/strategy/fiat/FiatStrategy.d.mts +7 -0
- package/dist/strategy/fiat/FiatStrategy.d.mts.map +1 -0
- package/dist/strategy/fiat/FiatStrategy.mjs +11 -0
- package/dist/strategy/fiat/FiatStrategy.mjs.map +1 -0
- package/dist/strategy/fiat/constants.cjs +24 -0
- package/dist/strategy/fiat/constants.cjs.map +1 -0
- package/dist/strategy/fiat/constants.d.cts +10 -0
- package/dist/strategy/fiat/constants.d.cts.map +1 -0
- package/dist/strategy/fiat/constants.d.mts +10 -0
- package/dist/strategy/fiat/constants.d.mts.map +1 -0
- package/dist/strategy/fiat/constants.mjs +21 -0
- package/dist/strategy/fiat/constants.mjs.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.cjs +214 -0
- package/dist/strategy/fiat/fiat-quotes.cjs.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.d.cts +17 -0
- package/dist/strategy/fiat/fiat-quotes.d.cts.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.d.mts +17 -0
- package/dist/strategy/fiat/fiat-quotes.d.mts.map +1 -0
- package/dist/strategy/fiat/fiat-quotes.mjs +210 -0
- package/dist/strategy/fiat/fiat-quotes.mjs.map +1 -0
- package/dist/strategy/fiat/fiat-submit.cjs +14 -0
- package/dist/strategy/fiat/fiat-submit.cjs.map +1 -0
- package/dist/strategy/fiat/fiat-submit.d.cts +10 -0
- package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -0
- package/dist/strategy/fiat/fiat-submit.d.mts +10 -0
- package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -0
- package/dist/strategy/fiat/fiat-submit.mjs +10 -0
- package/dist/strategy/fiat/fiat-submit.mjs.map +1 -0
- package/dist/strategy/fiat/types.cjs +3 -0
- package/dist/strategy/fiat/types.cjs.map +1 -0
- package/dist/strategy/fiat/types.d.cts +8 -0
- package/dist/strategy/fiat/types.d.cts.map +1 -0
- package/dist/strategy/fiat/types.d.mts +8 -0
- package/dist/strategy/fiat/types.d.mts.map +1 -0
- package/dist/strategy/fiat/types.mjs +2 -0
- package/dist/strategy/fiat/types.mjs.map +1 -0
- package/dist/strategy/fiat/utils.cjs +23 -0
- package/dist/strategy/fiat/utils.cjs.map +1 -0
- package/dist/strategy/fiat/utils.d.cts +6 -0
- package/dist/strategy/fiat/utils.d.cts.map +1 -0
- package/dist/strategy/fiat/utils.d.mts +6 -0
- package/dist/strategy/fiat/utils.d.mts.map +1 -0
- package/dist/strategy/fiat/utils.mjs +18 -0
- package/dist/strategy/fiat/utils.mjs.map +1 -0
- package/dist/strategy/relay/relay-quotes.cjs +49 -135
- 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 +51 -137
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +4 -3
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +4 -3
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/strategy/relay/types.cjs.map +1 -1
- package/dist/strategy/relay/types.d.cts +10 -5
- package/dist/strategy/relay/types.d.cts.map +1 -1
- package/dist/strategy/relay/types.d.mts +10 -5
- package/dist/strategy/relay/types.d.mts.map +1 -1
- package/dist/strategy/relay/types.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.map +1 -1
- package/dist/types.d.cts +6 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +6 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/quote-gas.cjs +143 -0
- package/dist/utils/quote-gas.cjs.map +1 -0
- package/dist/utils/quote-gas.d.cts +31 -0
- package/dist/utils/quote-gas.d.cts.map +1 -0
- package/dist/utils/quote-gas.d.mts +31 -0
- package/dist/utils/quote-gas.d.mts.map +1 -0
- package/dist/utils/quote-gas.mjs +139 -0
- package/dist/utils/quote-gas.mjs.map +1 -0
- package/dist/utils/quotes.cjs +4 -2
- package/dist/utils/quotes.cjs.map +1 -1
- package/dist/utils/quotes.d.cts.map +1 -1
- package/dist/utils/quotes.d.mts.map +1 -1
- package/dist/utils/quotes.mjs +4 -2
- package/dist/utils/quotes.mjs.map +1 -1
- package/dist/utils/strategy.cjs +3 -0
- package/dist/utils/strategy.cjs.map +1 -1
- package/dist/utils/strategy.d.cts.map +1 -1
- package/dist/utils/strategy.d.mts.map +1 -1
- package/dist/utils/strategy.mjs +3 -0
- package/dist/utils/strategy.mjs.map +1 -1
- package/dist/utils/token.cjs +26 -1
- package/dist/utils/token.cjs.map +1 -1
- package/dist/utils/token.d.cts +10 -0
- package/dist/utils/token.d.cts.map +1 -1
- package/dist/utils/token.d.mts +10 -0
- package/dist/utils/token.d.mts.map +1 -1
- package/dist/utils/token.mjs +24 -0
- package/dist/utils/token.mjs.map +1 -1
- package/dist/utils/totals.cjs +2 -0
- package/dist/utils/totals.cjs.map +1 -1
- package/dist/utils/totals.d.cts.map +1 -1
- package/dist/utils/totals.d.mts.map +1 -1
- package/dist/utils/totals.mjs +2 -0
- package/dist/utils/totals.mjs.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Quote, QuotesResponse } from '@metamask/ramps-controller';\n\nimport type { RelayQuote } from '../relay/types';\n\nexport type FiatQuote = {\n rampsQuote: Quote;\n relayQuote: RelayQuote;\n};\n\nexport type FiatQuotesResponse = QuotesResponse;\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pickBestFiatQuote = exports.deriveFiatAssetForFiatPayment = void 0;
|
|
4
|
+
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
5
|
+
const constants_1 = require("./constants.cjs");
|
|
6
|
+
function deriveFiatAssetForFiatPayment(transaction) {
|
|
7
|
+
const transactionType = transaction?.type;
|
|
8
|
+
if (transactionType === transaction_controller_1.TransactionType.batch) {
|
|
9
|
+
const firstMatchingType = transaction.nestedTransactions?.[0]?.type;
|
|
10
|
+
if (firstMatchingType) {
|
|
11
|
+
return constants_1.FIAT_ASSET_ID_BY_TX_TYPE[firstMatchingType];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return constants_1.FIAT_ASSET_ID_BY_TX_TYPE[transactionType];
|
|
15
|
+
}
|
|
16
|
+
exports.deriveFiatAssetForFiatPayment = deriveFiatAssetForFiatPayment;
|
|
17
|
+
function pickBestFiatQuote(quotes) {
|
|
18
|
+
return quotes.success?.find(
|
|
19
|
+
// TODO: Implement provider selection logic; force Transak staging for now.
|
|
20
|
+
(quote) => quote.provider === '/providers/transak-native-staging');
|
|
21
|
+
}
|
|
22
|
+
exports.pickBestFiatQuote = pickBestFiatQuote;
|
|
23
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":";;;AAIA,6EAG0C;AAE1C,+CAAgF;AAEhF,SAAgB,6BAA6B,CAC3C,WAA4B;IAE5B,MAAM,eAAe,GAAG,WAAW,EAAE,IAAI,CAAC;IAE1C,IAAI,eAAe,KAAK,wCAAe,CAAC,KAAK,EAAE,CAAC;QAC9C,MAAM,iBAAiB,GAAG,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACpE,IAAI,iBAAiB,EAAE,CAAC;YACtB,OAAO,oCAAwB,CAAC,iBAAiB,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,oCAAwB,CAAC,eAAkC,CAAC,CAAC;AACtE,CAAC;AAbD,sEAaC;AAED,SAAgB,iBAAiB,CAC/B,MAA2B;IAE3B,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI;IACzB,2EAA2E;IAC3E,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,mCAAmC,CAClE,CAAC;AACJ,CAAC;AAPD,8CAOC","sourcesContent":["import type {\n Quote as RampsQuote,\n QuotesResponse as RampsQuotesResponse,\n} from '@metamask/ramps-controller';\nimport {\n TransactionMeta,\n TransactionType,\n} from '@metamask/transaction-controller';\n\nimport { FIAT_ASSET_ID_BY_TX_TYPE, TransactionPayFiatAsset } from './constants';\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n): TransactionPayFiatAsset | undefined {\n const transactionType = transaction?.type;\n\n if (transactionType === TransactionType.batch) {\n const firstMatchingType = transaction.nestedTransactions?.[0]?.type;\n if (firstMatchingType) {\n return FIAT_ASSET_ID_BY_TX_TYPE[firstMatchingType];\n }\n }\n\n return FIAT_ASSET_ID_BY_TX_TYPE[transactionType as TransactionType];\n}\n\nexport function pickBestFiatQuote(\n quotes: RampsQuotesResponse,\n): RampsQuote | undefined {\n return quotes.success?.find(\n // TODO: Implement provider selection logic; force Transak staging for now.\n (quote) => quote.provider === '/providers/transak-native-staging',\n );\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Quote as RampsQuote, QuotesResponse as RampsQuotesResponse } from "@metamask/ramps-controller";
|
|
2
|
+
import { TransactionMeta } from "@metamask/transaction-controller";
|
|
3
|
+
import { TransactionPayFiatAsset } from "./constants.cjs";
|
|
4
|
+
export declare function deriveFiatAssetForFiatPayment(transaction: TransactionMeta): TransactionPayFiatAsset | undefined;
|
|
5
|
+
export declare function pickBestFiatQuote(quotes: RampsQuotesResponse): RampsQuote | undefined;
|
|
6
|
+
//# sourceMappingURL=utils.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,IAAI,UAAU,EACnB,cAAc,IAAI,mBAAmB,EACtC,mCAAmC;AACpC,OAAO,EACL,eAAe,EAEhB,yCAAyC;AAE1C,OAAO,EAA4B,uBAAuB,EAAE,wBAAoB;AAEhF,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,GAC3B,uBAAuB,GAAG,SAAS,CAWrC;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,mBAAmB,GAC1B,UAAU,GAAG,SAAS,CAKxB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Quote as RampsQuote, QuotesResponse as RampsQuotesResponse } from "@metamask/ramps-controller";
|
|
2
|
+
import { TransactionMeta } from "@metamask/transaction-controller";
|
|
3
|
+
import { TransactionPayFiatAsset } from "./constants.mjs";
|
|
4
|
+
export declare function deriveFiatAssetForFiatPayment(transaction: TransactionMeta): TransactionPayFiatAsset | undefined;
|
|
5
|
+
export declare function pickBestFiatQuote(quotes: RampsQuotesResponse): RampsQuote | undefined;
|
|
6
|
+
//# sourceMappingURL=utils.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,IAAI,UAAU,EACnB,cAAc,IAAI,mBAAmB,EACtC,mCAAmC;AACpC,OAAO,EACL,eAAe,EAEhB,yCAAyC;AAE1C,OAAO,EAA4B,uBAAuB,EAAE,wBAAoB;AAEhF,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,GAC3B,uBAAuB,GAAG,SAAS,CAWrC;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,mBAAmB,GAC1B,UAAU,GAAG,SAAS,CAKxB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TransactionType } from "@metamask/transaction-controller";
|
|
2
|
+
import { FIAT_ASSET_ID_BY_TX_TYPE } from "./constants.mjs";
|
|
3
|
+
export function deriveFiatAssetForFiatPayment(transaction) {
|
|
4
|
+
const transactionType = transaction?.type;
|
|
5
|
+
if (transactionType === TransactionType.batch) {
|
|
6
|
+
const firstMatchingType = transaction.nestedTransactions?.[0]?.type;
|
|
7
|
+
if (firstMatchingType) {
|
|
8
|
+
return FIAT_ASSET_ID_BY_TX_TYPE[firstMatchingType];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return FIAT_ASSET_ID_BY_TX_TYPE[transactionType];
|
|
12
|
+
}
|
|
13
|
+
export function pickBestFiatQuote(quotes) {
|
|
14
|
+
return quotes.success?.find(
|
|
15
|
+
// TODO: Implement provider selection logic; force Transak staging for now.
|
|
16
|
+
(quote) => quote.provider === '/providers/transak-native-staging');
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,eAAe,EAChB,yCAAyC;AAE1C,OAAO,EAAE,wBAAwB,EAA2B,wBAAoB;AAEhF,MAAM,UAAU,6BAA6B,CAC3C,WAA4B;IAE5B,MAAM,eAAe,GAAG,WAAW,EAAE,IAAI,CAAC;IAE1C,IAAI,eAAe,KAAK,eAAe,CAAC,KAAK,EAAE,CAAC;QAC9C,MAAM,iBAAiB,GAAG,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACpE,IAAI,iBAAiB,EAAE,CAAC;YACtB,OAAO,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,wBAAwB,CAAC,eAAkC,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAA2B;IAE3B,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI;IACzB,2EAA2E;IAC3E,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,mCAAmC,CAClE,CAAC;AACJ,CAAC","sourcesContent":["import type {\n Quote as RampsQuote,\n QuotesResponse as RampsQuotesResponse,\n} from '@metamask/ramps-controller';\nimport {\n TransactionMeta,\n TransactionType,\n} from '@metamask/transaction-controller';\n\nimport { FIAT_ASSET_ID_BY_TX_TYPE, TransactionPayFiatAsset } from './constants';\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n): TransactionPayFiatAsset | undefined {\n const transactionType = transaction?.type;\n\n if (transactionType === TransactionType.batch) {\n const firstMatchingType = transaction.nestedTransactions?.[0]?.type;\n if (firstMatchingType) {\n return FIAT_ASSET_ID_BY_TX_TYPE[firstMatchingType];\n }\n }\n\n return FIAT_ASSET_ID_BY_TX_TYPE[transactionType as TransactionType];\n}\n\nexport function pickBestFiatQuote(\n quotes: RampsQuotesResponse,\n): RampsQuote | undefined {\n return quotes.success?.find(\n // TODO: Implement provider selection logic; force Transak staging for now.\n (quote) => quote.provider === '/providers/transak-native-staging',\n );\n}\n"]}
|
|
@@ -16,6 +16,7 @@ const logger_1 = require("../../logger.cjs");
|
|
|
16
16
|
const amounts_1 = require("../../utils/amounts.cjs");
|
|
17
17
|
const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
18
18
|
const gas_1 = require("../../utils/gas.cjs");
|
|
19
|
+
const quote_gas_1 = require("../../utils/quote-gas.cjs");
|
|
19
20
|
const token_1 = require("../../utils/token.cjs");
|
|
20
21
|
const transaction_1 = require("../../utils/transaction.cjs");
|
|
21
22
|
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'relay-strategy');
|
|
@@ -262,7 +263,7 @@ async function normalizeQuote(quote, request, fullRequest) {
|
|
|
262
263
|
const provider = subsidizedFeeUsd.gt(0)
|
|
263
264
|
? { usd: '0', fiat: '0' }
|
|
264
265
|
: (0, amounts_1.getFiatValueFromUsd)(providerFeeUsd, usdToFiatRate);
|
|
265
|
-
const { gasLimits, isGasFeeToken: isSourceGasFeeToken, ...sourceNetwork } = await calculateSourceNetworkCost(quote, messenger, request, fullRequest.transaction);
|
|
266
|
+
const { gasLimits, is7702, isGasFeeToken: isSourceGasFeeToken, ...sourceNetwork } = await calculateSourceNetworkCost(quote, messenger, request, fullRequest.transaction);
|
|
266
267
|
const targetNetwork = {
|
|
267
268
|
usd: '0',
|
|
268
269
|
fiat: '0',
|
|
@@ -286,7 +287,8 @@ async function normalizeQuote(quote, request, fullRequest) {
|
|
|
286
287
|
const targetAmount = (0, amounts_1.getFiatValueFromUsd)(targetAmountUsd, usdToFiatRate);
|
|
287
288
|
const metamask = {
|
|
288
289
|
...quote.metamask,
|
|
289
|
-
gasLimits,
|
|
290
|
+
gasLimits: is7702 ? [gasLimits[0]] : gasLimits,
|
|
291
|
+
is7702,
|
|
290
292
|
};
|
|
291
293
|
return {
|
|
292
294
|
dust,
|
|
@@ -366,7 +368,12 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
366
368
|
if (quote.metamask?.isExecute) {
|
|
367
369
|
log('Zeroing network fees for execute flow');
|
|
368
370
|
const zeroAmount = { fiat: '0', human: '0', raw: '0', usd: '0' };
|
|
369
|
-
return {
|
|
371
|
+
return {
|
|
372
|
+
estimate: zeroAmount,
|
|
373
|
+
max: zeroAmount,
|
|
374
|
+
gasLimits: [],
|
|
375
|
+
is7702: false,
|
|
376
|
+
};
|
|
370
377
|
}
|
|
371
378
|
const relayParams = quote.steps
|
|
372
379
|
.flatMap((step) => step.items)
|
|
@@ -375,10 +382,11 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
375
382
|
const isPredictWithdraw = request.isPostQuote && (0, transaction_1.isPredictWithdrawTransaction)(transaction);
|
|
376
383
|
const fromOverride = isPredictWithdraw ? request.refundTo : undefined;
|
|
377
384
|
const relayOnlyGas = await calculateSourceNetworkGasLimit(relayParams, messenger, fromOverride);
|
|
378
|
-
const { totalGasEstimate, totalGasLimit
|
|
385
|
+
const { gasLimits, is7702, totalGasEstimate, totalGasLimit } = request.isPostQuote
|
|
379
386
|
? combinePostQuoteGas(relayOnlyGas, transaction)
|
|
380
387
|
: relayOnlyGas;
|
|
381
388
|
log('Gas limit', {
|
|
389
|
+
is7702,
|
|
382
390
|
totalGasEstimate,
|
|
383
391
|
totalGasLimit,
|
|
384
392
|
gasLimits,
|
|
@@ -399,7 +407,7 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
399
407
|
isMax: true,
|
|
400
408
|
});
|
|
401
409
|
const nativeBalance = (0, token_1.getTokenBalance)(messenger, from, sourceChainId, (0, token_1.getNativeToken)(sourceChainId));
|
|
402
|
-
const result = { estimate, max, gasLimits };
|
|
410
|
+
const result = { estimate, max, gasLimits, is7702 };
|
|
403
411
|
if (new bignumber_js_1.BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {
|
|
404
412
|
return result;
|
|
405
413
|
}
|
|
@@ -450,6 +458,7 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
450
458
|
estimate: gasFeeTokenCost,
|
|
451
459
|
max: gasFeeTokenCost,
|
|
452
460
|
gasLimits,
|
|
461
|
+
is7702,
|
|
453
462
|
};
|
|
454
463
|
}
|
|
455
464
|
return result;
|
|
@@ -480,6 +489,7 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
480
489
|
estimate: gasFeeTokenCost,
|
|
481
490
|
max: gasFeeTokenCost,
|
|
482
491
|
gasLimits,
|
|
492
|
+
is7702,
|
|
483
493
|
};
|
|
484
494
|
}
|
|
485
495
|
/**
|
|
@@ -493,9 +503,29 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
493
503
|
* @returns Total gas estimates and per-transaction gas limits.
|
|
494
504
|
*/
|
|
495
505
|
async function calculateSourceNetworkGasLimit(params, messenger, fromOverride) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
:
|
|
506
|
+
const transactions = params.map((singleParams) => toRelayQuoteGasTransaction(singleParams, fromOverride));
|
|
507
|
+
const relayGasResult = await (0, quote_gas_1.estimateQuoteGasLimits)({
|
|
508
|
+
fallbackGas: (0, feature_flags_1.getFeatureFlags)(messenger).relayFallbackGas,
|
|
509
|
+
fallbackOnSimulationFailure: true,
|
|
510
|
+
messenger,
|
|
511
|
+
transactions,
|
|
512
|
+
});
|
|
513
|
+
return {
|
|
514
|
+
gasLimits: relayGasResult.gasLimits.map((gasLimit) => gasLimit.max),
|
|
515
|
+
is7702: relayGasResult.is7702,
|
|
516
|
+
totalGasEstimate: relayGasResult.totalGasEstimate,
|
|
517
|
+
totalGasLimit: relayGasResult.totalGasLimit,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
function toRelayQuoteGasTransaction(singleParams, fromOverride) {
|
|
521
|
+
return {
|
|
522
|
+
chainId: (0, controller_utils_1.toHex)(singleParams.chainId),
|
|
523
|
+
data: singleParams.data,
|
|
524
|
+
from: fromOverride ?? singleParams.from,
|
|
525
|
+
gas: fromOverride ? undefined : singleParams.gas,
|
|
526
|
+
to: singleParams.to,
|
|
527
|
+
value: singleParams.value ?? '0',
|
|
528
|
+
};
|
|
499
529
|
}
|
|
500
530
|
/**
|
|
501
531
|
* Combine the original transaction's gas with relay gas for post-quote flows.
|
|
@@ -508,6 +538,7 @@ async function calculateSourceNetworkGasLimit(params, messenger, fromOverride) {
|
|
|
508
538
|
* @param relayGas.totalGasEstimate - Estimated gas total.
|
|
509
539
|
* @param relayGas.totalGasLimit - Maximum gas total.
|
|
510
540
|
* @param relayGas.gasLimits - Per-transaction gas limits.
|
|
541
|
+
* @param relayGas.is7702 - Whether the relay gas came from a combined 7702 batch estimate.
|
|
511
542
|
* @param transaction - Original transaction metadata.
|
|
512
543
|
* @returns Combined gas estimates including the original transaction.
|
|
513
544
|
*/
|
|
@@ -519,11 +550,9 @@ function combinePostQuoteGas(relayGas, transaction) {
|
|
|
519
550
|
return relayGas;
|
|
520
551
|
}
|
|
521
552
|
let { gasLimits } = relayGas;
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
// Single gas limit (either one relay param or 7702 combined) —
|
|
526
|
-
// add the original tx gas so the batch uses a single 7702 limit.
|
|
553
|
+
if (relayGas.is7702) {
|
|
554
|
+
// Combined 7702 gas limit — add the original tx gas so the batch
|
|
555
|
+
// keeps using a single 7702 limit.
|
|
527
556
|
gasLimits = [gasLimits[0] + originalTxGas];
|
|
528
557
|
}
|
|
529
558
|
else {
|
|
@@ -535,11 +564,16 @@ function combinePostQuoteGas(relayGas, transaction) {
|
|
|
535
564
|
const totalGasLimit = relayGas.totalGasLimit + originalTxGas;
|
|
536
565
|
log('Combined original tx gas with relay gas', {
|
|
537
566
|
originalTxGas,
|
|
538
|
-
|
|
567
|
+
is7702: relayGas.is7702,
|
|
539
568
|
gasLimits,
|
|
540
569
|
totalGasLimit,
|
|
541
570
|
});
|
|
542
|
-
return {
|
|
571
|
+
return {
|
|
572
|
+
totalGasEstimate,
|
|
573
|
+
totalGasLimit,
|
|
574
|
+
gasLimits,
|
|
575
|
+
is7702: relayGas.is7702,
|
|
576
|
+
};
|
|
543
577
|
}
|
|
544
578
|
/**
|
|
545
579
|
* Calculate the provider fee for a Relay quote.
|
|
@@ -573,126 +607,6 @@ function getTransferRecipient(data) {
|
|
|
573
607
|
.decodeFunctionData('transfer', data)
|
|
574
608
|
.to.toLowerCase();
|
|
575
609
|
}
|
|
576
|
-
async function calculateSourceNetworkGasLimitSingle(params, messenger, fromOverride) {
|
|
577
|
-
const paramGasLimit = params.gas
|
|
578
|
-
? new bignumber_js_1.BigNumber(params.gas).toNumber()
|
|
579
|
-
: undefined;
|
|
580
|
-
if (paramGasLimit && !fromOverride) {
|
|
581
|
-
log('Using single gas limit from params', { paramGasLimit });
|
|
582
|
-
return {
|
|
583
|
-
totalGasEstimate: paramGasLimit,
|
|
584
|
-
totalGasLimit: paramGasLimit,
|
|
585
|
-
gasLimits: [paramGasLimit],
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
try {
|
|
589
|
-
const { chainId: chainIdNumber, data, from: paramsFrom, to, value: valueString, } = params;
|
|
590
|
-
const from = fromOverride ?? paramsFrom;
|
|
591
|
-
const chainId = (0, controller_utils_1.toHex)(chainIdNumber);
|
|
592
|
-
const value = (0, controller_utils_1.toHex)(valueString ?? '0');
|
|
593
|
-
const gasBuffer = (0, feature_flags_1.getGasBuffer)(messenger, chainId);
|
|
594
|
-
const networkClientId = messenger.call('NetworkController:findNetworkClientIdByChainId', chainId);
|
|
595
|
-
const { gas: gasHex, simulationFails } = await messenger.call('TransactionController:estimateGas', { from, data, to, value }, networkClientId);
|
|
596
|
-
const estimatedGas = new bignumber_js_1.BigNumber(gasHex).toNumber();
|
|
597
|
-
const bufferedGas = Math.ceil(estimatedGas * gasBuffer);
|
|
598
|
-
if (!simulationFails) {
|
|
599
|
-
log('Estimated gas limit for single transaction', {
|
|
600
|
-
chainId,
|
|
601
|
-
estimatedGas,
|
|
602
|
-
bufferedGas,
|
|
603
|
-
gasBuffer,
|
|
604
|
-
});
|
|
605
|
-
return {
|
|
606
|
-
totalGasEstimate: bufferedGas,
|
|
607
|
-
totalGasLimit: bufferedGas,
|
|
608
|
-
gasLimits: [bufferedGas],
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
catch (error) {
|
|
613
|
-
log('Failed to estimate gas limit for single transaction', error);
|
|
614
|
-
}
|
|
615
|
-
const fallbackGas = (0, feature_flags_1.getFeatureFlags)(messenger).relayFallbackGas;
|
|
616
|
-
log('Using fallback gas for single transaction', { fallbackGas });
|
|
617
|
-
return {
|
|
618
|
-
totalGasEstimate: fallbackGas.estimate,
|
|
619
|
-
totalGasLimit: fallbackGas.max,
|
|
620
|
-
gasLimits: [fallbackGas.max],
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* Calculate the gas limits for a batch of transactions.
|
|
625
|
-
*
|
|
626
|
-
* @param params - Array of transaction parameters.
|
|
627
|
-
* @param messenger - Controller messenger.
|
|
628
|
-
* @param fromOverride - Optional address to use as `from` in gas estimation.
|
|
629
|
-
* @returns - Gas limits.
|
|
630
|
-
*/
|
|
631
|
-
async function calculateSourceNetworkGasLimitBatch(params, messenger, fromOverride) {
|
|
632
|
-
try {
|
|
633
|
-
const { chainId: chainIdNumber, from: paramsFrom } = params[0];
|
|
634
|
-
const from = fromOverride ?? paramsFrom;
|
|
635
|
-
const chainId = (0, controller_utils_1.toHex)(chainIdNumber);
|
|
636
|
-
const gasBuffer = (0, feature_flags_1.getGasBuffer)(messenger, chainId);
|
|
637
|
-
const transactions = params.map((singleParams) => ({
|
|
638
|
-
...singleParams,
|
|
639
|
-
gas: !fromOverride && singleParams.gas
|
|
640
|
-
? (0, controller_utils_1.toHex)(singleParams.gas)
|
|
641
|
-
: undefined,
|
|
642
|
-
maxFeePerGas: undefined,
|
|
643
|
-
maxPriorityFeePerGas: undefined,
|
|
644
|
-
value: (0, controller_utils_1.toHex)(singleParams.value ?? '0'),
|
|
645
|
-
}));
|
|
646
|
-
const paramGasLimits = params.map((singleParams) => singleParams.gas ? new bignumber_js_1.BigNumber(singleParams.gas).toNumber() : undefined);
|
|
647
|
-
const { totalGasLimit, gasLimits } = await messenger.call('TransactionController:estimateGasBatch', {
|
|
648
|
-
chainId,
|
|
649
|
-
from,
|
|
650
|
-
transactions,
|
|
651
|
-
});
|
|
652
|
-
const bufferedGasLimits = gasLimits.map((limit, index) => {
|
|
653
|
-
const useBuffer = gasLimits.length === 1 || paramGasLimits[index] !== gasLimits[index];
|
|
654
|
-
const buffer = useBuffer ? gasBuffer : 1;
|
|
655
|
-
return Math.ceil(limit * buffer);
|
|
656
|
-
});
|
|
657
|
-
const bufferedTotalGasLimit = bufferedGasLimits.reduce((acc, limit) => acc + limit, 0);
|
|
658
|
-
log('Estimated gas limit for batch', {
|
|
659
|
-
chainId,
|
|
660
|
-
totalGasLimit,
|
|
661
|
-
gasLimits,
|
|
662
|
-
bufferedTotalGasLimit,
|
|
663
|
-
bufferedGasLimits,
|
|
664
|
-
gasBuffer,
|
|
665
|
-
});
|
|
666
|
-
return {
|
|
667
|
-
totalGasEstimate: bufferedTotalGasLimit,
|
|
668
|
-
totalGasLimit: bufferedTotalGasLimit,
|
|
669
|
-
gasLimits: bufferedGasLimits,
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
|
-
catch (error) {
|
|
673
|
-
log('Failed to estimate gas limit for batch', error);
|
|
674
|
-
}
|
|
675
|
-
const fallbackGas = (0, feature_flags_1.getFeatureFlags)(messenger).relayFallbackGas;
|
|
676
|
-
const totalGasEstimate = params.reduce((acc, singleParams) => {
|
|
677
|
-
const gas = singleParams.gas ?? fallbackGas.estimate;
|
|
678
|
-
return acc + new bignumber_js_1.BigNumber(gas).toNumber();
|
|
679
|
-
}, 0);
|
|
680
|
-
const gasLimits = params.map((singleParams) => {
|
|
681
|
-
const gas = singleParams.gas ?? fallbackGas.max;
|
|
682
|
-
return new bignumber_js_1.BigNumber(gas).toNumber();
|
|
683
|
-
});
|
|
684
|
-
const totalGasLimit = gasLimits.reduce((acc, singleGasLimit) => acc + singleGasLimit, 0);
|
|
685
|
-
log('Using fallback gas for batch', {
|
|
686
|
-
totalGasEstimate,
|
|
687
|
-
totalGasLimit,
|
|
688
|
-
gasLimits,
|
|
689
|
-
});
|
|
690
|
-
return {
|
|
691
|
-
totalGasEstimate,
|
|
692
|
-
totalGasLimit,
|
|
693
|
-
gasLimits,
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
610
|
function getSubsidizedFeeAmountUsd(quote) {
|
|
697
611
|
const subsidizedFee = quote.fees?.subsidized;
|
|
698
612
|
const amountUsd = new bignumber_js_1.BigNumber(subsidizedFee?.amountUsd ?? '0');
|
|
@@ -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;AAEnD,2CAAqD;AACrD,+CAAyC;AAEzC,+CAAuD;AACvD,mDAGuB;AACvB,+CAA8C;AAC9C,uEAAqE;AAErE,uCAA+C;AAK/C,mDAOyB;AACzB,6CAA6C;AAS7C,qDAA0D;AAC1D,iEAOmC;AACnC,6CAAmD;AACnD,iDAM2B;AAC3B,6DAAuE;AAEvE,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,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;IAE/C,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,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,CAAC,CAAC;QAErD,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,oCAAoC,CAAC;QACrE,UAAU,CAAC,mBAAmB,GAAG,IAAI,wBAAS,CAAC,OAAO,CAAC,mBAAmB,CAAC;aACxE,SAAS,CAAC,CAAC,CAAC;aACZ,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,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,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,yBAAyB,GAC7B,KAAK,CAAC,OAAO,CAAC,SAAS,KAAK,aAAa;QACvC,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAEvB,IAAI,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpC,GAAG,CACD,2CAA2C,EAC3C,yBAAyB,CAAC,QAAQ,CAAC,EAAE,CAAC,CACvC,CAAC;IACJ,CAAC;IAED,MAAM,mBAAmB,GAAG,kBAAkB;QAC5C,CAAC,CAAC,IAAI,wBAAS,CAAC,WAAW,CAAC,eAAe,CAAC;QAC5C,CAAC,CAAC,IAAI,wBAAS,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAEzC,MAAM,eAAe,GAAG,mBAAmB,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAE5E,MAAM,YAAY,GAAG,IAAA,6BAAmB,EAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IAEzE,MAAM,QAAQ,GAAG;QACf,GAAG,KAAK,CAAC,QAAQ;QACjB,SAAS;KACV,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,MAAM,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAEtD,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;IAO5B,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,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAClE,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK;SAC5B,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,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,WAAW;QACxE,CAAC,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC;QAChD,CAAC,CAAC,YAAY,CAAC;IAEjB,GAAG,CAAC,WAAW,EAAE;QACf,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,CAAC;IAE5C,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;aACV,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;KACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,8BAA8B,CAC3C,MAAoD,EACpD,SAA4C,EAC5C,YAAkB;IAMlB,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC;QACxB,CAAC,CAAC,oCAAoC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC;QAC1E,CAAC,CAAC,mCAAmC,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,mBAAmB,CAC1B,QAIC,EACD,WAA4B;IAE5B,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;IAC7B,qFAAqF;IACrF,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;IAEzC,IAAI,SAAS,EAAE,CAAC;QACd,+DAA+D;QAC/D,iEAAiE;QACjE,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,SAAS;QACT,SAAS;QACT,aAAa;KACd,CAAC,CAAC;IAEH,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACxD,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;AAED,KAAK,UAAU,oCAAoC,CACjD,MAAkD,EAClD,SAA4C,EAC5C,YAAkB;IAMlB,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG;QAC9B,CAAC,CAAC,IAAI,wBAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;QACtC,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,aAAa,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,GAAG,CAAC,oCAAoC,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;QAE7D,OAAO;YACL,gBAAgB,EAAE,aAAa;YAC/B,aAAa,EAAE,aAAa;YAC5B,SAAS,EAAE,CAAC,aAAa,CAAC;SAC3B,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EACJ,OAAO,EAAE,aAAa,EACtB,IAAI,EACJ,IAAI,EAAE,UAAU,EAChB,EAAE,EACF,KAAK,EAAE,WAAW,GACnB,GAAG,MAAM,CAAC;QAEX,MAAM,IAAI,GAAG,YAAY,IAAI,UAAU,CAAC;QACxC,MAAM,OAAO,GAAG,IAAA,wBAAK,EAAC,aAAa,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,IAAA,wBAAK,EAAC,WAAW,IAAI,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,IAAA,4BAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnD,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CACpC,gDAAgD,EAChD,OAAO,CACR,CAAC;QAEF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CAC3D,mCAAmC,EACnC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EACzB,eAAe,CAChB,CAAC;QAEF,MAAM,YAAY,GAAG,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;QAExD,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,GAAG,CAAC,4CAA4C,EAAE;gBAChD,OAAO;gBACP,YAAY;gBACZ,WAAW;gBACX,SAAS;aACV,CAAC,CAAC;YAEH,OAAO;gBACL,gBAAgB,EAAE,WAAW;gBAC7B,aAAa,EAAE,WAAW;gBAC1B,SAAS,EAAE,CAAC,WAAW,CAAC;aACzB,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,qDAAqD,EAAE,KAAK,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,WAAW,GAAG,IAAA,+BAAe,EAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC;IAEhE,GAAG,CAAC,2CAA2C,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAElE,OAAO;QACL,gBAAgB,EAAE,WAAW,CAAC,QAAQ;QACtC,aAAa,EAAE,WAAW,CAAC,GAAG;QAC9B,SAAS,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC;KAC7B,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,mCAAmC,CAChD,MAAoD,EACpD,SAA4C,EAC5C,YAAkB;IAMlB,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,YAAY,IAAI,UAAU,CAAC;QACxC,MAAM,OAAO,GAAG,IAAA,wBAAK,EAAC,aAAa,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAA,4BAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnD,MAAM,YAAY,GAA6B,MAAM,CAAC,GAAG,CACvD,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YACjB,GAAG,YAAY;YACf,GAAG,EACD,CAAC,YAAY,IAAI,YAAY,CAAC,GAAG;gBAC/B,CAAC,CAAC,IAAA,wBAAK,EAAC,YAAY,CAAC,GAAG,CAAC;gBACzB,CAAC,CAAC,SAAS;YACf,YAAY,EAAE,SAAS;YACvB,oBAAoB,EAAE,SAAS;YAC/B,KAAK,EAAE,IAAA,wBAAK,EAAC,YAAY,CAAC,KAAK,IAAI,GAAG,CAAC;SACxC,CAAC,CACH,CAAC;QAEF,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CACjD,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,wBAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAC1E,CAAC;QAEF,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CACvD,wCAAwC,EACxC;YACE,OAAO;YACP,IAAI;YACJ,YAAY;SACb,CACF,CAAC;QAEF,MAAM,iBAAiB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACvD,MAAM,SAAS,GACb,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC;YAEvE,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAEzC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,MAAM,CACpD,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAC3B,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,+BAA+B,EAAE;YACnC,OAAO;YACP,aAAa;YACb,SAAS;YACT,qBAAqB;YACrB,iBAAiB;YACjB,SAAS;SACV,CAAC,CAAC;QAEH,OAAO;YACL,gBAAgB,EAAE,qBAAqB;YACvC,aAAa,EAAE,qBAAqB;YACpC,SAAS,EAAE,iBAAiB;SAC7B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,WAAW,GAAG,IAAA,+BAAe,EAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC;IAEhE,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,YAAY,EAAE,EAAE;QAC3D,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC;QACrD,OAAO,GAAG,GAAG,IAAI,wBAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC7C,CAAC,EAAE,CAAC,CAAC,CAAC;IAEN,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC;QAChD,OAAO,IAAI,wBAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CACpC,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,GAAG,GAAG,cAAc,EAC7C,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,8BAA8B,EAAE;QAClC,gBAAgB;QAChB,aAAa;QACb,SAAS;KACV,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,aAAa;QACb,SAAS;KACV,CAAC;AACJ,CAAC;AAED,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 { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TOKEN_TRANSFER_FOUR_BYTE } from './constants';\nimport {\n getGasStationEligibility,\n getGasStationCostInSourceTokenRaw,\n} from './gas-station';\nimport { fetchRelayQuote } from './relay-api';\nimport { getRelayMaxGasStationQuote } from './relay-max-gas-station';\nimport type { RelayQuote, RelayQuoteRequest } from './types';\nimport { TransactionPayStrategy } from '../..';\nimport type {\n BatchTransactionParams,\n TransactionMeta,\n} from '../../../../transaction-controller/src';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\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 isEIP7702Chain,\n isRelayExecuteEnabled,\n getFeatureFlags,\n getGasBuffer,\n getRelayOriginGasOverhead,\n getSlippage,\n} from '../../utils/feature-flags';\nimport { calculateGasCost } from '../../utils/gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport { isPredictWithdrawTransaction } from '../../utils/transaction';\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 { messenger, transaction } = 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 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);\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 = '0x00000000000000000000000000000000';\n newRequest.targetAmountMinimum = new BigNumber(request.targetAmountMinimum)\n .shiftedBy(2)\n .toString(10);\n\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: newRequest,\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 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 additionalTargetAmountUsd =\n quote.request.tradeType === 'EXACT_INPUT'\n ? subsidizedFeeUsd\n : new BigNumber(0);\n\n if (additionalTargetAmountUsd.gt(0)) {\n log(\n 'Including subsidized fee in target amount',\n additionalTargetAmountUsd.toString(10),\n );\n }\n\n const baseTargetAmountUsd = isTargetStablecoin\n ? new BigNumber(currencyOut.amountFormatted)\n : new BigNumber(currencyOut.amountUsd);\n\n const targetAmountUsd = baseTargetAmountUsd.plus(additionalTargetAmountUsd);\n\n const targetAmount = getFiatValueFromUsd(targetAmountUsd, usdToFiatRate);\n\n const metamask = {\n ...quote.metamask,\n gasLimits,\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 const { sourceChainId, sourceTokenAddress } = request;\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 }\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 { estimate: zeroAmount, max: zeroAmount, gasLimits: [] };\n }\n\n const relayParams = quote.steps\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 { totalGasEstimate, totalGasLimit, gasLimits } = request.isPostQuote\n ? combinePostQuoteGas(relayOnlyGas, transaction)\n : relayOnlyGas;\n\n log('Gas limit', {\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 };\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 };\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 };\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: RelayQuote['steps'][0]['items'][0]['data'][],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n}> {\n return params.length === 1\n ? calculateSourceNetworkGasLimitSingle(params[0], messenger, fromOverride)\n : calculateSourceNetworkGasLimitBatch(params, messenger, fromOverride);\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 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 },\n transaction: TransactionMeta,\n): { totalGasEstimate: number; totalGasLimit: number; gasLimits: number[] } {\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 // TODO: Test EIP-7702 support on the chain as well before assuming single gas limit.\n const isEIP7702 = gasLimits.length === 1;\n\n if (isEIP7702) {\n // Single gas limit (either one relay param or 7702 combined) —\n // add the original tx gas so the batch uses 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 isEIP7702,\n gasLimits,\n totalGasLimit,\n });\n\n return { totalGasEstimate, totalGasLimit, gasLimits };\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}\n\nasync function calculateSourceNetworkGasLimitSingle(\n params: RelayQuote['steps'][0]['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n}> {\n const paramGasLimit = params.gas\n ? new BigNumber(params.gas).toNumber()\n : undefined;\n\n if (paramGasLimit && !fromOverride) {\n log('Using single gas limit from params', { paramGasLimit });\n\n return {\n totalGasEstimate: paramGasLimit,\n totalGasLimit: paramGasLimit,\n gasLimits: [paramGasLimit],\n };\n }\n\n try {\n const {\n chainId: chainIdNumber,\n data,\n from: paramsFrom,\n to,\n value: valueString,\n } = params;\n\n const from = fromOverride ?? paramsFrom;\n const chainId = toHex(chainIdNumber);\n const value = toHex(valueString ?? '0');\n const gasBuffer = getGasBuffer(messenger, chainId);\n\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const { gas: gasHex, simulationFails } = await messenger.call(\n 'TransactionController:estimateGas',\n { from, data, to, value },\n networkClientId,\n );\n\n const estimatedGas = new BigNumber(gasHex).toNumber();\n const bufferedGas = Math.ceil(estimatedGas * gasBuffer);\n\n if (!simulationFails) {\n log('Estimated gas limit for single transaction', {\n chainId,\n estimatedGas,\n bufferedGas,\n gasBuffer,\n });\n\n return {\n totalGasEstimate: bufferedGas,\n totalGasLimit: bufferedGas,\n gasLimits: [bufferedGas],\n };\n }\n } catch (error) {\n log('Failed to estimate gas limit for single transaction', error);\n }\n\n const fallbackGas = getFeatureFlags(messenger).relayFallbackGas;\n\n log('Using fallback gas for single transaction', { fallbackGas });\n\n return {\n totalGasEstimate: fallbackGas.estimate,\n totalGasLimit: fallbackGas.max,\n gasLimits: [fallbackGas.max],\n };\n}\n\n/**\n * Calculate the gas limits for a batch of transactions.\n *\n * @param params - Array of transaction parameters.\n * @param messenger - Controller messenger.\n * @param fromOverride - Optional address to use as `from` in gas estimation.\n * @returns - Gas limits.\n */\nasync function calculateSourceNetworkGasLimitBatch(\n params: RelayQuote['steps'][0]['items'][0]['data'][],\n messenger: TransactionPayControllerMessenger,\n fromOverride?: Hex,\n): Promise<{\n totalGasEstimate: number;\n totalGasLimit: number;\n gasLimits: number[];\n}> {\n try {\n const { chainId: chainIdNumber, from: paramsFrom } = params[0];\n const from = fromOverride ?? paramsFrom;\n const chainId = toHex(chainIdNumber);\n const gasBuffer = getGasBuffer(messenger, chainId);\n\n const transactions: BatchTransactionParams[] = params.map(\n (singleParams) => ({\n ...singleParams,\n gas:\n !fromOverride && singleParams.gas\n ? toHex(singleParams.gas)\n : undefined,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n value: toHex(singleParams.value ?? '0'),\n }),\n );\n\n const paramGasLimits = params.map((singleParams) =>\n singleParams.gas ? new BigNumber(singleParams.gas).toNumber() : undefined,\n );\n\n const { totalGasLimit, gasLimits } = await messenger.call(\n 'TransactionController:estimateGasBatch',\n {\n chainId,\n from,\n transactions,\n },\n );\n\n const bufferedGasLimits = gasLimits.map((limit, index) => {\n const useBuffer =\n gasLimits.length === 1 || paramGasLimits[index] !== gasLimits[index];\n\n const buffer = useBuffer ? gasBuffer : 1;\n\n return Math.ceil(limit * buffer);\n });\n\n const bufferedTotalGasLimit = bufferedGasLimits.reduce(\n (acc, limit) => acc + limit,\n 0,\n );\n\n log('Estimated gas limit for batch', {\n chainId,\n totalGasLimit,\n gasLimits,\n bufferedTotalGasLimit,\n bufferedGasLimits,\n gasBuffer,\n });\n\n return {\n totalGasEstimate: bufferedTotalGasLimit,\n totalGasLimit: bufferedTotalGasLimit,\n gasLimits: bufferedGasLimits,\n };\n } catch (error) {\n log('Failed to estimate gas limit for batch', error);\n }\n\n const fallbackGas = getFeatureFlags(messenger).relayFallbackGas;\n\n const totalGasEstimate = params.reduce((acc, singleParams) => {\n const gas = singleParams.gas ?? fallbackGas.estimate;\n return acc + new BigNumber(gas).toNumber();\n }, 0);\n\n const gasLimits = params.map((singleParams) => {\n const gas = singleParams.gas ?? fallbackGas.max;\n return new BigNumber(gas).toNumber();\n });\n\n const totalGasLimit = gasLimits.reduce(\n (acc, singleGasLimit) => acc + singleGasLimit,\n 0,\n );\n\n log('Using fallback gas for batch', {\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n });\n\n return {\n totalGasEstimate,\n totalGasLimit,\n gasLimits,\n };\n}\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 { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { TOKEN_TRANSFER_FOUR_BYTE } from './constants';\nimport {\n getGasStationCostInSourceTokenRaw,\n getGasStationEligibility,\n} from './gas-station';\nimport { fetchRelayQuote } from './relay-api';\nimport { getRelayMaxGasStationQuote } from './relay-max-gas-station';\nimport type {\n RelayQuote,\n RelayQuoteMetamask,\n RelayQuoteRequest,\n} from './types';\nimport { TransactionPayStrategy } from '../..';\nimport type { TransactionMeta } from '../../../../transaction-controller/src';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\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 { 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';\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 { messenger, transaction } = 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 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);\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 = '0x00000000000000000000000000000000';\n newRequest.targetAmountMinimum = new BigNumber(request.targetAmountMinimum)\n .shiftedBy(2)\n .toString(10);\n\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: newRequest,\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 additionalTargetAmountUsd =\n quote.request.tradeType === 'EXACT_INPUT'\n ? subsidizedFeeUsd\n : new BigNumber(0);\n\n if (additionalTargetAmountUsd.gt(0)) {\n log(\n 'Including subsidized fee in target amount',\n additionalTargetAmountUsd.toString(10),\n );\n }\n\n const baseTargetAmountUsd = isTargetStablecoin\n ? new BigNumber(currencyOut.amountFormatted)\n : new BigNumber(currencyOut.amountUsd);\n\n const targetAmountUsd = baseTargetAmountUsd.plus(additionalTargetAmountUsd);\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 const { sourceChainId, sourceTokenAddress } = request;\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 const relayParams = quote.steps\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: RelayQuote['steps'][0]['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: RelayQuote['steps'][0]['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}\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":"AAeA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"relay-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,UAAU,EAGX,oBAAgB;AAYjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAuBrB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CA2B5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"relay-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,UAAU,EAGX,oBAAgB;AAYjB,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAuBrB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CA2B5C"}
|