{"version":3,"file":"token.mjs","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"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","sourcesContent":["import { toChecksumHexAddress } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\nimport { uniq } from 'lodash';\n\nimport { NATIVE_TOKEN_ADDRESS } from '../constants';\nimport type { FiatRates, TransactionPayControllerMessenger } from '../types';\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 The token balance as a BigNumber.\n */\nexport function getTokenBalance(\n  messenger: TransactionPayControllerMessenger,\n  account: Hex,\n  chainId: Hex,\n  tokenAddress: Hex,\n): string {\n  const tokenBalanceControllerState = messenger.call(\n    'TokenBalancesController:getState',\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    tokenBalanceControllerState.tokenBalances?.[normalizedAccount]?.[chainId]?.[\n      normalizedTokenAddress\n    ];\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 accountTrackerControllerState = messenger.call(\n    'AccountTrackerController:getState',\n  );\n\n  const chainAccounts =\n    accountTrackerControllerState.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 balance for a specific account and token.\n *\n * @param messenger - Controller messenger.\n * @param account - Address of the account.\n * @returns The token balance as a BigNumber.\n */\nexport function getAllTokenBalances(\n  messenger: TransactionPayControllerMessenger,\n  account: Hex,\n) {\n  const tokenBalanceControllerState = messenger.call(\n    'TokenBalancesController:getState',\n  );\n\n  const accountTrackerControllerState = messenger.call(\n    'AccountTrackerController:getState',\n  );\n\n  const nativeChainIds = Object.keys(\n    accountTrackerControllerState.accountsByChainId,\n  ) as Hex[];\n\n  const normalizedAccount = account.toLowerCase() as Hex;\n\n  const balancesByTokenByChain =\n    tokenBalanceControllerState.tokenBalances?.[normalizedAccount];\n\n  const tokenChainIds = Object.keys(balancesByTokenByChain) as Hex[];\n  const chainIds = uniq([...tokenChainIds, ...nativeChainIds]);\n\n  return chainIds.flatMap((chainId) => {\n    const tokenAddresses = [\n      ...(Object.keys(balancesByTokenByChain[chainId] ?? {}) as Hex[]),\n      getNativeToken(chainId),\n    ];\n\n    return tokenAddresses.map((tokenAddress) => ({\n      chainId,\n      tokenAddress,\n      balance: getTokenBalance(messenger, account, chainId, tokenAddress),\n    }));\n  });\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 controllerState = messenger.call('TokensController:getState');\n  const normalizedTokenAddress = tokenAddress.toLowerCase() as Hex;\n\n  const isNative =\n    normalizedTokenAddress === getNativeToken(chainId).toLowerCase();\n\n  const token = Object.values(controllerState.allTokens?.[chainId] ?? {})\n    .flat()\n    .find((t) => t.address.toLowerCase() === normalizedTokenAddress);\n\n  if (!token && !isNative) {\n    return undefined;\n  }\n\n  if (token && !isNative) {\n    return { decimals: 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 ticker = getTicker(chainId, messenger);\n\n  if (!ticker) {\n    return undefined;\n  }\n\n  const rateControllerState = messenger.call('TokenRatesController:getState');\n\n  const currencyRateControllerState = messenger.call(\n    'CurrencyRateController:getState',\n  );\n\n  const normalizedTokenAddress = toChecksumHexAddress(tokenAddress) as Hex;\n  const isNative = normalizedTokenAddress === getNativeToken(chainId);\n\n  const tokenToNativeRate =\n    rateControllerState.marketData?.[chainId]?.[normalizedTokenAddress]?.price;\n\n  if (tokenToNativeRate === undefined && !isNative) {\n    return undefined;\n  }\n\n  const {\n    conversionRate: nativeToFiatRate,\n    usdConversionRate: nativeToUsdRate,\n  } = currencyRateControllerState.currencyRates?.[ticker] ?? {\n    conversionRate: null,\n    usdConversionRate: null,\n  };\n\n  if (nativeToFiatRate === null || nativeToUsdRate === null) {\n    return undefined;\n  }\n\n  const usdRate = new BigNumber(tokenToNativeRate ?? 1)\n    .multipliedBy(nativeToUsdRate)\n    .toString(10);\n\n  const fiatRate = new BigNumber(tokenToNativeRate ?? 1)\n    .multipliedBy(nativeToFiatRate)\n    .toString(10);\n\n  return { usdRate, fiatRate };\n}\n\n/**\n * 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) {\n  switch (chainId) {\n    case '0x89':\n      return '0x0000000000000000000000000000000000001010';\n    default:\n      return NATIVE_TOKEN_ADDRESS;\n  }\n}\n\n/**\n * Get the ticker for a given chain ID.\n *\n * @param chainId - Chain ID.\n * @param messenger - Messenger instance.\n * @returns Ticker symbol for the given chain ID or undefined if not found.\n */\nfunction getTicker(\n  chainId: Hex,\n  messenger: TransactionPayControllerMessenger,\n): string | undefined {\n  try {\n    const networkClientId = messenger.call(\n      'NetworkController:findNetworkClientIdByChainId',\n      chainId,\n    );\n\n    const networkConfiguration = messenger.call(\n      'NetworkController:getNetworkClientById',\n      networkClientId,\n    );\n\n    return networkConfiguration.configuration.ticker;\n  } catch {\n    return undefined;\n  }\n}\n"]}