@metamask/transaction-pay-controller 24.0.3 → 25.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -1
- package/dist/constants.cjs +8 -2
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +7 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +7 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +8 -2
- package/dist/constants.mjs.map +1 -1
- package/dist/helpers/QuoteRefresher.cjs +2 -1
- package/dist/helpers/QuoteRefresher.cjs.map +1 -1
- package/dist/helpers/QuoteRefresher.d.cts.map +1 -1
- package/dist/helpers/QuoteRefresher.d.mts.map +1 -1
- package/dist/helpers/QuoteRefresher.mjs +2 -1
- package/dist/helpers/QuoteRefresher.mjs.map +1 -1
- package/dist/helpers/TransactionPayPublishHook.cjs +5 -3
- 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 +5 -3
- package/dist/helpers/TransactionPayPublishHook.mjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.cjs +6 -6
- package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.cts.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.mts.map +1 -1
- package/dist/strategy/relay/relay-quotes.mjs +8 -8
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/server/perps.cjs +18 -1
- package/dist/strategy/server/perps.cjs.map +1 -1
- package/dist/strategy/server/perps.d.cts +5 -1
- package/dist/strategy/server/perps.d.cts.map +1 -1
- package/dist/strategy/server/perps.d.mts +5 -1
- package/dist/strategy/server/perps.d.mts.map +1 -1
- package/dist/strategy/server/perps.mjs +18 -1
- package/dist/strategy/server/perps.mjs.map +1 -1
- package/dist/strategy/server/server-quotes.cjs +68 -19
- package/dist/strategy/server/server-quotes.cjs.map +1 -1
- package/dist/strategy/server/server-quotes.d.cts.map +1 -1
- package/dist/strategy/server/server-quotes.d.mts.map +1 -1
- package/dist/strategy/server/server-quotes.mjs +69 -20
- package/dist/strategy/server/server-quotes.mjs.map +1 -1
- package/dist/strategy/server/server-submit.cjs +389 -61
- package/dist/strategy/server/server-submit.cjs.map +1 -1
- package/dist/strategy/server/server-submit.d.cts.map +1 -1
- package/dist/strategy/server/server-submit.d.mts.map +1 -1
- package/dist/strategy/server/server-submit.mjs +390 -62
- package/dist/strategy/server/server-submit.mjs.map +1 -1
- package/dist/strategy/server/types.cjs.map +1 -1
- package/dist/strategy/server/types.d.cts +20 -4
- package/dist/strategy/server/types.d.cts.map +1 -1
- package/dist/strategy/server/types.d.mts +20 -4
- package/dist/strategy/server/types.d.mts.map +1 -1
- package/dist/strategy/server/types.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +24 -1
- package/dist/utils/feature-flags.cjs.map +1 -1
- package/dist/utils/feature-flags.d.cts +9 -0
- package/dist/utils/feature-flags.d.cts.map +1 -1
- package/dist/utils/feature-flags.d.mts +9 -0
- package/dist/utils/feature-flags.d.mts.map +1 -1
- package/dist/utils/feature-flags.mjs +23 -1
- package/dist/utils/feature-flags.mjs.map +1 -1
- package/dist/utils/no-op-quote.cjs +55 -0
- package/dist/utils/no-op-quote.cjs.map +1 -0
- package/dist/utils/no-op-quote.d.cts +18 -0
- package/dist/utils/no-op-quote.d.cts.map +1 -0
- package/dist/utils/no-op-quote.d.mts +18 -0
- package/dist/utils/no-op-quote.d.mts.map +1 -0
- package/dist/utils/no-op-quote.mjs +51 -0
- package/dist/utils/no-op-quote.mjs.map +1 -0
- package/dist/utils/quotes.cjs +29 -6
- 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 +29 -6
- package/dist/utils/quotes.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 +3 -3
- package/dist/utils/token.mjs.map +1 -1
- package/dist/utils/transaction.cjs +4 -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 +4 -1
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.mjs","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionStatus } from '@metamask/transaction-controller';\nimport type { BatchTransaction } from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex, Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { PaymentOverride, TransactionPayStrategy } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n QuoteRequest,\n TransactionData,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n TransactionPayRequiredToken,\n TransactionPaySourceAmount,\n TransactionPayTotals,\n TransactionPaymentToken,\n UpdateTransactionDataCallback,\n} from '../types';\nimport { accountSupports7702 } from './7702';\nimport {\n checkStrategyQuoteSupport,\n checkStrategySupport,\n getStrategiesByName,\n getStrategyByName,\n} from './strategy';\nimport {\n computeTokenAmounts,\n getLiveTokenBalance,\n getTokenFiatRate,\n} from './token';\nimport { calculateTotals } from './totals';\nimport { getTransaction, updateTransaction } from './transaction';\n\nconst DEFAULT_REFRESH_INTERVAL = 30 * 1000; // 30 Seconds\n\nconst log = createModuleLogger(projectLogger, 'quotes');\n\nconst inFlightQuoteRequests = new Map<string, AbortController>();\n\nexport type UpdateQuotesRequest = {\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[];\n messenger: TransactionPayControllerMessenger;\n transactionData: TransactionData | undefined;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n};\n\n/**\n * Update the quotes for a specific transaction.\n *\n * Calls for the same `transactionId` are serialised: a fresh call aborts any\n * previous in-flight call so a slower stale response cannot overwrite a newer\n * one in state.\n *\n * @param request - Request parameters.\n * @returns Boolean indicating if the quotes were updated. Returns `false` when\n * the call was aborted by a subsequent call for the same transaction.\n */\nexport async function updateQuotes(\n request: UpdateQuotesRequest,\n): Promise<boolean> {\n const {\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n } = request;\n\n const transaction = getTransaction(transactionId, messenger);\n\n if (!transaction || !transactionData) {\n throw new Error('Transaction not found');\n }\n\n if (transaction?.status !== TransactionStatus.unapproved) {\n return false;\n }\n\n log('Updating quotes', { transactionId });\n\n const {\n accountOverride,\n isMaxAmount,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken: originalPaymentToken,\n fiatPayment,\n refundTo,\n sourceAmounts,\n tokens,\n } = transactionData;\n\n const from = accountOverride ?? (transaction.txParams.from as Hex);\n\n const controller = abortPreviousAndCreateController(transactionId);\n const { signal } = controller;\n\n updateTransactionData(transactionId, (data) => {\n data.isLoading = true;\n });\n\n try {\n const paymentToken = await refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken: originalPaymentToken,\n signal,\n transactionId,\n updateTransactionData,\n });\n\n if (signal.aborted) {\n log('Quote request aborted before building requests', { transactionId });\n return false;\n }\n\n const requests = buildQuoteRequests({\n from,\n isMaxAmount: isMaxAmount ?? false,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n });\n\n const supports7702 = accountSupports7702(messenger, from);\n\n const { batchTransactions, quotes } = await getQuotes(\n transaction,\n from,\n requests,\n supports7702,\n getStrategies,\n messenger,\n fiatPayment?.selectedPaymentMethodId,\n signal,\n );\n\n if (signal.aborted) {\n log('Quote request aborted before persisting results', { transactionId });\n return false;\n }\n\n const totals = calculateTotals({\n fiatPaymentAmount: fiatPayment?.amountFiat,\n isMaxAmount,\n messenger,\n quotes: quotes as TransactionPayQuote<unknown>[],\n tokens,\n transaction,\n });\n\n log('Calculated totals', { transactionId, totals });\n\n syncTransaction({\n batchTransactions,\n selectedFiatPayment: fiatPayment?.selectedPaymentMethodId,\n hasQuotes: quotes.length > 0,\n isPostQuote,\n messenger: messenger as never,\n paymentToken,\n totals,\n transactionId,\n });\n\n updateTransactionData(transactionId, (data) => {\n data.quotes = quotes as never;\n data.quotesLastUpdated = Date.now();\n data.totals = totals;\n });\n } catch (error) {\n if (signal.aborted) {\n log('Quote request aborted', { transactionId, reason: signal.reason });\n return false;\n }\n throw error;\n } finally {\n if (!signal.aborted) {\n updateTransactionData(transactionId, (data) => {\n data.isLoading = false;\n });\n }\n clearControllerIfCurrent(transactionId, controller);\n }\n\n return true;\n}\n\n/**\n * Sync batch transactions to the transaction meta.\n *\n * @param request - Request object.\n * @param request.batchTransactions - Batch transactions to sync.\n * @param request.hasQuotes - Whether MM Pay produced any quotes for this transaction.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.messenger - Messenger instance.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.selectedFiatPayment - Selected fiat payment method ID.\n * @param request.totals - Calculated totals.\n * @param request.transactionId - ID of the transaction to sync.\n */\nfunction syncTransaction({\n batchTransactions,\n hasQuotes,\n isPostQuote,\n messenger,\n paymentToken,\n selectedFiatPayment,\n totals,\n transactionId,\n}: {\n batchTransactions: BatchTransaction[];\n selectedFiatPayment?: string;\n hasQuotes: boolean;\n isPostQuote?: boolean;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n totals: TransactionPayTotals;\n transactionId: string;\n}): void {\n if (!paymentToken && !selectedFiatPayment) {\n return;\n }\n\n updateTransaction(\n {\n transactionId,\n messenger: messenger as never,\n note: 'Update transaction pay data',\n },\n (tx: TransactionMeta) => {\n tx.batchTransactions = batchTransactions;\n tx.batchTransactionsOptions = {};\n\n // When MM Pay has produced quotes, it owns submission of this transaction\n // via its strategy publish hook, so the parent must be marked externally\n // signed to skip the local `KeyringController:signTransaction` call.\n // When there are no quotes (e.g. user selected the target token as the\n // payment token in a Predict flow), the transaction falls back to normal\n // local signing, so the flag is cleared to allow that.\n // If gas is sponsored, TC owns this field — it is set based on the\n // Sentinel simulation result and must not be cleared here. Same-token\n // flows (e.g. Monad mUSD withdrawal via a Money Account) produce no\n // quotes but still need external sign because the account cannot sign\n // locally.\n if (!tx.isGasFeeSponsored) {\n tx.isExternalSign = hasQuotes;\n }\n\n tx.metamaskPay = {\n bridgeFeeFiat: totals.fees.provider.usd,\n chainId: paymentToken?.chainId,\n isPostQuote,\n networkFeeFiat: totals.fees.sourceNetwork.estimate.usd,\n targetFiat: totals.targetAmount.usd,\n tokenAddress: paymentToken?.address,\n totalFiat: totals.total.usd,\n };\n },\n );\n}\n\n/**\n * Refresh quotes for all transactions if expired.\n *\n * @param messenger - Messenger instance.\n * @param updateTransactionData - Callback to update transaction data.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n */\nexport async function refreshQuotes(\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n): Promise<void> {\n const state = messenger.call('TransactionPayController:getState');\n const transactionIds = Object.keys(state.transactionData);\n\n for (const transactionId of transactionIds) {\n const transactionData = state.transactionData[transactionId];\n const { isLoading, quotes, quotesLastUpdated } = transactionData;\n\n if (isLoading || !quotes?.length) {\n continue;\n }\n\n const strategyName = quotes[0].strategy;\n const strategy = getStrategyByName(strategyName);\n\n const refreshInterval =\n (await strategy.getRefreshInterval?.({\n chainId: quotes[0].request.sourceChainId,\n messenger,\n })) ?? DEFAULT_REFRESH_INTERVAL;\n\n const isExpired = Date.now() - (quotesLastUpdated ?? 0) > refreshInterval;\n\n if (!isExpired) {\n continue;\n }\n\n const isUpdated = await updateQuotes({\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n });\n\n if (isUpdated) {\n log('Refreshed quotes', { transactionId, strategy: strategyName });\n }\n }\n}\n\nfunction abortPreviousAndCreateController(\n transactionId: string,\n): AbortController {\n const previous = inFlightQuoteRequests.get(transactionId);\n\n if (previous && !previous.signal.aborted) {\n log('Aborting previous quote request', { transactionId });\n previous.abort(new Error('Superseded by newer quote request'));\n }\n\n const controller = new AbortController();\n inFlightQuoteRequests.set(transactionId, controller);\n return controller;\n}\n\nfunction clearControllerIfCurrent(\n transactionId: string,\n controller: AbortController,\n): void {\n if (inFlightQuoteRequests.get(transactionId) === controller) {\n inFlightQuoteRequests.delete(transactionId);\n }\n}\n\n/**\n * Build quote requests required to retrieve quotes.\n *\n * @param request - Request parameters.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction.\n * @param request.tokens - Required tokens for the transaction.\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests.\n */\nfunction buildQuoteRequests({\n from,\n isMaxAmount,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n}: {\n from: Hex;\n isMaxAmount: boolean;\n isPostQuote?: boolean;\n isHyperliquidSource?: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n paymentToken: TransactionPaymentToken | undefined;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n tokens: TransactionPayRequiredToken[];\n transactionId: string;\n}): QuoteRequest[] {\n if (!paymentToken) {\n return [];\n }\n\n if (isPostQuote) {\n return buildPostQuoteRequests({\n from,\n isMaxAmount,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n destinationToken: paymentToken,\n refundTo,\n sourceAmounts,\n transactionId,\n });\n }\n\n // Standard flow: source = paymentToken, target = required tokens\n const requests = (sourceAmounts ?? []).map((sourceAmount) => {\n const token = tokens.find(\n (singleToken) => singleToken.address === sourceAmount.targetTokenAddress,\n ) as TransactionPayRequiredToken;\n\n return {\n from,\n isMaxAmount,\n paymentOverride,\n sourceBalanceRaw: paymentToken.balanceRaw,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n sourceChainId: paymentToken.chainId,\n sourceTokenAddress: paymentToken.address,\n targetAmountMinimum: token.allowUnderMinimum ? '0' : token.amountRaw,\n targetChainId: token.chainId,\n targetTokenAddress: token.address,\n };\n });\n\n if (!requests.length) {\n log('No quote requests', { transactionId });\n }\n\n return requests;\n}\n\n/**\n * Build quote requests for post-quote flows.\n * In this flow, the source is the transaction's required token,\n * and the target is the user's selected destination token (paymentToken).\n *\n * @param request - Request parameters.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.destinationToken - Destination token (paymentToken in post-quote mode).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction (includes source token info).\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests for post-quote flow.\n */\nfunction buildPostQuoteRequests({\n from,\n isMaxAmount,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n destinationToken,\n refundTo,\n sourceAmounts,\n transactionId,\n}: {\n from: Hex;\n isMaxAmount: boolean;\n isHyperliquidSource?: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n destinationToken: TransactionPaymentToken;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n transactionId: string;\n}): QuoteRequest[] {\n // Find the source amount where targetTokenAddress matches the destination token\n const sourceAmount = sourceAmounts?.find(\n (amount) =>\n amount.targetTokenAddress.toLowerCase() ===\n destinationToken.address.toLowerCase(),\n );\n\n // Same-token-same-chain cases are already filtered in source-amounts.ts\n if (\n !sourceAmount?.sourceBalanceRaw ||\n !sourceAmount.sourceChainId ||\n !sourceAmount.sourceTokenAddress\n ) {\n log('No valid source amount found for post-quote request', {\n transactionId,\n });\n return [];\n }\n\n const request: QuoteRequest = {\n from,\n isMaxAmount,\n isPostQuote: true,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n refundTo,\n sourceBalanceRaw: sourceAmount.sourceBalanceRaw,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n sourceChainId: sourceAmount.sourceChainId,\n sourceTokenAddress: sourceAmount.sourceTokenAddress,\n targetAmountMinimum: '0',\n targetChainId: destinationToken.chainId,\n targetTokenAddress: destinationToken.address,\n };\n\n log('Post-quote request built', { transactionId, request });\n\n // Currently only single token post-quote flows are supported.\n // Multiple token support would require multiple quotes for each required token.\n return [request];\n}\n\nasync function refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken,\n signal,\n transactionId,\n updateTransactionData,\n}: {\n from: Hex;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n signal: AbortSignal;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n}): Promise<TransactionPaymentToken | undefined> {\n if (!paymentToken) {\n return undefined;\n }\n\n try {\n const fiatRates = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!fiatRates) {\n return paymentToken;\n }\n\n const liveBalance = await getLiveTokenBalance(\n messenger,\n from,\n paymentToken.chainId,\n paymentToken.address,\n );\n\n if (signal.aborted) {\n log('Payment token balance refresh aborted', { transactionId });\n return paymentToken;\n }\n\n const {\n raw: balanceRaw,\n human: balanceHuman,\n usd: balanceUsd,\n fiat: balanceFiat,\n } = computeTokenAmounts(liveBalance, paymentToken.decimals, fiatRates);\n\n const updatedToken = {\n ...paymentToken,\n balanceFiat,\n balanceHuman,\n balanceRaw,\n balanceUsd,\n };\n\n updateTransactionData(transactionId, (data) => {\n data.paymentToken = updatedToken;\n });\n\n log('Refreshed payment token balance', { transactionId, balanceRaw });\n\n return updatedToken;\n } catch (error) {\n log('Failed to refresh payment token balance', { transactionId, error });\n return paymentToken;\n }\n}\n\n/**\n * Retrieve quotes for a transaction.\n *\n * @param transaction - Transaction metadata.\n * @param from - Resolved wallet address (`accountOverride ?? txParams.from`).\n * @param requests - Quote requests.\n * @param isAccountEIP7702Compatible - Whether the account supports EIP-7702.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n * @param messenger - Controller messenger.\n * @param fiatPaymentMethod - Selected fiat payment method ID, if applicable.\n * @param signal - Signal that aborts when the quote request is superseded.\n * @returns An object containing batch transactions and quotes.\n */\nasync function getQuotes(\n transaction: TransactionMeta,\n from: Hex,\n requests: QuoteRequest[],\n isAccountEIP7702Compatible: boolean,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n messenger: TransactionPayControllerMessenger,\n fiatPaymentMethod?: string,\n signal?: AbortSignal,\n): Promise<{\n batchTransactions: BatchTransaction[];\n quotes: TransactionPayQuote<Json>[];\n}> {\n const { id: transactionId } = transaction;\n const strategies = getStrategiesByName(\n getStrategies(transaction),\n (strategyName) => {\n log('Skipping unknown strategy', {\n strategy: strategyName,\n transactionId,\n });\n },\n );\n\n if (!requests?.length && !fiatPaymentMethod) {\n return {\n batchTransactions: [],\n quotes: [],\n };\n }\n\n const request = {\n accountSupports7702: isAccountEIP7702Compatible,\n fiatPaymentMethod,\n from,\n messenger,\n requests,\n signal,\n transaction,\n };\n\n for (const { name, strategy } of strategies) {\n try {\n const support = await checkStrategySupport(strategy, request);\n\n if (!support) {\n log('Strategy does not support request', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n const quotes = (await strategy.getQuotes(\n request,\n )) as TransactionPayQuote<Json>[];\n\n if (!quotes.length) {\n log('Strategy returned no quotes', { strategy: name, transactionId });\n continue;\n }\n\n const quoteSupport = await checkStrategyQuoteSupport(strategy, {\n messenger,\n quotes,\n signal,\n transaction,\n });\n\n if (!quoteSupport) {\n log('Strategy does not support quotes', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n log('Updated', { transactionId, quotes });\n\n const batchTransactions = strategy.getBatchTransactions\n ? await strategy.getBatchTransactions({\n messenger,\n quotes,\n signal,\n })\n : [];\n\n log('Batch transactions', { transactionId, batchTransactions });\n\n return {\n batchTransactions,\n quotes,\n };\n } catch (error) {\n if (signal?.aborted) {\n throw error;\n }\n\n log('Strategy failed, trying next', {\n error,\n strategy: name,\n transactionId,\n });\n continue;\n }\n }\n\n log('No quotes available', { transactionId });\n\n return {\n batchTransactions: [],\n quotes: [],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"quotes.mjs","sourceRoot":"","sources":["../../src/utils/quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { TransactionStatus } from '@metamask/transaction-controller';\nimport type { BatchTransaction } from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex, Json } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { PaymentOverride, TransactionPayStrategy } from '../constants';\nimport { projectLogger } from '../logger';\nimport type {\n QuoteRequest,\n TransactionData,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n TransactionPayRequiredToken,\n TransactionPaySourceAmount,\n TransactionPayTotals,\n TransactionPaymentToken,\n UpdateTransactionDataCallback,\n} from '../types';\nimport { accountSupports7702 } from './7702';\nimport { buildNoOpQuote } from './no-op-quote';\nimport {\n checkStrategyQuoteSupport,\n checkStrategySupport,\n getStrategiesByName,\n getStrategyByName,\n} from './strategy';\nimport {\n computeTokenAmounts,\n getLiveTokenBalance,\n getTokenFiatRate,\n} from './token';\nimport { calculateTotals } from './totals';\nimport { getTransaction, updateTransaction } from './transaction';\n\nconst DEFAULT_REFRESH_INTERVAL = 30 * 1000; // 30 Seconds\n\nconst log = createModuleLogger(projectLogger, 'quotes');\n\nconst inFlightQuoteRequests = new Map<string, AbortController>();\n\nexport type UpdateQuotesRequest = {\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[];\n messenger: TransactionPayControllerMessenger;\n transactionData: TransactionData | undefined;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n};\n\n/**\n * Update the quotes for a specific transaction.\n *\n * Calls for the same `transactionId` are serialised: a fresh call aborts any\n * previous in-flight call so a slower stale response cannot overwrite a newer\n * one in state.\n *\n * @param request - Request parameters.\n * @returns Boolean indicating if the quotes were updated. Returns `false` when\n * the call was aborted by a subsequent call for the same transaction.\n */\nexport async function updateQuotes(\n request: UpdateQuotesRequest,\n): Promise<boolean> {\n const {\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n } = request;\n\n const transaction = getTransaction(transactionId, messenger);\n\n if (!transaction || !transactionData) {\n throw new Error('Transaction not found');\n }\n\n if (transaction?.status !== TransactionStatus.unapproved) {\n return false;\n }\n\n log('Updating quotes', { transactionId });\n\n const {\n accountOverride,\n isMaxAmount,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n isQuoteRequired,\n paymentOverride,\n paymentToken: originalPaymentToken,\n fiatPayment,\n refundTo,\n sourceAmounts,\n tokens,\n } = transactionData;\n\n const from = accountOverride ?? (transaction.txParams.from as Hex);\n\n const controller = abortPreviousAndCreateController(transactionId);\n const { signal } = controller;\n\n updateTransactionData(transactionId, (data) => {\n data.isLoading = true;\n });\n\n try {\n const paymentToken = await refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken: originalPaymentToken,\n signal,\n transactionId,\n updateTransactionData,\n });\n\n if (signal.aborted) {\n log('Quote request aborted before building requests', { transactionId });\n return false;\n }\n\n const requests = buildQuoteRequests({\n from,\n isMaxAmount: isMaxAmount ?? false,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n });\n\n const supports7702 = accountSupports7702(messenger, from);\n\n const { batchTransactions, quotes } = await getQuotes(\n transaction,\n from,\n requests,\n paymentToken,\n isQuoteRequired ?? false,\n supports7702,\n getStrategies,\n messenger,\n fiatPayment?.selectedPaymentMethodId,\n signal,\n );\n\n if (signal.aborted) {\n log('Quote request aborted before persisting results', { transactionId });\n return false;\n }\n\n // No-op quotes mark direct routes. They have no fees or amounts and the\n // transaction is signed and submitted locally, so totals and transaction\n // sync must treat them as \"no quotes\".\n const executableQuotes = quotes.filter(\n (quote) => quote.strategy !== TransactionPayStrategy.None,\n );\n\n const totals = calculateTotals({\n fiatPaymentAmount: fiatPayment?.amountFiat,\n isMaxAmount,\n messenger,\n quotes: executableQuotes as TransactionPayQuote<unknown>[],\n tokens,\n transaction,\n });\n\n log('Calculated totals', { transactionId, totals });\n\n syncTransaction({\n batchTransactions,\n selectedFiatPayment: fiatPayment?.selectedPaymentMethodId,\n hasQuotes: executableQuotes.length > 0,\n isPostQuote,\n messenger: messenger as never,\n paymentToken,\n totals,\n transactionId,\n });\n\n updateTransactionData(transactionId, (data) => {\n data.quotes = quotes as never;\n data.quotesLastUpdated = Date.now();\n data.totals = totals;\n });\n } catch (error) {\n if (signal.aborted) {\n log('Quote request aborted', { transactionId, reason: signal.reason });\n return false;\n }\n throw error;\n } finally {\n if (!signal.aborted) {\n updateTransactionData(transactionId, (data) => {\n data.isLoading = false;\n });\n }\n clearControllerIfCurrent(transactionId, controller);\n }\n\n return true;\n}\n\n/**\n * Sync batch transactions to the transaction meta.\n *\n * @param request - Request object.\n * @param request.batchTransactions - Batch transactions to sync.\n * @param request.hasQuotes - Whether MM Pay produced any quotes for this transaction.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.messenger - Messenger instance.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.selectedFiatPayment - Selected fiat payment method ID.\n * @param request.totals - Calculated totals.\n * @param request.transactionId - ID of the transaction to sync.\n */\nfunction syncTransaction({\n batchTransactions,\n hasQuotes,\n isPostQuote,\n messenger,\n paymentToken,\n selectedFiatPayment,\n totals,\n transactionId,\n}: {\n batchTransactions: BatchTransaction[];\n selectedFiatPayment?: string;\n hasQuotes: boolean;\n isPostQuote?: boolean;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n totals: TransactionPayTotals;\n transactionId: string;\n}): void {\n if (!paymentToken && !selectedFiatPayment) {\n return;\n }\n\n updateTransaction(\n {\n transactionId,\n messenger: messenger as never,\n note: 'Update transaction pay data',\n },\n (tx: TransactionMeta) => {\n tx.batchTransactions = batchTransactions;\n tx.batchTransactionsOptions = {};\n\n // When MM Pay has produced quotes, it owns submission of this transaction\n // via its strategy publish hook, so the parent must be marked externally\n // signed to skip the local `KeyringController:signTransaction` call.\n // When there are no quotes (e.g. user selected the target token as the\n // payment token in a Predict flow), the transaction falls back to normal\n // local signing, so the flag is cleared to allow that.\n // If gas is sponsored, TC owns this field — it is set based on the\n // Sentinel simulation result and must not be cleared here. Same-token\n // flows (e.g. Monad mUSD withdrawal via a Money Account) produce no\n // quotes but still need external sign because the account cannot sign\n // locally.\n if (!tx.isGasFeeSponsored) {\n tx.isExternalSign = hasQuotes;\n }\n\n tx.metamaskPay = {\n bridgeFeeFiat: totals.fees.provider.usd,\n chainId: paymentToken?.chainId,\n isPostQuote,\n networkFeeFiat: totals.fees.sourceNetwork.estimate.usd,\n targetFiat: totals.targetAmount.usd,\n tokenAddress: paymentToken?.address,\n totalFiat: totals.total.usd,\n };\n },\n );\n}\n\n/**\n * Refresh quotes for all transactions if expired.\n *\n * @param messenger - Messenger instance.\n * @param updateTransactionData - Callback to update transaction data.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n */\nexport async function refreshQuotes(\n messenger: TransactionPayControllerMessenger,\n updateTransactionData: UpdateTransactionDataCallback,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n): Promise<void> {\n const state = messenger.call('TransactionPayController:getState');\n const transactionIds = Object.keys(state.transactionData);\n\n for (const transactionId of transactionIds) {\n const transactionData = state.transactionData[transactionId];\n const { isLoading, quotes, quotesLastUpdated } = transactionData;\n\n if (isLoading || !quotes?.length) {\n continue;\n }\n\n // No-op quotes mark direct routes and have nothing to refresh. They are\n // regenerated whenever the transaction data changes.\n if (\n quotes.every((quote) => quote.strategy === TransactionPayStrategy.None)\n ) {\n continue;\n }\n\n const strategyName = quotes[0].strategy;\n const strategy = getStrategyByName(strategyName);\n\n const refreshInterval =\n (await strategy.getRefreshInterval?.({\n chainId: quotes[0].request.sourceChainId,\n messenger,\n })) ?? DEFAULT_REFRESH_INTERVAL;\n\n const isExpired = Date.now() - (quotesLastUpdated ?? 0) > refreshInterval;\n\n if (!isExpired) {\n continue;\n }\n\n const isUpdated = await updateQuotes({\n getStrategies,\n messenger,\n transactionData,\n transactionId,\n updateTransactionData,\n });\n\n if (isUpdated) {\n log('Refreshed quotes', { transactionId, strategy: strategyName });\n }\n }\n}\n\nfunction abortPreviousAndCreateController(\n transactionId: string,\n): AbortController {\n const previous = inFlightQuoteRequests.get(transactionId);\n\n if (previous && !previous.signal.aborted) {\n log('Aborting previous quote request', { transactionId });\n previous.abort(new Error('Superseded by newer quote request'));\n }\n\n const controller = new AbortController();\n inFlightQuoteRequests.set(transactionId, controller);\n return controller;\n}\n\nfunction clearControllerIfCurrent(\n transactionId: string,\n controller: AbortController,\n): void {\n if (inFlightQuoteRequests.get(transactionId) === controller) {\n inFlightQuoteRequests.delete(transactionId);\n }\n}\n\n/**\n * Build quote requests required to retrieve quotes.\n *\n * @param request - Request parameters.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.isPostQuote - Whether this is a post-quote flow.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.paymentToken - Payment token (source for standard flows, destination for post-quote).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction.\n * @param request.tokens - Required tokens for the transaction.\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests.\n */\nfunction buildQuoteRequests({\n from,\n isMaxAmount,\n isPostQuote,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n paymentToken,\n refundTo,\n sourceAmounts,\n tokens,\n transactionId,\n}: {\n from: Hex;\n isMaxAmount: boolean;\n isPostQuote?: boolean;\n isHyperliquidSource?: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n paymentToken: TransactionPaymentToken | undefined;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n tokens: TransactionPayRequiredToken[];\n transactionId: string;\n}): QuoteRequest[] {\n if (!paymentToken) {\n return [];\n }\n\n if (isPostQuote) {\n return buildPostQuoteRequests({\n from,\n isMaxAmount,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n destinationToken: paymentToken,\n refundTo,\n sourceAmounts,\n transactionId,\n });\n }\n\n // Standard flow: source = paymentToken, target = required tokens\n const requests = (sourceAmounts ?? []).map((sourceAmount) => {\n const token = tokens.find(\n (singleToken) => singleToken.address === sourceAmount.targetTokenAddress,\n ) as TransactionPayRequiredToken;\n\n return {\n from,\n isMaxAmount,\n paymentOverride,\n sourceBalanceRaw: paymentToken.balanceRaw,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n sourceChainId: paymentToken.chainId,\n sourceTokenAddress: paymentToken.address,\n targetAmountMinimum: token.allowUnderMinimum ? '0' : token.amountRaw,\n targetChainId: token.chainId,\n targetTokenAddress: token.address,\n };\n });\n\n if (!requests.length) {\n log('No quote requests', { transactionId });\n }\n\n return requests;\n}\n\n/**\n * Build quote requests for post-quote flows.\n * In this flow, the source is the transaction's required token,\n * and the target is the user's selected destination token (paymentToken).\n *\n * @param request - Request parameters.\n * @param request.from - Address from which the transaction is sent.\n * @param request.isMaxAmount - Whether the transaction is a maximum amount transaction.\n * @param request.isHyperliquidSource - Whether the source of funds is HyperLiquid.\n * @param request.isPolymarketDepositWallet - Whether the source of funds is a Polymarket deposit wallet.\n * @param request.paymentOverride - Optional payment override type for the transaction.\n * @param request.destinationToken - Destination token (paymentToken in post-quote mode).\n * @param request.refundTo - Optional address to receive refunds if the Relay transaction fails.\n * @param request.sourceAmounts - Source amounts for the transaction (includes source token info).\n * @param request.transactionId - ID of the transaction.\n * @returns Array of quote requests for post-quote flow.\n */\nfunction buildPostQuoteRequests({\n from,\n isMaxAmount,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n destinationToken,\n refundTo,\n sourceAmounts,\n transactionId,\n}: {\n from: Hex;\n isMaxAmount: boolean;\n isHyperliquidSource?: boolean;\n isPolymarketDepositWallet?: boolean;\n paymentOverride?: PaymentOverride;\n destinationToken: TransactionPaymentToken;\n refundTo?: Hex;\n sourceAmounts: TransactionPaySourceAmount[] | undefined;\n transactionId: string;\n}): QuoteRequest[] {\n // Find the source amount where targetTokenAddress matches the destination token\n const sourceAmount = sourceAmounts?.find(\n (amount) =>\n amount.targetTokenAddress.toLowerCase() ===\n destinationToken.address.toLowerCase(),\n );\n\n // Same-token-same-chain cases are already filtered in source-amounts.ts\n if (\n !sourceAmount?.sourceBalanceRaw ||\n !sourceAmount.sourceChainId ||\n !sourceAmount.sourceTokenAddress\n ) {\n log('No valid source amount found for post-quote request', {\n transactionId,\n });\n return [];\n }\n\n const request: QuoteRequest = {\n from,\n isMaxAmount,\n isPostQuote: true,\n isHyperliquidSource,\n isPolymarketDepositWallet,\n paymentOverride,\n refundTo,\n sourceBalanceRaw: sourceAmount.sourceBalanceRaw,\n sourceTokenAmount: sourceAmount.sourceAmountRaw,\n sourceChainId: sourceAmount.sourceChainId,\n sourceTokenAddress: sourceAmount.sourceTokenAddress,\n targetAmountMinimum: '0',\n targetChainId: destinationToken.chainId,\n targetTokenAddress: destinationToken.address,\n };\n\n log('Post-quote request built', { transactionId, request });\n\n // Currently only single token post-quote flows are supported.\n // Multiple token support would require multiple quotes for each required token.\n return [request];\n}\n\nasync function refreshPaymentTokenBalance({\n from,\n messenger,\n paymentToken,\n signal,\n transactionId,\n updateTransactionData,\n}: {\n from: Hex;\n messenger: TransactionPayControllerMessenger;\n paymentToken: TransactionPaymentToken | undefined;\n signal: AbortSignal;\n transactionId: string;\n updateTransactionData: UpdateTransactionDataCallback;\n}): Promise<TransactionPaymentToken | undefined> {\n if (!paymentToken) {\n return undefined;\n }\n\n try {\n const fiatRates = getTokenFiatRate(\n messenger,\n paymentToken.address,\n paymentToken.chainId,\n );\n\n if (!fiatRates) {\n return paymentToken;\n }\n\n const liveBalance = await getLiveTokenBalance(\n messenger,\n from,\n paymentToken.chainId,\n paymentToken.address,\n );\n\n if (signal.aborted) {\n log('Payment token balance refresh aborted', { transactionId });\n return paymentToken;\n }\n\n const {\n raw: balanceRaw,\n human: balanceHuman,\n usd: balanceUsd,\n fiat: balanceFiat,\n } = computeTokenAmounts(liveBalance, paymentToken.decimals, fiatRates);\n\n const updatedToken = {\n ...paymentToken,\n balanceFiat,\n balanceHuman,\n balanceRaw,\n balanceUsd,\n };\n\n updateTransactionData(transactionId, (data) => {\n data.paymentToken = updatedToken;\n });\n\n log('Refreshed payment token balance', { transactionId, balanceRaw });\n\n return updatedToken;\n } catch (error) {\n log('Failed to refresh payment token balance', { transactionId, error });\n return paymentToken;\n }\n}\n\n/**\n * Retrieve quotes for a transaction.\n *\n * @param transaction - Transaction metadata.\n * @param from - Resolved wallet address (`accountOverride ?? txParams.from`).\n * @param requests - Quote requests.\n * @param paymentToken - Selected payment token, if any.\n * @param isQuoteRequired - Whether a quote is always required for the transaction.\n * @param isAccountEIP7702Compatible - Whether the account supports EIP-7702.\n * @param getStrategies - Callback to get ordered strategy names for a transaction.\n * @param messenger - Controller messenger.\n * @param fiatPaymentMethod - Selected fiat payment method ID, if applicable.\n * @param signal - Signal that aborts when the quote request is superseded.\n * @returns An object containing batch transactions and quotes.\n */\nasync function getQuotes(\n transaction: TransactionMeta,\n from: Hex,\n requests: QuoteRequest[],\n paymentToken: TransactionPaymentToken | undefined,\n isQuoteRequired: boolean,\n isAccountEIP7702Compatible: boolean,\n getStrategies: (transaction: TransactionMeta) => TransactionPayStrategy[],\n messenger: TransactionPayControllerMessenger,\n fiatPaymentMethod?: string,\n signal?: AbortSignal,\n): Promise<{\n batchTransactions: BatchTransaction[];\n quotes: TransactionPayQuote<Json>[];\n}> {\n const { id: transactionId } = transaction;\n const strategies = getStrategiesByName(\n getStrategies(transaction),\n (strategyName) => {\n log('Skipping unknown strategy', {\n strategy: strategyName,\n transactionId,\n });\n },\n );\n\n if (!requests?.length && !fiatPaymentMethod) {\n // A selected payment token with no conversion requests means the route is\n // direct. Return an explicit no-op quote so clients and the publish hook\n // can distinguish \"no conversion needed\" from \"quote needed but missing\".\n // Not applicable when a quote is always required, as an empty requests\n // list then means the source amounts could not be calculated.\n const noOpQuote =\n paymentToken && !isQuoteRequired\n ? buildNoOpQuote(from, paymentToken)\n : undefined;\n\n if (noOpQuote) {\n log('Built no-op quote for direct route', { transactionId });\n }\n\n return {\n batchTransactions: [],\n quotes: noOpQuote ? [noOpQuote] : [],\n };\n }\n\n const request = {\n accountSupports7702: isAccountEIP7702Compatible,\n fiatPaymentMethod,\n from,\n messenger,\n requests,\n signal,\n transaction,\n };\n\n for (const { name, strategy } of strategies) {\n try {\n const support = await checkStrategySupport(strategy, request);\n\n if (!support) {\n log('Strategy does not support request', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n const quotes = (await strategy.getQuotes(\n request,\n )) as TransactionPayQuote<Json>[];\n\n if (!quotes.length) {\n log('Strategy returned no quotes', { strategy: name, transactionId });\n continue;\n }\n\n const quoteSupport = await checkStrategyQuoteSupport(strategy, {\n messenger,\n quotes,\n signal,\n transaction,\n });\n\n if (!quoteSupport) {\n log('Strategy does not support quotes', {\n strategy: name,\n transactionId,\n });\n continue;\n }\n\n log('Updated', { transactionId, quotes });\n\n const batchTransactions = strategy.getBatchTransactions\n ? await strategy.getBatchTransactions({\n messenger,\n quotes,\n signal,\n })\n : [];\n\n log('Batch transactions', { transactionId, batchTransactions });\n\n return {\n batchTransactions,\n quotes,\n };\n } catch (error) {\n if (signal?.aborted) {\n throw error;\n }\n\n log('Strategy failed, trying next', {\n error,\n strategy: name,\n transactionId,\n });\n continue;\n }\n }\n\n log('No quotes available', { transactionId });\n\n return {\n batchTransactions: [],\n quotes: [],\n };\n}\n"]}
|
package/dist/utils/token.cjs
CHANGED
|
@@ -136,7 +136,7 @@ function getTokenFiatRate(messenger, tokenAddress, chainId) {
|
|
|
136
136
|
if (nativeToFiatRate === null || nativeToUsdRate === null) {
|
|
137
137
|
return undefined;
|
|
138
138
|
}
|
|
139
|
-
const isStablecoin =
|
|
139
|
+
const isStablecoin = (0, feature_flags_1.getStablecoins)(messenger)[chainId]?.includes(tokenAddress.toLowerCase());
|
|
140
140
|
const usdRate = isStablecoin
|
|
141
141
|
? '1'
|
|
142
142
|
: new bignumber_js_1.BigNumber(String(tokenToNativeRate ?? 1))
|
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 { Interface } from '@ethersproject/abi';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { CaipAssetType, Hex } from '@metamask/utils';\nimport { hexToBigInt, toCaipAssetType } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n SLIP44_COIN_TYPE_BY_CHAIN,\n STABLECOINS,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\nimport {\n getAssetsUnifyStateFeature,\n isChainExcludedFromInfura,\n} from './feature-flags';\nimport { getNetworkClientId, rpcRequest } from './provider';\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(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(nativeToUsdRate))\n .toString(10);\n\n const fiatRate = new BigNumber(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(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 * Uses the Infura RPC endpoint for the chain when one is configured, falling\n * back to the chain's default endpoint. This avoids errors on custom mainnet\n * RPC endpoints that may not support pending block queries.\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 options = {\n preferInfura: !isChainExcludedFromInfura(messenger, chainId),\n };\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_getBalance',\n params: [account, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n }\n\n const calldata = new Interface(abiERC20).encodeFunctionData('balanceOf', [\n account,\n ]) as Hex;\n\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_call',\n params: [{ to: tokenAddress, data: calldata }, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n}\n\n/**\n * Build a CAIP-19 asset type identifier for an EVM token.\n *\n * For native tokens the SLIP-44 coin type is resolved automatically from\n * a built-in chain→coin-type map, falling back to 60 (ETH). Callers can\n * override via the optional third parameter.\n *\n * @param chainId - Hex chain ID (e.g. `0x1`).\n * @param tokenAddress - Token contract address, or the native token address.\n * @param slip44CoinType - Optional SLIP-44 coin type override for native tokens.\n * @returns CAIP-19 asset type string.\n */\nexport function buildCaipAssetType(\n chainId: Hex,\n tokenAddress: Hex,\n slip44CoinType?: number,\n): CaipAssetType {\n const chainReference = String(hexToBigInt(chainId));\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const coinType = slip44CoinType ?? SLIP44_COIN_TYPE_BY_CHAIN[chainId] ?? 60;\n\n return toCaipAssetType(\n 'eip155',\n chainReference,\n 'slip44',\n String(coinType),\n );\n }\n\n return toCaipAssetType('eip155', chainReference, 'erc20', tokenAddress);\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = getNetworkClientId(messenger, chainId);\n\n return messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n ).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 { Interface } from '@ethersproject/abi';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { CaipAssetType, Hex } from '@metamask/utils';\nimport { hexToBigInt, toCaipAssetType } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n SLIP44_COIN_TYPE_BY_CHAIN,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\nimport {\n getAssetsUnifyStateFeature,\n getStablecoins,\n isChainExcludedFromInfura,\n} from './feature-flags';\nimport { getNetworkClientId, rpcRequest } from './provider';\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 = getStablecoins(messenger)[chainId]?.includes(\n tokenAddress.toLowerCase() as Hex,\n );\n\n const usdRate = isStablecoin\n ? '1'\n : new BigNumber(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(nativeToUsdRate))\n .toString(10);\n\n const fiatRate = new BigNumber(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(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 * Uses the Infura RPC endpoint for the chain when one is configured, falling\n * back to the chain's default endpoint. This avoids errors on custom mainnet\n * RPC endpoints that may not support pending block queries.\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 options = {\n preferInfura: !isChainExcludedFromInfura(messenger, chainId),\n };\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_getBalance',\n params: [account, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n }\n\n const calldata = new Interface(abiERC20).encodeFunctionData('balanceOf', [\n account,\n ]) as Hex;\n\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_call',\n params: [{ to: tokenAddress, data: calldata }, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n}\n\n/**\n * Build a CAIP-19 asset type identifier for an EVM token.\n *\n * For native tokens the SLIP-44 coin type is resolved automatically from\n * a built-in chain→coin-type map, falling back to 60 (ETH). Callers can\n * override via the optional third parameter.\n *\n * @param chainId - Hex chain ID (e.g. `0x1`).\n * @param tokenAddress - Token contract address, or the native token address.\n * @param slip44CoinType - Optional SLIP-44 coin type override for native tokens.\n * @returns CAIP-19 asset type string.\n */\nexport function buildCaipAssetType(\n chainId: Hex,\n tokenAddress: Hex,\n slip44CoinType?: number,\n): CaipAssetType {\n const chainReference = String(hexToBigInt(chainId));\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const coinType = slip44CoinType ?? SLIP44_COIN_TYPE_BY_CHAIN[chainId] ?? 60;\n\n return toCaipAssetType(\n 'eip155',\n chainReference,\n 'slip44',\n String(coinType),\n );\n }\n\n return toCaipAssetType('eip155', chainReference, 'erc20', tokenAddress);\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = getNetworkClientId(messenger, chainId);\n\n return messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n ).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":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAE1D,OAAO,EAAE,SAAS,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"token.d.cts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAE1D,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAOzC,OAAO,KAAK,EAAE,SAAS,EAAE,iCAAiC,EAAE,qBAAiB;AAQ7E;;;;;;;;;;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;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,iCAAiC,EAC5C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,GAChB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,aAAa,CAiBf;AAkBD,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":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAE1D,OAAO,EAAE,SAAS,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"token.d.mts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,wBAAwB;AAE1D,OAAO,EAAE,SAAS,EAAE,qBAAqB;AAOzC,OAAO,KAAK,EAAE,SAAS,EAAE,iCAAiC,EAAE,qBAAiB;AAQ7E;;;;;;;;;;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;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,iCAAiC,EAC5C,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,GAChB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,GAAG,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,aAAa,CAiBf;AAkBD,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 { toChecksumHexAddress } from "@metamask/controller-utils";
|
|
|
3
3
|
import { abiERC20 } from "@metamask/metamask-eth-abis";
|
|
4
4
|
import { hexToBigInt, toCaipAssetType } from "@metamask/utils";
|
|
5
5
|
import { BigNumber } from "bignumber.js";
|
|
6
|
-
import { CHAIN_ID_POLYGON, NATIVE_TOKEN_ADDRESS, SLIP44_COIN_TYPE_BY_CHAIN
|
|
7
|
-
import { getAssetsUnifyStateFeature, isChainExcludedFromInfura } from "./feature-flags.mjs";
|
|
6
|
+
import { CHAIN_ID_POLYGON, NATIVE_TOKEN_ADDRESS, SLIP44_COIN_TYPE_BY_CHAIN } from "../constants.mjs";
|
|
7
|
+
import { getAssetsUnifyStateFeature, getStablecoins, isChainExcludedFromInfura } from "./feature-flags.mjs";
|
|
8
8
|
import { getNetworkClientId, rpcRequest } from "./provider.mjs";
|
|
9
9
|
/**
|
|
10
10
|
* Check if two tokens are the same (same address and chain).
|
|
@@ -130,7 +130,7 @@ export function getTokenFiatRate(messenger, tokenAddress, chainId) {
|
|
|
130
130
|
if (nativeToFiatRate === null || nativeToUsdRate === null) {
|
|
131
131
|
return undefined;
|
|
132
132
|
}
|
|
133
|
-
const isStablecoin =
|
|
133
|
+
const isStablecoin = getStablecoins(messenger)[chainId]?.includes(tokenAddress.toLowerCase());
|
|
134
134
|
const usdRate = isStablecoin
|
|
135
135
|
? '1'
|
|
136
136
|
: new BigNumber(String(tokenToNativeRate ?? 1))
|
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 { Interface } from '@ethersproject/abi';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { CaipAssetType, Hex } from '@metamask/utils';\nimport { hexToBigInt, toCaipAssetType } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n SLIP44_COIN_TYPE_BY_CHAIN,\n STABLECOINS,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\nimport {\n getAssetsUnifyStateFeature,\n isChainExcludedFromInfura,\n} from './feature-flags';\nimport { getNetworkClientId, rpcRequest } from './provider';\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(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(nativeToUsdRate))\n .toString(10);\n\n const fiatRate = new BigNumber(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(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 * Uses the Infura RPC endpoint for the chain when one is configured, falling\n * back to the chain's default endpoint. This avoids errors on custom mainnet\n * RPC endpoints that may not support pending block queries.\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 options = {\n preferInfura: !isChainExcludedFromInfura(messenger, chainId),\n };\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_getBalance',\n params: [account, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n }\n\n const calldata = new Interface(abiERC20).encodeFunctionData('balanceOf', [\n account,\n ]) as Hex;\n\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_call',\n params: [{ to: tokenAddress, data: calldata }, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n}\n\n/**\n * Build a CAIP-19 asset type identifier for an EVM token.\n *\n * For native tokens the SLIP-44 coin type is resolved automatically from\n * a built-in chain→coin-type map, falling back to 60 (ETH). Callers can\n * override via the optional third parameter.\n *\n * @param chainId - Hex chain ID (e.g. `0x1`).\n * @param tokenAddress - Token contract address, or the native token address.\n * @param slip44CoinType - Optional SLIP-44 coin type override for native tokens.\n * @returns CAIP-19 asset type string.\n */\nexport function buildCaipAssetType(\n chainId: Hex,\n tokenAddress: Hex,\n slip44CoinType?: number,\n): CaipAssetType {\n const chainReference = String(hexToBigInt(chainId));\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const coinType = slip44CoinType ?? SLIP44_COIN_TYPE_BY_CHAIN[chainId] ?? 60;\n\n return toCaipAssetType(\n 'eip155',\n chainReference,\n 'slip44',\n String(coinType),\n );\n }\n\n return toCaipAssetType('eip155', chainReference, 'erc20', tokenAddress);\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = getNetworkClientId(messenger, chainId);\n\n return messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n ).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 { Interface } from '@ethersproject/abi';\nimport { TokensControllerState } from '@metamask/assets-controllers';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type { CaipAssetType, Hex } from '@metamask/utils';\nimport { hexToBigInt, toCaipAssetType } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n CHAIN_ID_POLYGON,\n NATIVE_TOKEN_ADDRESS,\n SLIP44_COIN_TYPE_BY_CHAIN,\n} from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\nimport {\n getAssetsUnifyStateFeature,\n getStablecoins,\n isChainExcludedFromInfura,\n} from './feature-flags';\nimport { getNetworkClientId, rpcRequest } from './provider';\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 = getStablecoins(messenger)[chainId]?.includes(\n tokenAddress.toLowerCase() as Hex,\n );\n\n const usdRate = isStablecoin\n ? '1'\n : new BigNumber(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(nativeToUsdRate))\n .toString(10);\n\n const fiatRate = new BigNumber(String(tokenToNativeRate ?? 1))\n .multipliedBy(String(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 * Uses the Infura RPC endpoint for the chain when one is configured, falling\n * back to the chain's default endpoint. This avoids errors on custom mainnet\n * RPC endpoints that may not support pending block queries.\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 options = {\n preferInfura: !isChainExcludedFromInfura(messenger, chainId),\n };\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_getBalance',\n params: [account, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n }\n\n const calldata = new Interface(abiERC20).encodeFunctionData('balanceOf', [\n account,\n ]) as Hex;\n\n const result = await rpcRequest<string>({\n messenger,\n chainId,\n method: 'eth_call',\n params: [{ to: tokenAddress, data: calldata }, 'pending'],\n options,\n });\n\n return new BigNumber(result, 16).toString(10);\n}\n\n/**\n * Build a CAIP-19 asset type identifier for an EVM token.\n *\n * For native tokens the SLIP-44 coin type is resolved automatically from\n * a built-in chain→coin-type map, falling back to 60 (ETH). Callers can\n * override via the optional third parameter.\n *\n * @param chainId - Hex chain ID (e.g. `0x1`).\n * @param tokenAddress - Token contract address, or the native token address.\n * @param slip44CoinType - Optional SLIP-44 coin type override for native tokens.\n * @returns CAIP-19 asset type string.\n */\nexport function buildCaipAssetType(\n chainId: Hex,\n tokenAddress: Hex,\n slip44CoinType?: number,\n): CaipAssetType {\n const chainReference = String(hexToBigInt(chainId));\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const coinType = slip44CoinType ?? SLIP44_COIN_TYPE_BY_CHAIN[chainId] ?? 60;\n\n return toCaipAssetType(\n 'eip155',\n chainReference,\n 'slip44',\n String(coinType),\n );\n }\n\n return toCaipAssetType('eip155', chainReference, 'erc20', tokenAddress);\n}\n\nfunction getTicker(\n chainId: Hex,\n messenger: TransactionPayControllerMessenger,\n): string | undefined {\n try {\n const networkClientId = getNetworkClientId(messenger, chainId);\n\n return messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n ).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"]}
|
|
@@ -42,7 +42,10 @@ function subscribeTransactionChanges(messenger, updateTransactionData, removeTra
|
|
|
42
42
|
const updatedTransactions = transactions.filter((tx) => {
|
|
43
43
|
const previousTransaction = previousTransactions?.find((prevTx) => prevTx.id === tx.id);
|
|
44
44
|
return (previousTransaction &&
|
|
45
|
-
previousTransaction?.txParams.data !== tx.txParams.data
|
|
45
|
+
(previousTransaction?.txParams.data !== tx.txParams.data ||
|
|
46
|
+
previousTransaction?.txParams.to !== tx.txParams.to ||
|
|
47
|
+
JSON.stringify(previousTransaction?.requiredAssets) !==
|
|
48
|
+
JSON.stringify(tx.requiredAssets)));
|
|
46
49
|
});
|
|
47
50
|
const finalizedTransactions = transactions.filter((tx) => {
|
|
48
51
|
const previousTransaction = previousTransactions?.find((prevTx) => prevTx.id === tx.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.cjs","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport {\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 { BigNumber } from 'bignumber.js';\nimport type { Patch } from 'immer';\nimport { cloneDeep } from 'lodash';\n\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayControllerState,\n UpdateTransactionDataCallback,\n} from '../types';\nimport { rpcRequest } from './provider';\nimport { parseRequiredTokens } from './required-tokens';\nimport { getNativeToken } from './token';\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 * Subscribe to 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 subscribeTransactionChanges(\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 * Subscribe to asset state changes and re-parse required tokens for\n * in-flight transactions whose tokens have not yet resolved.\n *\n * Subscribes to all known asset event sources unconditionally, rather than\n * choosing a single source based on the unify-state feature flag. The flag\n * value can change between when this controller is constructed and when it\n * is read elsewhere (e.g. remote feature flags loading after startup), so\n * relying on it here to pick a single source risks missing the events that\n * actually fire. The handler is idempotent, so subscribing to extra sources\n * that never fire is harmless.\n *\n * @param messenger - Controller messenger.\n * @param getControllerState - Callback returning the current controller state.\n * @param updateTransactionData - Callback to update transaction data.\n */\nexport function subscribeAssetChanges(\n messenger: TransactionPayControllerMessenger,\n getControllerState: () => TransactionPayControllerState,\n updateTransactionData: UpdateTransactionDataCallback,\n): void {\n const buildHandler =\n (source: string) =>\n (_state: unknown, patches: Patch[] | undefined): void => {\n const { transactionData } = getControllerState();\n\n for (const [transactionId, data] of Object.entries(transactionData)) {\n if (data.tokens.length > 0) {\n continue;\n }\n\n const transaction = getTransaction(transactionId, messenger);\n\n if (!transaction || FINALIZED_STATUSES.includes(transaction.status)) {\n continue;\n }\n\n log('Asset data changed', { transactionId, source, patches });\n\n onTransactionChange(transaction, messenger, updateTransactionData);\n }\n };\n\n messenger.subscribe(\n 'AssetsController:stateChange',\n buildHandler('AssetsController'),\n );\n messenger.subscribe(\n 'TokensController:stateChange',\n buildHandler('TokensController'),\n );\n messenger.subscribe(\n 'TokenRatesController:stateChange',\n buildHandler('TokenRatesController'),\n );\n messenger.subscribe(\n 'CurrencyRateController:stateChange',\n buildHandler('CurrencyRateController'),\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\nconst erc20Interface = new Interface(abiERC20);\n\nconst ERC20_TRANSFER_EVENT_TOPIC = erc20Interface.getEventTopic('Transfer');\n\n/**\n * Result from {@link getTransferredAmountFromTxHash}.\n */\nexport type TransferredAmountResult = {\n /** Raw (atomic) transferred amount as a decimal string, or `undefined`. */\n amountRaw: string | undefined;\n /**\n * Block number of the on-chain transaction as a 0x-prefixed hex string.\n * Populated only for ERC-20 tokens (sourced from the receipt); `undefined`\n * for native token transactions.\n */\n blockNumber: Hex | undefined;\n};\n\n/**\n * Reads the transferred token amount from a completed on-chain transaction.\n *\n * For native tokens the amount is resolved via `debug_traceTransaction`\n * (internal-call aware), falling back to the top-level `tx.value`.\n * For ERC-20 tokens the amount is decoded from `Transfer` event logs\n * in the transaction receipt, and the receipt `blockNumber` is also returned.\n *\n * @param options - The options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.txHash - Transaction hash of the completed on-chain transaction.\n * @param options.chainId - Chain ID where the transaction was executed.\n * @param options.tokenAddress - Address of the transferred token.\n * @param options.walletAddress - Recipient wallet address to filter transfers to.\n * @returns The raw transferred amount and, for ERC-20, the receipt block number.\n */\nexport async function getTransferredAmountFromTxHash({\n messenger,\n txHash,\n chainId,\n tokenAddress,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n txHash: string;\n chainId: Hex;\n tokenAddress: Hex;\n walletAddress: Hex;\n}): Promise<TransferredAmountResult> {\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const amountRaw = await getNativeTransferAmount(\n messenger,\n chainId,\n txHash,\n walletAddress,\n );\n\n return { amountRaw, blockNumber: undefined };\n }\n\n return await getErc20TransferAmount(\n messenger,\n chainId,\n txHash,\n tokenAddress,\n walletAddress,\n );\n}\n\n/**\n * Resolves the native token amount received by a wallet from a transaction.\n *\n * 1. Attempts `debug_traceTransaction` with `callTracer` to walk internal\n * calls and sum all native value transfers targeting `walletAddress`.\n * 2. Falls back to the top-level `tx.value` when the wallet is the direct\n * recipient and the trace RPC is unavailable or errors.\n *\n * @param messenger - Controller messenger.\n * @param chainId - Chain ID where the transaction was executed.\n * @param txHash - Transaction hash.\n * @param walletAddress - Recipient wallet address.\n * @returns Raw amount as a decimal string, or `undefined`.\n */\nasync function getNativeTransferAmount(\n messenger: TransactionPayControllerMessenger,\n chainId: Hex,\n txHash: string,\n walletAddress: Hex,\n): Promise<string | undefined> {\n try {\n const trace = await rpcRequest<CallTrace>({\n messenger,\n chainId,\n method: 'debug_traceTransaction',\n params: [txHash, { tracer: 'callTracer' }],\n });\n\n const amount = sumNativeValueFromTrace(trace, walletAddress);\n if (amount.gt(0)) {\n return amount.toFixed(0);\n }\n } catch {\n // debug_traceTransaction not supported — fall through to tx.value\n }\n\n const tx = await rpcRequest<{ to?: string; value: string } | null>({\n messenger,\n chainId,\n method: 'eth_getTransactionByHash',\n params: [txHash],\n });\n\n if (!tx) {\n return undefined;\n }\n\n if (tx.to?.toLowerCase() !== walletAddress.toLowerCase()) {\n return undefined;\n }\n\n return positiveOrUndefined(new BigNumber(tx.value).toFixed(0));\n}\n\n/**\n * Resolves the ERC-20 token amount received by a wallet from a transaction\n * by decoding `Transfer` event logs from the transaction receipt. Also\n * returns the receipt `blockNumber` so callers can reuse it without a\n * second network request.\n *\n * @param messenger - Controller messenger.\n * @param chainId - Chain ID where the transaction was executed.\n * @param txHash - Transaction hash.\n * @param tokenAddress - ERC-20 token contract address.\n * @param walletAddress - Recipient wallet address.\n * @returns Raw amount (or `undefined`) and the receipt block number (or `undefined`).\n */\nasync function getErc20TransferAmount(\n messenger: TransactionPayControllerMessenger,\n chainId: Hex,\n txHash: string,\n tokenAddress: Hex,\n walletAddress: Hex,\n): Promise<TransferredAmountResult> {\n const receipt = await rpcRequest<{\n blockNumber: Hex;\n logs: { address: string; topics: string[]; data: string }[];\n } | null>({\n messenger,\n chainId,\n method: 'eth_getTransactionReceipt',\n params: [txHash],\n });\n\n if (!receipt) {\n return { amountRaw: undefined, blockNumber: undefined };\n }\n\n const { blockNumber } = receipt;\n let total = new BigNumber(0);\n\n for (const txLog of receipt.logs) {\n if (txLog.address.toLowerCase() !== tokenAddress.toLowerCase()) {\n continue;\n }\n\n if (!txLog.topics[0] || txLog.topics[0] !== ERC20_TRANSFER_EVENT_TOPIC) {\n continue;\n }\n\n try {\n const parsed = erc20Interface.parseLog(txLog);\n const to = (parsed.args[1] as string).toLowerCase();\n\n if (to !== walletAddress.toLowerCase()) {\n continue;\n }\n\n total = total.plus(parsed.args[2].toString());\n } catch {\n continue;\n }\n }\n\n return { amountRaw: positiveOrUndefined(total.toFixed(0)), blockNumber };\n}\n\ntype CallTrace = {\n to?: string;\n value?: string;\n calls?: CallTrace[];\n};\n\n/**\n * Recursively walks a `callTracer` result and sums native value\n * transferred to a specific address.\n *\n * @param trace - Call trace node.\n * @param walletAddress - Target address to accumulate value for.\n * @returns Accumulated native value as BigNumber.\n */\nfunction sumNativeValueFromTrace(\n trace: CallTrace,\n walletAddress: Hex,\n): BigNumber {\n let total = new BigNumber(0);\n\n if (\n trace.to?.toLowerCase() === walletAddress.toLowerCase() &&\n trace.value &&\n trace.value !== '0x0'\n ) {\n total = total.plus(new BigNumber(trace.value));\n }\n\n if (trace.calls) {\n for (const child of trace.calls) {\n total = total.plus(sumNativeValueFromTrace(child, walletAddress));\n }\n }\n\n return total;\n}\n\nfunction positiveOrUndefined(amount: string): string | undefined {\n return new BigNumber(amount).gt(0) ? amount : undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transaction.cjs","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":";;;AAAA,4CAA+C;AAC/C,mEAAuD;AACvD,6EAG0C;AAG1C,2CAAqD;AACrD,+CAAyC;AAEzC,mCAAmC;AAEnC,0CAA0C;AAM1C,6CAAwC;AACxC,2DAAwD;AACxD,uCAAyC;AAEzC,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,aAAa,CAAC,CAAC;AAEhD,QAAA,kBAAkB,GAAG;IAChC,0CAAiB,CAAC,SAAS;IAC3B,0CAAiB,CAAC,OAAO;IACzB,0CAAiB,CAAC,MAAM;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,SAAgB,cAAc,CAC5B,aAAqB,EACrB,SAA4C;IAE5C,MAAM,0BAA0B,GAAG,SAAS,CAAC,IAAI,CAC/C,gCAAgC,CACjC,CAAC;IAEF,OAAO,0BAA0B,CAAC,YAAY,CAAC,IAAI,CACjD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,aAAa,CAChC,CAAC;AACJ,CAAC;AAXD,wCAWC;AAED;;;;;;GAMG;AACH,SAAgB,2BAA2B,CACzC,SAA4C,EAC5C,qBAAoD,EACpD,qBAAsD;IAEtD,SAAS,CAAC,SAAS,CACjB,mCAAmC,EACnC,CACE,YAA+B,EAC/B,oBAAmD,EACnD,EAAE;QACF,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CACzC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CACrE,CAAC;QAEF,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;YACrD,MAAM,mBAAmB,GAAG,oBAAoB,EAAE,IAAI,CACpD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAChC,CAAC;YAEF,OAAO,CACL,mBAAmB;gBACnB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,QAAQ,CAAC,IAAI;oBACtD,mBAAmB,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE;oBACnD,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,cAAc,CAAC;wBACjD,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CACvC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,qBAAqB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;YACvD,MAAM,mBAAmB,GAAG,oBAAoB,EAAE,IAAI,CACpD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAChC,CAAC;YAEF,OAAO,CACL,mBAAmB;gBACnB,CAAC,0BAAkB,CAAC,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC;gBACxD,0BAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CACvC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,MAAM,CAC7D,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAC5D,CAAC;QAEF,CAAC,GAAG,qBAAqB,EAAE,GAAG,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAChE,sBAAsB,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAClD,CAAC;QAEF,CAAC,GAAG,eAAe,EAAE,GAAG,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAC1D,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAC1D,CAAC;IACJ,CAAC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAC9B,CAAC;AACJ,CAAC;AAvDD,kEAuDC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,qBAAqB,CACnC,SAA4C,EAC5C,kBAAuD,EACvD,qBAAoD;IAEpD,MAAM,YAAY,GAChB,CAAC,MAAc,EAAE,EAAE,CACnB,CAAC,MAAe,EAAE,OAA4B,EAAQ,EAAE;QACtD,MAAM,EAAE,eAAe,EAAE,GAAG,kBAAkB,EAAE,CAAC;QAEjD,KAAK,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YACpE,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;YAE7D,IAAI,CAAC,WAAW,IAAI,0BAAkB,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpE,SAAS;YACX,CAAC;YAED,GAAG,CAAC,oBAAoB,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YAE9D,mBAAmB,CAAC,WAAW,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;QACrE,CAAC;IACH,CAAC,CAAC;IAEJ,SAAS,CAAC,SAAS,CACjB,8BAA8B,EAC9B,YAAY,CAAC,kBAAkB,CAAC,CACjC,CAAC;IACF,SAAS,CAAC,SAAS,CACjB,8BAA8B,EAC9B,YAAY,CAAC,kBAAkB,CAAC,CACjC,CAAC;IACF,SAAS,CAAC,SAAS,CACjB,kCAAkC,EAClC,YAAY,CAAC,sBAAsB,CAAC,CACrC,CAAC;IACF,SAAS,CAAC,SAAS,CACjB,oCAAoC,EACpC,YAAY,CAAC,wBAAwB,CAAC,CACvC,CAAC;AACJ,CAAC;AA3CD,sDA2CC;AAED;;;;;;GAMG;AACH,SAAgB,2BAA2B,CACzC,aAAqB,EACrB,SAA4C;IAE5C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,WAAW,GAAG,CAAC,EAAoB,EAAE,EAAe,EAAW,EAAE;YACrE,GAAG,CAAC,6BAA6B,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;YAEzD,IAAI,EAAE,EAAE,MAAM,KAAK,0CAAiB,CAAC,SAAS,EAAE,CAAC;gBAC/C,EAAE,EAAE,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IACE,CAAC,0CAAiB,CAAC,OAAO,EAAE,0CAAiB,CAAC,MAAM,CAAC,CAAC,QAAQ,CAC5D,EAAE,EAAE,MAA2B,CAChC,EACD,CAAC;gBACD,EAAE,EAAE,EAAE,CAAC;gBACP,MAAM,CACJ,IAAI,KAAK,CAAC,wBAAwB,EAAE,EAAE,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CACtE,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAEtE,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,CAC9C,CAAC,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,aAAa,CAC9D,CAAC;QAEF,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,EAAoB,EAAQ,EAAE;YAC7C,MAAM,WAAW,GAAG,GAAS,EAAE,CAC7B,SAAS,CAAC,WAAW,CAAC,mCAAmC,EAAE,OAAO,CAAC,CAAC;YAEtE,WAAW,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,SAAS,CAAC,SAAS,CAAC,mCAAmC,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAC1E,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,aAAa,CAAC,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAlDD,kEAkDC;AAED;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAC/B,EACE,aAAa,EACb,SAAS,EACT,IAAI,GAKL,EACD,EAAoC;IAEpC,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,EAAE,SAAkB,CAAC,CAAC;IAEtE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,aAAa,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,kBAAS,EAAC,WAAW,CAAC,CAAC;IAE9C,EAAE,CAAC,cAAc,CAAC,CAAC;IAEnB,SAAS,CAAC,IAAI,CACZ,yCAAyC,EACzC,cAAc,EACd,IAAI,CACL,CAAC;AACJ,CAAC;AA3BD,8CA2BC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CACnC,OAAY,EACZ,IAAS,EACT,SAA4C,EAC5C,aAA8C;IAE9C,MAAM,QAAQ,GAAG,CAAC,EAAmB,EAAQ,EAAE;QAC7C,IACE,EAAE,CAAC,OAAO,KAAK,OAAO;YACtB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,EACrD,CAAC;YACD,OAAO;QACT,CAAC;QAED,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,SAAS,CAAC,SAAS,CACjB,kDAAkD,EAClD,QAAQ,CACT,CAAC;IAEF,MAAM,GAAG,GAAG,GAAS,EAAE;QACrB,SAAS,CAAC,WAAW,CACnB,kDAAkD,EAClD,QAAQ,CACT,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC;AA9BD,sDA8BC;AAED;;;;;;;;GAQG;AACH,SAAgB,4BAA4B,CAC1C,WAA4B;IAE5B,OAAO,CACL,WAAW,CAAC,IAAI,KAAK,wCAAe,CAAC,eAAe;QACpD,CAAC,WAAW,CAAC,kBAAkB,EAAE,IAAI,CACnC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,wCAAe,CAAC,eAAe,CACpD;YACC,KAAK,CAAC,CACT,CAAC;AACJ,CAAC;AAVD,oEAUC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAC1B,WAA4B,EAC5B,SAA4C,EAC5C,qBAAoD;IAEpD,MAAM,MAAM,GAAG,IAAA,qCAAmB,EAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE3D,GAAG,CAAC,qBAAqB,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IAEpD,qBAAqB,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAC7B,WAA4B,EAC5B,qBAAsD;IAEtD,GAAG,CAAC,uBAAuB,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC9C,qBAAqB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,eAAS,CAAC,4BAAQ,CAAC,CAAC;AAE/C,MAAM,0BAA0B,GAAG,cAAc,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;AAgB5E;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,8BAA8B,CAAC,EACnD,SAAS,EACT,MAAM,EACN,OAAO,EACP,YAAY,EACZ,aAAa,GAOd;IACC,MAAM,QAAQ,GACZ,YAAY,CAAC,WAAW,EAAE,KAAK,IAAA,sBAAc,EAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAEvE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAC7C,SAAS,EACT,OAAO,EACP,MAAM,EACN,aAAa,CACd,CAAC;QAEF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO,MAAM,sBAAsB,CACjC,SAAS,EACT,OAAO,EACP,MAAM,EACN,YAAY,EACZ,aAAa,CACd,CAAC;AACJ,CAAC;AAlCD,wEAkCC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,uBAAuB,CACpC,SAA4C,EAC5C,OAAY,EACZ,MAAc,EACd,aAAkB;IAElB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAU,EAAY;YACxC,SAAS;YACT,OAAO;YACP,MAAM,EAAE,wBAAwB;YAChC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QAC7D,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,IAAA,qBAAU,EAAwC;QACjE,SAAS;QACT,OAAO;QACP,MAAM,EAAE,0BAA0B;QAClC,MAAM,EAAE,CAAC,MAAM,CAAC;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC;QACzD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,mBAAmB,CAAC,IAAI,wBAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,sBAAsB,CACnC,SAA4C,EAC5C,OAAY,EACZ,MAAc,EACd,YAAiB,EACjB,aAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,IAAA,qBAAU,EAGtB;QACR,SAAS;QACT,OAAO;QACP,MAAM,EAAE,2BAA2B;QACnC,MAAM,EAAE,CAAC,MAAM,CAAC;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAChC,IAAI,KAAK,GAAG,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAE7B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/D,SAAS;QACX,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,0BAA0B,EAAE,CAAC;YACvE,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,EAAE,GAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAY,CAAC,WAAW,EAAE,CAAC;YAEpD,IAAI,EAAE,KAAK,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;AAC3E,CAAC;AAQD;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAC9B,KAAgB,EAChB,aAAkB;IAElB,IAAI,KAAK,GAAG,IAAI,wBAAS,CAAC,CAAC,CAAC,CAAC;IAE7B,IACE,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,aAAa,CAAC,WAAW,EAAE;QACvD,KAAK,CAAC,KAAK;QACX,KAAK,CAAC,KAAK,KAAK,KAAK,EACrB,CAAC;QACD,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,wBAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IACzC,OAAO,IAAI,wBAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1D,CAAC","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport {\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 { BigNumber } from 'bignumber.js';\nimport type { Patch } from 'immer';\nimport { cloneDeep } from 'lodash';\n\nimport { projectLogger } from '../logger';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayControllerState,\n UpdateTransactionDataCallback,\n} from '../types';\nimport { rpcRequest } from './provider';\nimport { parseRequiredTokens } from './required-tokens';\nimport { getNativeToken } from './token';\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 * Subscribe to 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 subscribeTransactionChanges(\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 previousTransaction?.txParams.to !== tx.txParams.to ||\n JSON.stringify(previousTransaction?.requiredAssets) !==\n JSON.stringify(tx.requiredAssets))\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 * Subscribe to asset state changes and re-parse required tokens for\n * in-flight transactions whose tokens have not yet resolved.\n *\n * Subscribes to all known asset event sources unconditionally, rather than\n * choosing a single source based on the unify-state feature flag. The flag\n * value can change between when this controller is constructed and when it\n * is read elsewhere (e.g. remote feature flags loading after startup), so\n * relying on it here to pick a single source risks missing the events that\n * actually fire. The handler is idempotent, so subscribing to extra sources\n * that never fire is harmless.\n *\n * @param messenger - Controller messenger.\n * @param getControllerState - Callback returning the current controller state.\n * @param updateTransactionData - Callback to update transaction data.\n */\nexport function subscribeAssetChanges(\n messenger: TransactionPayControllerMessenger,\n getControllerState: () => TransactionPayControllerState,\n updateTransactionData: UpdateTransactionDataCallback,\n): void {\n const buildHandler =\n (source: string) =>\n (_state: unknown, patches: Patch[] | undefined): void => {\n const { transactionData } = getControllerState();\n\n for (const [transactionId, data] of Object.entries(transactionData)) {\n if (data.tokens.length > 0) {\n continue;\n }\n\n const transaction = getTransaction(transactionId, messenger);\n\n if (!transaction || FINALIZED_STATUSES.includes(transaction.status)) {\n continue;\n }\n\n log('Asset data changed', { transactionId, source, patches });\n\n onTransactionChange(transaction, messenger, updateTransactionData);\n }\n };\n\n messenger.subscribe(\n 'AssetsController:stateChange',\n buildHandler('AssetsController'),\n );\n messenger.subscribe(\n 'TokensController:stateChange',\n buildHandler('TokensController'),\n );\n messenger.subscribe(\n 'TokenRatesController:stateChange',\n buildHandler('TokenRatesController'),\n );\n messenger.subscribe(\n 'CurrencyRateController:stateChange',\n buildHandler('CurrencyRateController'),\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\nconst erc20Interface = new Interface(abiERC20);\n\nconst ERC20_TRANSFER_EVENT_TOPIC = erc20Interface.getEventTopic('Transfer');\n\n/**\n * Result from {@link getTransferredAmountFromTxHash}.\n */\nexport type TransferredAmountResult = {\n /** Raw (atomic) transferred amount as a decimal string, or `undefined`. */\n amountRaw: string | undefined;\n /**\n * Block number of the on-chain transaction as a 0x-prefixed hex string.\n * Populated only for ERC-20 tokens (sourced from the receipt); `undefined`\n * for native token transactions.\n */\n blockNumber: Hex | undefined;\n};\n\n/**\n * Reads the transferred token amount from a completed on-chain transaction.\n *\n * For native tokens the amount is resolved via `debug_traceTransaction`\n * (internal-call aware), falling back to the top-level `tx.value`.\n * For ERC-20 tokens the amount is decoded from `Transfer` event logs\n * in the transaction receipt, and the receipt `blockNumber` is also returned.\n *\n * @param options - The options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.txHash - Transaction hash of the completed on-chain transaction.\n * @param options.chainId - Chain ID where the transaction was executed.\n * @param options.tokenAddress - Address of the transferred token.\n * @param options.walletAddress - Recipient wallet address to filter transfers to.\n * @returns The raw transferred amount and, for ERC-20, the receipt block number.\n */\nexport async function getTransferredAmountFromTxHash({\n messenger,\n txHash,\n chainId,\n tokenAddress,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n txHash: string;\n chainId: Hex;\n tokenAddress: Hex;\n walletAddress: Hex;\n}): Promise<TransferredAmountResult> {\n const isNative =\n tokenAddress.toLowerCase() === getNativeToken(chainId).toLowerCase();\n\n if (isNative) {\n const amountRaw = await getNativeTransferAmount(\n messenger,\n chainId,\n txHash,\n walletAddress,\n );\n\n return { amountRaw, blockNumber: undefined };\n }\n\n return await getErc20TransferAmount(\n messenger,\n chainId,\n txHash,\n tokenAddress,\n walletAddress,\n );\n}\n\n/**\n * Resolves the native token amount received by a wallet from a transaction.\n *\n * 1. Attempts `debug_traceTransaction` with `callTracer` to walk internal\n * calls and sum all native value transfers targeting `walletAddress`.\n * 2. Falls back to the top-level `tx.value` when the wallet is the direct\n * recipient and the trace RPC is unavailable or errors.\n *\n * @param messenger - Controller messenger.\n * @param chainId - Chain ID where the transaction was executed.\n * @param txHash - Transaction hash.\n * @param walletAddress - Recipient wallet address.\n * @returns Raw amount as a decimal string, or `undefined`.\n */\nasync function getNativeTransferAmount(\n messenger: TransactionPayControllerMessenger,\n chainId: Hex,\n txHash: string,\n walletAddress: Hex,\n): Promise<string | undefined> {\n try {\n const trace = await rpcRequest<CallTrace>({\n messenger,\n chainId,\n method: 'debug_traceTransaction',\n params: [txHash, { tracer: 'callTracer' }],\n });\n\n const amount = sumNativeValueFromTrace(trace, walletAddress);\n if (amount.gt(0)) {\n return amount.toFixed(0);\n }\n } catch {\n // debug_traceTransaction not supported — fall through to tx.value\n }\n\n const tx = await rpcRequest<{ to?: string; value: string } | null>({\n messenger,\n chainId,\n method: 'eth_getTransactionByHash',\n params: [txHash],\n });\n\n if (!tx) {\n return undefined;\n }\n\n if (tx.to?.toLowerCase() !== walletAddress.toLowerCase()) {\n return undefined;\n }\n\n return positiveOrUndefined(new BigNumber(tx.value).toFixed(0));\n}\n\n/**\n * Resolves the ERC-20 token amount received by a wallet from a transaction\n * by decoding `Transfer` event logs from the transaction receipt. Also\n * returns the receipt `blockNumber` so callers can reuse it without a\n * second network request.\n *\n * @param messenger - Controller messenger.\n * @param chainId - Chain ID where the transaction was executed.\n * @param txHash - Transaction hash.\n * @param tokenAddress - ERC-20 token contract address.\n * @param walletAddress - Recipient wallet address.\n * @returns Raw amount (or `undefined`) and the receipt block number (or `undefined`).\n */\nasync function getErc20TransferAmount(\n messenger: TransactionPayControllerMessenger,\n chainId: Hex,\n txHash: string,\n tokenAddress: Hex,\n walletAddress: Hex,\n): Promise<TransferredAmountResult> {\n const receipt = await rpcRequest<{\n blockNumber: Hex;\n logs: { address: string; topics: string[]; data: string }[];\n } | null>({\n messenger,\n chainId,\n method: 'eth_getTransactionReceipt',\n params: [txHash],\n });\n\n if (!receipt) {\n return { amountRaw: undefined, blockNumber: undefined };\n }\n\n const { blockNumber } = receipt;\n let total = new BigNumber(0);\n\n for (const txLog of receipt.logs) {\n if (txLog.address.toLowerCase() !== tokenAddress.toLowerCase()) {\n continue;\n }\n\n if (!txLog.topics[0] || txLog.topics[0] !== ERC20_TRANSFER_EVENT_TOPIC) {\n continue;\n }\n\n try {\n const parsed = erc20Interface.parseLog(txLog);\n const to = (parsed.args[1] as string).toLowerCase();\n\n if (to !== walletAddress.toLowerCase()) {\n continue;\n }\n\n total = total.plus(parsed.args[2].toString());\n } catch {\n continue;\n }\n }\n\n return { amountRaw: positiveOrUndefined(total.toFixed(0)), blockNumber };\n}\n\ntype CallTrace = {\n to?: string;\n value?: string;\n calls?: CallTrace[];\n};\n\n/**\n * Recursively walks a `callTracer` result and sums native value\n * transferred to a specific address.\n *\n * @param trace - Call trace node.\n * @param walletAddress - Target address to accumulate value for.\n * @returns Accumulated native value as BigNumber.\n */\nfunction sumNativeValueFromTrace(\n trace: CallTrace,\n walletAddress: Hex,\n): BigNumber {\n let total = new BigNumber(0);\n\n if (\n trace.to?.toLowerCase() === walletAddress.toLowerCase() &&\n trace.value &&\n trace.value !== '0x0'\n ) {\n total = total.plus(new BigNumber(trace.value));\n }\n\n if (trace.calls) {\n for (const child of trace.calls) {\n total = total.plus(sumNativeValueFromTrace(child, walletAddress));\n }\n }\n\n return total;\n}\n\nfunction positiveOrUndefined(amount: string): string | undefined {\n return new BigNumber(amount).gt(0) ? amount : undefined;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.cts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EAElB,yCAAyC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAO3C,OAAO,KAAK,EACV,iCAAiC,EACjC,6BAA6B,EAC7B,6BAA6B,EAC9B,qBAAiB;AAOlB,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,2BAA2B,CACzC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,qBAAqB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GACrD,IAAI,
|
|
1
|
+
{"version":3,"file":"transaction.d.cts","sourceRoot":"","sources":["../../src/utils/transaction.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EAElB,yCAAyC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAO3C,OAAO,KAAK,EACV,iCAAiC,EACjC,6BAA6B,EAC7B,6BAA6B,EAC9B,qBAAiB;AAOlB,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,2BAA2B,CACzC,SAAS,EAAE,iCAAiC,EAC5C,qBAAqB,EAAE,6BAA6B,EACpD,qBAAqB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GACrD,IAAI,CAmDN;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,iCAAiC,EAC5C,kBAAkB,EAAE,MAAM,6BAA6B,EACvD,qBAAqB,EAAE,6BAA6B,GACnD,IAAI,CAuCN;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;AAyCD;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,GAAG,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,8BAA8B,CAAC,EACnD,SAAS,EACT,MAAM,EACN,OAAO,EACP,YAAY,EACZ,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,GAAG,CAAC;IACb,YAAY,EAAE,GAAG,CAAC;IAClB,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAsBnC"}
|