@metamask/transaction-pay-controller 19.1.0 → 19.1.2
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 +23 -1
- package/dist/helpers/TransactionPayPublishHook.cjs +8 -0
- package/dist/helpers/TransactionPayPublishHook.cjs.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.d.cts.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.d.mts.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.mjs +8 -0
- package/dist/helpers/TransactionPayPublishHook.mjs.map +1 -1
- package/dist/strategy/across/AcrossStrategy.cjs +1 -1
- package/dist/strategy/across/AcrossStrategy.cjs.map +1 -1
- package/dist/strategy/across/AcrossStrategy.d.cts +1 -1
- package/dist/strategy/across/AcrossStrategy.d.cts.map +1 -1
- package/dist/strategy/across/AcrossStrategy.d.mts +1 -1
- package/dist/strategy/across/AcrossStrategy.d.mts.map +1 -1
- package/dist/strategy/across/AcrossStrategy.mjs +1 -1
- package/dist/strategy/across/AcrossStrategy.mjs.map +1 -1
- package/dist/strategy/across/across-actions.cjs.map +1 -1
- package/dist/strategy/across/across-actions.d.cts +1 -1
- package/dist/strategy/across/across-actions.d.cts.map +1 -1
- package/dist/strategy/across/across-actions.d.mts +1 -1
- package/dist/strategy/across/across-actions.d.mts.map +1 -1
- package/dist/strategy/across/across-actions.mjs.map +1 -1
- package/dist/strategy/across/across-quotes.cjs +3 -3
- package/dist/strategy/across/across-quotes.cjs.map +1 -1
- package/dist/strategy/across/across-quotes.d.cts +1 -1
- package/dist/strategy/across/across-quotes.d.cts.map +1 -1
- package/dist/strategy/across/across-quotes.d.mts +1 -1
- package/dist/strategy/across/across-quotes.d.mts.map +1 -1
- package/dist/strategy/across/across-quotes.mjs +3 -3
- package/dist/strategy/across/across-quotes.mjs.map +1 -1
- package/dist/strategy/across/across-submit.cjs +1 -1
- package/dist/strategy/across/across-submit.cjs.map +1 -1
- package/dist/strategy/across/across-submit.d.cts +1 -1
- package/dist/strategy/across/across-submit.d.cts.map +1 -1
- package/dist/strategy/across/across-submit.d.mts +1 -1
- package/dist/strategy/across/across-submit.d.mts.map +1 -1
- package/dist/strategy/across/across-submit.mjs +1 -1
- package/dist/strategy/across/across-submit.mjs.map +1 -1
- package/dist/strategy/bridge/BridgeStrategy.cjs.map +1 -1
- package/dist/strategy/bridge/BridgeStrategy.d.cts +1 -1
- package/dist/strategy/bridge/BridgeStrategy.d.cts.map +1 -1
- package/dist/strategy/bridge/BridgeStrategy.d.mts +1 -1
- package/dist/strategy/bridge/BridgeStrategy.d.mts.map +1 -1
- package/dist/strategy/bridge/BridgeStrategy.mjs.map +1 -1
- package/dist/strategy/bridge/bridge-quotes.cjs.map +1 -1
- package/dist/strategy/bridge/bridge-quotes.d.cts +1 -1
- package/dist/strategy/bridge/bridge-quotes.d.cts.map +1 -1
- package/dist/strategy/bridge/bridge-quotes.d.mts +1 -1
- package/dist/strategy/bridge/bridge-quotes.d.mts.map +1 -1
- package/dist/strategy/bridge/bridge-quotes.mjs.map +1 -1
- package/dist/strategy/bridge/bridge-submit.cjs +1 -1
- package/dist/strategy/bridge/bridge-submit.cjs.map +1 -1
- package/dist/strategy/bridge/bridge-submit.d.cts +1 -1
- package/dist/strategy/bridge/bridge-submit.d.cts.map +1 -1
- package/dist/strategy/bridge/bridge-submit.d.mts +1 -1
- package/dist/strategy/bridge/bridge-submit.d.mts.map +1 -1
- package/dist/strategy/bridge/bridge-submit.mjs +1 -1
- package/dist/strategy/bridge/bridge-submit.mjs.map +1 -1
- package/dist/strategy/fiat/FiatStrategy.cjs.map +1 -1
- package/dist/strategy/fiat/FiatStrategy.d.cts +1 -1
- package/dist/strategy/fiat/FiatStrategy.d.cts.map +1 -1
- package/dist/strategy/fiat/FiatStrategy.d.mts +1 -1
- package/dist/strategy/fiat/FiatStrategy.d.mts.map +1 -1
- package/dist/strategy/fiat/FiatStrategy.mjs.map +1 -1
- package/dist/strategy/fiat/fiat-quotes.cjs +1 -1
- package/dist/strategy/fiat/fiat-quotes.cjs.map +1 -1
- package/dist/strategy/fiat/fiat-quotes.d.cts +1 -1
- package/dist/strategy/fiat/fiat-quotes.d.cts.map +1 -1
- package/dist/strategy/fiat/fiat-quotes.d.mts +1 -1
- package/dist/strategy/fiat/fiat-quotes.d.mts.map +1 -1
- package/dist/strategy/fiat/fiat-quotes.mjs +1 -1
- package/dist/strategy/fiat/fiat-quotes.mjs.map +1 -1
- package/dist/strategy/fiat/fiat-submit.cjs.map +1 -1
- package/dist/strategy/fiat/fiat-submit.d.cts +1 -1
- package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -1
- package/dist/strategy/fiat/fiat-submit.d.mts +1 -1
- package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -1
- package/dist/strategy/fiat/fiat-submit.mjs.map +1 -1
- package/dist/strategy/relay/RelayStrategy.cjs +1 -1
- package/dist/strategy/relay/RelayStrategy.cjs.map +1 -1
- package/dist/strategy/relay/RelayStrategy.d.cts +1 -1
- package/dist/strategy/relay/RelayStrategy.d.cts.map +1 -1
- package/dist/strategy/relay/RelayStrategy.d.mts +1 -1
- package/dist/strategy/relay/RelayStrategy.d.mts.map +1 -1
- package/dist/strategy/relay/RelayStrategy.mjs +1 -1
- package/dist/strategy/relay/RelayStrategy.mjs.map +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.cjs +5 -5
- package/dist/strategy/relay/hyperliquid-withdraw.cjs.map +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.d.cts +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.d.cts.map +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.d.mts +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.d.mts.map +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.mjs +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.mjs.map +1 -1
- package/dist/strategy/relay/relay-api.cjs +1 -1
- package/dist/strategy/relay/relay-api.cjs.map +1 -1
- package/dist/strategy/relay/relay-api.d.cts +1 -1
- package/dist/strategy/relay/relay-api.d.cts.map +1 -1
- package/dist/strategy/relay/relay-api.d.mts +1 -1
- package/dist/strategy/relay/relay-api.d.mts.map +1 -1
- package/dist/strategy/relay/relay-api.mjs +1 -1
- package/dist/strategy/relay/relay-api.mjs.map +1 -1
- package/dist/strategy/relay/relay-max-gas-station.cjs +1 -1
- package/dist/strategy/relay/relay-max-gas-station.cjs.map +1 -1
- package/dist/strategy/relay/relay-max-gas-station.d.cts +1 -1
- package/dist/strategy/relay/relay-max-gas-station.d.cts.map +1 -1
- package/dist/strategy/relay/relay-max-gas-station.d.mts +1 -1
- package/dist/strategy/relay/relay-max-gas-station.d.mts.map +1 -1
- package/dist/strategy/relay/relay-max-gas-station.mjs +1 -1
- package/dist/strategy/relay/relay-max-gas-station.mjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.cjs +21 -21
- package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.cts +1 -1
- package/dist/strategy/relay/relay-quotes.d.cts.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.mts +1 -1
- package/dist/strategy/relay/relay-quotes.d.mts.map +1 -1
- package/dist/strategy/relay/relay-quotes.mjs +4 -4
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +3 -3
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.d.cts +1 -1
- package/dist/strategy/relay/relay-submit.d.cts.map +1 -1
- package/dist/strategy/relay/relay-submit.d.mts +1 -1
- package/dist/strategy/relay/relay-submit.d.mts.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +3 -3
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/utils/gas.cjs +1 -1
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +1 -1
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/quote-gas.cjs +1 -1
- package/dist/utils/quote-gas.cjs.map +1 -1
- package/dist/utils/quote-gas.d.cts.map +1 -1
- package/dist/utils/quote-gas.d.mts.map +1 -1
- package/dist/utils/quote-gas.mjs +1 -1
- package/dist/utils/quote-gas.mjs.map +1 -1
- package/dist/utils/quotes.cjs +2 -2
- package/dist/utils/quotes.cjs.map +1 -1
- package/dist/utils/quotes.d.cts.map +1 -1
- package/dist/utils/quotes.d.mts.map +1 -1
- package/dist/utils/quotes.mjs +2 -2
- package/dist/utils/quotes.mjs.map +1 -1
- package/dist/utils/required-tokens.cjs.map +1 -1
- package/dist/utils/required-tokens.d.cts.map +1 -1
- package/dist/utils/required-tokens.d.mts.map +1 -1
- package/dist/utils/required-tokens.mjs.map +1 -1
- package/dist/utils/source-amounts.cjs +2 -2
- package/dist/utils/source-amounts.cjs.map +1 -1
- package/dist/utils/source-amounts.d.cts.map +1 -1
- package/dist/utils/source-amounts.d.mts.map +1 -1
- package/dist/utils/source-amounts.mjs +2 -2
- package/dist/utils/source-amounts.mjs.map +1 -1
- package/dist/utils/token.cjs +1 -1
- package/dist/utils/token.cjs.map +1 -1
- package/dist/utils/token.d.cts.map +1 -1
- package/dist/utils/token.d.mts.map +1 -1
- package/dist/utils/token.mjs +1 -1
- package/dist/utils/token.mjs.map +1 -1
- 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.map +1 -1
- package/dist/utils/transaction.cjs +1 -1
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +1 -1
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +20 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-amounts.cjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const { isHyperliquidSource } = transactionData;\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n isHyperliquidSource,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n isHyperliquidSource?: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain, unless the source is HyperLiquid.\n // For HyperLiquid withdrawals the relay strategy renormalizes the\n // source from Arbitrum USDC to HyperCore USDC (a different chain),\n // so the tokens are not actually the same after normalization.\n if (isSameToken(token, paymentToken) && !isHyperliquidSource) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const { parentTransactionType, strategy } = getStrategyContext(\n transactionId,\n messenger,\n );\n const isAlwaysRequired = isQuoteAlwaysRequired(\n token,\n strategy,\n parentTransactionType,\n );\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @param parentTransactionType - Parent transaction type, if available.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n parentTransactionType?: TransactionType,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return (\n isHyperliquidDeposit &&\n (strategy === TransactionPayStrategy.Relay ||\n (strategy === TransactionPayStrategy.Across &&\n parentTransactionType === TransactionType.perpsDeposit))\n );\n}\n\nfunction getStrategyContext(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): {\n parentTransactionType?: TransactionType;\n strategy: TransactionPayStrategy;\n} {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return {\n parentTransactionType: transaction.type,\n strategy: messenger.call(\n 'TransactionPayController:getStrategy',\n transaction,\n ),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"source-amounts.cjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const { isHyperliquidSource } = transactionData;\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n isHyperliquidSource,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n isHyperliquidSource?: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain, unless the source is HyperLiquid.\n // For HyperLiquid withdrawals the relay strategy renormalizes the\n // source from Arbitrum USDC to HyperCore USDC (a different chain),\n // so the tokens are not actually the same after normalization.\n if (isSameToken(token, paymentToken) && !isHyperliquidSource) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const { parentTransactionType, strategy } = getStrategyContext(\n transactionId,\n messenger,\n );\n const isAlwaysRequired = isQuoteAlwaysRequired(\n token,\n strategy,\n parentTransactionType,\n );\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @param parentTransactionType - Parent transaction type, if available.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n parentTransactionType?: TransactionType,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return (\n isHyperliquidDeposit &&\n (strategy === TransactionPayStrategy.Relay ||\n (strategy === TransactionPayStrategy.Across &&\n parentTransactionType === TransactionType.perpsDeposit))\n );\n}\n\nfunction getStrategyContext(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): {\n parentTransactionType?: TransactionType;\n strategy: TransactionPayStrategy;\n} {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return {\n parentTransactionType: transaction.type,\n strategy: messenger.call(\n 'TransactionPayController:getStrategy',\n transaction,\n ),\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-amounts.d.cts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-amounts.d.cts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iCAAiC,EAElC,qBAAW;AAKZ,OAAO,KAAK,EAEV,eAAe,EAEhB,qBAAiB;AAMlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,SAAS,EAAE,iCAAiC,GAC3C,IAAI,CAyCN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-amounts.d.mts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-amounts.d.mts","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iCAAiC,EAElC,qBAAW;AAKZ,OAAO,KAAK,EAEV,eAAe,EAEhB,qBAAiB;AAMlB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,SAAS,EAAE,iCAAiC,GAC3C,IAAI,CAyCN"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { TransactionType } from "@metamask/transaction-controller";
|
|
2
2
|
import { createModuleLogger } from "@metamask/utils";
|
|
3
3
|
import { BigNumber } from "bignumber.js";
|
|
4
|
-
import { getTokenFiatRate, isSameToken } from "./token.mjs";
|
|
5
|
-
import { getTransaction } from "./transaction.mjs";
|
|
6
4
|
import { TransactionPayStrategy } from "../index.mjs";
|
|
7
5
|
import { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from "../constants.mjs";
|
|
8
6
|
import { projectLogger } from "../logger.mjs";
|
|
7
|
+
import { getTokenFiatRate, isSameToken } from "./token.mjs";
|
|
8
|
+
import { getTransaction } from "./transaction.mjs";
|
|
9
9
|
const log = createModuleLogger(projectLogger, 'source-amounts');
|
|
10
10
|
/**
|
|
11
11
|
* Update the source amounts for a transaction.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-amounts.mjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const { isHyperliquidSource } = transactionData;\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n isHyperliquidSource,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n isHyperliquidSource?: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain, unless the source is HyperLiquid.\n // For HyperLiquid withdrawals the relay strategy renormalizes the\n // source from Arbitrum USDC to HyperCore USDC (a different chain),\n // so the tokens are not actually the same after normalization.\n if (isSameToken(token, paymentToken) && !isHyperliquidSource) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const { parentTransactionType, strategy } = getStrategyContext(\n transactionId,\n messenger,\n );\n const isAlwaysRequired = isQuoteAlwaysRequired(\n token,\n strategy,\n parentTransactionType,\n );\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @param parentTransactionType - Parent transaction type, if available.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n parentTransactionType?: TransactionType,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return (\n isHyperliquidDeposit &&\n (strategy === TransactionPayStrategy.Relay ||\n (strategy === TransactionPayStrategy.Across &&\n parentTransactionType === TransactionType.perpsDeposit))\n );\n}\n\nfunction getStrategyContext(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): {\n parentTransactionType?: TransactionType;\n strategy: TransactionPayStrategy;\n} {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return {\n parentTransactionType: transaction.type,\n strategy: messenger.call(\n 'TransactionPayController:getStrategy',\n transaction,\n ),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"source-amounts.mjs","sourceRoot":"","sources":["../../src/utils/source-amounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n TransactionPayControllerMessenger,\n TransactionPaymentToken,\n} from '..';\nimport { TransactionPayStrategy } from '..';\nimport type { TransactionMeta } from '../../../transaction-controller/src';\nimport { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPaySourceAmount,\n TransactionData,\n TransactionPayRequiredToken,\n} from '../types';\nimport { getTokenFiatRate, isSameToken } from './token';\nimport { getTransaction } from './transaction';\n\nconst log = createModuleLogger(projectLogger, 'source-amounts');\n\n/**\n * Update the source amounts for a transaction.\n *\n * @param transactionId - ID of the transaction to update.\n * @param transactionData - Existing transaction data.\n * @param messenger - Controller messenger.\n */\nexport function updateSourceAmounts(\n transactionId: string,\n transactionData: TransactionData | undefined,\n messenger: TransactionPayControllerMessenger,\n): void {\n if (!transactionData) {\n return;\n }\n\n const { isMaxAmount, isPostQuote, paymentToken, tokens } = transactionData;\n\n if (!tokens.length || !paymentToken) {\n return;\n }\n\n // For post-quote flows, source amounts are calculated differently\n // The source is the transaction's required token, not the selected token\n if (isPostQuote) {\n const { isHyperliquidSource } = transactionData;\n const sourceAmounts = calculatePostQuoteSourceAmounts(\n tokens,\n paymentToken,\n isMaxAmount ?? false,\n isHyperliquidSource,\n );\n log('Updated post-quote source amounts', { transactionId, sourceAmounts });\n transactionData.sourceAmounts = sourceAmounts;\n return;\n }\n\n const sourceAmounts = tokens\n .map((singleToken) =>\n calculateSourceAmount(\n paymentToken,\n singleToken,\n messenger,\n transactionId,\n isMaxAmount ?? false,\n ),\n )\n .filter(Boolean) as TransactionPaySourceAmount[];\n\n log('Updated source amounts', { transactionId, sourceAmounts });\n\n transactionData.sourceAmounts = sourceAmounts;\n}\n\n/**\n * Calculate source amounts for post-quote flows.\n * In this flow, the required tokens ARE the source tokens,\n * and the payment token is the target (destination).\n *\n * @param tokens - Required tokens from the transaction.\n * @param paymentToken - Selected payment/destination token.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param isHyperliquidSource - Whether the source is HyperLiquid (perps withdrawal).\n * @returns Array of source amounts.\n */\nfunction calculatePostQuoteSourceAmounts(\n tokens: TransactionPayRequiredToken[],\n paymentToken: TransactionPaymentToken,\n isMaxAmount: boolean,\n isHyperliquidSource?: boolean,\n): TransactionPaySourceAmount[] {\n return tokens\n .filter((token) => {\n if (token.skipIfBalance) {\n return false;\n }\n\n // Skip zero amounts (unless max amount, where we use balance)\n if (token.amountRaw === '0' && !isMaxAmount) {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return false;\n }\n\n // Skip same token on same chain, unless the source is HyperLiquid.\n // For HyperLiquid withdrawals the relay strategy renormalizes the\n // source from Arbitrum USDC to HyperCore USDC (a different chain),\n // so the tokens are not actually the same after normalization.\n if (isSameToken(token, paymentToken) && !isHyperliquidSource) {\n log('Skipping token as same as destination token');\n return false;\n }\n\n return true;\n })\n .map((token) => ({\n sourceAmountHuman: isMaxAmount ? token.balanceHuman : token.amountHuman,\n sourceAmountRaw: isMaxAmount ? token.balanceRaw : token.amountRaw,\n sourceBalanceRaw: token.balanceRaw,\n sourceChainId: token.chainId,\n sourceTokenAddress: token.address,\n targetTokenAddress: paymentToken.address,\n }));\n}\n\n/**\n * Calculate the required source amount for a payment token to cover a target token.\n *\n * @param paymentToken - Selected payment token.\n * @param token - Target token to cover.\n * @param messenger - Controller messenger.\n * @param transactionId - ID of the transaction.\n * @param isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @returns The source amount or undefined if calculation failed.\n */\nfunction calculateSourceAmount(\n paymentToken: TransactionPaymentToken,\n token: TransactionPayRequiredToken,\n messenger: TransactionPayControllerMessenger,\n transactionId: string,\n isMaxAmount: boolean,\n): TransactionPaySourceAmount | undefined {\n const paymentTokenFiatRate = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!paymentTokenFiatRate) {\n return undefined;\n }\n\n const hasBalance = new BigNumber(token.balanceRaw).gte(token.amountRaw);\n\n if (token.skipIfBalance && hasBalance) {\n log('Skipping token as sufficient balance', {\n tokenAddress: token.address,\n });\n return undefined;\n }\n\n const { parentTransactionType, strategy } = getStrategyContext(\n transactionId,\n messenger,\n );\n const isAlwaysRequired = isQuoteAlwaysRequired(\n token,\n strategy,\n parentTransactionType,\n );\n\n if (isSameToken(token, paymentToken) && !isAlwaysRequired) {\n log('Skipping token as same as payment token');\n return undefined;\n }\n\n const sourceAmountHumanValue = new BigNumber(token.amountUsd).div(\n paymentTokenFiatRate.usdRate,\n );\n\n const sourceAmountHuman = sourceAmountHumanValue.toString(10);\n\n const sourceAmountRaw = sourceAmountHumanValue\n .shiftedBy(paymentToken.decimals)\n .toFixed(0);\n\n if (token.amountRaw === '0') {\n log('Skipping token as zero amount', { tokenAddress: token.address });\n return undefined;\n }\n\n if (isMaxAmount) {\n return {\n sourceAmountHuman: paymentToken.balanceHuman,\n sourceAmountRaw: paymentToken.balanceRaw,\n targetTokenAddress: token.address,\n };\n }\n\n return {\n sourceAmountHuman,\n sourceAmountRaw,\n targetTokenAddress: token.address,\n };\n}\n\n/**\n * Determine if a quote is always required for a token and strategy.\n *\n * @param token - Target token.\n * @param strategy - Payment strategy.\n * @param parentTransactionType - Parent transaction type, if available.\n * @returns True if a quote is always required, false otherwise.\n */\nfunction isQuoteAlwaysRequired(\n token: TransactionPayRequiredToken,\n strategy: TransactionPayStrategy,\n parentTransactionType?: TransactionType,\n): boolean {\n const isHyperliquidDeposit =\n token.chainId === CHAIN_ID_ARBITRUM &&\n token.address.toLowerCase() === ARBITRUM_USDC_ADDRESS.toLowerCase();\n\n return (\n isHyperliquidDeposit &&\n (strategy === TransactionPayStrategy.Relay ||\n (strategy === TransactionPayStrategy.Across &&\n parentTransactionType === TransactionType.perpsDeposit))\n );\n}\n\nfunction getStrategyContext(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): {\n parentTransactionType?: TransactionType;\n strategy: TransactionPayStrategy;\n} {\n const transaction = getTransaction(\n transactionId,\n messenger,\n ) as TransactionMeta;\n\n return {\n parentTransactionType: transaction.type,\n strategy: messenger.call(\n 'TransactionPayController:getStrategy',\n transaction,\n ),\n };\n}\n"]}
|
package/dist/utils/token.cjs
CHANGED
|
@@ -6,8 +6,8 @@ const providers_1 = require("@ethersproject/providers");
|
|
|
6
6
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
7
7
|
const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
|
|
8
8
|
const bignumber_js_1 = require("bignumber.js");
|
|
9
|
-
const feature_flags_1 = require("./feature-flags.cjs");
|
|
10
9
|
const constants_1 = require("../constants.cjs");
|
|
10
|
+
const feature_flags_1 = require("./feature-flags.cjs");
|
|
11
11
|
/**
|
|
12
12
|
* Check if two tokens are the same (same address and chain).
|
|
13
13
|
*
|
package/dist/utils/token.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.cjs","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAssetsUnifyStateFeature } from './feature-flags';\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n STABLECOINS,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\n\n/**\n * Check if two tokens are the same (same address and chain).\n *\n * @param token1 - First token identifier.\n * @param token1.address - Token address.\n * @param token1.chainId - Token chain ID.\n * @param token2 - Second token identifier.\n * @param token2.address - Token address.\n * @param token2.chainId - Token chain ID.\n * @returns True if tokens are the same, false otherwise.\n */\nexport function isSameToken(\n token1: { address: Hex; chainId: Hex },\n token2: { address: Hex; chainId: Hex },\n): boolean {\n return (\n token1.address.toLowerCase() === token2.address.toLowerCase() &&\n token1.chainId === token2.chainId\n );\n}\n\n/**\n * Get the token balance for a specific account and token.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Id of the chain.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport function getTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): string {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let tokenBalances;\n let accountsByChainId;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n tokenBalances = assetsControllerState?.tokenBalances;\n accountsByChainId = assetsControllerState?.accountsByChainId;\n } else {\n tokenBalances = messenger.call(\n 'TokenBalancesController:getState',\n )?.tokenBalances;\n accountsByChainId = messenger.call(\n 'AccountTrackerController:getState',\n )?.accountsByChainId;\n }\n\n const normalizedAccount = account.toLowerCase() as Hex;\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const balanceHex =\n tokenBalances?.[normalizedAccount]?.[chainId]?.[normalizedTokenAddress];\n\n if (!isNative && balanceHex === undefined) {\n return '0';\n }\n\n if (!isNative && balanceHex) {\n return new BigNumber(balanceHex, 16).toString(10);\n }\n\n const chainAccounts = accountsByChainId?.[chainId];\n\n const checksumAccount = toChecksumHexAddress(normalizedAccount) as Hex;\n const nativeBalanceHex = chainAccounts?.[checksumAccount]?.balance as Hex;\n\n return new BigNumber(nativeBalanceHex ?? '0x0', 16).toString(10);\n}\n\n/**\n * Get the token decimals for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns The token decimals or undefined if the token is not found.\n */\nexport function getTokenInfo(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): { decimals: number; symbol: string } | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let allTokens: TokensControllerState['allTokens'];\n if (assetsUnifyStateFeatureEnabled) {\n allTokens = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n )?.allTokens;\n } else {\n allTokens = messenger.call('TokensController:getState')?.allTokens;\n }\n\n const normalizedTokenAddress = tokenAddress.toLowerCase() as Hex;\n\n const isNative =\n normalizedTokenAddress === getNativeToken(chainId).toLowerCase();\n\n const token = Object.values(allTokens?.[chainId] ?? {})\n .flat()\n .find(\n (singleToken) =>\n singleToken.address.toLowerCase() === normalizedTokenAddress,\n );\n\n if (!token && !isNative) {\n return undefined;\n }\n\n if (token && !isNative) {\n return { decimals: Number(token.decimals), symbol: token.symbol };\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n return { decimals: 18, symbol: ticker };\n}\n\n/**\n * Calculate fiat rates for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns An object containing the USD and fiat rates, or undefined if rates are not available.\n */\nexport function getTokenFiatRate(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): FiatRates | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let marketData;\n let currencyRates;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n marketData = assetsControllerState?.marketData;\n currencyRates = assetsControllerState?.currencyRates;\n } else {\n marketData = messenger.call('TokenRatesController:getState')?.marketData;\n currencyRates = messenger.call(\n 'CurrencyRateController:getState',\n )?.currencyRates;\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const tokenToNativeRate =\n marketData?.[chainId]?.[normalizedTokenAddress]?.price;\n\n if (tokenToNativeRate === undefined && !isNative) {\n return undefined;\n }\n\n const {\n conversionRate: nativeToFiatRate,\n usdConversionRate: nativeToUsdRate,\n } = currencyRates?.[ticker] ?? {\n conversionRate: null,\n usdConversionRate: null,\n };\n\n if (nativeToFiatRate === null || nativeToUsdRate === null) {\n return undefined;\n }\n const isStablecoin = STABLECOINS[chainId]?.includes(\n tokenAddress.toLowerCase() as Hex,\n );\n\n const usdRate = isStablecoin\n ? '1'\n : new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToUsdRate)\n .toString(10);\n\n const fiatRate = new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToFiatRate)\n .toString(10);\n\n return { usdRate, fiatRate };\n}\n\n/**\n * Calculate the human-readable, raw, USD, and fiat representations of a token amount.\n *\n * @param rawInput - Raw token amount (decimal string, hex, or BigNumber).\n * @param decimals - Number of decimals for the token.\n * @param fiatRates - Fiat rates for the token.\n * @returns Object containing the amount in raw, human-readable, USD, and fiat formats.\n */\nexport function computeTokenAmounts(\n rawInput: BigNumber.Value,\n decimals: number,\n fiatRates: FiatRates,\n): {\n raw: string;\n human: string;\n usd: string;\n fiat: string;\n} {\n const rawValue = new BigNumber(rawInput);\n const humanValue = rawValue.shiftedBy(-decimals);\n\n return {\n raw: rawValue.toFixed(0),\n human: humanValue.toString(10),\n usd: humanValue.multipliedBy(fiatRates.usdRate).toString(10),\n fiat: humanValue.multipliedBy(fiatRates.fiatRate).toString(10),\n };\n}\n\n/**\n * Compute a raw token amount from a fiat (USD) amount.\n * This is the inverse of `computeTokenAmounts` — it goes from USD to raw.\n *\n * @param fiatAmount - Amount in fiat/USD.\n * @param decimals - Token decimals.\n * @param usdRate - USD rate for the token (price per one unit of the token).\n * @returns Raw token amount string, or undefined if the conversion produces an invalid result.\n */\nexport function computeRawFromFiatAmount(\n fiatAmount: BigNumber.Value,\n decimals: number,\n usdRate: BigNumber.Value,\n): string | undefined {\n const rate = new BigNumber(usdRate);\n if (!rate.isFinite() || !rate.gt(0)) {\n return undefined;\n }\n\n const humanAmount = new BigNumber(fiatAmount).dividedBy(rate);\n if (!humanAmount.isFinite() || !humanAmount.gt(0)) {\n return undefined;\n }\n\n const raw = humanAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n return new BigNumber(raw).gt(0) ? raw : undefined;\n}\n\n/**\n * Get the native token address for a given chain ID.\n *\n * @param chainId - Chain ID.\n * @returns - Native token address for the given chain ID.\n */\nexport function getNativeToken(chainId: Hex): Hex {\n switch (chainId) {\n case '0x89':\n return '0x0000000000000000000000000000000000001010';\n default:\n return NATIVE_TOKEN_ADDRESS;\n }\n}\n\n/**\n * Get the live on-chain token balance via an RPC `eth_call` to the ERC-20\n * `balanceOf` function, or `eth_getBalance` for native tokens.\n *\n * Unlike {@link getTokenBalance}, this bypasses the cached state in\n * `TokenBalancesController` and reads directly from the chain.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Chain ID.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport async function getLiveTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): Promise<string> {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const { provider } = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n const ethersProvider = new Web3Provider(provider);\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const balance = await ethersProvider.getBalance(account);\n return balance.toString();\n }\n\n const contract = new Contract(tokenAddress, abiERC20, ethersProvider);\n const balance = await contract.balanceOf(account);\n return balance.toString();\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const networkConfiguration = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n return networkConfiguration.configuration.ticker;\n } catch {\n return undefined;\n }\n}\n\nexport enum TokenAddressTarget {\n Relay = 'relay',\n MetaMask = 'metamask',\n}\n\n/**\n * Normalize token address formats between MetaMask and Relay for Polygon native\n * token handling.\n *\n * MetaMask uses Polygon's native token contract-like address (`0x...1010`),\n * while Relay expects the zero address for native tokens.\n *\n * @param tokenAddress - Token address to normalize.\n * @param chainId - Chain ID for the token.\n * @param target - Optional target system format.\n * @returns Normalized token address for the target system, or the original\n * address if no target is provided.\n */\nexport function normalizeTokenAddress(\n tokenAddress: Hex,\n chainId: Hex,\n target?: TokenAddressTarget,\n): Hex {\n if (chainId !== CHAIN_ID_POLYGON) {\n return tokenAddress;\n }\n\n const nativeTokenAddress = getNativeToken(chainId).toLowerCase() as Hex;\n const normalizedTokenAddress = tokenAddress.toLowerCase();\n\n if (\n target === TokenAddressTarget.Relay &&\n normalizedTokenAddress === nativeTokenAddress\n ) {\n return NATIVE_TOKEN_ADDRESS;\n }\n\n if (\n target === TokenAddressTarget.MetaMask &&\n normalizedTokenAddress === NATIVE_TOKEN_ADDRESS.toLowerCase()\n ) {\n return nativeTokenAddress;\n }\n\n return tokenAddress;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"token.cjs","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n STABLECOINS,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\nimport { getAssetsUnifyStateFeature } from './feature-flags';\n\n/**\n * Check if two tokens are the same (same address and chain).\n *\n * @param token1 - First token identifier.\n * @param token1.address - Token address.\n * @param token1.chainId - Token chain ID.\n * @param token2 - Second token identifier.\n * @param token2.address - Token address.\n * @param token2.chainId - Token chain ID.\n * @returns True if tokens are the same, false otherwise.\n */\nexport function isSameToken(\n token1: { address: Hex; chainId: Hex },\n token2: { address: Hex; chainId: Hex },\n): boolean {\n return (\n token1.address.toLowerCase() === token2.address.toLowerCase() &&\n token1.chainId === token2.chainId\n );\n}\n\n/**\n * Get the token balance for a specific account and token.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Id of the chain.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport function getTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): string {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let tokenBalances;\n let accountsByChainId;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n tokenBalances = assetsControllerState?.tokenBalances;\n accountsByChainId = assetsControllerState?.accountsByChainId;\n } else {\n tokenBalances = messenger.call(\n 'TokenBalancesController:getState',\n )?.tokenBalances;\n accountsByChainId = messenger.call(\n 'AccountTrackerController:getState',\n )?.accountsByChainId;\n }\n\n const normalizedAccount = account.toLowerCase() as Hex;\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const balanceHex =\n tokenBalances?.[normalizedAccount]?.[chainId]?.[normalizedTokenAddress];\n\n if (!isNative && balanceHex === undefined) {\n return '0';\n }\n\n if (!isNative && balanceHex) {\n return new BigNumber(balanceHex, 16).toString(10);\n }\n\n const chainAccounts = accountsByChainId?.[chainId];\n\n const checksumAccount = toChecksumHexAddress(normalizedAccount) as Hex;\n const nativeBalanceHex = chainAccounts?.[checksumAccount]?.balance as Hex;\n\n return new BigNumber(nativeBalanceHex ?? '0x0', 16).toString(10);\n}\n\n/**\n * Get the token decimals for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns The token decimals or undefined if the token is not found.\n */\nexport function getTokenInfo(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): { decimals: number; symbol: string } | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let allTokens: TokensControllerState['allTokens'];\n if (assetsUnifyStateFeatureEnabled) {\n allTokens = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n )?.allTokens;\n } else {\n allTokens = messenger.call('TokensController:getState')?.allTokens;\n }\n\n const normalizedTokenAddress = tokenAddress.toLowerCase() as Hex;\n\n const isNative =\n normalizedTokenAddress === getNativeToken(chainId).toLowerCase();\n\n const token = Object.values(allTokens?.[chainId] ?? {})\n .flat()\n .find(\n (singleToken) =>\n singleToken.address.toLowerCase() === normalizedTokenAddress,\n );\n\n if (!token && !isNative) {\n return undefined;\n }\n\n if (token && !isNative) {\n return { decimals: Number(token.decimals), symbol: token.symbol };\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n return { decimals: 18, symbol: ticker };\n}\n\n/**\n * Calculate fiat rates for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns An object containing the USD and fiat rates, or undefined if rates are not available.\n */\nexport function getTokenFiatRate(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): FiatRates | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let marketData;\n let currencyRates;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n marketData = assetsControllerState?.marketData;\n currencyRates = assetsControllerState?.currencyRates;\n } else {\n marketData = messenger.call('TokenRatesController:getState')?.marketData;\n currencyRates = messenger.call(\n 'CurrencyRateController:getState',\n )?.currencyRates;\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const tokenToNativeRate =\n marketData?.[chainId]?.[normalizedTokenAddress]?.price;\n\n if (tokenToNativeRate === undefined && !isNative) {\n return undefined;\n }\n\n const {\n conversionRate: nativeToFiatRate,\n usdConversionRate: nativeToUsdRate,\n } = currencyRates?.[ticker] ?? {\n conversionRate: null,\n usdConversionRate: null,\n };\n\n if (nativeToFiatRate === null || nativeToUsdRate === null) {\n return undefined;\n }\n const isStablecoin = STABLECOINS[chainId]?.includes(\n tokenAddress.toLowerCase() as Hex,\n );\n\n const usdRate = isStablecoin\n ? '1'\n : new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToUsdRate)\n .toString(10);\n\n const fiatRate = new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToFiatRate)\n .toString(10);\n\n return { usdRate, fiatRate };\n}\n\n/**\n * Calculate the human-readable, raw, USD, and fiat representations of a token amount.\n *\n * @param rawInput - Raw token amount (decimal string, hex, or BigNumber).\n * @param decimals - Number of decimals for the token.\n * @param fiatRates - Fiat rates for the token.\n * @returns Object containing the amount in raw, human-readable, USD, and fiat formats.\n */\nexport function computeTokenAmounts(\n rawInput: BigNumber.Value,\n decimals: number,\n fiatRates: FiatRates,\n): {\n raw: string;\n human: string;\n usd: string;\n fiat: string;\n} {\n const rawValue = new BigNumber(rawInput);\n const humanValue = rawValue.shiftedBy(-decimals);\n\n return {\n raw: rawValue.toFixed(0),\n human: humanValue.toString(10),\n usd: humanValue.multipliedBy(fiatRates.usdRate).toString(10),\n fiat: humanValue.multipliedBy(fiatRates.fiatRate).toString(10),\n };\n}\n\n/**\n * Compute a raw token amount from a fiat (USD) amount.\n * This is the inverse of `computeTokenAmounts` — it goes from USD to raw.\n *\n * @param fiatAmount - Amount in fiat/USD.\n * @param decimals - Token decimals.\n * @param usdRate - USD rate for the token (price per one unit of the token).\n * @returns Raw token amount string, or undefined if the conversion produces an invalid result.\n */\nexport function computeRawFromFiatAmount(\n fiatAmount: BigNumber.Value,\n decimals: number,\n usdRate: BigNumber.Value,\n): string | undefined {\n const rate = new BigNumber(usdRate);\n if (!rate.isFinite() || !rate.gt(0)) {\n return undefined;\n }\n\n const humanAmount = new BigNumber(fiatAmount).dividedBy(rate);\n if (!humanAmount.isFinite() || !humanAmount.gt(0)) {\n return undefined;\n }\n\n const raw = humanAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n return new BigNumber(raw).gt(0) ? raw : undefined;\n}\n\n/**\n * Get the native token address for a given chain ID.\n *\n * @param chainId - Chain ID.\n * @returns - Native token address for the given chain ID.\n */\nexport function getNativeToken(chainId: Hex): Hex {\n switch (chainId) {\n case '0x89':\n return '0x0000000000000000000000000000000000001010';\n default:\n return NATIVE_TOKEN_ADDRESS;\n }\n}\n\n/**\n * Get the live on-chain token balance via an RPC `eth_call` to the ERC-20\n * `balanceOf` function, or `eth_getBalance` for native tokens.\n *\n * Unlike {@link getTokenBalance}, this bypasses the cached state in\n * `TokenBalancesController` and reads directly from the chain.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Chain ID.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport async function getLiveTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): Promise<string> {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const { provider } = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n const ethersProvider = new Web3Provider(provider);\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const balance = await ethersProvider.getBalance(account);\n return balance.toString();\n }\n\n const contract = new Contract(tokenAddress, abiERC20, ethersProvider);\n const balance = await contract.balanceOf(account);\n return balance.toString();\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const networkConfiguration = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n return networkConfiguration.configuration.ticker;\n } catch {\n return undefined;\n }\n}\n\nexport enum TokenAddressTarget {\n Relay = 'relay',\n MetaMask = 'metamask',\n}\n\n/**\n * Normalize token address formats between MetaMask and Relay for Polygon native\n * token handling.\n *\n * MetaMask uses Polygon's native token contract-like address (`0x...1010`),\n * while Relay expects the zero address for native tokens.\n *\n * @param tokenAddress - Token address to normalize.\n * @param chainId - Chain ID for the token.\n * @param target - Optional target system format.\n * @returns Normalized token address for the target system, or the original\n * address if no target is provided.\n */\nexport function normalizeTokenAddress(\n tokenAddress: Hex,\n chainId: Hex,\n target?: TokenAddressTarget,\n): Hex {\n if (chainId !== CHAIN_ID_POLYGON) {\n return tokenAddress;\n }\n\n const nativeTokenAddress = getNativeToken(chainId).toLowerCase() as Hex;\n const normalizedTokenAddress = tokenAddress.toLowerCase();\n\n if (\n target === TokenAddressTarget.Relay &&\n normalizedTokenAddress === nativeTokenAddress\n ) {\n return NATIVE_TOKEN_ADDRESS;\n }\n\n if (\n target === TokenAddressTarget.MetaMask &&\n normalizedTokenAddress === NATIVE_TOKEN_ADDRESS.toLowerCase()\n ) {\n return nativeTokenAddress;\n }\n\n return tokenAddress;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.cts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,SAAS,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"token.d.cts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAOzC,OAAO,KAAK,EAAE,SAAS,EAAE,iCAAiC,EAAE,qBAAiB;AAG7E;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE;IAAE,OAAO,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,EACtC,MAAM,EAAE;IAAE,OAAO,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,GACrC,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,iCAAiC,EAC5C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,GAChB,MAAM,CA0CR;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,iCAAiC,EAC5C,YAAY,EAAE,GAAG,EACjB,OAAO,EAAE,GAAG,GACX;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuClD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,iCAAiC,EAC5C,YAAY,EAAE,GAAG,EACjB,OAAO,EAAE,GAAG,GACX,SAAS,GAAG,SAAS,CA6DvB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,CAAC,KAAK,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GACnB;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,SAAS,CAAC,KAAK,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,CAAC,KAAK,GACvB,MAAM,GAAG,SAAS,CAiBpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CAOhD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,iCAAiC,EAC5C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,GAChB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAuBD,oBAAY,kBAAkB;IAC5B,KAAK,UAAU;IACf,QAAQ,aAAa;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,GAAG,EACjB,OAAO,EAAE,GAAG,EACZ,MAAM,CAAC,EAAE,kBAAkB,GAC1B,GAAG,CAuBL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.mts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,SAAS,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"token.d.mts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAOzC,OAAO,KAAK,EAAE,SAAS,EAAE,iCAAiC,EAAE,qBAAiB;AAG7E;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE;IAAE,OAAO,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,EACtC,MAAM,EAAE;IAAE,OAAO,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,GACrC,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,iCAAiC,EAC5C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,GAChB,MAAM,CA0CR;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,iCAAiC,EAC5C,YAAY,EAAE,GAAG,EACjB,OAAO,EAAE,GAAG,GACX;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuClD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,iCAAiC,EAC5C,YAAY,EAAE,GAAG,EACjB,OAAO,EAAE,GAAG,GACX,SAAS,GAAG,SAAS,CA6DvB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,CAAC,KAAK,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GACnB;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,SAAS,CAAC,KAAK,EAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,CAAC,KAAK,GACvB,MAAM,GAAG,SAAS,CAiBpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CAOhD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,iCAAiC,EAC5C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,GAChB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAuBD,oBAAY,kBAAkB;IAC5B,KAAK,UAAU;IACf,QAAQ,aAAa;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,GAAG,EACjB,OAAO,EAAE,GAAG,EACZ,MAAM,CAAC,EAAE,kBAAkB,GAC1B,GAAG,CAuBL"}
|
package/dist/utils/token.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { Web3Provider } from "@ethersproject/providers";
|
|
|
3
3
|
import { toChecksumHexAddress } from "@metamask/controller-utils";
|
|
4
4
|
import { abiERC20 } from "@metamask/metamask-eth-abis";
|
|
5
5
|
import { BigNumber } from "bignumber.js";
|
|
6
|
-
import { getAssetsUnifyStateFeature } from "./feature-flags.mjs";
|
|
7
6
|
import { CHAIN_ID_POLYGON, NATIVE_TOKEN_ADDRESS, STABLECOINS } from "../constants.mjs";
|
|
7
|
+
import { getAssetsUnifyStateFeature } from "./feature-flags.mjs";
|
|
8
8
|
/**
|
|
9
9
|
* Check if two tokens are the same (same address and chain).
|
|
10
10
|
*
|
package/dist/utils/token.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.mjs","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { getAssetsUnifyStateFeature } from './feature-flags';\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n STABLECOINS,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\n\n/**\n * Check if two tokens are the same (same address and chain).\n *\n * @param token1 - First token identifier.\n * @param token1.address - Token address.\n * @param token1.chainId - Token chain ID.\n * @param token2 - Second token identifier.\n * @param token2.address - Token address.\n * @param token2.chainId - Token chain ID.\n * @returns True if tokens are the same, false otherwise.\n */\nexport function isSameToken(\n token1: { address: Hex; chainId: Hex },\n token2: { address: Hex; chainId: Hex },\n): boolean {\n return (\n token1.address.toLowerCase() === token2.address.toLowerCase() &&\n token1.chainId === token2.chainId\n );\n}\n\n/**\n * Get the token balance for a specific account and token.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Id of the chain.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport function getTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): string {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let tokenBalances;\n let accountsByChainId;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n tokenBalances = assetsControllerState?.tokenBalances;\n accountsByChainId = assetsControllerState?.accountsByChainId;\n } else {\n tokenBalances = messenger.call(\n 'TokenBalancesController:getState',\n )?.tokenBalances;\n accountsByChainId = messenger.call(\n 'AccountTrackerController:getState',\n )?.accountsByChainId;\n }\n\n const normalizedAccount = account.toLowerCase() as Hex;\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const balanceHex =\n tokenBalances?.[normalizedAccount]?.[chainId]?.[normalizedTokenAddress];\n\n if (!isNative && balanceHex === undefined) {\n return '0';\n }\n\n if (!isNative && balanceHex) {\n return new BigNumber(balanceHex, 16).toString(10);\n }\n\n const chainAccounts = accountsByChainId?.[chainId];\n\n const checksumAccount = toChecksumHexAddress(normalizedAccount) as Hex;\n const nativeBalanceHex = chainAccounts?.[checksumAccount]?.balance as Hex;\n\n return new BigNumber(nativeBalanceHex ?? '0x0', 16).toString(10);\n}\n\n/**\n * Get the token decimals for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns The token decimals or undefined if the token is not found.\n */\nexport function getTokenInfo(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): { decimals: number; symbol: string } | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let allTokens: TokensControllerState['allTokens'];\n if (assetsUnifyStateFeatureEnabled) {\n allTokens = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n )?.allTokens;\n } else {\n allTokens = messenger.call('TokensController:getState')?.allTokens;\n }\n\n const normalizedTokenAddress = tokenAddress.toLowerCase() as Hex;\n\n const isNative =\n normalizedTokenAddress === getNativeToken(chainId).toLowerCase();\n\n const token = Object.values(allTokens?.[chainId] ?? {})\n .flat()\n .find(\n (singleToken) =>\n singleToken.address.toLowerCase() === normalizedTokenAddress,\n );\n\n if (!token && !isNative) {\n return undefined;\n }\n\n if (token && !isNative) {\n return { decimals: Number(token.decimals), symbol: token.symbol };\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n return { decimals: 18, symbol: ticker };\n}\n\n/**\n * Calculate fiat rates for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns An object containing the USD and fiat rates, or undefined if rates are not available.\n */\nexport function getTokenFiatRate(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): FiatRates | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let marketData;\n let currencyRates;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n marketData = assetsControllerState?.marketData;\n currencyRates = assetsControllerState?.currencyRates;\n } else {\n marketData = messenger.call('TokenRatesController:getState')?.marketData;\n currencyRates = messenger.call(\n 'CurrencyRateController:getState',\n )?.currencyRates;\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const tokenToNativeRate =\n marketData?.[chainId]?.[normalizedTokenAddress]?.price;\n\n if (tokenToNativeRate === undefined && !isNative) {\n return undefined;\n }\n\n const {\n conversionRate: nativeToFiatRate,\n usdConversionRate: nativeToUsdRate,\n } = currencyRates?.[ticker] ?? {\n conversionRate: null,\n usdConversionRate: null,\n };\n\n if (nativeToFiatRate === null || nativeToUsdRate === null) {\n return undefined;\n }\n const isStablecoin = STABLECOINS[chainId]?.includes(\n tokenAddress.toLowerCase() as Hex,\n );\n\n const usdRate = isStablecoin\n ? '1'\n : new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToUsdRate)\n .toString(10);\n\n const fiatRate = new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToFiatRate)\n .toString(10);\n\n return { usdRate, fiatRate };\n}\n\n/**\n * Calculate the human-readable, raw, USD, and fiat representations of a token amount.\n *\n * @param rawInput - Raw token amount (decimal string, hex, or BigNumber).\n * @param decimals - Number of decimals for the token.\n * @param fiatRates - Fiat rates for the token.\n * @returns Object containing the amount in raw, human-readable, USD, and fiat formats.\n */\nexport function computeTokenAmounts(\n rawInput: BigNumber.Value,\n decimals: number,\n fiatRates: FiatRates,\n): {\n raw: string;\n human: string;\n usd: string;\n fiat: string;\n} {\n const rawValue = new BigNumber(rawInput);\n const humanValue = rawValue.shiftedBy(-decimals);\n\n return {\n raw: rawValue.toFixed(0),\n human: humanValue.toString(10),\n usd: humanValue.multipliedBy(fiatRates.usdRate).toString(10),\n fiat: humanValue.multipliedBy(fiatRates.fiatRate).toString(10),\n };\n}\n\n/**\n * Compute a raw token amount from a fiat (USD) amount.\n * This is the inverse of `computeTokenAmounts` — it goes from USD to raw.\n *\n * @param fiatAmount - Amount in fiat/USD.\n * @param decimals - Token decimals.\n * @param usdRate - USD rate for the token (price per one unit of the token).\n * @returns Raw token amount string, or undefined if the conversion produces an invalid result.\n */\nexport function computeRawFromFiatAmount(\n fiatAmount: BigNumber.Value,\n decimals: number,\n usdRate: BigNumber.Value,\n): string | undefined {\n const rate = new BigNumber(usdRate);\n if (!rate.isFinite() || !rate.gt(0)) {\n return undefined;\n }\n\n const humanAmount = new BigNumber(fiatAmount).dividedBy(rate);\n if (!humanAmount.isFinite() || !humanAmount.gt(0)) {\n return undefined;\n }\n\n const raw = humanAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n return new BigNumber(raw).gt(0) ? raw : undefined;\n}\n\n/**\n * Get the native token address for a given chain ID.\n *\n * @param chainId - Chain ID.\n * @returns - Native token address for the given chain ID.\n */\nexport function getNativeToken(chainId: Hex): Hex {\n switch (chainId) {\n case '0x89':\n return '0x0000000000000000000000000000000000001010';\n default:\n return NATIVE_TOKEN_ADDRESS;\n }\n}\n\n/**\n * Get the live on-chain token balance via an RPC `eth_call` to the ERC-20\n * `balanceOf` function, or `eth_getBalance` for native tokens.\n *\n * Unlike {@link getTokenBalance}, this bypasses the cached state in\n * `TokenBalancesController` and reads directly from the chain.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Chain ID.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport async function getLiveTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): Promise<string> {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const { provider } = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n const ethersProvider = new Web3Provider(provider);\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const balance = await ethersProvider.getBalance(account);\n return balance.toString();\n }\n\n const contract = new Contract(tokenAddress, abiERC20, ethersProvider);\n const balance = await contract.balanceOf(account);\n return balance.toString();\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const networkConfiguration = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n return networkConfiguration.configuration.ticker;\n } catch {\n return undefined;\n }\n}\n\nexport enum TokenAddressTarget {\n Relay = 'relay',\n MetaMask = 'metamask',\n}\n\n/**\n * Normalize token address formats between MetaMask and Relay for Polygon native\n * token handling.\n *\n * MetaMask uses Polygon's native token contract-like address (`0x...1010`),\n * while Relay expects the zero address for native tokens.\n *\n * @param tokenAddress - Token address to normalize.\n * @param chainId - Chain ID for the token.\n * @param target - Optional target system format.\n * @returns Normalized token address for the target system, or the original\n * address if no target is provided.\n */\nexport function normalizeTokenAddress(\n tokenAddress: Hex,\n chainId: Hex,\n target?: TokenAddressTarget,\n): Hex {\n if (chainId !== CHAIN_ID_POLYGON) {\n return tokenAddress;\n }\n\n const nativeTokenAddress = getNativeToken(chainId).toLowerCase() as Hex;\n const normalizedTokenAddress = tokenAddress.toLowerCase();\n\n if (\n target === TokenAddressTarget.Relay &&\n normalizedTokenAddress === nativeTokenAddress\n ) {\n return NATIVE_TOKEN_ADDRESS;\n }\n\n if (\n target === TokenAddressTarget.MetaMask &&\n normalizedTokenAddress === NATIVE_TOKEN_ADDRESS.toLowerCase()\n ) {\n return nativeTokenAddress;\n }\n\n return tokenAddress;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"token.mjs","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n STABLECOINS,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\nimport { getAssetsUnifyStateFeature } from './feature-flags';\n\n/**\n * Check if two tokens are the same (same address and chain).\n *\n * @param token1 - First token identifier.\n * @param token1.address - Token address.\n * @param token1.chainId - Token chain ID.\n * @param token2 - Second token identifier.\n * @param token2.address - Token address.\n * @param token2.chainId - Token chain ID.\n * @returns True if tokens are the same, false otherwise.\n */\nexport function isSameToken(\n token1: { address: Hex; chainId: Hex },\n token2: { address: Hex; chainId: Hex },\n): boolean {\n return (\n token1.address.toLowerCase() === token2.address.toLowerCase() &&\n token1.chainId === token2.chainId\n );\n}\n\n/**\n * Get the token balance for a specific account and token.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Id of the chain.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport function getTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): string {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let tokenBalances;\n let accountsByChainId;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n tokenBalances = assetsControllerState?.tokenBalances;\n accountsByChainId = assetsControllerState?.accountsByChainId;\n } else {\n tokenBalances = messenger.call(\n 'TokenBalancesController:getState',\n )?.tokenBalances;\n accountsByChainId = messenger.call(\n 'AccountTrackerController:getState',\n )?.accountsByChainId;\n }\n\n const normalizedAccount = account.toLowerCase() as Hex;\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const balanceHex =\n tokenBalances?.[normalizedAccount]?.[chainId]?.[normalizedTokenAddress];\n\n if (!isNative && balanceHex === undefined) {\n return '0';\n }\n\n if (!isNative && balanceHex) {\n return new BigNumber(balanceHex, 16).toString(10);\n }\n\n const chainAccounts = accountsByChainId?.[chainId];\n\n const checksumAccount = toChecksumHexAddress(normalizedAccount) as Hex;\n const nativeBalanceHex = chainAccounts?.[checksumAccount]?.balance as Hex;\n\n return new BigNumber(nativeBalanceHex ?? '0x0', 16).toString(10);\n}\n\n/**\n * Get the token decimals for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns The token decimals or undefined if the token is not found.\n */\nexport function getTokenInfo(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): { decimals: number; symbol: string } | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let allTokens: TokensControllerState['allTokens'];\n if (assetsUnifyStateFeatureEnabled) {\n allTokens = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n )?.allTokens;\n } else {\n allTokens = messenger.call('TokensController:getState')?.allTokens;\n }\n\n const normalizedTokenAddress = tokenAddress.toLowerCase() as Hex;\n\n const isNative =\n normalizedTokenAddress === getNativeToken(chainId).toLowerCase();\n\n const token = Object.values(allTokens?.[chainId] ?? {})\n .flat()\n .find(\n (singleToken) =>\n singleToken.address.toLowerCase() === normalizedTokenAddress,\n );\n\n if (!token && !isNative) {\n return undefined;\n }\n\n if (token && !isNative) {\n return { decimals: Number(token.decimals), symbol: token.symbol };\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n return { decimals: 18, symbol: ticker };\n}\n\n/**\n * Calculate fiat rates for a specific token.\n *\n * @param messenger - Controller messenger.\n * @param tokenAddress - Address of the token contract.\n * @param chainId - Id of the chain.\n * @returns An object containing the USD and fiat rates, or undefined if rates are not available.\n */\nexport function getTokenFiatRate(\n messenger: TransactionPayControllerMessenger,\n tokenAddress: Hex,\n chainId: Hex,\n): FiatRates | undefined {\n const assetsUnifyStateFeatureEnabled = getAssetsUnifyStateFeature(messenger);\n\n let marketData;\n let currencyRates;\n if (assetsUnifyStateFeatureEnabled) {\n const assetsControllerState = messenger.call(\n 'AssetsController:getStateForTransactionPay',\n );\n\n marketData = assetsControllerState?.marketData;\n currencyRates = assetsControllerState?.currencyRates;\n } else {\n marketData = messenger.call('TokenRatesController:getState')?.marketData;\n currencyRates = messenger.call(\n 'CurrencyRateController:getState',\n )?.currencyRates;\n }\n\n const ticker = getTicker(chainId, messenger);\n\n if (!ticker) {\n return undefined;\n }\n\n const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n const tokenToNativeRate =\n marketData?.[chainId]?.[normalizedTokenAddress]?.price;\n\n if (tokenToNativeRate === undefined && !isNative) {\n return undefined;\n }\n\n const {\n conversionRate: nativeToFiatRate,\n usdConversionRate: nativeToUsdRate,\n } = currencyRates?.[ticker] ?? {\n conversionRate: null,\n usdConversionRate: null,\n };\n\n if (nativeToFiatRate === null || nativeToUsdRate === null) {\n return undefined;\n }\n const isStablecoin = STABLECOINS[chainId]?.includes(\n tokenAddress.toLowerCase() as Hex,\n );\n\n const usdRate = isStablecoin\n ? '1'\n : new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToUsdRate)\n .toString(10);\n\n const fiatRate = new BigNumber(tokenToNativeRate ?? 1)\n .multipliedBy(nativeToFiatRate)\n .toString(10);\n\n return { usdRate, fiatRate };\n}\n\n/**\n * Calculate the human-readable, raw, USD, and fiat representations of a token amount.\n *\n * @param rawInput - Raw token amount (decimal string, hex, or BigNumber).\n * @param decimals - Number of decimals for the token.\n * @param fiatRates - Fiat rates for the token.\n * @returns Object containing the amount in raw, human-readable, USD, and fiat formats.\n */\nexport function computeTokenAmounts(\n rawInput: BigNumber.Value,\n decimals: number,\n fiatRates: FiatRates,\n): {\n raw: string;\n human: string;\n usd: string;\n fiat: string;\n} {\n const rawValue = new BigNumber(rawInput);\n const humanValue = rawValue.shiftedBy(-decimals);\n\n return {\n raw: rawValue.toFixed(0),\n human: humanValue.toString(10),\n usd: humanValue.multipliedBy(fiatRates.usdRate).toString(10),\n fiat: humanValue.multipliedBy(fiatRates.fiatRate).toString(10),\n };\n}\n\n/**\n * Compute a raw token amount from a fiat (USD) amount.\n * This is the inverse of `computeTokenAmounts` — it goes from USD to raw.\n *\n * @param fiatAmount - Amount in fiat/USD.\n * @param decimals - Token decimals.\n * @param usdRate - USD rate for the token (price per one unit of the token).\n * @returns Raw token amount string, or undefined if the conversion produces an invalid result.\n */\nexport function computeRawFromFiatAmount(\n fiatAmount: BigNumber.Value,\n decimals: number,\n usdRate: BigNumber.Value,\n): string | undefined {\n const rate = new BigNumber(usdRate);\n if (!rate.isFinite() || !rate.gt(0)) {\n return undefined;\n }\n\n const humanAmount = new BigNumber(fiatAmount).dividedBy(rate);\n if (!humanAmount.isFinite() || !humanAmount.gt(0)) {\n return undefined;\n }\n\n const raw = humanAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n return new BigNumber(raw).gt(0) ? raw : undefined;\n}\n\n/**\n * Get the native token address for a given chain ID.\n *\n * @param chainId - Chain ID.\n * @returns - Native token address for the given chain ID.\n */\nexport function getNativeToken(chainId: Hex): Hex {\n switch (chainId) {\n case '0x89':\n return '0x0000000000000000000000000000000000001010';\n default:\n return NATIVE_TOKEN_ADDRESS;\n }\n}\n\n/**\n * Get the live on-chain token balance via an RPC `eth_call` to the ERC-20\n * `balanceOf` function, or `eth_getBalance` for native tokens.\n *\n * Unlike {@link getTokenBalance}, this bypasses the cached state in\n * `TokenBalancesController` and reads directly from the chain.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @param chainId - Chain ID.\n * @param tokenAddress - Address of the token contract.\n * @returns Raw token balance as a decimal string.\n */\nexport async function getLiveTokenBalance(\n messenger: TransactionPayControllerMessenger,\n account: Hex,\n chainId: Hex,\n tokenAddress: Hex,\n): Promise<string> {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const { provider } = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n const ethersProvider = new Web3Provider(provider);\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const balance = await ethersProvider.getBalance(account);\n return balance.toString();\n }\n\n const contract = new Contract(tokenAddress, abiERC20, ethersProvider);\n const balance = await contract.balanceOf(account);\n return balance.toString();\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n const networkConfiguration = messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n\n return networkConfiguration.configuration.ticker;\n } catch {\n return undefined;\n }\n}\n\nexport enum TokenAddressTarget {\n Relay = 'relay',\n MetaMask = 'metamask',\n}\n\n/**\n * Normalize token address formats between MetaMask and Relay for Polygon native\n * token handling.\n *\n * MetaMask uses Polygon's native token contract-like address (`0x...1010`),\n * while Relay expects the zero address for native tokens.\n *\n * @param tokenAddress - Token address to normalize.\n * @param chainId - Chain ID for the token.\n * @param target - Optional target system format.\n * @returns Normalized token address for the target system, or the original\n * address if no target is provided.\n */\nexport function normalizeTokenAddress(\n tokenAddress: Hex,\n chainId: Hex,\n target?: TokenAddressTarget,\n): Hex {\n if (chainId !== CHAIN_ID_POLYGON) {\n return tokenAddress;\n }\n\n const nativeTokenAddress = getNativeToken(chainId).toLowerCase() as Hex;\n const normalizedTokenAddress = tokenAddress.toLowerCase();\n\n if (\n target === TokenAddressTarget.Relay &&\n normalizedTokenAddress === nativeTokenAddress\n ) {\n return NATIVE_TOKEN_ADDRESS;\n }\n\n if (\n target === TokenAddressTarget.MetaMask &&\n normalizedTokenAddress === NATIVE_TOKEN_ADDRESS.toLowerCase()\n ) {\n return nativeTokenAddress;\n }\n\n return tokenAddress;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"totals.cjs","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":";;;AACA,+CAAyC;
|
|
1
|
+
{"version":3,"file":"totals.cjs","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n FiatValue,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n TransactionPayRequiredToken,\n TransactionPayTotals,\n} from '../types';\nimport { sumAmounts } from './amounts';\nimport { calculateTransactionGasCost } from './gas';\n\n/**\n * Calculate totals for a list of quotes and tokens.\n *\n * @param request - Request parameters.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.quotes - List of bridge quotes.\n * @param request.messenger - Controller messenger.\n * @param request.tokens - List of required tokens.\n * @param request.transaction - Transaction metadata.\n * @returns The calculated totals in USD and fiat currency.\n */\nexport function calculateTotals({\n isMaxAmount,\n quotes,\n messenger,\n tokens,\n transaction,\n}: {\n isMaxAmount?: boolean;\n quotes: TransactionPayQuote<unknown>[];\n messenger: TransactionPayControllerMessenger;\n tokens: TransactionPayRequiredToken[];\n transaction: TransactionMeta;\n}): TransactionPayTotals {\n const metaMaskFee = sumFiat(quotes.map((quote) => quote.fees.metaMask));\n const providerFee = sumFiat(quotes.map((quote) => quote.fees.provider));\n const providerFiatFee = sumFiat(\n quotes.map((quote) => quote.fees.providerFiat ?? { fiat: '0', usd: '0' }),\n );\n\n const sourceNetworkFeeMax = sumAmounts(\n quotes.map((quote) => quote.fees.sourceNetwork.max),\n );\n\n const sourceNetworkFeeEstimate = sumAmounts(\n quotes.map((quote) => quote.fees.sourceNetwork.estimate),\n );\n\n const transactionNetworkFee = calculateTransactionGasCost(\n transaction,\n messenger,\n );\n\n const targetNetworkFee = quotes?.length\n ? {\n ...sumFiat(quotes.map((quote) => quote.fees.targetNetwork)),\n isGasFeeToken: false,\n }\n : transactionNetworkFee;\n\n const sourceAmount = sumAmounts(quotes.map((quote) => quote.sourceAmount));\n const targetAmount = sumFiat(quotes.map((quote) => quote.targetAmount));\n\n const quoteTokens = tokens.filter(\n (singleToken) => !singleToken.skipIfBalance,\n );\n\n const amountFiat = sumProperty(quoteTokens, (token) => token.amountFiat);\n const amountUsd = sumProperty(quoteTokens, (token) => token.amountUsd);\n const hasQuotes = quotes.length > 0;\n\n const totalFiat = new BigNumber(providerFee.fiat)\n .plus(metaMaskFee.fiat)\n .plus(sourceNetworkFeeEstimate.fiat)\n .plus(targetNetworkFee.fiat)\n .plus(isMaxAmount && hasQuotes ? targetAmount.fiat : amountFiat)\n .toString(10);\n\n const totalUsd = new BigNumber(providerFee.usd)\n .plus(metaMaskFee.usd)\n .plus(sourceNetworkFeeEstimate.usd)\n .plus(targetNetworkFee.usd)\n .plus(isMaxAmount && hasQuotes ? targetAmount.usd : amountUsd)\n .toString(10);\n\n const estimatedDuration = Number(\n sumProperty(quotes, (quote) => quote.estimatedDuration),\n );\n\n const isSourceGasFeeToken = quotes.some(\n (quote) => quote.fees.isSourceGasFeeToken,\n );\n\n const isTargetGasFeeToken =\n Boolean(targetNetworkFee.isGasFeeToken) ||\n quotes.some((quote) => quote.fees.isTargetGasFeeToken);\n\n return {\n estimatedDuration,\n fees: {\n isSourceGasFeeToken,\n isTargetGasFeeToken,\n providerFiat: providerFiatFee,\n metaMask: metaMaskFee,\n provider: providerFee,\n sourceNetwork: {\n estimate: sourceNetworkFeeEstimate,\n max: sourceNetworkFeeMax,\n },\n targetNetwork: targetNetworkFee,\n },\n sourceAmount,\n targetAmount,\n total: {\n fiat: totalFiat,\n usd: totalUsd,\n },\n };\n}\n\n/**\n * Sum a list of fiat value.\n *\n * @param data - List of fiat values.\n * @returns Total fiat value.\n */\nfunction sumFiat(data: FiatValue[]): FiatValue {\n const fiat = sumProperty(data, (item) => item.fiat);\n const usd = sumProperty(data, (item) => item.usd);\n return { fiat, usd };\n}\n\n/**\n * Sum a specific property from a list of items.\n *\n * @param data - List of items.\n * @param getProperty - Function to extract the property to sum from each item.\n * @returns The summed value as a string.\n */\nfunction sumProperty<DataType>(\n data: DataType[],\n getProperty: (item: DataType) => BigNumber.Value,\n): string {\n return data\n .map(getProperty)\n .reduce<BigNumber>((total, value) => total.plus(value), new BigNumber(0))\n .toString(10);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"totals.d.cts","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;
|
|
1
|
+
{"version":3,"file":"totals.d.cts","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAGxE,OAAO,KAAK,EAEV,iCAAiC,EACjC,mBAAmB,EACnB,2BAA2B,EAC3B,oBAAoB,EACrB,qBAAiB;AAIlB;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,WAAW,GACZ,EAAE;IACD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,SAAS,EAAE,iCAAiC,CAAC;IAC7C,MAAM,EAAE,2BAA2B,EAAE,CAAC;IACtC,WAAW,EAAE,eAAe,CAAC;CAC9B,GAAG,oBAAoB,CAqFvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"totals.d.mts","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;
|
|
1
|
+
{"version":3,"file":"totals.d.mts","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAGxE,OAAO,KAAK,EAEV,iCAAiC,EACjC,mBAAmB,EACnB,2BAA2B,EAC3B,oBAAoB,EACrB,qBAAiB;AAIlB;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,WAAW,GACZ,EAAE;IACD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,SAAS,EAAE,iCAAiC,CAAC;IAC7C,MAAM,EAAE,2BAA2B,EAAE,CAAC;IACtC,WAAW,EAAE,eAAe,CAAC;CAC9B,GAAG,oBAAoB,CAqFvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"totals.mjs","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"totals.mjs","sourceRoot":"","sources":["../../src/utils/totals.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport { BigNumber } from 'bignumber.js';\n\nimport type {\n FiatValue,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n TransactionPayRequiredToken,\n TransactionPayTotals,\n} from '../types';\nimport { sumAmounts } from './amounts';\nimport { calculateTransactionGasCost } from './gas';\n\n/**\n * Calculate totals for a list of quotes and tokens.\n *\n * @param request - Request parameters.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.quotes - List of bridge quotes.\n * @param request.messenger - Controller messenger.\n * @param request.tokens - List of required tokens.\n * @param request.transaction - Transaction metadata.\n * @returns The calculated totals in USD and fiat currency.\n */\nexport function calculateTotals({\n isMaxAmount,\n quotes,\n messenger,\n tokens,\n transaction,\n}: {\n isMaxAmount?: boolean;\n quotes: TransactionPayQuote<unknown>[];\n messenger: TransactionPayControllerMessenger;\n tokens: TransactionPayRequiredToken[];\n transaction: TransactionMeta;\n}): TransactionPayTotals {\n const metaMaskFee = sumFiat(quotes.map((quote) => quote.fees.metaMask));\n const providerFee = sumFiat(quotes.map((quote) => quote.fees.provider));\n const providerFiatFee = sumFiat(\n quotes.map((quote) => quote.fees.providerFiat ?? { fiat: '0', usd: '0' }),\n );\n\n const sourceNetworkFeeMax = sumAmounts(\n quotes.map((quote) => quote.fees.sourceNetwork.max),\n );\n\n const sourceNetworkFeeEstimate = sumAmounts(\n quotes.map((quote) => quote.fees.sourceNetwork.estimate),\n );\n\n const transactionNetworkFee = calculateTransactionGasCost(\n transaction,\n messenger,\n );\n\n const targetNetworkFee = quotes?.length\n ? {\n ...sumFiat(quotes.map((quote) => quote.fees.targetNetwork)),\n isGasFeeToken: false,\n }\n : transactionNetworkFee;\n\n const sourceAmount = sumAmounts(quotes.map((quote) => quote.sourceAmount));\n const targetAmount = sumFiat(quotes.map((quote) => quote.targetAmount));\n\n const quoteTokens = tokens.filter(\n (singleToken) => !singleToken.skipIfBalance,\n );\n\n const amountFiat = sumProperty(quoteTokens, (token) => token.amountFiat);\n const amountUsd = sumProperty(quoteTokens, (token) => token.amountUsd);\n const hasQuotes = quotes.length > 0;\n\n const totalFiat = new BigNumber(providerFee.fiat)\n .plus(metaMaskFee.fiat)\n .plus(sourceNetworkFeeEstimate.fiat)\n .plus(targetNetworkFee.fiat)\n .plus(isMaxAmount && hasQuotes ? targetAmount.fiat : amountFiat)\n .toString(10);\n\n const totalUsd = new BigNumber(providerFee.usd)\n .plus(metaMaskFee.usd)\n .plus(sourceNetworkFeeEstimate.usd)\n .plus(targetNetworkFee.usd)\n .plus(isMaxAmount && hasQuotes ? targetAmount.usd : amountUsd)\n .toString(10);\n\n const estimatedDuration = Number(\n sumProperty(quotes, (quote) => quote.estimatedDuration),\n );\n\n const isSourceGasFeeToken = quotes.some(\n (quote) => quote.fees.isSourceGasFeeToken,\n );\n\n const isTargetGasFeeToken =\n Boolean(targetNetworkFee.isGasFeeToken) ||\n quotes.some((quote) => quote.fees.isTargetGasFeeToken);\n\n return {\n estimatedDuration,\n fees: {\n isSourceGasFeeToken,\n isTargetGasFeeToken,\n providerFiat: providerFiatFee,\n metaMask: metaMaskFee,\n provider: providerFee,\n sourceNetwork: {\n estimate: sourceNetworkFeeEstimate,\n max: sourceNetworkFeeMax,\n },\n targetNetwork: targetNetworkFee,\n },\n sourceAmount,\n targetAmount,\n total: {\n fiat: totalFiat,\n usd: totalUsd,\n },\n };\n}\n\n/**\n * Sum a list of fiat value.\n *\n * @param data - List of fiat values.\n * @returns Total fiat value.\n */\nfunction sumFiat(data: FiatValue[]): FiatValue {\n const fiat = sumProperty(data, (item) => item.fiat);\n const usd = sumProperty(data, (item) => item.usd);\n return { fiat, usd };\n}\n\n/**\n * Sum a specific property from a list of items.\n *\n * @param data - List of items.\n * @param getProperty - Function to extract the property to sum from each item.\n * @returns The summed value as a string.\n */\nfunction sumProperty<DataType>(\n data: DataType[],\n getProperty: (item: DataType) => BigNumber.Value,\n): string {\n return data\n .map(getProperty)\n .reduce<BigNumber>((total, value) => total.plus(value), new BigNumber(0))\n .toString(10);\n}\n"]}
|
|
@@ -4,8 +4,8 @@ exports.isPredictWithdrawTransaction = exports.collectTransactionIds = exports.u
|
|
|
4
4
|
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
5
5
|
const utils_1 = require("@metamask/utils");
|
|
6
6
|
const lodash_1 = require("lodash");
|
|
7
|
-
const required_tokens_1 = require("./required-tokens.cjs");
|
|
8
7
|
const logger_1 = require("../logger.cjs");
|
|
8
|
+
const required_tokens_1 = require("./required-tokens.cjs");
|
|
9
9
|
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'transaction');
|
|
10
10
|
exports.FINALIZED_STATUSES = [
|
|
11
11
|
transaction_controller_1.TransactionStatus.confirmed,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.cjs","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport { parseRequiredTokens } from './required-tokens';\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPayControllerMessenger,\n UpdateTransactionDataCallback,\n} from '../types';\n\nconst log = createModuleLogger(projectLogger, 'transaction');\n\nexport const FINALIZED_STATUSES = [\n TransactionStatus.confirmed,\n TransactionStatus.dropped,\n TransactionStatus.failed,\n];\n\n/**\n * Retrieve transaction metadata by ID.\n *\n * @param transactionId - ID of the transaction to retrieve.\n * @param messenger - Controller messenger.\n * @returns The transaction metadata or undefined if not found.\n */\nexport function getTransaction(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): TransactionMeta | undefined {\n const transactionControllerState = messenger.call(\n 'TransactionController:getState',\n );\n\n return transactionControllerState.transactions.find(\n (tx) => tx.id === transactionId,\n );\n}\n\n/**\n * Poll for transaction changes and update the transaction data accordingly.\n *\n * @param messenger - Controller messenger.\n * @param updateTransactionData - Callback to update transaction data.\n * @param removeTransactionData - Callback to remove transaction data.\n */\nexport function pollTransactionChanges(\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n removeTransactionData: (transactionId: string) => void,\n): void {\n messenger.subscribe(\n 'TransactionController:stateChange',\n (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => {\n const newTransactions = transactions.filter(\n (tx) => !previousTransactions?.find((prevTx) => prevTx.id === tx.id),\n );\n\n const updatedTransactions = transactions.filter((tx) => {\n const previousTransaction = previousTransactions?.find(\n (prevTx) => prevTx.id === tx.id,\n );\n\n return (\n previousTransaction &&\n previousTransaction?.txParams.data !== tx.txParams.data\n );\n });\n\n const finalizedTransactions = transactions.filter((tx) => {\n const previousTransaction = previousTransactions?.find(\n (prevTx) => prevTx.id === tx.id,\n );\n\n return (\n previousTransaction &&\n !FINALIZED_STATUSES.includes(previousTransaction.status) &&\n FINALIZED_STATUSES.includes(tx.status)\n );\n });\n\n const deletedTransactions = (previousTransactions ?? []).filter(\n (prevTx) => !transactions.find((tx) => tx.id === prevTx.id),\n );\n\n [...finalizedTransactions, ...deletedTransactions].forEach((tx) =>\n onTransactionFinalized(tx, removeTransactionData),\n );\n\n [...newTransactions, ...updatedTransactions].forEach((tx) =>\n onTransactionChange(tx, messenger, updateTransactionData),\n );\n },\n (state) => state.transactions,\n );\n}\n\n/**\n * Wait for a transaction to be confirmed or fail.\n *\n * @param transactionId - ID of the transaction to wait for.\n * @param messenger - Controller messenger.\n * @returns A promise that resolves when the transaction is confirmed or rejects if it fails.\n */\nexport function waitForTransactionConfirmed(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const isConfirmed = (tx?: TransactionMeta, fn?: () => void): boolean => {\n log('Checking transaction status', tx?.status, tx?.type);\n\n if (tx?.status === TransactionStatus.confirmed) {\n fn?.();\n resolve();\n return true;\n }\n\n if (\n [TransactionStatus.dropped, TransactionStatus.failed].includes(\n tx?.status as TransactionStatus,\n )\n ) {\n fn?.();\n reject(\n new Error(`Transaction failed - ${tx?.type} - ${tx?.error?.message}`),\n );\n return true;\n }\n\n return false;\n };\n\n const initialState = messenger.call('TransactionController:getState');\n\n const initialTx = initialState.transactions.find(\n (singleTransaction) => singleTransaction.id === transactionId,\n );\n\n if (isConfirmed(initialTx)) {\n return;\n }\n\n const handler = (tx?: TransactionMeta): void => {\n const unsubscribe = (): void =>\n messenger.unsubscribe('TransactionController:stateChange', handler);\n\n isConfirmed(tx, unsubscribe);\n };\n\n messenger.subscribe('TransactionController:stateChange', handler, (state) =>\n state.transactions.find((tx) => tx.id === transactionId),\n );\n });\n}\n\n/**\n * Update a transaction by applying a function to its draft.\n *\n * @param request - Request object.\n * @param request.transactionId - ID of the transaction to update.\n * @param request.messenger - Controller messenger.\n * @param request.note - Note describing the update.\n * @param fn - Function that applies updates to the transaction draft.\n */\nexport function updateTransaction(\n {\n transactionId,\n messenger,\n note,\n }: {\n transactionId: string;\n messenger: TransactionPayControllerMessenger;\n note: string;\n },\n fn: (draft: TransactionMeta) => void,\n): void {\n const transaction = getTransaction(transactionId, messenger as never);\n\n if (!transaction) {\n throw new Error(`Transaction not found: ${transactionId}`);\n }\n\n const newTransaction = cloneDeep(transaction);\n\n fn(newTransaction);\n\n messenger.call(\n 'TransactionController:updateTransaction',\n newTransaction,\n note,\n );\n}\n\n/**\n * Collect all new transactions until `end` is called.\n *\n * @param chainId - The chain ID to filter transactions by.\n * @param from - The address to filter transactions by.\n * @param messenger - The controller messenger.\n * @param onTransaction - Callback called with each matching transaction ID.\n * @returns An object with an `end` method to stop collecting transactions.\n */\nexport function collectTransactionIds(\n chainId: Hex,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n onTransaction: (transactionId: string) => void,\n): { end: () => void } {\n const listener = (tx: TransactionMeta): void => {\n if (\n tx.chainId !== chainId ||\n tx.txParams.from.toLowerCase() !== from.toLowerCase()\n ) {\n return;\n }\n\n onTransaction(tx.id);\n };\n\n messenger.subscribe(\n 'TransactionController:unapprovedTransactionAdded',\n listener,\n );\n\n const end = (): void => {\n messenger.unsubscribe(\n 'TransactionController:unapprovedTransactionAdded',\n listener,\n );\n };\n\n return { end };\n}\n\n/**\n * Check whether a transaction is a Predict withdrawal.\n *\n * Returns `true` when the transaction's own type is `predictWithdraw`, or\n * when any of its nested transactions has that type.\n *\n * @param transaction - Transaction metadata.\n * @returns `true` when the transaction is a Predict withdrawal.\n */\nexport function isPredictWithdrawTransaction(\n transaction: TransactionMeta,\n): boolean {\n return (\n transaction.type === TransactionType.predictWithdraw ||\n (transaction.nestedTransactions?.some(\n (nt) => nt.type === TransactionType.predictWithdraw,\n ) ??\n false)\n );\n}\n\n/**\n * Handle a transaction change by updating its associated data.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @param updateTransactionData - Callback to update transaction data.\n */\nfunction onTransactionChange(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n): void {\n const tokens = parseRequiredTokens(transaction, messenger);\n\n log('Transaction changed', { transaction, tokens });\n\n updateTransactionData(transaction.id, (data) => {\n data.tokens = tokens;\n });\n}\n\n/**\n * Handle a finalized transaction by removing its associated data.\n *\n * @param transaction - Transaction metadata.\n * @param removeTransactionData - Callback to remove transaction data.\n */\nfunction onTransactionFinalized(\n transaction: TransactionMeta,\n removeTransactionData: (transactionId: string) => void,\n): void {\n log('Transaction finalized', { transaction });\n removeTransactionData(transaction.id);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transaction.cjs","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n TransactionStatus,\n TransactionType,\n} from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPayControllerMessenger,\n UpdateTransactionDataCallback,\n} from '../types';\nimport { parseRequiredTokens } from './required-tokens';\n\nconst log = createModuleLogger(projectLogger, 'transaction');\n\nexport const FINALIZED_STATUSES = [\n TransactionStatus.confirmed,\n TransactionStatus.dropped,\n TransactionStatus.failed,\n];\n\n/**\n * Retrieve transaction metadata by ID.\n *\n * @param transactionId - ID of the transaction to retrieve.\n * @param messenger - Controller messenger.\n * @returns The transaction metadata or undefined if not found.\n */\nexport function getTransaction(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): TransactionMeta | undefined {\n const transactionControllerState = messenger.call(\n 'TransactionController:getState',\n );\n\n return transactionControllerState.transactions.find(\n (tx) => tx.id === transactionId,\n );\n}\n\n/**\n * Poll for transaction changes and update the transaction data accordingly.\n *\n * @param messenger - Controller messenger.\n * @param updateTransactionData - Callback to update transaction data.\n * @param removeTransactionData - Callback to remove transaction data.\n */\nexport function pollTransactionChanges(\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n removeTransactionData: (transactionId: string) => void,\n): void {\n messenger.subscribe(\n 'TransactionController:stateChange',\n (\n transactions: TransactionMeta[],\n previousTransactions: TransactionMeta[] | undefined,\n ) => {\n const newTransactions = transactions.filter(\n (tx) => !previousTransactions?.find((prevTx) => prevTx.id === tx.id),\n );\n\n const updatedTransactions = transactions.filter((tx) => {\n const previousTransaction = previousTransactions?.find(\n (prevTx) => prevTx.id === tx.id,\n );\n\n return (\n previousTransaction &&\n previousTransaction?.txParams.data !== tx.txParams.data\n );\n });\n\n const finalizedTransactions = transactions.filter((tx) => {\n const previousTransaction = previousTransactions?.find(\n (prevTx) => prevTx.id === tx.id,\n );\n\n return (\n previousTransaction &&\n !FINALIZED_STATUSES.includes(previousTransaction.status) &&\n FINALIZED_STATUSES.includes(tx.status)\n );\n });\n\n const deletedTransactions = (previousTransactions ?? []).filter(\n (prevTx) => !transactions.find((tx) => tx.id === prevTx.id),\n );\n\n [...finalizedTransactions, ...deletedTransactions].forEach((tx) =>\n onTransactionFinalized(tx, removeTransactionData),\n );\n\n [...newTransactions, ...updatedTransactions].forEach((tx) =>\n onTransactionChange(tx, messenger, updateTransactionData),\n );\n },\n (state) => state.transactions,\n );\n}\n\n/**\n * Wait for a transaction to be confirmed or fail.\n *\n * @param transactionId - ID of the transaction to wait for.\n * @param messenger - Controller messenger.\n * @returns A promise that resolves when the transaction is confirmed or rejects if it fails.\n */\nexport function waitForTransactionConfirmed(\n transactionId: string,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const isConfirmed = (tx?: TransactionMeta, fn?: () => void): boolean => {\n log('Checking transaction status', tx?.status, tx?.type);\n\n if (tx?.status === TransactionStatus.confirmed) {\n fn?.();\n resolve();\n return true;\n }\n\n if (\n [TransactionStatus.dropped, TransactionStatus.failed].includes(\n tx?.status as TransactionStatus,\n )\n ) {\n fn?.();\n reject(\n new Error(`Transaction failed - ${tx?.type} - ${tx?.error?.message}`),\n );\n return true;\n }\n\n return false;\n };\n\n const initialState = messenger.call('TransactionController:getState');\n\n const initialTx = initialState.transactions.find(\n (singleTransaction) => singleTransaction.id === transactionId,\n );\n\n if (isConfirmed(initialTx)) {\n return;\n }\n\n const handler = (tx?: TransactionMeta): void => {\n const unsubscribe = (): void =>\n messenger.unsubscribe('TransactionController:stateChange', handler);\n\n isConfirmed(tx, unsubscribe);\n };\n\n messenger.subscribe('TransactionController:stateChange', handler, (state) =>\n state.transactions.find((tx) => tx.id === transactionId),\n );\n });\n}\n\n/**\n * Update a transaction by applying a function to its draft.\n *\n * @param request - Request object.\n * @param request.transactionId - ID of the transaction to update.\n * @param request.messenger - Controller messenger.\n * @param request.note - Note describing the update.\n * @param fn - Function that applies updates to the transaction draft.\n */\nexport function updateTransaction(\n {\n transactionId,\n messenger,\n note,\n }: {\n transactionId: string;\n messenger: TransactionPayControllerMessenger;\n note: string;\n },\n fn: (draft: TransactionMeta) => void,\n): void {\n const transaction = getTransaction(transactionId, messenger as never);\n\n if (!transaction) {\n throw new Error(`Transaction not found: ${transactionId}`);\n }\n\n const newTransaction = cloneDeep(transaction);\n\n fn(newTransaction);\n\n messenger.call(\n 'TransactionController:updateTransaction',\n newTransaction,\n note,\n );\n}\n\n/**\n * Collect all new transactions until `end` is called.\n *\n * @param chainId - The chain ID to filter transactions by.\n * @param from - The address to filter transactions by.\n * @param messenger - The controller messenger.\n * @param onTransaction - Callback called with each matching transaction ID.\n * @returns An object with an `end` method to stop collecting transactions.\n */\nexport function collectTransactionIds(\n chainId: Hex,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n onTransaction: (transactionId: string) => void,\n): { end: () => void } {\n const listener = (tx: TransactionMeta): void => {\n if (\n tx.chainId !== chainId ||\n tx.txParams.from.toLowerCase() !== from.toLowerCase()\n ) {\n return;\n }\n\n onTransaction(tx.id);\n };\n\n messenger.subscribe(\n 'TransactionController:unapprovedTransactionAdded',\n listener,\n );\n\n const end = (): void => {\n messenger.unsubscribe(\n 'TransactionController:unapprovedTransactionAdded',\n listener,\n );\n };\n\n return { end };\n}\n\n/**\n * Check whether a transaction is a Predict withdrawal.\n *\n * Returns `true` when the transaction's own type is `predictWithdraw`, or\n * when any of its nested transactions has that type.\n *\n * @param transaction - Transaction metadata.\n * @returns `true` when the transaction is a Predict withdrawal.\n */\nexport function isPredictWithdrawTransaction(\n transaction: TransactionMeta,\n): boolean {\n return (\n transaction.type === TransactionType.predictWithdraw ||\n (transaction.nestedTransactions?.some(\n (nt) => nt.type === TransactionType.predictWithdraw,\n ) ??\n false)\n );\n}\n\n/**\n * Handle a transaction change by updating its associated data.\n *\n * @param transaction - Transaction metadata.\n * @param messenger - Controller messenger.\n * @param updateTransactionData - Callback to update transaction data.\n */\nfunction onTransactionChange(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n): void {\n const tokens = parseRequiredTokens(transaction, messenger);\n\n log('Transaction changed', { transaction, tokens });\n\n updateTransactionData(transaction.id, (data) => {\n data.tokens = tokens;\n });\n}\n\n/**\n * Handle a finalized transaction by removing its associated data.\n *\n * @param transaction - Transaction metadata.\n * @param removeTransactionData - Callback to remove transaction data.\n */\nfunction onTransactionFinalized(\n transaction: TransactionMeta,\n removeTransactionData: (transactionId: string) => void,\n): void {\n log('Transaction finalized', { transaction });\n removeTransactionData(transaction.id);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.cts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAElB,yCAAyC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"transaction.d.cts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAElB,yCAAyC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,iCAAiC,EACjC,6BAA6B,EAC9B,qBAAiB;AAKlB,eAAO,MAAM,kBAAkB,qBAI9B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,iCAAiC,GAC3C,eAAe,GAAG,SAAS,CAQ7B;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,qBAAqB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GACrD,IAAI,CAgDN;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,iCAAiC,GAC3C,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,EACE,aAAa,EACb,SAAS,EACT,IAAI,GACL,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,iCAAiC,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd,EACD,EAAE,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GACnC,IAAI,CAgBN;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,iCAAiC,EAC5C,aAAa,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GAC7C;IAAE,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,CAyBrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAQT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.mts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAElB,yCAAyC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"transaction.d.mts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAElB,yCAAyC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,iCAAiC,EACjC,6BAA6B,EAC9B,qBAAiB;AAKlB,eAAO,MAAM,kBAAkB,qBAI9B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,iCAAiC,GAC3C,eAAe,GAAG,SAAS,CAQ7B;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,qBAAqB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GACrD,IAAI,CAgDN;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,iCAAiC,GAC3C,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,EACE,aAAa,EACb,SAAS,EACT,IAAI,GACL,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,iCAAiC,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd,EACD,EAAE,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GACnC,IAAI,CAgBN;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,iCAAiC,EAC5C,aAAa,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GAC7C;IAAE,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,CAyBrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,eAAe,GAC3B,OAAO,CAQT"}
|