@metamask/transaction-pay-controller 16.4.0 → 16.5.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 +29 -1
- package/dist/strategy/across/across-quotes.cjs +42 -8
- 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 +42 -8
- package/dist/strategy/across/across-quotes.mjs.map +1 -1
- package/dist/strategy/relay/constants.cjs +3 -1
- package/dist/strategy/relay/constants.cjs.map +1 -1
- package/dist/strategy/relay/constants.d.cts +2 -0
- package/dist/strategy/relay/constants.d.cts.map +1 -1
- package/dist/strategy/relay/constants.d.mts +2 -0
- package/dist/strategy/relay/constants.d.mts.map +1 -1
- package/dist/strategy/relay/constants.mjs +2 -0
- package/dist/strategy/relay/constants.mjs.map +1 -1
- package/dist/strategy/relay/gas-station.cjs +1 -2
- package/dist/strategy/relay/gas-station.cjs.map +1 -1
- package/dist/strategy/relay/gas-station.d.cts.map +1 -1
- package/dist/strategy/relay/gas-station.d.mts.map +1 -1
- package/dist/strategy/relay/gas-station.mjs +2 -3
- package/dist/strategy/relay/gas-station.mjs.map +1 -1
- package/dist/strategy/relay/relay-api.cjs +55 -0
- package/dist/strategy/relay/relay-api.cjs.map +1 -0
- package/dist/strategy/relay/relay-api.d.cts +26 -0
- package/dist/strategy/relay/relay-api.d.cts.map +1 -0
- package/dist/strategy/relay/relay-api.d.mts +26 -0
- package/dist/strategy/relay/relay-api.d.mts.map +1 -0
- package/dist/strategy/relay/relay-api.mjs +49 -0
- package/dist/strategy/relay/relay-api.mjs.map +1 -0
- package/dist/strategy/relay/relay-quotes.cjs +114 -31
- 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 +116 -33
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +120 -8
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.d.cts.map +1 -1
- package/dist/strategy/relay/relay-submit.d.mts.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +123 -11
- 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 +27 -0
- package/dist/strategy/relay/types.d.cts.map +1 -1
- package/dist/strategy/relay/types.d.mts +27 -0
- 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 +8 -1
- package/dist/tests/messenger-mock.d.cts.map +1 -1
- package/dist/tests/messenger-mock.d.mts +8 -1
- package/dist/tests/messenger-mock.d.mts.map +1 -1
- package/dist/utils/feature-flags.cjs +37 -7
- package/dist/utils/feature-flags.cjs.map +1 -1
- package/dist/utils/feature-flags.d.cts +24 -3
- package/dist/utils/feature-flags.d.cts.map +1 -1
- package/dist/utils/feature-flags.d.mts +24 -3
- package/dist/utils/feature-flags.d.mts.map +1 -1
- package/dist/utils/feature-flags.mjs +34 -6
- package/dist/utils/feature-flags.mjs.map +1 -1
- package/dist/utils/transaction.cjs +16 -1
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +10 -0
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +10 -0
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +15 -1
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,cAAc,oBAAoB,CAAC;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AACvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAC;AAErD,MAAM,CAAC,MAAM,mBAAmB,GAAoC;IAClE,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC,mBAAmB;IACrE,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC,iBAAiB;CAClE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nexport const RELAY_URL_BASE = 'https://api.relay.link';\nexport const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;\nexport const RELAY_POLLING_INTERVAL = 1000; // 1 Second\nexport const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\n\nexport const RELAY_DEPOSIT_TYPES: Record<string, TransactionType> = {\n [TransactionType.predictDeposit]: TransactionType.predictRelayDeposit,\n [TransactionType.perpsDeposit]: TransactionType.perpsRelayDeposit,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,cAAc,UAAU,CAAC;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,cAAc,QAAQ,CAAC;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,cAAc,oBAAoB,CAAC;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AACvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAC;AAErD,MAAM,CAAC,MAAM,mBAAmB,GAAoC;IAClE,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC,mBAAmB;IACrE,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC,iBAAiB;CAClE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nexport const RELAY_URL_BASE = 'https://api.relay.link';\nexport const RELAY_EXECUTE_URL = `${RELAY_URL_BASE}/execute`;\nexport const RELAY_QUOTE_URL = `${RELAY_URL_BASE}/quote`;\nexport const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;\nexport const RELAY_POLLING_INTERVAL = 1000; // 1 Second\nexport const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\n\nexport const RELAY_DEPOSIT_TYPES: Record<string, TransactionType> = {\n [TransactionType.predictDeposit]: TransactionType.predictRelayDeposit,\n [TransactionType.perpsDeposit]: TransactionType.perpsRelayDeposit,\n};\n"]}
|
|
@@ -10,8 +10,7 @@ const gas_1 = require("../../utils/gas.cjs");
|
|
|
10
10
|
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'relay-gas-station');
|
|
11
11
|
function getGasStationEligibility(messenger, sourceChainId) {
|
|
12
12
|
const { relayDisabledGasStationChains } = (0, feature_flags_1.getFeatureFlags)(messenger);
|
|
13
|
-
const
|
|
14
|
-
const chainSupportsGasStation = supportedChains.some((supportedChainId) => supportedChainId.toLowerCase() === sourceChainId.toLowerCase());
|
|
13
|
+
const chainSupportsGasStation = (0, feature_flags_1.isEIP7702Chain)(messenger, sourceChainId);
|
|
15
14
|
const isDisabledChain = relayDisabledGasStationChains.includes(sourceChainId);
|
|
16
15
|
return {
|
|
17
16
|
chainSupportsGasStation,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gas-station.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":";;;AAAA,iEAAmD;AAGnD,2CAAqD;AACrD,+CAAyC;AAEzC,6CAA6C;AAM7C,
|
|
1
|
+
{"version":3,"file":"gas-station.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"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","sourcesContent":["import { toHex } from '@metamask/controller-utils';\nimport type { GasFeeToken } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { getFeatureFlags, isEIP7702Chain } from '../../utils/feature-flags';\nimport { calculateGasFeeTokenCost } from '../../utils/gas';\n\nconst log = createModuleLogger(projectLogger, 'relay-gas-station');\n\ntype GasStationCostParams = {\n firstStepData: {\n data: Hex;\n to: Hex;\n value?: string;\n };\n messenger: TransactionPayControllerMessenger;\n request: Pick<QuoteRequest, 'from' | 'sourceChainId' | 'sourceTokenAddress'>;\n totalGasEstimate: number;\n totalItemCount: number;\n};\n\nexport type GasStationEligibility = {\n chainSupportsGasStation: boolean;\n isDisabledChain: boolean;\n isEligible: boolean;\n};\n\nexport function getGasStationEligibility(\n messenger: TransactionPayControllerMessenger,\n sourceChainId: QuoteRequest['sourceChainId'],\n): GasStationEligibility {\n const { relayDisabledGasStationChains } = getFeatureFlags(messenger);\n const chainSupportsGasStation = isEIP7702Chain(messenger, sourceChainId);\n\n const isDisabledChain = relayDisabledGasStationChains.includes(sourceChainId);\n\n return {\n chainSupportsGasStation,\n isDisabledChain,\n isEligible: !isDisabledChain && chainSupportsGasStation,\n };\n}\n\nexport async function getGasStationCostInSourceTokenRaw({\n firstStepData,\n messenger,\n request,\n totalGasEstimate,\n totalItemCount,\n}: GasStationCostParams): Promise<Amount | undefined> {\n const { data, to, value } = firstStepData;\n const { from, sourceChainId, sourceTokenAddress } = request;\n\n let gasFeeTokens: GasFeeToken[];\n\n try {\n gasFeeTokens = await messenger.call(\n 'TransactionController:getGasFeeTokens',\n {\n chainId: sourceChainId,\n data,\n from,\n to,\n value: toHex(value ?? '0'),\n },\n );\n } catch (error) {\n log('Failed to estimate gas fee tokens', {\n error,\n sourceChainId,\n });\n return undefined;\n }\n\n const gasFeeToken = gasFeeTokens.find(\n (singleGasFeeToken) =>\n singleGasFeeToken.tokenAddress.toLowerCase() ===\n sourceTokenAddress.toLowerCase(),\n );\n\n if (!gasFeeToken) {\n log('No matching source token in gas fee token estimate', {\n sourceTokenAddress,\n sourceChainId,\n });\n return undefined;\n }\n\n const gasFeeTokenWithNormalizedAmount = {\n ...gasFeeToken,\n amount: toHex(\n getNormalizedGasFeeTokenAmount({\n gasFeeToken,\n totalGasEstimate,\n totalItemCount,\n }),\n ),\n };\n\n const gasFeeTokenCost = calculateGasFeeTokenCost({\n chainId: sourceChainId,\n gasFeeToken: gasFeeTokenWithNormalizedAmount,\n messenger,\n });\n\n if (!gasFeeTokenCost) {\n log('Unable to calculate gas fee token cost using fiat rates', {\n sourceTokenAddress,\n sourceChainId,\n });\n return undefined;\n }\n\n log('Estimated gas station cost for source token', {\n amount: gasFeeTokenCost.raw,\n sourceTokenAddress,\n sourceChainId,\n });\n\n return gasFeeTokenCost;\n}\n\nfunction getNormalizedGasFeeTokenAmount({\n gasFeeToken,\n totalGasEstimate,\n totalItemCount,\n}: {\n gasFeeToken: GasFeeToken;\n totalGasEstimate: number;\n totalItemCount: number;\n}): string {\n let amount = new BigNumber(gasFeeToken.amount);\n\n if (totalItemCount > 1) {\n const gas = new BigNumber(gasFeeToken.gas);\n const gasFeeAmount = new BigNumber(gasFeeToken.amount);\n\n if (totalGasEstimate > 0 && gas.isGreaterThan(0)) {\n const gasRate = gasFeeAmount.dividedBy(gas);\n amount = gasRate.multipliedBy(totalGasEstimate);\n }\n }\n\n return amount.integerValue(BigNumber.ROUND_CEIL).toFixed(0);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gas-station.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,iCAAiC,EAClC,wBAAoB;
|
|
1
|
+
{"version":3,"file":"gas-station.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,iCAAiC,EAClC,wBAAoB;AAMrB,KAAK,oBAAoB,GAAG;IAC1B,aAAa,EAAE;QACb,IAAI,EAAE,GAAG,CAAC;QACV,EAAE,EAAE,GAAG,CAAC;QACR,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,iCAAiC,CAAC;IAC7C,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,GAAG,oBAAoB,CAAC,CAAC;IAC7E,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,uBAAuB,EAAE,OAAO,CAAC;IACjC,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,iCAAiC,EAC5C,aAAa,EAAE,YAAY,CAAC,eAAe,CAAC,GAC3C,qBAAqB,CAWvB;AAED,wBAAsB,iCAAiC,CAAC,EACtD,aAAa,EACb,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,cAAc,GACf,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuEpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gas-station.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,iCAAiC,EAClC,wBAAoB;
|
|
1
|
+
{"version":3,"file":"gas-station.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,iCAAiC,EAClC,wBAAoB;AAMrB,KAAK,oBAAoB,GAAG;IAC1B,aAAa,EAAE;QACb,IAAI,EAAE,GAAG,CAAC;QACV,EAAE,EAAE,GAAG,CAAC;QACR,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,iCAAiC,CAAC;IAC7C,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,GAAG,oBAAoB,CAAC,CAAC;IAC7E,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,uBAAuB,EAAE,OAAO,CAAC;IACjC,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,iCAAiC,EAC5C,aAAa,EAAE,YAAY,CAAC,eAAe,CAAC,GAC3C,qBAAqB,CAWvB;AAED,wBAAsB,iCAAiC,CAAC,EACtD,aAAa,EACb,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,cAAc,GACf,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuEpD"}
|
|
@@ -2,13 +2,12 @@ import { toHex } from "@metamask/controller-utils";
|
|
|
2
2
|
import { createModuleLogger } from "@metamask/utils";
|
|
3
3
|
import { BigNumber } from "bignumber.js";
|
|
4
4
|
import { projectLogger } from "../../logger.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { getFeatureFlags, isEIP7702Chain } from "../../utils/feature-flags.mjs";
|
|
6
6
|
import { calculateGasFeeTokenCost } from "../../utils/gas.mjs";
|
|
7
7
|
const log = createModuleLogger(projectLogger, 'relay-gas-station');
|
|
8
8
|
export function getGasStationEligibility(messenger, sourceChainId) {
|
|
9
9
|
const { relayDisabledGasStationChains } = getFeatureFlags(messenger);
|
|
10
|
-
const
|
|
11
|
-
const chainSupportsGasStation = supportedChains.some((supportedChainId) => supportedChainId.toLowerCase() === sourceChainId.toLowerCase());
|
|
10
|
+
const chainSupportsGasStation = isEIP7702Chain(messenger, sourceChainId);
|
|
12
11
|
const isDisabledChain = relayDisabledGasStationChains.includes(sourceChainId);
|
|
13
12
|
return {
|
|
14
13
|
chainSupportsGasStation,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gas-station.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,mCAAmC;AAGnD,OAAO,EAAE,kBAAkB,EAAE,wBAAwB;AACrD,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAEzC,OAAO,EAAE,aAAa,EAAE,yBAAqB;AAM7C,OAAO,
|
|
1
|
+
{"version":3,"file":"gas-station.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/gas-station.ts"],"names":[],"mappings":"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","sourcesContent":["import { toHex } from '@metamask/controller-utils';\nimport type { GasFeeToken } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { getFeatureFlags, isEIP7702Chain } from '../../utils/feature-flags';\nimport { calculateGasFeeTokenCost } from '../../utils/gas';\n\nconst log = createModuleLogger(projectLogger, 'relay-gas-station');\n\ntype GasStationCostParams = {\n firstStepData: {\n data: Hex;\n to: Hex;\n value?: string;\n };\n messenger: TransactionPayControllerMessenger;\n request: Pick<QuoteRequest, 'from' | 'sourceChainId' | 'sourceTokenAddress'>;\n totalGasEstimate: number;\n totalItemCount: number;\n};\n\nexport type GasStationEligibility = {\n chainSupportsGasStation: boolean;\n isDisabledChain: boolean;\n isEligible: boolean;\n};\n\nexport function getGasStationEligibility(\n messenger: TransactionPayControllerMessenger,\n sourceChainId: QuoteRequest['sourceChainId'],\n): GasStationEligibility {\n const { relayDisabledGasStationChains } = getFeatureFlags(messenger);\n const chainSupportsGasStation = isEIP7702Chain(messenger, sourceChainId);\n\n const isDisabledChain = relayDisabledGasStationChains.includes(sourceChainId);\n\n return {\n chainSupportsGasStation,\n isDisabledChain,\n isEligible: !isDisabledChain && chainSupportsGasStation,\n };\n}\n\nexport async function getGasStationCostInSourceTokenRaw({\n firstStepData,\n messenger,\n request,\n totalGasEstimate,\n totalItemCount,\n}: GasStationCostParams): Promise<Amount | undefined> {\n const { data, to, value } = firstStepData;\n const { from, sourceChainId, sourceTokenAddress } = request;\n\n let gasFeeTokens: GasFeeToken[];\n\n try {\n gasFeeTokens = await messenger.call(\n 'TransactionController:getGasFeeTokens',\n {\n chainId: sourceChainId,\n data,\n from,\n to,\n value: toHex(value ?? '0'),\n },\n );\n } catch (error) {\n log('Failed to estimate gas fee tokens', {\n error,\n sourceChainId,\n });\n return undefined;\n }\n\n const gasFeeToken = gasFeeTokens.find(\n (singleGasFeeToken) =>\n singleGasFeeToken.tokenAddress.toLowerCase() ===\n sourceTokenAddress.toLowerCase(),\n );\n\n if (!gasFeeToken) {\n log('No matching source token in gas fee token estimate', {\n sourceTokenAddress,\n sourceChainId,\n });\n return undefined;\n }\n\n const gasFeeTokenWithNormalizedAmount = {\n ...gasFeeToken,\n amount: toHex(\n getNormalizedGasFeeTokenAmount({\n gasFeeToken,\n totalGasEstimate,\n totalItemCount,\n }),\n ),\n };\n\n const gasFeeTokenCost = calculateGasFeeTokenCost({\n chainId: sourceChainId,\n gasFeeToken: gasFeeTokenWithNormalizedAmount,\n messenger,\n });\n\n if (!gasFeeTokenCost) {\n log('Unable to calculate gas fee token cost using fiat rates', {\n sourceTokenAddress,\n sourceChainId,\n });\n return undefined;\n }\n\n log('Estimated gas station cost for source token', {\n amount: gasFeeTokenCost.raw,\n sourceTokenAddress,\n sourceChainId,\n });\n\n return gasFeeTokenCost;\n}\n\nfunction getNormalizedGasFeeTokenAmount({\n gasFeeToken,\n totalGasEstimate,\n totalItemCount,\n}: {\n gasFeeToken: GasFeeToken;\n totalGasEstimate: number;\n totalItemCount: number;\n}): string {\n let amount = new BigNumber(gasFeeToken.amount);\n\n if (totalItemCount > 1) {\n const gas = new BigNumber(gasFeeToken.gas);\n const gasFeeAmount = new BigNumber(gasFeeToken.amount);\n\n if (totalGasEstimate > 0 && gas.isGreaterThan(0)) {\n const gasRate = gasFeeAmount.dividedBy(gas);\n amount = gasRate.multipliedBy(totalGasEstimate);\n }\n }\n\n return amount.integerValue(BigNumber.ROUND_CEIL).toFixed(0);\n}\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRelayStatus = exports.submitRelayExecute = exports.fetchRelayQuote = void 0;
|
|
4
|
+
const controller_utils_1 = require("@metamask/controller-utils");
|
|
5
|
+
const constants_1 = require("./constants.cjs");
|
|
6
|
+
const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
7
|
+
/**
|
|
8
|
+
* Fetch a quote from the Relay API.
|
|
9
|
+
*
|
|
10
|
+
* @param messenger - Controller messenger.
|
|
11
|
+
* @param body - Quote request parameters.
|
|
12
|
+
* @returns The Relay quote with the request attached.
|
|
13
|
+
*/
|
|
14
|
+
async function fetchRelayQuote(messenger, body) {
|
|
15
|
+
const { relayQuoteUrl } = (0, feature_flags_1.getFeatureFlags)(messenger);
|
|
16
|
+
const response = await (0, controller_utils_1.successfulFetch)(relayQuoteUrl, {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
headers: { 'Content-Type': 'application/json' },
|
|
19
|
+
body: JSON.stringify(body),
|
|
20
|
+
});
|
|
21
|
+
const quote = (await response.json());
|
|
22
|
+
quote.request = body;
|
|
23
|
+
return quote;
|
|
24
|
+
}
|
|
25
|
+
exports.fetchRelayQuote = fetchRelayQuote;
|
|
26
|
+
/**
|
|
27
|
+
* Submit a gasless transaction via the Relay /execute endpoint.
|
|
28
|
+
*
|
|
29
|
+
* @param messenger - Controller messenger.
|
|
30
|
+
* @param body - Execute request parameters.
|
|
31
|
+
* @returns The execute response containing the request ID.
|
|
32
|
+
*/
|
|
33
|
+
async function submitRelayExecute(messenger, body) {
|
|
34
|
+
const { relayExecuteUrl } = (0, feature_flags_1.getFeatureFlags)(messenger);
|
|
35
|
+
const response = await (0, controller_utils_1.successfulFetch)(relayExecuteUrl, {
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: { 'Content-Type': 'application/json' },
|
|
38
|
+
body: JSON.stringify(body),
|
|
39
|
+
});
|
|
40
|
+
return (await response.json());
|
|
41
|
+
}
|
|
42
|
+
exports.submitRelayExecute = submitRelayExecute;
|
|
43
|
+
/**
|
|
44
|
+
* Poll the Relay status endpoint for a given request ID.
|
|
45
|
+
*
|
|
46
|
+
* @param requestId - The Relay request ID to check.
|
|
47
|
+
* @returns The current status of the request.
|
|
48
|
+
*/
|
|
49
|
+
async function getRelayStatus(requestId) {
|
|
50
|
+
const url = `${constants_1.RELAY_STATUS_URL}?requestId=${requestId}`;
|
|
51
|
+
const response = await (0, controller_utils_1.successfulFetch)(url, { method: 'GET' });
|
|
52
|
+
return (await response.json());
|
|
53
|
+
}
|
|
54
|
+
exports.getRelayStatus = getRelayStatus;
|
|
55
|
+
//# sourceMappingURL=relay-api.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-api.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-api.ts"],"names":[],"mappings":";;;AAAA,iEAA6D;AAE7D,+CAA+C;AAS/C,iEAA4D;AAE5D;;;;;;GAMG;AACI,KAAK,UAAU,eAAe,CACnC,SAA4C,EAC5C,IAAuB;IAEvB,MAAM,EAAE,aAAa,EAAE,GAAG,IAAA,+BAAe,EAAC,SAAS,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,aAAa,EAAE;QACpD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAe,CAAC;IACpD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;IAErB,OAAO,KAAK,CAAC;AACf,CAAC;AAhBD,0CAgBC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,kBAAkB,CACtC,SAA4C,EAC5C,IAAyB;IAEzB,MAAM,EAAE,eAAe,EAAE,GAAG,IAAA,+BAAe,EAAC,SAAS,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,eAAe,EAAE;QACtD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyB,CAAC;AACzD,CAAC;AAbD,gDAaC;AAED;;;;;GAKG;AACI,KAAK,UAAU,cAAc,CAClC,SAAiB;IAEjB,MAAM,GAAG,GAAG,GAAG,4BAAgB,cAAc,SAAS,EAAE,CAAC;IAEzD,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE/D,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;AACxD,CAAC;AARD,wCAQC","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\n\nimport { RELAY_STATUS_URL } from './constants';\nimport type {\n RelayExecuteRequest,\n RelayExecuteResponse,\n RelayQuote,\n RelayQuoteRequest,\n RelayStatusResponse,\n} from './types';\nimport type { TransactionPayControllerMessenger } from '../../types';\nimport { getFeatureFlags } from '../../utils/feature-flags';\n\n/**\n * Fetch a quote from the Relay API.\n *\n * @param messenger - Controller messenger.\n * @param body - Quote request parameters.\n * @returns The Relay quote with the request attached.\n */\nexport async function fetchRelayQuote(\n messenger: TransactionPayControllerMessenger,\n body: RelayQuoteRequest,\n): Promise<RelayQuote> {\n const { relayQuoteUrl } = getFeatureFlags(messenger);\n\n const response = await successfulFetch(relayQuoteUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n const quote = (await response.json()) as RelayQuote;\n quote.request = body;\n\n return quote;\n}\n\n/**\n * Submit a gasless transaction via the Relay /execute endpoint.\n *\n * @param messenger - Controller messenger.\n * @param body - Execute request parameters.\n * @returns The execute response containing the request ID.\n */\nexport async function submitRelayExecute(\n messenger: TransactionPayControllerMessenger,\n body: RelayExecuteRequest,\n): Promise<RelayExecuteResponse> {\n const { relayExecuteUrl } = getFeatureFlags(messenger);\n\n const response = await successfulFetch(relayExecuteUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n return (await response.json()) as RelayExecuteResponse;\n}\n\n/**\n * Poll the Relay status endpoint for a given request ID.\n *\n * @param requestId - The Relay request ID to check.\n * @returns The current status of the request.\n */\nexport async function getRelayStatus(\n requestId: string,\n): Promise<RelayStatusResponse> {\n const url = `${RELAY_STATUS_URL}?requestId=${requestId}`;\n\n const response = await successfulFetch(url, { method: 'GET' });\n\n return (await response.json()) as RelayStatusResponse;\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RelayExecuteRequest, RelayExecuteResponse, RelayQuote, RelayQuoteRequest, RelayStatusResponse } from "./types.cjs";
|
|
2
|
+
import type { TransactionPayControllerMessenger } from "../../types.cjs";
|
|
3
|
+
/**
|
|
4
|
+
* Fetch a quote from the Relay API.
|
|
5
|
+
*
|
|
6
|
+
* @param messenger - Controller messenger.
|
|
7
|
+
* @param body - Quote request parameters.
|
|
8
|
+
* @returns The Relay quote with the request attached.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fetchRelayQuote(messenger: TransactionPayControllerMessenger, body: RelayQuoteRequest): Promise<RelayQuote>;
|
|
11
|
+
/**
|
|
12
|
+
* Submit a gasless transaction via the Relay /execute endpoint.
|
|
13
|
+
*
|
|
14
|
+
* @param messenger - Controller messenger.
|
|
15
|
+
* @param body - Execute request parameters.
|
|
16
|
+
* @returns The execute response containing the request ID.
|
|
17
|
+
*/
|
|
18
|
+
export declare function submitRelayExecute(messenger: TransactionPayControllerMessenger, body: RelayExecuteRequest): Promise<RelayExecuteResponse>;
|
|
19
|
+
/**
|
|
20
|
+
* Poll the Relay status endpoint for a given request ID.
|
|
21
|
+
*
|
|
22
|
+
* @param requestId - The Relay request ID to check.
|
|
23
|
+
* @returns The current status of the request.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getRelayStatus(requestId: string): Promise<RelayStatusResponse>;
|
|
26
|
+
//# sourceMappingURL=relay-api.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-api.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACpB,oBAAgB;AACjB,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAGrE;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,iCAAiC,EAC5C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,UAAU,CAAC,CAarB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,iCAAiC,EAC5C,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAU/B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,CAAC,CAM9B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RelayExecuteRequest, RelayExecuteResponse, RelayQuote, RelayQuoteRequest, RelayStatusResponse } from "./types.mjs";
|
|
2
|
+
import type { TransactionPayControllerMessenger } from "../../types.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Fetch a quote from the Relay API.
|
|
5
|
+
*
|
|
6
|
+
* @param messenger - Controller messenger.
|
|
7
|
+
* @param body - Quote request parameters.
|
|
8
|
+
* @returns The Relay quote with the request attached.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fetchRelayQuote(messenger: TransactionPayControllerMessenger, body: RelayQuoteRequest): Promise<RelayQuote>;
|
|
11
|
+
/**
|
|
12
|
+
* Submit a gasless transaction via the Relay /execute endpoint.
|
|
13
|
+
*
|
|
14
|
+
* @param messenger - Controller messenger.
|
|
15
|
+
* @param body - Execute request parameters.
|
|
16
|
+
* @returns The execute response containing the request ID.
|
|
17
|
+
*/
|
|
18
|
+
export declare function submitRelayExecute(messenger: TransactionPayControllerMessenger, body: RelayExecuteRequest): Promise<RelayExecuteResponse>;
|
|
19
|
+
/**
|
|
20
|
+
* Poll the Relay status endpoint for a given request ID.
|
|
21
|
+
*
|
|
22
|
+
* @param requestId - The Relay request ID to check.
|
|
23
|
+
* @returns The current status of the request.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getRelayStatus(requestId: string): Promise<RelayStatusResponse>;
|
|
26
|
+
//# sourceMappingURL=relay-api.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-api.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACpB,oBAAgB;AACjB,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAGrE;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,iCAAiC,EAC5C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,UAAU,CAAC,CAarB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,iCAAiC,EAC5C,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAU/B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,CAAC,CAM9B"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { successfulFetch } from "@metamask/controller-utils";
|
|
2
|
+
import { RELAY_STATUS_URL } from "./constants.mjs";
|
|
3
|
+
import { getFeatureFlags } from "../../utils/feature-flags.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Fetch a quote from the Relay API.
|
|
6
|
+
*
|
|
7
|
+
* @param messenger - Controller messenger.
|
|
8
|
+
* @param body - Quote request parameters.
|
|
9
|
+
* @returns The Relay quote with the request attached.
|
|
10
|
+
*/
|
|
11
|
+
export async function fetchRelayQuote(messenger, body) {
|
|
12
|
+
const { relayQuoteUrl } = getFeatureFlags(messenger);
|
|
13
|
+
const response = await successfulFetch(relayQuoteUrl, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: { 'Content-Type': 'application/json' },
|
|
16
|
+
body: JSON.stringify(body),
|
|
17
|
+
});
|
|
18
|
+
const quote = (await response.json());
|
|
19
|
+
quote.request = body;
|
|
20
|
+
return quote;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Submit a gasless transaction via the Relay /execute endpoint.
|
|
24
|
+
*
|
|
25
|
+
* @param messenger - Controller messenger.
|
|
26
|
+
* @param body - Execute request parameters.
|
|
27
|
+
* @returns The execute response containing the request ID.
|
|
28
|
+
*/
|
|
29
|
+
export async function submitRelayExecute(messenger, body) {
|
|
30
|
+
const { relayExecuteUrl } = getFeatureFlags(messenger);
|
|
31
|
+
const response = await successfulFetch(relayExecuteUrl, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
body: JSON.stringify(body),
|
|
35
|
+
});
|
|
36
|
+
return (await response.json());
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Poll the Relay status endpoint for a given request ID.
|
|
40
|
+
*
|
|
41
|
+
* @param requestId - The Relay request ID to check.
|
|
42
|
+
* @returns The current status of the request.
|
|
43
|
+
*/
|
|
44
|
+
export async function getRelayStatus(requestId) {
|
|
45
|
+
const url = `${RELAY_STATUS_URL}?requestId=${requestId}`;
|
|
46
|
+
const response = await successfulFetch(url, { method: 'GET' });
|
|
47
|
+
return (await response.json());
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=relay-api.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-api.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mCAAmC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,wBAAoB;AAS/C,OAAO,EAAE,eAAe,EAAE,sCAAkC;AAE5D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAA4C,EAC5C,IAAuB;IAEvB,MAAM,EAAE,aAAa,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,aAAa,EAAE;QACpD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAe,CAAC;IACpD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;IAErB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAA4C,EAC5C,IAAyB;IAEzB,MAAM,EAAE,eAAe,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,eAAe,EAAE;QACtD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyB,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAiB;IAEjB,MAAM,GAAG,GAAG,GAAG,gBAAgB,cAAc,SAAS,EAAE,CAAC;IAEzD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAE/D,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;AACxD,CAAC","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\n\nimport { RELAY_STATUS_URL } from './constants';\nimport type {\n RelayExecuteRequest,\n RelayExecuteResponse,\n RelayQuote,\n RelayQuoteRequest,\n RelayStatusResponse,\n} from './types';\nimport type { TransactionPayControllerMessenger } from '../../types';\nimport { getFeatureFlags } from '../../utils/feature-flags';\n\n/**\n * Fetch a quote from the Relay API.\n *\n * @param messenger - Controller messenger.\n * @param body - Quote request parameters.\n * @returns The Relay quote with the request attached.\n */\nexport async function fetchRelayQuote(\n messenger: TransactionPayControllerMessenger,\n body: RelayQuoteRequest,\n): Promise<RelayQuote> {\n const { relayQuoteUrl } = getFeatureFlags(messenger);\n\n const response = await successfulFetch(relayQuoteUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n const quote = (await response.json()) as RelayQuote;\n quote.request = body;\n\n return quote;\n}\n\n/**\n * Submit a gasless transaction via the Relay /execute endpoint.\n *\n * @param messenger - Controller messenger.\n * @param body - Execute request parameters.\n * @returns The execute response containing the request ID.\n */\nexport async function submitRelayExecute(\n messenger: TransactionPayControllerMessenger,\n body: RelayExecuteRequest,\n): Promise<RelayExecuteResponse> {\n const { relayExecuteUrl } = getFeatureFlags(messenger);\n\n const response = await successfulFetch(relayExecuteUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n return (await response.json()) as RelayExecuteResponse;\n}\n\n/**\n * Poll the Relay status endpoint for a given request ID.\n *\n * @param requestId - The Relay request ID to check.\n * @returns The current status of the request.\n */\nexport async function getRelayStatus(\n requestId: string,\n): Promise<RelayStatusResponse> {\n const url = `${RELAY_STATUS_URL}?requestId=${requestId}`;\n\n const response = await successfulFetch(url, { method: 'GET' });\n\n return (await response.json()) as RelayStatusResponse;\n}\n"]}
|
|
@@ -8,6 +8,7 @@ const utils_1 = require("@metamask/utils");
|
|
|
8
8
|
const bignumber_js_1 = require("bignumber.js");
|
|
9
9
|
const constants_1 = require("./constants.cjs");
|
|
10
10
|
const gas_station_1 = require("./gas-station.cjs");
|
|
11
|
+
const relay_api_1 = require("./relay-api.cjs");
|
|
11
12
|
const relay_max_gas_station_1 = require("./relay-max-gas-station.cjs");
|
|
12
13
|
const __1 = require("../../index.cjs");
|
|
13
14
|
const constants_2 = require("../../constants.cjs");
|
|
@@ -16,6 +17,7 @@ const amounts_1 = require("../../utils/amounts.cjs");
|
|
|
16
17
|
const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
17
18
|
const gas_1 = require("../../utils/gas.cjs");
|
|
18
19
|
const token_1 = require("../../utils/token.cjs");
|
|
20
|
+
const transaction_1 = require("../../utils/transaction.cjs");
|
|
19
21
|
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'relay-strategy');
|
|
20
22
|
/**
|
|
21
23
|
* Fetches Relay quotes.
|
|
@@ -45,10 +47,56 @@ exports.getRelayQuotes = getRelayQuotes;
|
|
|
45
47
|
async function getQuoteWithMaxAmountHandling(request, fullRequest) {
|
|
46
48
|
const { isMaxAmount } = request;
|
|
47
49
|
if (!isMaxAmount) {
|
|
48
|
-
return
|
|
50
|
+
return getQuoteWithPostQuoteGasHandling(request, fullRequest);
|
|
49
51
|
}
|
|
50
52
|
return (0, relay_max_gas_station_1.getRelayMaxGasStationQuote)(request, fullRequest, getSingleQuote);
|
|
51
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* For post-quote flows, fetch an initial quote to compute gas cost in source
|
|
56
|
+
* token, then re-quote with the source amount reduced by the gas cost.
|
|
57
|
+
* This ensures Relay reserves enough for the gas fee token payment.
|
|
58
|
+
*
|
|
59
|
+
* For non-post-quote flows, just returns a single quote.
|
|
60
|
+
*
|
|
61
|
+
* @param request - Quote request.
|
|
62
|
+
* @param fullRequest - Full request context.
|
|
63
|
+
* @returns The final quote (phase 2 for post-quote, or phase 1 for normal).
|
|
64
|
+
*/
|
|
65
|
+
async function getQuoteWithPostQuoteGasHandling(request, fullRequest) {
|
|
66
|
+
const phase1Quote = await getSingleQuote(request, fullRequest);
|
|
67
|
+
if (!request.isPostQuote || !phase1Quote.fees.isSourceGasFeeToken) {
|
|
68
|
+
return phase1Quote;
|
|
69
|
+
}
|
|
70
|
+
const gasCostRaw = phase1Quote.fees.sourceNetwork.max.raw;
|
|
71
|
+
const adjustedSourceAmount = new bignumber_js_1.BigNumber(request.sourceTokenAmount)
|
|
72
|
+
.minus(gasCostRaw)
|
|
73
|
+
.integerValue(bignumber_js_1.BigNumber.ROUND_DOWN);
|
|
74
|
+
log('Subtracting gas from source for post-quote two-call', {
|
|
75
|
+
originalSourceAmount: request.sourceTokenAmount,
|
|
76
|
+
gasCostRaw,
|
|
77
|
+
adjustedSourceAmount: adjustedSourceAmount.toString(10),
|
|
78
|
+
});
|
|
79
|
+
if (!adjustedSourceAmount.isGreaterThan(0)) {
|
|
80
|
+
log('Insufficient balance after gas subtraction for post-quote, using phase 1');
|
|
81
|
+
return phase1Quote;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const phase2Quote = await getSingleQuote({
|
|
85
|
+
...request,
|
|
86
|
+
sourceTokenAmount: adjustedSourceAmount.toFixed(0, bignumber_js_1.BigNumber.ROUND_DOWN),
|
|
87
|
+
}, fullRequest);
|
|
88
|
+
if (phase1Quote.fees.isSourceGasFeeToken &&
|
|
89
|
+
!phase2Quote.fees.isSourceGasFeeToken) {
|
|
90
|
+
log('Phase 2 lost gas fee token eligibility, falling back to phase 1');
|
|
91
|
+
return phase1Quote;
|
|
92
|
+
}
|
|
93
|
+
return phase2Quote;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
log('Phase 2 quote failed, falling back to phase 1', { error });
|
|
97
|
+
return phase1Quote;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
52
100
|
/**
|
|
53
101
|
* Fetches a single Relay quote.
|
|
54
102
|
*
|
|
@@ -67,12 +115,17 @@ async function getSingleQuote(request, fullRequest) {
|
|
|
67
115
|
// For regular flows with a target amount, use EXPECTED_OUTPUT.
|
|
68
116
|
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
69
117
|
const useExactInput = isMaxAmount || request.isPostQuote;
|
|
118
|
+
const useExecute = (0, feature_flags_1.isRelayExecuteEnabled)(messenger) &&
|
|
119
|
+
(0, feature_flags_1.isEIP7702Chain)(messenger, sourceChainId);
|
|
70
120
|
const body = {
|
|
71
121
|
amount: useExactInput ? sourceTokenAmount : targetAmountMinimum,
|
|
72
122
|
destinationChainId: Number(targetChainId),
|
|
73
123
|
destinationCurrency: targetTokenAddress,
|
|
74
124
|
originChainId: Number(sourceChainId),
|
|
75
125
|
originCurrency: sourceTokenAddress,
|
|
126
|
+
...(useExecute
|
|
127
|
+
? { originGasOverhead: (0, feature_flags_1.getRelayOriginGasOverhead)(messenger) }
|
|
128
|
+
: {}),
|
|
76
129
|
recipient: from,
|
|
77
130
|
slippageTolerance,
|
|
78
131
|
tradeType: useExactInput ? 'EXACT_INPUT' : 'EXPECTED_OUTPUT',
|
|
@@ -89,15 +142,8 @@ async function getSingleQuote(request, fullRequest) {
|
|
|
89
142
|
// Safe proxy) rather than defaulting to the EOA.
|
|
90
143
|
body.refundTo = request.refundTo;
|
|
91
144
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const response = await (0, controller_utils_1.successfulFetch)(url, {
|
|
95
|
-
method: 'POST',
|
|
96
|
-
headers: { 'Content-Type': 'application/json' },
|
|
97
|
-
body: JSON.stringify(body),
|
|
98
|
-
});
|
|
99
|
-
const quote = (await response.json());
|
|
100
|
-
quote.request = body;
|
|
145
|
+
log('Request body', body);
|
|
146
|
+
const quote = await (0, relay_api_1.fetchRelayQuote)(messenger, body);
|
|
101
147
|
log('Fetched relay quote', quote);
|
|
102
148
|
return await normalizeQuote(quote, request, fullRequest);
|
|
103
149
|
}
|
|
@@ -317,7 +363,12 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
317
363
|
.flatMap((step) => step.items)
|
|
318
364
|
.map((item) => item.data);
|
|
319
365
|
const { chainId, data, maxFeePerGas, maxPriorityFeePerGas, to, value } = relayParams[0];
|
|
320
|
-
const
|
|
366
|
+
const isPredictWithdraw = request.isPostQuote && (0, transaction_1.isPredictWithdrawTransaction)(transaction);
|
|
367
|
+
const fromOverride = isPredictWithdraw ? request.refundTo : undefined;
|
|
368
|
+
const relayOnlyGas = await calculateSourceNetworkGasLimit(relayParams, messenger, fromOverride);
|
|
369
|
+
const { totalGasEstimate, totalGasLimit, gasLimits } = request.isPostQuote
|
|
370
|
+
? combinePostQuoteGas(relayOnlyGas, transaction)
|
|
371
|
+
: relayOnlyGas;
|
|
321
372
|
log('Gas limit', {
|
|
322
373
|
totalGasEstimate,
|
|
323
374
|
totalGasLimit,
|
|
@@ -360,6 +411,40 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
360
411
|
nativeBalance,
|
|
361
412
|
max: max.raw,
|
|
362
413
|
});
|
|
414
|
+
if (isPredictWithdraw && request.refundTo) {
|
|
415
|
+
log('Using proxy address for predict withdraw gas station simulation', {
|
|
416
|
+
proxyAddress: request.refundTo,
|
|
417
|
+
sourceTokenAddress,
|
|
418
|
+
totalGasEstimate,
|
|
419
|
+
});
|
|
420
|
+
const gasFeeTokenCost = await (0, gas_station_1.getGasStationCostInSourceTokenRaw)({
|
|
421
|
+
firstStepData: {
|
|
422
|
+
data,
|
|
423
|
+
to,
|
|
424
|
+
value,
|
|
425
|
+
},
|
|
426
|
+
messenger,
|
|
427
|
+
request: {
|
|
428
|
+
from: request.refundTo,
|
|
429
|
+
sourceChainId,
|
|
430
|
+
sourceTokenAddress,
|
|
431
|
+
},
|
|
432
|
+
totalGasEstimate,
|
|
433
|
+
totalItemCount: relayParams.length + 1,
|
|
434
|
+
});
|
|
435
|
+
if (gasFeeTokenCost) {
|
|
436
|
+
log('Using predict withdraw gas fee token for source network', {
|
|
437
|
+
gasFeeTokenCost,
|
|
438
|
+
});
|
|
439
|
+
return {
|
|
440
|
+
isGasFeeToken: true,
|
|
441
|
+
estimate: gasFeeTokenCost,
|
|
442
|
+
max: gasFeeTokenCost,
|
|
443
|
+
gasLimits,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
return result;
|
|
447
|
+
}
|
|
363
448
|
const gasFeeTokenCost = await (0, gas_station_1.getGasStationCostInSourceTokenRaw)({
|
|
364
449
|
firstStepData: {
|
|
365
450
|
data,
|
|
@@ -391,24 +476,17 @@ async function calculateSourceNetworkCost(quote, messenger, request, transaction
|
|
|
391
476
|
/**
|
|
392
477
|
* Calculate the total gas limit for the source network.
|
|
393
478
|
*
|
|
394
|
-
* For post-quote flows (e.g. predict withdrawals), the original transaction's
|
|
395
|
-
* gas is combined with the relay gas so that source network cost accounts for
|
|
396
|
-
* both the user's transaction and the relay transactions.
|
|
397
|
-
*
|
|
398
479
|
* @param params - Array of relay transaction parameters.
|
|
399
480
|
* @param messenger - Controller messenger.
|
|
400
|
-
* @param
|
|
401
|
-
*
|
|
481
|
+
* @param fromOverride - Optional address to use as `from` in gas estimation
|
|
482
|
+
* instead of the address in the relay params. Used in predict withdraw flows
|
|
483
|
+
* to estimate with the proxy/Safe address that holds the source token balance.
|
|
402
484
|
* @returns Total gas estimates and per-transaction gas limits.
|
|
403
485
|
*/
|
|
404
|
-
async function calculateSourceNetworkGasLimit(params, messenger,
|
|
405
|
-
|
|
406
|
-
?
|
|
407
|
-
:
|
|
408
|
-
if (!postQuoteTransaction?.txParams.to) {
|
|
409
|
-
return relayGas;
|
|
410
|
-
}
|
|
411
|
-
return combinePostQuoteGas(relayGas, postQuoteTransaction);
|
|
486
|
+
async function calculateSourceNetworkGasLimit(params, messenger, fromOverride) {
|
|
487
|
+
return params.length === 1
|
|
488
|
+
? calculateSourceNetworkGasLimitSingle(params[0], messenger, fromOverride)
|
|
489
|
+
: calculateSourceNetworkGasLimitBatch(params, messenger, fromOverride);
|
|
412
490
|
}
|
|
413
491
|
/**
|
|
414
492
|
* Combine the original transaction's gas with relay gas for post-quote flows.
|
|
@@ -486,11 +564,11 @@ function getTransferRecipient(data) {
|
|
|
486
564
|
.decodeFunctionData('transfer', data)
|
|
487
565
|
.to.toLowerCase();
|
|
488
566
|
}
|
|
489
|
-
async function calculateSourceNetworkGasLimitSingle(params, messenger) {
|
|
567
|
+
async function calculateSourceNetworkGasLimitSingle(params, messenger, fromOverride) {
|
|
490
568
|
const paramGasLimit = params.gas
|
|
491
569
|
? new bignumber_js_1.BigNumber(params.gas).toNumber()
|
|
492
570
|
: undefined;
|
|
493
|
-
if (paramGasLimit) {
|
|
571
|
+
if (paramGasLimit && !fromOverride) {
|
|
494
572
|
log('Using single gas limit from params', { paramGasLimit });
|
|
495
573
|
return {
|
|
496
574
|
totalGasEstimate: paramGasLimit,
|
|
@@ -499,7 +577,8 @@ async function calculateSourceNetworkGasLimitSingle(params, messenger) {
|
|
|
499
577
|
};
|
|
500
578
|
}
|
|
501
579
|
try {
|
|
502
|
-
const { chainId: chainIdNumber, data, from, to, value: valueString, } = params;
|
|
580
|
+
const { chainId: chainIdNumber, data, from: paramsFrom, to, value: valueString, } = params;
|
|
581
|
+
const from = fromOverride ?? paramsFrom;
|
|
503
582
|
const chainId = (0, controller_utils_1.toHex)(chainIdNumber);
|
|
504
583
|
const value = (0, controller_utils_1.toHex)(valueString ?? '0');
|
|
505
584
|
const gasBuffer = (0, feature_flags_1.getGasBuffer)(messenger, chainId);
|
|
@@ -537,16 +616,20 @@ async function calculateSourceNetworkGasLimitSingle(params, messenger) {
|
|
|
537
616
|
*
|
|
538
617
|
* @param params - Array of transaction parameters.
|
|
539
618
|
* @param messenger - Controller messenger.
|
|
619
|
+
* @param fromOverride - Optional address to use as `from` in gas estimation.
|
|
540
620
|
* @returns - Gas limits.
|
|
541
621
|
*/
|
|
542
|
-
async function calculateSourceNetworkGasLimitBatch(params, messenger) {
|
|
622
|
+
async function calculateSourceNetworkGasLimitBatch(params, messenger, fromOverride) {
|
|
543
623
|
try {
|
|
544
|
-
const { chainId: chainIdNumber, from } = params[0];
|
|
624
|
+
const { chainId: chainIdNumber, from: paramsFrom } = params[0];
|
|
625
|
+
const from = fromOverride ?? paramsFrom;
|
|
545
626
|
const chainId = (0, controller_utils_1.toHex)(chainIdNumber);
|
|
546
627
|
const gasBuffer = (0, feature_flags_1.getGasBuffer)(messenger, chainId);
|
|
547
628
|
const transactions = params.map((singleParams) => ({
|
|
548
629
|
...singleParams,
|
|
549
|
-
gas:
|
|
630
|
+
gas: !fromOverride && singleParams.gas
|
|
631
|
+
? (0, controller_utils_1.toHex)(singleParams.gas)
|
|
632
|
+
: undefined,
|
|
550
633
|
maxFeePerGas: undefined,
|
|
551
634
|
maxPriorityFeePerGas: undefined,
|
|
552
635
|
value: (0, controller_utils_1.toHex)(singleParams.value ?? '0'),
|