@metamask/transaction-pay-controller 8.0.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -1
- package/dist/strategy/relay/relay-quotes.cjs +60 -6
- 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 +63 -9
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +19 -17
- 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 +19 -17
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/tests/messenger-mock.cjs +3 -0
- package/dist/tests/messenger-mock.cjs.map +1 -1
- package/dist/tests/messenger-mock.d.cts +2 -1
- package/dist/tests/messenger-mock.d.cts.map +1 -1
- package/dist/tests/messenger-mock.d.mts +2 -1
- package/dist/tests/messenger-mock.d.mts.map +1 -1
- package/dist/tests/messenger-mock.mjs +3 -0
- package/dist/tests/messenger-mock.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +4 -7
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +4 -7
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/gas.cjs +39 -22
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +17 -1
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +17 -1
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +38 -22
- package/dist/utils/gas.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 +15 -15
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [10.0.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Use gas fee token for Relay deposit transactions if insufficient native balance ([#7193](https://github.com/MetaMask/core/pull/7193))
|
|
15
|
+
- Add optional `fees.isSourceGasFeeToken` property to `TransactionPayQuote` and `TransactionPayTotals` type.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **BREAKING:** Bump `@metamask/bridge-status-controller` from `^62.0.0` to `^63.0.0` ([#7207](https://github.com/MetaMask/core/pull/7207))
|
|
20
|
+
- **BREAKING:** Bump `@metamask/bridge-controller` from `^62.0.0` to `^63.0.0` ([#7207](https://github.com/MetaMask/core/pull/7207))
|
|
21
|
+
- **BREAKING:** Bump `@metamask/assets-controllers` from `^90.0.0` to `^91.0.0` ([#7207](https://github.com/MetaMask/core/pull/7207))
|
|
22
|
+
|
|
23
|
+
## [9.0.0]
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Bump `@metamask/controller-utils` from `^11.15.0` to `^11.16.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
28
|
+
- **BREAKING:** Bump `@metamask/transaction-controller` from `^61.0.0` to `^62.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
29
|
+
- **BREAKING:** Bump `@metamask/network-controller` from `^25.0.0` to `^26.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
30
|
+
- **BREAKING:** Bump `@metamask/gas-fee-controller` from `^25.0.0` to `^26.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
31
|
+
- **BREAKING:** Bump `@metamask/bridge-status-controller` from `^61.0.0` to `^62.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
32
|
+
- **BREAKING:** Bump `@metamask/bridge-controller` from `^61.0.0` to `^62.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
33
|
+
- **BREAKING:** Bump `@metamask/assets-controllers` from `^89.0.0` to `^90.0.0` ([#7202](https://github.com/MetaMask/core/pull/7202))
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Ensure source network fee for Relay quotes includes all items and steps ([#7191](https://github.com/MetaMask/core/pull/7191))
|
|
38
|
+
|
|
10
39
|
## [8.0.0]
|
|
11
40
|
|
|
12
41
|
### Changed
|
|
@@ -108,7 +137,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
108
137
|
|
|
109
138
|
- Initial release ([#6820](https://github.com/MetaMask/core/pull/6820))
|
|
110
139
|
|
|
111
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@
|
|
140
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@10.0.0...HEAD
|
|
141
|
+
[10.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@9.0.0...@metamask/transaction-pay-controller@10.0.0
|
|
142
|
+
[9.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@8.0.0...@metamask/transaction-pay-controller@9.0.0
|
|
112
143
|
[8.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@7.0.0...@metamask/transaction-pay-controller@8.0.0
|
|
113
144
|
[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@6.0.0...@metamask/transaction-pay-controller@7.0.0
|
|
114
145
|
[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@5.0.0...@metamask/transaction-pay-controller@6.0.0
|
|
@@ -160,14 +160,14 @@ function normalizeRequest(request) {
|
|
|
160
160
|
* @param fullRequest - Full quotes request.
|
|
161
161
|
* @returns Normalized quote.
|
|
162
162
|
*/
|
|
163
|
-
function normalizeQuote(quote, request, fullRequest) {
|
|
163
|
+
async function normalizeQuote(quote, request, fullRequest) {
|
|
164
164
|
const { messenger } = fullRequest;
|
|
165
165
|
const { details } = quote;
|
|
166
166
|
const { currencyIn } = details;
|
|
167
167
|
const { usdToFiatRate } = getFiatRates(messenger, request);
|
|
168
168
|
const dust = getFiatValueFromUsd(calculateDustUsd(quote, request), usdToFiatRate);
|
|
169
169
|
const provider = getFiatValueFromUsd(calculateProviderFee(quote), usdToFiatRate);
|
|
170
|
-
const sourceNetwork = calculateSourceNetworkCost(quote, messenger);
|
|
170
|
+
const { isGasFeeToken: isSourceGasFeeToken, ...sourceNetwork } = await calculateSourceNetworkCost(quote, messenger, request);
|
|
171
171
|
const targetNetwork = {
|
|
172
172
|
usd: '0',
|
|
173
173
|
fiat: '0',
|
|
@@ -181,6 +181,7 @@ function normalizeQuote(quote, request, fullRequest) {
|
|
|
181
181
|
dust,
|
|
182
182
|
estimatedDuration: details.timeEstimate,
|
|
183
183
|
fees: {
|
|
184
|
+
isSourceGasFeeToken,
|
|
184
185
|
provider,
|
|
185
186
|
sourceNetwork,
|
|
186
187
|
targetNetwork,
|
|
@@ -260,11 +261,13 @@ function getFeatureFlags(messenger) {
|
|
|
260
261
|
*
|
|
261
262
|
* @param quote - Relay quote.
|
|
262
263
|
* @param messenger - Controller messenger.
|
|
264
|
+
* @param request - Quote request.
|
|
263
265
|
* @returns Total source network cost in USD and fiat.
|
|
264
266
|
*/
|
|
265
|
-
function calculateSourceNetworkCost(quote, messenger) {
|
|
266
|
-
const
|
|
267
|
-
const
|
|
267
|
+
async function calculateSourceNetworkCost(quote, messenger, request) {
|
|
268
|
+
const { from, sourceChainId, sourceTokenAddress } = request;
|
|
269
|
+
const allParams = quote.steps.flatMap((s) => s.items).map((i) => i.data);
|
|
270
|
+
const { chainId, data, to, value } = allParams[0];
|
|
268
271
|
const totalGasLimit = calculateSourceNetworkGasLimit(allParams);
|
|
269
272
|
const estimate = (0, gas_1.calculateGasCost)({
|
|
270
273
|
chainId,
|
|
@@ -277,7 +280,58 @@ function calculateSourceNetworkCost(quote, messenger) {
|
|
|
277
280
|
messenger,
|
|
278
281
|
isMax: true,
|
|
279
282
|
});
|
|
280
|
-
|
|
283
|
+
const nativeBalance = (0, token_1.getTokenBalance)(messenger, from, sourceChainId, (0, token_1.getNativeToken)(sourceChainId));
|
|
284
|
+
if (new bignumber_js_1.BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {
|
|
285
|
+
return { estimate, max };
|
|
286
|
+
}
|
|
287
|
+
log('Checking gas fee tokens as insufficient native balance', {
|
|
288
|
+
nativeBalance,
|
|
289
|
+
max: max.raw,
|
|
290
|
+
});
|
|
291
|
+
const gasFeeTokens = await messenger.call('TransactionController:getGasFeeTokens', {
|
|
292
|
+
chainId: sourceChainId,
|
|
293
|
+
data,
|
|
294
|
+
from,
|
|
295
|
+
to,
|
|
296
|
+
value: (0, controller_utils_1.toHex)(value ?? '0'),
|
|
297
|
+
});
|
|
298
|
+
log('Source gas fee tokens', { gasFeeTokens });
|
|
299
|
+
const gasFeeToken = gasFeeTokens.find((t) => t.tokenAddress.toLowerCase() === sourceTokenAddress.toLowerCase());
|
|
300
|
+
if (!gasFeeToken) {
|
|
301
|
+
log('No matching gas fee token found', {
|
|
302
|
+
sourceTokenAddress,
|
|
303
|
+
gasFeeTokens,
|
|
304
|
+
});
|
|
305
|
+
return { estimate, max };
|
|
306
|
+
}
|
|
307
|
+
let finalAmount = gasFeeToken.amount;
|
|
308
|
+
if (allParams.length > 1) {
|
|
309
|
+
const gasRate = new bignumber_js_1.BigNumber(gasFeeToken.amount, 16).dividedBy(gasFeeToken.gas, 16);
|
|
310
|
+
const finalAmountValue = gasRate.multipliedBy(totalGasLimit);
|
|
311
|
+
finalAmount = (0, controller_utils_1.toHex)(finalAmountValue.toFixed(0));
|
|
312
|
+
log('Estimated gas fee token amount for batch', {
|
|
313
|
+
finalAmount: finalAmountValue.toString(10),
|
|
314
|
+
gasRate: gasRate.toString(10),
|
|
315
|
+
totalGasLimit,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
const finalGasFeeToken = { ...gasFeeToken, amount: finalAmount };
|
|
319
|
+
const gasFeeTokenCost = (0, gas_1.calculateGasFeeTokenCost)({
|
|
320
|
+
chainId: sourceChainId,
|
|
321
|
+
gasFeeToken: finalGasFeeToken,
|
|
322
|
+
messenger,
|
|
323
|
+
});
|
|
324
|
+
if (!gasFeeTokenCost) {
|
|
325
|
+
return { estimate, max };
|
|
326
|
+
}
|
|
327
|
+
log('Using gas fee token for source network', {
|
|
328
|
+
gasFeeTokenCost,
|
|
329
|
+
});
|
|
330
|
+
return {
|
|
331
|
+
isGasFeeToken: true,
|
|
332
|
+
estimate: gasFeeTokenCost,
|
|
333
|
+
max: gasFeeTokenCost,
|
|
334
|
+
};
|
|
281
335
|
}
|
|
282
336
|
/**
|
|
283
337
|
* Calculate the total gas limit for the source network transactions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { successfulFetch } from '@metamask/controller-utils';\nimport type { Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_HYPERCORE,\n RELAY_FALLBACK_GAS_LIMIT,\n RELAY_URL_QUOTE,\n} from './constants';\nimport type { RelayQuote } from './types';\nimport { TransactionPayStrategy } from '../..';\nimport type { TransactionMeta } from '../../../../transaction-controller/src';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatValue,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { calculateGasCost } from '../../utils/gas';\nimport { getNativeToken, getTokenFiatRate } from '../../utils/token';\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\n .filter((r) => r.targetAmountMinimum !== '0')\n .map((r) => normalizeRequest(r));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((r) => getSingleQuote(r, request)),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\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 try {\n const body = {\n amount: request.targetAmountMinimum,\n destinationChainId: Number(request.targetChainId),\n destinationCurrency: request.targetTokenAddress,\n originChainId: Number(request.sourceChainId),\n originCurrency: request.sourceTokenAddress,\n recipient: request.from,\n tradeType: 'EXPECTED_OUTPUT',\n user: request.from,\n };\n\n await processTransactions(transaction, request, body, messenger);\n\n const url = getFeatureFlags(messenger).relayQuoteUrl;\n\n log('Request body', { body, url });\n\n const response = await successfulFetch(url, {\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\n log('Fetched relay quote', quote);\n\n return normalizeQuote(quote, request, fullRequest);\n } catch (e) {\n log('Error fetching relay quote', e);\n throw e;\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: Record<string, Json | undefined>,\n messenger: TransactionPayControllerMessenger,\n) {\n const { data, value } = transaction.txParams;\n\n /* istanbul ignore next */\n const hasNoParams = (!data || data === '0x') && (!value || value === '0x0');\n\n const skipDelegation =\n hasNoParams || request.targetChainId === CHAIN_ID_HYPERCORE;\n\n if (skipDelegation) {\n log('Skipping delegation as no transaction data');\n return;\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 yParity: Number(a.yParity),\n }),\n );\n\n const tokenTransferData = new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [\n request.from,\n request.targetAmountMinimum,\n ]);\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: tokenTransferData,\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) {\n const isHyperliquidDeposit =\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n const isPolygonNativeSource =\n request.sourceChainId === CHAIN_ID_POLYGON &&\n request.sourceTokenAddress === getNativeToken(request.sourceChainId);\n\n const requestOutput: QuoteRequest = {\n ...request,\n sourceTokenAddress: isPolygonNativeSource\n ? NATIVE_TOKEN_ADDRESS\n : request.sourceTokenAddress,\n targetChainId: isHyperliquidDeposit\n ? CHAIN_ID_HYPERCORE\n : request.targetChainId,\n targetTokenAddress: isHyperliquidDeposit\n ? '0x00000000000000000000000000000000'\n : request.targetTokenAddress,\n targetAmountMinimum: isHyperliquidDeposit\n ? new BigNumber(request.targetAmountMinimum).shiftedBy(2).toString(10)\n : request.targetAmountMinimum,\n };\n\n if (isHyperliquidDeposit) {\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: requestOutput,\n });\n }\n\n return requestOutput;\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 */\nfunction normalizeQuote(\n quote: RelayQuote,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): TransactionPayQuote<RelayQuote> {\n const { messenger } = fullRequest;\n const { details } = quote;\n const { currencyIn } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const provider = getFiatValueFromUsd(\n calculateProviderFee(quote),\n usdToFiatRate,\n );\n\n const sourceNetwork = calculateSourceNetworkCost(quote, messenger);\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 return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: quote,\n request,\n sourceAmount,\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) {\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 * Converts USD value to fiat value.\n *\n * @param usdValue - USD value.\n * @param usdToFiatRate - USD to fiat rate.\n * @returns Fiat value.\n */\nfunction getFiatValueFromUsd(\n usdValue: BigNumber,\n usdToFiatRate: BigNumber,\n): FiatValue {\n const fiatValue = usdValue.multipliedBy(usdToFiatRate);\n\n return {\n usd: usdValue.toString(10),\n fiat: fiatValue.toString(10),\n };\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 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 * Gets feature flags for Relay quotes.\n *\n * @param messenger - Controller messenger.\n * @returns Feature flags.\n */\nfunction getFeatureFlags(messenger: TransactionPayControllerMessenger) {\n const featureFlagState = messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n\n const featureFlags = featureFlagState.remoteFeatureFlags\n ?.confirmations_pay as Record<string, string> | undefined;\n\n const relayQuoteUrl = featureFlags?.relayQuoteUrl ?? RELAY_URL_QUOTE;\n\n return {\n relayQuoteUrl,\n };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @returns Total source network cost in USD and fiat.\n */\nfunction calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] {\n const allParams = quote.steps[0].items.map((i) => i.data);\n const { chainId } = allParams[0];\n const totalGasLimit = calculateSourceNetworkGasLimit(allParams);\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n isMax: true,\n });\n\n return { estimate, max };\n}\n\n/**\n * Calculate the total gas limit for the source network transactions.\n *\n * @param params - Array of transaction parameters.\n * @returns - Total gas limit.\n */\nfunction calculateSourceNetworkGasLimit(\n params: RelayQuote['steps'][0]['items'][0]['data'][],\n): number {\n const allParamsHasGas = params.every((p) => p.gas !== undefined);\n\n if (allParamsHasGas) {\n return params.reduce(\n (total, p) => total + new BigNumber(p.gas as string).toNumber(),\n 0,\n );\n }\n\n // In future, call `TransactionController:estimateGas`\n // or `TransactionController:estimateGasBatch` based on params length.\n\n return params.reduce(\n (total, p) =>\n total + new BigNumber(p.gas ?? RELAY_FALLBACK_GAS_LIMIT).toNumber(),\n 0,\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) {\n const relayerFee = new BigNumber(quote.fees.relayer.amountUsd);\n\n const valueLoss = new BigNumber(quote.details.currencyIn.amountUsd).minus(\n quote.details.currencyOut.amountUsd,\n );\n\n return relayerFee.gt(valueLoss) ? relayerFee : valueLoss;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-quotes.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_HYPERCORE,\n RELAY_FALLBACK_GAS_LIMIT,\n RELAY_URL_QUOTE,\n} from './constants';\nimport type { RelayQuote } from './types';\nimport { TransactionPayStrategy } from '../..';\nimport type { TransactionMeta } from '../../../../transaction-controller/src';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatValue,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { calculateGasCost, calculateGasFeeTokenCost } from '../../utils/gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n} from '../../utils/token';\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\n .filter((r) => r.targetAmountMinimum !== '0')\n .map((r) => normalizeRequest(r));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((r) => getSingleQuote(r, request)),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\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 try {\n const body = {\n amount: request.targetAmountMinimum,\n destinationChainId: Number(request.targetChainId),\n destinationCurrency: request.targetTokenAddress,\n originChainId: Number(request.sourceChainId),\n originCurrency: request.sourceTokenAddress,\n recipient: request.from,\n tradeType: 'EXPECTED_OUTPUT',\n user: request.from,\n };\n\n await processTransactions(transaction, request, body, messenger);\n\n const url = getFeatureFlags(messenger).relayQuoteUrl;\n\n log('Request body', { body, url });\n\n const response = await successfulFetch(url, {\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\n log('Fetched relay quote', quote);\n\n return normalizeQuote(quote, request, fullRequest);\n } catch (e) {\n log('Error fetching relay quote', e);\n throw e;\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: Record<string, Json | undefined>,\n messenger: TransactionPayControllerMessenger,\n) {\n const { data, value } = transaction.txParams;\n\n /* istanbul ignore next */\n const hasNoParams = (!data || data === '0x') && (!value || value === '0x0');\n\n const skipDelegation =\n hasNoParams || request.targetChainId === CHAIN_ID_HYPERCORE;\n\n if (skipDelegation) {\n log('Skipping delegation as no transaction data');\n return;\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 yParity: Number(a.yParity),\n }),\n );\n\n const tokenTransferData = new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [\n request.from,\n request.targetAmountMinimum,\n ]);\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: tokenTransferData,\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) {\n const isHyperliquidDeposit =\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n const isPolygonNativeSource =\n request.sourceChainId === CHAIN_ID_POLYGON &&\n request.sourceTokenAddress === getNativeToken(request.sourceChainId);\n\n const requestOutput: QuoteRequest = {\n ...request,\n sourceTokenAddress: isPolygonNativeSource\n ? NATIVE_TOKEN_ADDRESS\n : request.sourceTokenAddress,\n targetChainId: isHyperliquidDeposit\n ? CHAIN_ID_HYPERCORE\n : request.targetChainId,\n targetTokenAddress: isHyperliquidDeposit\n ? '0x00000000000000000000000000000000'\n : request.targetTokenAddress,\n targetAmountMinimum: isHyperliquidDeposit\n ? new BigNumber(request.targetAmountMinimum).shiftedBy(2).toString(10)\n : request.targetAmountMinimum,\n };\n\n if (isHyperliquidDeposit) {\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: requestOutput,\n });\n }\n\n return requestOutput;\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 } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const provider = getFiatValueFromUsd(\n calculateProviderFee(quote),\n usdToFiatRate,\n );\n\n const { isGasFeeToken: isSourceGasFeeToken, ...sourceNetwork } =\n await calculateSourceNetworkCost(quote, messenger, request);\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 return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n isSourceGasFeeToken,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: quote,\n request,\n sourceAmount,\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) {\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 * Converts USD value to fiat value.\n *\n * @param usdValue - USD value.\n * @param usdToFiatRate - USD to fiat rate.\n * @returns Fiat value.\n */\nfunction getFiatValueFromUsd(\n usdValue: BigNumber,\n usdToFiatRate: BigNumber,\n): FiatValue {\n const fiatValue = usdValue.multipliedBy(usdToFiatRate);\n\n return {\n usd: usdValue.toString(10),\n fiat: fiatValue.toString(10),\n };\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 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 * Gets feature flags for Relay quotes.\n *\n * @param messenger - Controller messenger.\n * @returns Feature flags.\n */\nfunction getFeatureFlags(messenger: TransactionPayControllerMessenger) {\n const featureFlagState = messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n\n const featureFlags = featureFlagState.remoteFeatureFlags\n ?.confirmations_pay as Record<string, string> | undefined;\n\n const relayQuoteUrl = featureFlags?.relayQuoteUrl ?? RELAY_URL_QUOTE;\n\n return {\n relayQuoteUrl,\n };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @returns Total source network cost in USD and fiat.\n */\nasync function calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<\n TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] & {\n isGasFeeToken?: boolean;\n }\n> {\n const { from, sourceChainId, sourceTokenAddress } = request;\n const allParams = quote.steps.flatMap((s) => s.items).map((i) => i.data);\n const { chainId, data, to, value } = allParams[0];\n const totalGasLimit = calculateSourceNetworkGasLimit(allParams);\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n isMax: true,\n });\n\n const nativeBalance = getTokenBalance(\n messenger,\n from,\n sourceChainId,\n getNativeToken(sourceChainId),\n );\n\n if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {\n return { estimate, max };\n }\n\n log('Checking gas fee tokens as insufficient native balance', {\n nativeBalance,\n max: max.raw,\n });\n\n const 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\n log('Source gas fee tokens', { gasFeeTokens });\n\n const gasFeeToken = gasFeeTokens.find(\n (t) => t.tokenAddress.toLowerCase() === sourceTokenAddress.toLowerCase(),\n );\n\n if (!gasFeeToken) {\n log('No matching gas fee token found', {\n sourceTokenAddress,\n gasFeeTokens,\n });\n\n return { estimate, max };\n }\n\n let finalAmount = gasFeeToken.amount;\n\n if (allParams.length > 1) {\n const gasRate = new BigNumber(gasFeeToken.amount, 16).dividedBy(\n gasFeeToken.gas,\n 16,\n );\n\n const finalAmountValue = gasRate.multipliedBy(totalGasLimit);\n\n finalAmount = toHex(finalAmountValue.toFixed(0));\n\n log('Estimated gas fee token amount for batch', {\n finalAmount: finalAmountValue.toString(10),\n gasRate: gasRate.toString(10),\n totalGasLimit,\n });\n }\n\n const finalGasFeeToken = { ...gasFeeToken, amount: finalAmount };\n\n const gasFeeTokenCost = calculateGasFeeTokenCost({\n chainId: sourceChainId,\n gasFeeToken: finalGasFeeToken,\n messenger,\n });\n\n if (!gasFeeTokenCost) {\n return { estimate, max };\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 };\n}\n\n/**\n * Calculate the total gas limit for the source network transactions.\n *\n * @param params - Array of transaction parameters.\n * @returns - Total gas limit.\n */\nfunction calculateSourceNetworkGasLimit(\n params: RelayQuote['steps'][0]['items'][0]['data'][],\n): number {\n const allParamsHasGas = params.every((p) => p.gas !== undefined);\n\n if (allParamsHasGas) {\n return params.reduce(\n (total, p) => total + new BigNumber(p.gas as string).toNumber(),\n 0,\n );\n }\n\n // In future, call `TransactionController:estimateGas`\n // or `TransactionController:estimateGasBatch` based on params length.\n\n return params.reduce(\n (total, p) =>\n total + new BigNumber(p.gas ?? RELAY_FALLBACK_GAS_LIMIT).toNumber(),\n 0,\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) {\n const relayerFee = new BigNumber(quote.fees.relayer.amountUsd);\n\n const valueLoss = new BigNumber(quote.details.currencyIn.amountUsd).minus(\n quote.details.currencyOut.amountUsd,\n );\n\n return relayerFee.gt(valueLoss) ? relayerFee : valueLoss;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAgB;AAU1C,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;
|
|
1
|
+
{"version":3,"file":"relay-quotes.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAgB;AAU1C,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAUrB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CAoB5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAgB;AAU1C,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;
|
|
1
|
+
{"version":3,"file":"relay-quotes.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAgB;AAU1C,OAAO,KAAK,EAGV,2BAA2B,EAG3B,mBAAmB,EACpB,wBAAoB;AAUrB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC,CAoB5C"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Interface } from "@ethersproject/abi";
|
|
2
|
-
import { successfulFetch } from "@metamask/controller-utils";
|
|
2
|
+
import { successfulFetch, toHex } from "@metamask/controller-utils";
|
|
3
3
|
import { createModuleLogger } from "@metamask/utils";
|
|
4
4
|
import { BigNumber } from "bignumber.js";
|
|
5
5
|
import { CHAIN_ID_HYPERCORE, RELAY_FALLBACK_GAS_LIMIT, RELAY_URL_QUOTE } from "./constants.mjs";
|
|
6
6
|
import { TransactionPayStrategy } from "../../index.mjs";
|
|
7
7
|
import { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM, CHAIN_ID_POLYGON, NATIVE_TOKEN_ADDRESS } from "../../constants.mjs";
|
|
8
8
|
import { projectLogger } from "../../logger.mjs";
|
|
9
|
-
import { calculateGasCost } from "../../utils/gas.mjs";
|
|
10
|
-
import { getNativeToken, getTokenFiatRate } from "../../utils/token.mjs";
|
|
9
|
+
import { calculateGasCost, calculateGasFeeTokenCost } from "../../utils/gas.mjs";
|
|
10
|
+
import { getNativeToken, getTokenBalance, getTokenFiatRate } from "../../utils/token.mjs";
|
|
11
11
|
const log = createModuleLogger(projectLogger, 'relay-strategy');
|
|
12
12
|
/**
|
|
13
13
|
* Fetches Relay quotes.
|
|
@@ -156,14 +156,14 @@ function normalizeRequest(request) {
|
|
|
156
156
|
* @param fullRequest - Full quotes request.
|
|
157
157
|
* @returns Normalized quote.
|
|
158
158
|
*/
|
|
159
|
-
function normalizeQuote(quote, request, fullRequest) {
|
|
159
|
+
async function normalizeQuote(quote, request, fullRequest) {
|
|
160
160
|
const { messenger } = fullRequest;
|
|
161
161
|
const { details } = quote;
|
|
162
162
|
const { currencyIn } = details;
|
|
163
163
|
const { usdToFiatRate } = getFiatRates(messenger, request);
|
|
164
164
|
const dust = getFiatValueFromUsd(calculateDustUsd(quote, request), usdToFiatRate);
|
|
165
165
|
const provider = getFiatValueFromUsd(calculateProviderFee(quote), usdToFiatRate);
|
|
166
|
-
const sourceNetwork = calculateSourceNetworkCost(quote, messenger);
|
|
166
|
+
const { isGasFeeToken: isSourceGasFeeToken, ...sourceNetwork } = await calculateSourceNetworkCost(quote, messenger, request);
|
|
167
167
|
const targetNetwork = {
|
|
168
168
|
usd: '0',
|
|
169
169
|
fiat: '0',
|
|
@@ -177,6 +177,7 @@ function normalizeQuote(quote, request, fullRequest) {
|
|
|
177
177
|
dust,
|
|
178
178
|
estimatedDuration: details.timeEstimate,
|
|
179
179
|
fees: {
|
|
180
|
+
isSourceGasFeeToken,
|
|
180
181
|
provider,
|
|
181
182
|
sourceNetwork,
|
|
182
183
|
targetNetwork,
|
|
@@ -256,11 +257,13 @@ function getFeatureFlags(messenger) {
|
|
|
256
257
|
*
|
|
257
258
|
* @param quote - Relay quote.
|
|
258
259
|
* @param messenger - Controller messenger.
|
|
260
|
+
* @param request - Quote request.
|
|
259
261
|
* @returns Total source network cost in USD and fiat.
|
|
260
262
|
*/
|
|
261
|
-
function calculateSourceNetworkCost(quote, messenger) {
|
|
262
|
-
const
|
|
263
|
-
const
|
|
263
|
+
async function calculateSourceNetworkCost(quote, messenger, request) {
|
|
264
|
+
const { from, sourceChainId, sourceTokenAddress } = request;
|
|
265
|
+
const allParams = quote.steps.flatMap((s) => s.items).map((i) => i.data);
|
|
266
|
+
const { chainId, data, to, value } = allParams[0];
|
|
264
267
|
const totalGasLimit = calculateSourceNetworkGasLimit(allParams);
|
|
265
268
|
const estimate = calculateGasCost({
|
|
266
269
|
chainId,
|
|
@@ -273,7 +276,58 @@ function calculateSourceNetworkCost(quote, messenger) {
|
|
|
273
276
|
messenger,
|
|
274
277
|
isMax: true,
|
|
275
278
|
});
|
|
276
|
-
|
|
279
|
+
const nativeBalance = getTokenBalance(messenger, from, sourceChainId, getNativeToken(sourceChainId));
|
|
280
|
+
if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {
|
|
281
|
+
return { estimate, max };
|
|
282
|
+
}
|
|
283
|
+
log('Checking gas fee tokens as insufficient native balance', {
|
|
284
|
+
nativeBalance,
|
|
285
|
+
max: max.raw,
|
|
286
|
+
});
|
|
287
|
+
const gasFeeTokens = await messenger.call('TransactionController:getGasFeeTokens', {
|
|
288
|
+
chainId: sourceChainId,
|
|
289
|
+
data,
|
|
290
|
+
from,
|
|
291
|
+
to,
|
|
292
|
+
value: toHex(value ?? '0'),
|
|
293
|
+
});
|
|
294
|
+
log('Source gas fee tokens', { gasFeeTokens });
|
|
295
|
+
const gasFeeToken = gasFeeTokens.find((t) => t.tokenAddress.toLowerCase() === sourceTokenAddress.toLowerCase());
|
|
296
|
+
if (!gasFeeToken) {
|
|
297
|
+
log('No matching gas fee token found', {
|
|
298
|
+
sourceTokenAddress,
|
|
299
|
+
gasFeeTokens,
|
|
300
|
+
});
|
|
301
|
+
return { estimate, max };
|
|
302
|
+
}
|
|
303
|
+
let finalAmount = gasFeeToken.amount;
|
|
304
|
+
if (allParams.length > 1) {
|
|
305
|
+
const gasRate = new BigNumber(gasFeeToken.amount, 16).dividedBy(gasFeeToken.gas, 16);
|
|
306
|
+
const finalAmountValue = gasRate.multipliedBy(totalGasLimit);
|
|
307
|
+
finalAmount = toHex(finalAmountValue.toFixed(0));
|
|
308
|
+
log('Estimated gas fee token amount for batch', {
|
|
309
|
+
finalAmount: finalAmountValue.toString(10),
|
|
310
|
+
gasRate: gasRate.toString(10),
|
|
311
|
+
totalGasLimit,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
const finalGasFeeToken = { ...gasFeeToken, amount: finalAmount };
|
|
315
|
+
const gasFeeTokenCost = calculateGasFeeTokenCost({
|
|
316
|
+
chainId: sourceChainId,
|
|
317
|
+
gasFeeToken: finalGasFeeToken,
|
|
318
|
+
messenger,
|
|
319
|
+
});
|
|
320
|
+
if (!gasFeeTokenCost) {
|
|
321
|
+
return { estimate, max };
|
|
322
|
+
}
|
|
323
|
+
log('Using gas fee token for source network', {
|
|
324
|
+
gasFeeTokenCost,
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
isGasFeeToken: true,
|
|
328
|
+
estimate: gasFeeTokenCost,
|
|
329
|
+
max: gasFeeTokenCost,
|
|
330
|
+
};
|
|
277
331
|
}
|
|
278
332
|
/**
|
|
279
333
|
* Calculate the total gas limit for the source network transactions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-quotes.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { successfulFetch } from '@metamask/controller-utils';\nimport type { Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_HYPERCORE,\n RELAY_FALLBACK_GAS_LIMIT,\n RELAY_URL_QUOTE,\n} from './constants';\nimport type { RelayQuote } from './types';\nimport { TransactionPayStrategy } from '../..';\nimport type { TransactionMeta } from '../../../../transaction-controller/src';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatValue,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { calculateGasCost } from '../../utils/gas';\nimport { getNativeToken, getTokenFiatRate } from '../../utils/token';\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\n .filter((r) => r.targetAmountMinimum !== '0')\n .map((r) => normalizeRequest(r));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((r) => getSingleQuote(r, request)),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\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 try {\n const body = {\n amount: request.targetAmountMinimum,\n destinationChainId: Number(request.targetChainId),\n destinationCurrency: request.targetTokenAddress,\n originChainId: Number(request.sourceChainId),\n originCurrency: request.sourceTokenAddress,\n recipient: request.from,\n tradeType: 'EXPECTED_OUTPUT',\n user: request.from,\n };\n\n await processTransactions(transaction, request, body, messenger);\n\n const url = getFeatureFlags(messenger).relayQuoteUrl;\n\n log('Request body', { body, url });\n\n const response = await successfulFetch(url, {\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\n log('Fetched relay quote', quote);\n\n return normalizeQuote(quote, request, fullRequest);\n } catch (e) {\n log('Error fetching relay quote', e);\n throw e;\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: Record<string, Json | undefined>,\n messenger: TransactionPayControllerMessenger,\n) {\n const { data, value } = transaction.txParams;\n\n /* istanbul ignore next */\n const hasNoParams = (!data || data === '0x') && (!value || value === '0x0');\n\n const skipDelegation =\n hasNoParams || request.targetChainId === CHAIN_ID_HYPERCORE;\n\n if (skipDelegation) {\n log('Skipping delegation as no transaction data');\n return;\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 yParity: Number(a.yParity),\n }),\n );\n\n const tokenTransferData = new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [\n request.from,\n request.targetAmountMinimum,\n ]);\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: tokenTransferData,\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) {\n const isHyperliquidDeposit =\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n const isPolygonNativeSource =\n request.sourceChainId === CHAIN_ID_POLYGON &&\n request.sourceTokenAddress === getNativeToken(request.sourceChainId);\n\n const requestOutput: QuoteRequest = {\n ...request,\n sourceTokenAddress: isPolygonNativeSource\n ? NATIVE_TOKEN_ADDRESS\n : request.sourceTokenAddress,\n targetChainId: isHyperliquidDeposit\n ? CHAIN_ID_HYPERCORE\n : request.targetChainId,\n targetTokenAddress: isHyperliquidDeposit\n ? '0x00000000000000000000000000000000'\n : request.targetTokenAddress,\n targetAmountMinimum: isHyperliquidDeposit\n ? new BigNumber(request.targetAmountMinimum).shiftedBy(2).toString(10)\n : request.targetAmountMinimum,\n };\n\n if (isHyperliquidDeposit) {\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: requestOutput,\n });\n }\n\n return requestOutput;\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 */\nfunction normalizeQuote(\n quote: RelayQuote,\n request: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): TransactionPayQuote<RelayQuote> {\n const { messenger } = fullRequest;\n const { details } = quote;\n const { currencyIn } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const provider = getFiatValueFromUsd(\n calculateProviderFee(quote),\n usdToFiatRate,\n );\n\n const sourceNetwork = calculateSourceNetworkCost(quote, messenger);\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 return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: quote,\n request,\n sourceAmount,\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) {\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 * Converts USD value to fiat value.\n *\n * @param usdValue - USD value.\n * @param usdToFiatRate - USD to fiat rate.\n * @returns Fiat value.\n */\nfunction getFiatValueFromUsd(\n usdValue: BigNumber,\n usdToFiatRate: BigNumber,\n): FiatValue {\n const fiatValue = usdValue.multipliedBy(usdToFiatRate);\n\n return {\n usd: usdValue.toString(10),\n fiat: fiatValue.toString(10),\n };\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 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 * Gets feature flags for Relay quotes.\n *\n * @param messenger - Controller messenger.\n * @returns Feature flags.\n */\nfunction getFeatureFlags(messenger: TransactionPayControllerMessenger) {\n const featureFlagState = messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n\n const featureFlags = featureFlagState.remoteFeatureFlags\n ?.confirmations_pay as Record<string, string> | undefined;\n\n const relayQuoteUrl = featureFlags?.relayQuoteUrl ?? RELAY_URL_QUOTE;\n\n return {\n relayQuoteUrl,\n };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @returns Total source network cost in USD and fiat.\n */\nfunction calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] {\n const allParams = quote.steps[0].items.map((i) => i.data);\n const { chainId } = allParams[0];\n const totalGasLimit = calculateSourceNetworkGasLimit(allParams);\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n isMax: true,\n });\n\n return { estimate, max };\n}\n\n/**\n * Calculate the total gas limit for the source network transactions.\n *\n * @param params - Array of transaction parameters.\n * @returns - Total gas limit.\n */\nfunction calculateSourceNetworkGasLimit(\n params: RelayQuote['steps'][0]['items'][0]['data'][],\n): number {\n const allParamsHasGas = params.every((p) => p.gas !== undefined);\n\n if (allParamsHasGas) {\n return params.reduce(\n (total, p) => total + new BigNumber(p.gas as string).toNumber(),\n 0,\n );\n }\n\n // In future, call `TransactionController:estimateGas`\n // or `TransactionController:estimateGasBatch` based on params length.\n\n return params.reduce(\n (total, p) =>\n total + new BigNumber(p.gas ?? RELAY_FALLBACK_GAS_LIMIT).toNumber(),\n 0,\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) {\n const relayerFee = new BigNumber(quote.fees.relayer.amountUsd);\n\n const valueLoss = new BigNumber(quote.details.currencyIn.amountUsd).minus(\n quote.details.currencyOut.amountUsd,\n );\n\n return relayerFee.gt(valueLoss) ? relayerFee : valueLoss;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-quotes.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { successfulFetch, toHex } from '@metamask/controller-utils';\nimport type { Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_HYPERCORE,\n RELAY_FALLBACK_GAS_LIMIT,\n RELAY_URL_QUOTE,\n} from './constants';\nimport type { RelayQuote } from './types';\nimport { TransactionPayStrategy } from '../..';\nimport type { TransactionMeta } from '../../../../transaction-controller/src';\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n} from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n Amount,\n FiatValue,\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport { calculateGasCost, calculateGasFeeTokenCost } from '../../utils/gas';\nimport {\n getNativeToken,\n getTokenBalance,\n getTokenFiatRate,\n} from '../../utils/token';\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\n .filter((r) => r.targetAmountMinimum !== '0')\n .map((r) => normalizeRequest(r));\n\n log('Normalized requests', normalizedRequests);\n\n return await Promise.all(\n normalizedRequests.map((r) => getSingleQuote(r, request)),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n throw new Error(`Failed to fetch Relay quotes: ${String(error)}`);\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 try {\n const body = {\n amount: request.targetAmountMinimum,\n destinationChainId: Number(request.targetChainId),\n destinationCurrency: request.targetTokenAddress,\n originChainId: Number(request.sourceChainId),\n originCurrency: request.sourceTokenAddress,\n recipient: request.from,\n tradeType: 'EXPECTED_OUTPUT',\n user: request.from,\n };\n\n await processTransactions(transaction, request, body, messenger);\n\n const url = getFeatureFlags(messenger).relayQuoteUrl;\n\n log('Request body', { body, url });\n\n const response = await successfulFetch(url, {\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\n log('Fetched relay quote', quote);\n\n return normalizeQuote(quote, request, fullRequest);\n } catch (e) {\n log('Error fetching relay quote', e);\n throw e;\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: Record<string, Json | undefined>,\n messenger: TransactionPayControllerMessenger,\n) {\n const { data, value } = transaction.txParams;\n\n /* istanbul ignore next */\n const hasNoParams = (!data || data === '0x') && (!value || value === '0x0');\n\n const skipDelegation =\n hasNoParams || request.targetChainId === CHAIN_ID_HYPERCORE;\n\n if (skipDelegation) {\n log('Skipping delegation as no transaction data');\n return;\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 yParity: Number(a.yParity),\n }),\n );\n\n const tokenTransferData = new Interface([\n 'function transfer(address to, uint256 amount)',\n ]).encodeFunctionData('transfer', [\n request.from,\n request.targetAmountMinimum,\n ]);\n\n requestBody.authorizationList = normalizedAuthorizationList;\n requestBody.tradeType = 'EXACT_OUTPUT';\n\n requestBody.txs = [\n {\n to: request.targetTokenAddress,\n data: tokenTransferData,\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) {\n const isHyperliquidDeposit =\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n const isPolygonNativeSource =\n request.sourceChainId === CHAIN_ID_POLYGON &&\n request.sourceTokenAddress === getNativeToken(request.sourceChainId);\n\n const requestOutput: QuoteRequest = {\n ...request,\n sourceTokenAddress: isPolygonNativeSource\n ? NATIVE_TOKEN_ADDRESS\n : request.sourceTokenAddress,\n targetChainId: isHyperliquidDeposit\n ? CHAIN_ID_HYPERCORE\n : request.targetChainId,\n targetTokenAddress: isHyperliquidDeposit\n ? '0x00000000000000000000000000000000'\n : request.targetTokenAddress,\n targetAmountMinimum: isHyperliquidDeposit\n ? new BigNumber(request.targetAmountMinimum).shiftedBy(2).toString(10)\n : request.targetAmountMinimum,\n };\n\n if (isHyperliquidDeposit) {\n log('Converting Arbitrum Hyperliquid deposit to direct deposit', {\n originalRequest: request,\n normalizedRequest: requestOutput,\n });\n }\n\n return requestOutput;\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 } = details;\n\n const { usdToFiatRate } = getFiatRates(messenger, request);\n\n const dust = getFiatValueFromUsd(\n calculateDustUsd(quote, request),\n usdToFiatRate,\n );\n\n const provider = getFiatValueFromUsd(\n calculateProviderFee(quote),\n usdToFiatRate,\n );\n\n const { isGasFeeToken: isSourceGasFeeToken, ...sourceNetwork } =\n await calculateSourceNetworkCost(quote, messenger, request);\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 return {\n dust,\n estimatedDuration: details.timeEstimate,\n fees: {\n isSourceGasFeeToken,\n provider,\n sourceNetwork,\n targetNetwork,\n },\n original: quote,\n request,\n sourceAmount,\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) {\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 * Converts USD value to fiat value.\n *\n * @param usdValue - USD value.\n * @param usdToFiatRate - USD to fiat rate.\n * @returns Fiat value.\n */\nfunction getFiatValueFromUsd(\n usdValue: BigNumber,\n usdToFiatRate: BigNumber,\n): FiatValue {\n const fiatValue = usdValue.multipliedBy(usdToFiatRate);\n\n return {\n usd: usdValue.toString(10),\n fiat: fiatValue.toString(10),\n };\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 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 * Gets feature flags for Relay quotes.\n *\n * @param messenger - Controller messenger.\n * @returns Feature flags.\n */\nfunction getFeatureFlags(messenger: TransactionPayControllerMessenger) {\n const featureFlagState = messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n\n const featureFlags = featureFlagState.remoteFeatureFlags\n ?.confirmations_pay as Record<string, string> | undefined;\n\n const relayQuoteUrl = featureFlags?.relayQuoteUrl ?? RELAY_URL_QUOTE;\n\n return {\n relayQuoteUrl,\n };\n}\n\n/**\n * Calculates source network cost from a Relay quote.\n *\n * @param quote - Relay quote.\n * @param messenger - Controller messenger.\n * @param request - Quote request.\n * @returns Total source network cost in USD and fiat.\n */\nasync function calculateSourceNetworkCost(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n request: QuoteRequest,\n): Promise<\n TransactionPayQuote<RelayQuote>['fees']['sourceNetwork'] & {\n isGasFeeToken?: boolean;\n }\n> {\n const { from, sourceChainId, sourceTokenAddress } = request;\n const allParams = quote.steps.flatMap((s) => s.items).map((i) => i.data);\n const { chainId, data, to, value } = allParams[0];\n const totalGasLimit = calculateSourceNetworkGasLimit(allParams);\n\n const estimate = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n });\n\n const max = calculateGasCost({\n chainId,\n gas: totalGasLimit,\n messenger,\n isMax: true,\n });\n\n const nativeBalance = getTokenBalance(\n messenger,\n from,\n sourceChainId,\n getNativeToken(sourceChainId),\n );\n\n if (new BigNumber(nativeBalance).isGreaterThanOrEqualTo(max.raw)) {\n return { estimate, max };\n }\n\n log('Checking gas fee tokens as insufficient native balance', {\n nativeBalance,\n max: max.raw,\n });\n\n const 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\n log('Source gas fee tokens', { gasFeeTokens });\n\n const gasFeeToken = gasFeeTokens.find(\n (t) => t.tokenAddress.toLowerCase() === sourceTokenAddress.toLowerCase(),\n );\n\n if (!gasFeeToken) {\n log('No matching gas fee token found', {\n sourceTokenAddress,\n gasFeeTokens,\n });\n\n return { estimate, max };\n }\n\n let finalAmount = gasFeeToken.amount;\n\n if (allParams.length > 1) {\n const gasRate = new BigNumber(gasFeeToken.amount, 16).dividedBy(\n gasFeeToken.gas,\n 16,\n );\n\n const finalAmountValue = gasRate.multipliedBy(totalGasLimit);\n\n finalAmount = toHex(finalAmountValue.toFixed(0));\n\n log('Estimated gas fee token amount for batch', {\n finalAmount: finalAmountValue.toString(10),\n gasRate: gasRate.toString(10),\n totalGasLimit,\n });\n }\n\n const finalGasFeeToken = { ...gasFeeToken, amount: finalAmount };\n\n const gasFeeTokenCost = calculateGasFeeTokenCost({\n chainId: sourceChainId,\n gasFeeToken: finalGasFeeToken,\n messenger,\n });\n\n if (!gasFeeTokenCost) {\n return { estimate, max };\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 };\n}\n\n/**\n * Calculate the total gas limit for the source network transactions.\n *\n * @param params - Array of transaction parameters.\n * @returns - Total gas limit.\n */\nfunction calculateSourceNetworkGasLimit(\n params: RelayQuote['steps'][0]['items'][0]['data'][],\n): number {\n const allParamsHasGas = params.every((p) => p.gas !== undefined);\n\n if (allParamsHasGas) {\n return params.reduce(\n (total, p) => total + new BigNumber(p.gas as string).toNumber(),\n 0,\n );\n }\n\n // In future, call `TransactionController:estimateGas`\n // or `TransactionController:estimateGasBatch` based on params length.\n\n return params.reduce(\n (total, p) =>\n total + new BigNumber(p.gas ?? RELAY_FALLBACK_GAS_LIMIT).toNumber(),\n 0,\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) {\n const relayerFee = new BigNumber(quote.fees.relayer.amountUsd);\n\n const valueLoss = new BigNumber(quote.details.currencyIn.amountUsd).minus(\n quote.details.currencyOut.amountUsd,\n );\n\n return relayerFee.gt(valueLoss) ? relayerFee : valueLoss;\n}\n"]}
|
|
@@ -20,7 +20,7 @@ async function submitRelayQuotes(request) {
|
|
|
20
20
|
const { quotes, messenger, transaction } = request;
|
|
21
21
|
let transactionHash;
|
|
22
22
|
for (const quote of quotes) {
|
|
23
|
-
({ transactionHash } = await executeSingleQuote(quote
|
|
23
|
+
({ transactionHash } = await executeSingleQuote(quote, messenger, transaction));
|
|
24
24
|
}
|
|
25
25
|
return { transactionHash };
|
|
26
26
|
}
|
|
@@ -35,13 +35,6 @@ exports.submitRelayQuotes = submitRelayQuotes;
|
|
|
35
35
|
*/
|
|
36
36
|
async function executeSingleQuote(quote, messenger, transaction) {
|
|
37
37
|
log('Executing single quote', quote);
|
|
38
|
-
const { kind } = quote.steps[0];
|
|
39
|
-
if (kind !== 'transaction') {
|
|
40
|
-
throw new Error(`Unsupported step kind: ${kind}`);
|
|
41
|
-
}
|
|
42
|
-
const transactionParams = quote.steps[0].items[0].data;
|
|
43
|
-
const chainId = (0, controller_utils_1.toHex)(transactionParams.chainId);
|
|
44
|
-
const from = transactionParams.from;
|
|
45
38
|
(0, transaction_1.updateTransaction)({
|
|
46
39
|
transactionId: transaction.id,
|
|
47
40
|
messenger,
|
|
@@ -49,8 +42,8 @@ async function executeSingleQuote(quote, messenger, transaction) {
|
|
|
49
42
|
}, (tx) => {
|
|
50
43
|
tx.txParams.nonce = undefined;
|
|
51
44
|
});
|
|
52
|
-
await submitTransactions(quote,
|
|
53
|
-
const targetHash = await waitForRelayCompletion(quote);
|
|
45
|
+
await submitTransactions(quote, transaction.id, messenger);
|
|
46
|
+
const targetHash = await waitForRelayCompletion(quote.original);
|
|
54
47
|
log('Relay request completed', targetHash);
|
|
55
48
|
(0, transaction_1.updateTransaction)({
|
|
56
49
|
transactionId: transaction.id,
|
|
@@ -112,24 +105,28 @@ function normalizeParams(params) {
|
|
|
112
105
|
* Submit transactions for a relay quote.
|
|
113
106
|
*
|
|
114
107
|
* @param quote - Relay quote.
|
|
115
|
-
* @param chainId - ID of the chain.
|
|
116
|
-
* @param from - Address of the sender.
|
|
117
108
|
* @param parentTransactionId - ID of the parent transaction.
|
|
118
109
|
* @param messenger - Controller messenger.
|
|
119
110
|
* @returns Hash of the last submitted transaction.
|
|
120
111
|
*/
|
|
121
|
-
async function submitTransactions(quote,
|
|
122
|
-
const
|
|
112
|
+
async function submitTransactions(quote, parentTransactionId, messenger) {
|
|
113
|
+
const { steps } = quote.original;
|
|
114
|
+
const params = steps.flatMap((s) => s.items).map((i) => i.data);
|
|
115
|
+
const invalidKind = steps.find((s) => s.kind !== 'transaction')?.kind;
|
|
116
|
+
if (invalidKind) {
|
|
117
|
+
throw new Error(`Unsupported step kind: ${invalidKind}`);
|
|
118
|
+
}
|
|
123
119
|
const normalizedParams = params.map(normalizeParams);
|
|
124
120
|
const transactionIds = [];
|
|
125
|
-
const
|
|
121
|
+
const { from, sourceChainId, sourceTokenAddress } = quote.request;
|
|
122
|
+
const networkClientId = messenger.call('NetworkController:findNetworkClientIdByChainId', sourceChainId);
|
|
126
123
|
log('Adding transactions', {
|
|
127
124
|
normalizedParams,
|
|
128
|
-
|
|
125
|
+
sourceChainId,
|
|
129
126
|
from,
|
|
130
127
|
networkClientId,
|
|
131
128
|
});
|
|
132
|
-
const { end } = (0, transaction_1.collectTransactionIds)(
|
|
129
|
+
const { end } = (0, transaction_1.collectTransactionIds)(sourceChainId, from, messenger, (transactionId) => {
|
|
133
130
|
transactionIds.push(transactionId);
|
|
134
131
|
(0, transaction_1.updateTransaction)({
|
|
135
132
|
transactionId: parentTransactionId,
|
|
@@ -143,8 +140,12 @@ async function submitTransactions(quote, chainId, from, parentTransactionId, mes
|
|
|
143
140
|
});
|
|
144
141
|
});
|
|
145
142
|
let result;
|
|
143
|
+
const gasFeeToken = quote.fees.isSourceGasFeeToken
|
|
144
|
+
? sourceTokenAddress
|
|
145
|
+
: undefined;
|
|
146
146
|
if (params.length === 1) {
|
|
147
147
|
result = await messenger.call('TransactionController:addTransaction', normalizedParams[0], {
|
|
148
|
+
gasFeeToken,
|
|
148
149
|
networkClientId,
|
|
149
150
|
origin: controller_utils_1.ORIGIN_METAMASK,
|
|
150
151
|
requireApproval: false,
|
|
@@ -153,6 +154,7 @@ async function submitTransactions(quote, chainId, from, parentTransactionId, mes
|
|
|
153
154
|
else {
|
|
154
155
|
await messenger.call('TransactionController:addTransactionBatch', {
|
|
155
156
|
from,
|
|
157
|
+
gasFeeToken,
|
|
156
158
|
networkClientId,
|
|
157
159
|
origin: controller_utils_1.ORIGIN_METAMASK,
|
|
158
160
|
requireApproval: false,
|