@metamask-previews/assets-controllers 95.3.0-preview-ab102d86 → 96.0.0-preview-863782e

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/dist/NftController.cjs +1 -22
  3. package/dist/NftController.cjs.map +1 -1
  4. package/dist/NftController.d.cts +0 -10
  5. package/dist/NftController.d.cts.map +1 -1
  6. package/dist/NftController.d.mts +0 -10
  7. package/dist/NftController.d.mts.map +1 -1
  8. package/dist/NftController.mjs +1 -22
  9. package/dist/NftController.mjs.map +1 -1
  10. package/dist/TokenRatesController.cjs +8 -1
  11. package/dist/TokenRatesController.cjs.map +1 -1
  12. package/dist/TokenRatesController.d.cts +2 -1
  13. package/dist/TokenRatesController.d.cts.map +1 -1
  14. package/dist/TokenRatesController.d.mts +2 -1
  15. package/dist/TokenRatesController.d.mts.map +1 -1
  16. package/dist/TokenRatesController.mjs +8 -1
  17. package/dist/TokenRatesController.mjs.map +1 -1
  18. package/dist/selectors/token-selectors.cjs +1 -1
  19. package/dist/selectors/token-selectors.cjs.map +1 -1
  20. package/dist/selectors/token-selectors.mjs +1 -1
  21. package/dist/selectors/token-selectors.mjs.map +1 -1
  22. package/dist/token-prices-service/abstract-token-prices-service.cjs.map +1 -1
  23. package/dist/token-prices-service/abstract-token-prices-service.d.cts +12 -1
  24. package/dist/token-prices-service/abstract-token-prices-service.d.cts.map +1 -1
  25. package/dist/token-prices-service/abstract-token-prices-service.d.mts +12 -1
  26. package/dist/token-prices-service/abstract-token-prices-service.d.mts.map +1 -1
  27. package/dist/token-prices-service/abstract-token-prices-service.mjs.map +1 -1
  28. package/dist/token-prices-service/codefi-v2.cjs +228 -18
  29. package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
  30. package/dist/token-prices-service/codefi-v2.d.cts +76 -2
  31. package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
  32. package/dist/token-prices-service/codefi-v2.d.mts +76 -2
  33. package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
  34. package/dist/token-prices-service/codefi-v2.mjs +222 -18
  35. package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
  36. package/dist/token-prices-service/index.cjs +4 -1
  37. package/dist/token-prices-service/index.cjs.map +1 -1
  38. package/dist/token-prices-service/index.d.cts +2 -2
  39. package/dist/token-prices-service/index.d.cts.map +1 -1
  40. package/dist/token-prices-service/index.d.mts +2 -2
  41. package/dist/token-prices-service/index.d.mts.map +1 -1
  42. package/dist/token-prices-service/index.mjs +1 -1
  43. package/dist/token-prices-service/index.mjs.map +1 -1
  44. package/package.json +3 -2
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _TokenRatesController_instances, _TokenRatesController_tokenPricesService, _TokenRatesController_disabled, _TokenRatesController_allTokens, _TokenRatesController_allDetectedTokens, _TokenRatesController_subscribeToTokensStateChange, _TokenRatesController_subscribeToNetworkStateChange, _TokenRatesController_getTokenAddresses, _TokenRatesController_getTokensControllerState, _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency, _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency;
13
+ var _TokenRatesController_instances, _TokenRatesController_tokenPricesService, _TokenRatesController_disabled, _TokenRatesController_allTokens, _TokenRatesController_allDetectedTokens, _TokenRatesController_subscribeToTokensStateChange, _TokenRatesController_subscribeToNetworkStateChange, _TokenRatesController_initNativeAssetIdentifiers, _TokenRatesController_getTokenAddresses, _TokenRatesController_getTokensControllerState, _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency, _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.TokenRatesController = exports.getDefaultTokenRatesControllerState = exports.controllerName = void 0;
16
16
  const controller_utils_1 = require("@metamask/controller-utils");
@@ -75,6 +75,8 @@ class TokenRatesController extends (0, polling_controller_1.StaticIntervalPollin
75
75
  const { allTokens, allDetectedTokens } = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokensControllerState).call(this);
76
76
  __classPrivateFieldSet(this, _TokenRatesController_allTokens, allTokens, "f");
77
77
  __classPrivateFieldSet(this, _TokenRatesController_allDetectedTokens, allDetectedTokens, "f");
78
+ // Set native asset identifiers from NetworkEnablementController for CAIP-19 native token lookups
79
+ __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_initNativeAssetIdentifiers).call(this);
78
80
  __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_subscribeToTokensStateChange).call(this);
79
81
  __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_subscribeToNetworkStateChange).call(this);
80
82
  }
@@ -220,6 +222,11 @@ _TokenRatesController_tokenPricesService = new WeakMap(), _TokenRatesController_
220
222
  }
221
223
  }
222
224
  });
225
+ }, _TokenRatesController_initNativeAssetIdentifiers = function _TokenRatesController_initNativeAssetIdentifiers() {
226
+ if (__classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").setNativeAssetIdentifiers) {
227
+ const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
228
+ __classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").setNativeAssetIdentifiers(nativeAssetIdentifiers);
229
+ }
223
230
  }, _TokenRatesController_getTokenAddresses = function _TokenRatesController_getTokenAddresses(chainId) {
224
231
  const getTokens = (allTokens) => Object.values(allTokens ?? {}).flatMap((tokens) => tokens.map(({ address }) => (0, controller_utils_1.toChecksumHexAddress)(address)));
225
232
  const tokenAddresses = getTokens(__classPrivateFieldGet(this, _TokenRatesController_allTokens, "f")[chainId]);
@@ -1 +1 @@
1
- {"version":3,"file":"TokenRatesController.cjs","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { reduceInBatchesSerially, TOKEN_PRICES_BATCH_SIZE } from './assetsUtil';\nimport type { AbstractTokenPricesService } from './token-prices-service/abstract-token-prices-service';\nimport { getNativeTokenAddress } from './token-prices-service/codefi-v2';\nimport { TokenRwaData } from './token-service';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerStateChangeEvent,\n TokensControllerState,\n} from './TokensController';\n\n/**\n * @type Token\n *\n * Token representation\n *\n * @property address - Hex address of the token contract\n * @property decimals - Number of decimals the token uses\n * @property symbol - Symbol of the token\n * @property aggregators - An array containing the token's aggregators\n * @property image - Image of the token, url or bit32 image\n * @property hasBalanceError - 'true' if there is an error while updating the token balance\n * @property isERC721 - 'true' if the token is a ERC721 token\n * @property name - Name of the token\n */\nexport type Token = {\n address: string;\n decimals: number;\n symbol: string;\n aggregators?: string[];\n image?: string;\n hasBalanceError?: boolean;\n isERC721?: boolean;\n name?: string;\n rwaData?: TokenRwaData;\n};\n\nconst DEFAULT_INTERVAL = 180000;\n\nexport type ContractExchangeRates = {\n [address: string]: number | undefined;\n};\n\nexport type MarketDataDetails = {\n tokenAddress: `0x${string}`;\n currency: string;\n allTimeHigh: number;\n allTimeLow: number;\n circulatingSupply: number;\n dilutedMarketCap: number;\n high1d: number;\n low1d: number;\n marketCap: number;\n marketCapPercentChange1d: number;\n price: number;\n priceChange1d: number;\n pricePercentChange1d: number;\n pricePercentChange1h: number;\n pricePercentChange1y: number;\n pricePercentChange7d: number;\n pricePercentChange14d: number;\n pricePercentChange30d: number;\n pricePercentChange200d: number;\n totalVolume: number;\n};\n\n/**\n * Represents a mapping of token contract addresses to their market data.\n */\nexport type ContractMarketData = Record<Hex, MarketDataDetails>;\n\ntype ChainIdAndNativeCurrency = {\n chainId: Hex;\n nativeCurrency: string;\n};\n\n/**\n * The external actions available to the {@link TokenRatesController}.\n */\nexport type AllowedActions =\n | TokensControllerGetStateAction\n | NetworkControllerGetStateAction;\n\n/**\n * The external events available to the {@link TokenRatesController}.\n */\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The name of the {@link TokenRatesController}.\n */\nexport const controllerName = 'TokenRatesController';\n\n/**\n * @type TokenRatesState\n *\n * Token rates controller state\n *\n * @property marketData - Market data for tokens, keyed by chain ID and then token contract address.\n */\nexport type TokenRatesControllerState = {\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>;\n};\n\n/**\n * The action that can be performed to get the state of the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerActions = TokenRatesControllerGetStateAction;\n\n/**\n * The event that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The events that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerEvents = TokenRatesControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link TokenRatesController} for communication.\n */\nexport type TokenRatesControllerMessenger = Messenger<\n typeof controllerName,\n TokenRatesControllerActions | AllowedActions,\n TokenRatesControllerEvents | AllowedEvents\n>;\n\nconst tokenRatesControllerMetadata: StateMetadata<TokenRatesControllerState> = {\n marketData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n/**\n * Get the default {@link TokenRatesController} state.\n *\n * @returns The default {@link TokenRatesController} state.\n */\nexport const getDefaultTokenRatesControllerState =\n (): TokenRatesControllerState => {\n return {\n marketData: {},\n };\n };\n\n/** The input to start polling for the {@link TokenRatesController} */\nexport type TokenRatesPollingInput = {\n chainIds: Hex[];\n};\n\n/**\n * Controller that passively polls on a set interval for token-to-fiat exchange rates\n * for tokens stored in the TokensController\n */\nexport class TokenRatesController extends StaticIntervalPollingController<TokenRatesPollingInput>()<\n typeof controllerName,\n TokenRatesControllerState,\n TokenRatesControllerMessenger\n> {\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n #disabled: boolean;\n\n #allTokens: TokensControllerState['allTokens'];\n\n #allDetectedTokens: TokensControllerState['allDetectedTokens'];\n\n /**\n * Creates a TokenRatesController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The polling interval in ms\n * @param options.disabled - Boolean to track if network requests are blocked\n * @param options.tokenPricesService - An object in charge of retrieving token price\n * @param options.messenger - The messenger instance for communication\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = false,\n tokenPricesService,\n messenger,\n state,\n }: {\n interval?: number;\n disabled?: boolean;\n tokenPricesService: AbstractTokenPricesService;\n messenger: TokenRatesControllerMessenger;\n state?: Partial<TokenRatesControllerState>;\n }) {\n super({\n name: controllerName,\n messenger,\n state: { ...getDefaultTokenRatesControllerState(), ...state },\n metadata: tokenRatesControllerMetadata,\n });\n\n this.setIntervalLength(interval);\n this.#tokenPricesService = tokenPricesService;\n this.#disabled = disabled;\n\n const { allTokens, allDetectedTokens } = this.#getTokensControllerState();\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n this.#subscribeToTokensStateChange();\n\n this.#subscribeToNetworkStateChange();\n }\n\n #subscribeToTokensStateChange() {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ allTokens, allDetectedTokens }) => {\n if (this.#disabled) {\n return;\n }\n\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIds = [\n ...new Set([\n ...Object.keys(allTokens),\n ...Object.keys(allDetectedTokens),\n ]),\n ] as Hex[];\n\n const chainIdsToUpdate = chainIds.filter(\n (chainId) =>\n !isEqual(this.#allTokens[chainId], allTokens[chainId]) ||\n !isEqual(\n this.#allDetectedTokens[chainId],\n allDetectedTokens[chainId],\n ),\n );\n\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n const chainIdAndNativeCurrency = chainIdsToUpdate.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n },\n ({ allTokens, allDetectedTokens }) => {\n return { allTokens, allDetectedTokens };\n },\n );\n }\n\n #subscribeToNetworkStateChange() {\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n (_state, patches) => {\n // Remove state for deleted networks\n for (const patch of patches) {\n if (\n patch.op === 'remove' &&\n patch.path[0] === 'networkConfigurationsByChainId'\n ) {\n const removedChainId = patch.path[1] as Hex;\n this.update((state) => {\n delete state.marketData[removedChainId];\n });\n }\n }\n },\n );\n }\n\n /**\n * Get the tokens for the given chain.\n *\n * @param chainId - The chain ID.\n * @returns The list of tokens addresses for the current chain\n */\n #getTokenAddresses(chainId: Hex): Hex[] {\n const getTokens = (allTokens: Record<Hex, { address: string }[]>) =>\n Object.values(allTokens ?? {}).flatMap((tokens) =>\n tokens.map(({ address }) => toChecksumHexAddress(address) as Hex),\n );\n\n const tokenAddresses = getTokens(this.#allTokens[chainId]);\n const detectedTokenAddresses = getTokens(this.#allDetectedTokens[chainId]);\n\n return [\n ...new Set([\n ...tokenAddresses,\n ...detectedTokenAddresses,\n getNativeTokenAddress(chainId),\n ]),\n ].sort();\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable(): void {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable(): void {\n this.#disabled = true;\n }\n\n #getTokensControllerState(): {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n } {\n const { allTokens, allDetectedTokens } = this.messenger.call(\n 'TokensController:getState',\n );\n\n return {\n allTokens,\n allDetectedTokens,\n };\n }\n\n /**\n * Updates exchange rates for all tokens.\n *\n * @param chainIdAndNativeCurrency - The chain ID and native currency.\n */\n async updateExchangeRates(\n chainIdAndNativeCurrency: ChainIdAndNativeCurrency[],\n ): Promise<void> {\n if (this.#disabled) {\n return;\n }\n\n const marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {};\n const assetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n const unsupportedAssetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n for (const { chainId, nativeCurrency } of chainIdAndNativeCurrency) {\n if (this.#tokenPricesService.validateChainIdSupported(chainId)) {\n for (const tokenAddress of this.#getTokenAddresses(chainId)) {\n if (\n this.#tokenPricesService.validateCurrencySupported(nativeCurrency)\n ) {\n (assetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n } else {\n (unsupportedAssetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n }\n }\n }\n }\n\n const promises = [\n ...Object.entries(assetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ...Object.entries(unsupportedAssetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ];\n\n await Promise.allSettled(promises);\n\n const chainIds = new Set(\n Object.values(chainIdAndNativeCurrency).map((chain) => chain.chainId),\n );\n\n for (const chainId of chainIds) {\n if (!marketData[chainId]) {\n marketData[chainId] = {};\n }\n }\n\n if (Object.keys(marketData).length > 0) {\n this.update((state) => {\n state.marketData = {\n ...state.marketData,\n ...marketData,\n };\n });\n }\n }\n\n async #fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {},\n ) {\n return await reduceInBatchesSerially<\n { chainId: Hex; tokenAddress: Hex },\n Record<Hex, Record<Hex, MarketDataDetails>>\n >({\n values: assets,\n batchSize: TOKEN_PRICES_BATCH_SIZE,\n eachBatch: async (partialMarketData, assetsBatch) => {\n const batchMarketData = await this.#tokenPricesService.fetchTokenPrices(\n {\n assets: assetsBatch,\n currency,\n },\n );\n\n for (const tokenPrice of batchMarketData) {\n (partialMarketData[tokenPrice.chainId] ??= {})[\n tokenPrice.tokenAddress\n ] = tokenPrice;\n }\n\n return partialMarketData;\n },\n initialResult: marketData,\n });\n }\n\n async #fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>,\n ) {\n // Step -1: Then fetch all tracked tokens priced in USD\n const marketDataInUSD =\n await this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n 'usd', // Fallback currency when the native currency is not supported\n );\n\n // Formula: price_in_native = token_usd / native_usd\n const convertUSDToNative = (\n valueInUSD: number,\n nativeTokenPriceInUSD: number,\n ) => valueInUSD / nativeTokenPriceInUSD;\n\n // Step -2: Convert USD prices to native currency\n for (const [chainId, marketDataByTokenAddress] of Object.entries(\n marketDataInUSD,\n ) as [Hex, Record<Hex, MarketDataDetails>][]) {\n const nativeTokenPriceInUSD =\n marketDataByTokenAddress[getNativeTokenAddress(chainId)]?.price;\n\n // Return here if it's null, undefined or 0\n if (!nativeTokenPriceInUSD) {\n continue;\n }\n\n for (const [tokenAddress, tokenData] of Object.entries(\n marketDataByTokenAddress,\n ) as [Hex, MarketDataDetails][]) {\n (marketData[chainId] ??= {})[tokenAddress] = {\n ...tokenData,\n currency,\n price: convertUSDToNative(tokenData.price, nativeTokenPriceInUSD),\n marketCap: convertUSDToNative(\n tokenData.marketCap,\n nativeTokenPriceInUSD,\n ),\n allTimeHigh: convertUSDToNative(\n tokenData.allTimeHigh,\n nativeTokenPriceInUSD,\n ),\n allTimeLow: convertUSDToNative(\n tokenData.allTimeLow,\n nativeTokenPriceInUSD,\n ),\n totalVolume: convertUSDToNative(\n tokenData.totalVolume,\n nativeTokenPriceInUSD,\n ),\n high1d: convertUSDToNative(tokenData.high1d, nativeTokenPriceInUSD),\n low1d: convertUSDToNative(tokenData.low1d, nativeTokenPriceInUSD),\n dilutedMarketCap: convertUSDToNative(\n tokenData.dilutedMarketCap,\n nativeTokenPriceInUSD,\n ),\n };\n }\n }\n }\n\n /**\n * Updates token rates for the given networkClientId\n *\n * @param input - The input for the poll.\n * @param input.chainIds - The chain ids to poll token rates on.\n */\n async _executePoll({ chainIds }: TokenRatesPollingInput): Promise<void> {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIdAndNativeCurrency = chainIds.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n }\n\n /**\n * Reset the controller state to the default state.\n */\n resetState() {\n this.update(() => {\n return getDefaultTokenRatesControllerState();\n });\n }\n}\n\nexport default TokenRatesController;\n"]}
1
+ {"version":3,"file":"TokenRatesController.cjs","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { NetworkEnablementControllerGetStateAction } from '@metamask/network-enablement-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { reduceInBatchesSerially, TOKEN_PRICES_BATCH_SIZE } from './assetsUtil';\nimport type { AbstractTokenPricesService } from './token-prices-service/abstract-token-prices-service';\nimport { getNativeTokenAddress } from './token-prices-service/codefi-v2';\nimport { TokenRwaData } from './token-service';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerStateChangeEvent,\n TokensControllerState,\n} from './TokensController';\n\n/**\n * @type Token\n *\n * Token representation\n *\n * @property address - Hex address of the token contract\n * @property decimals - Number of decimals the token uses\n * @property symbol - Symbol of the token\n * @property aggregators - An array containing the token's aggregators\n * @property image - Image of the token, url or bit32 image\n * @property hasBalanceError - 'true' if there is an error while updating the token balance\n * @property isERC721 - 'true' if the token is a ERC721 token\n * @property name - Name of the token\n */\nexport type Token = {\n address: string;\n decimals: number;\n symbol: string;\n aggregators?: string[];\n image?: string;\n hasBalanceError?: boolean;\n isERC721?: boolean;\n name?: string;\n rwaData?: TokenRwaData;\n};\n\nconst DEFAULT_INTERVAL = 180000;\n\nexport type ContractExchangeRates = {\n [address: string]: number | undefined;\n};\n\nexport type MarketDataDetails = {\n tokenAddress: `0x${string}`;\n currency: string;\n allTimeHigh: number;\n allTimeLow: number;\n circulatingSupply: number;\n dilutedMarketCap: number;\n high1d: number;\n low1d: number;\n marketCap: number;\n marketCapPercentChange1d: number;\n price: number;\n priceChange1d: number;\n pricePercentChange1d: number;\n pricePercentChange1h: number;\n pricePercentChange1y: number;\n pricePercentChange7d: number;\n pricePercentChange14d: number;\n pricePercentChange30d: number;\n pricePercentChange200d: number;\n totalVolume: number;\n};\n\n/**\n * Represents a mapping of token contract addresses to their market data.\n */\nexport type ContractMarketData = Record<Hex, MarketDataDetails>;\n\ntype ChainIdAndNativeCurrency = {\n chainId: Hex;\n nativeCurrency: string;\n};\n\n/**\n * The external actions available to the {@link TokenRatesController}.\n */\nexport type AllowedActions =\n | TokensControllerGetStateAction\n | NetworkControllerGetStateAction\n | NetworkEnablementControllerGetStateAction;\n\n/**\n * The external events available to the {@link TokenRatesController}.\n */\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The name of the {@link TokenRatesController}.\n */\nexport const controllerName = 'TokenRatesController';\n\n/**\n * @type TokenRatesState\n *\n * Token rates controller state\n *\n * @property marketData - Market data for tokens, keyed by chain ID and then token contract address.\n */\nexport type TokenRatesControllerState = {\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>;\n};\n\n/**\n * The action that can be performed to get the state of the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerActions = TokenRatesControllerGetStateAction;\n\n/**\n * The event that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The events that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerEvents = TokenRatesControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link TokenRatesController} for communication.\n */\nexport type TokenRatesControllerMessenger = Messenger<\n typeof controllerName,\n TokenRatesControllerActions | AllowedActions,\n TokenRatesControllerEvents | AllowedEvents\n>;\n\nconst tokenRatesControllerMetadata: StateMetadata<TokenRatesControllerState> = {\n marketData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n/**\n * Get the default {@link TokenRatesController} state.\n *\n * @returns The default {@link TokenRatesController} state.\n */\nexport const getDefaultTokenRatesControllerState =\n (): TokenRatesControllerState => {\n return {\n marketData: {},\n };\n };\n\n/** The input to start polling for the {@link TokenRatesController} */\nexport type TokenRatesPollingInput = {\n chainIds: Hex[];\n};\n\n/**\n * Controller that passively polls on a set interval for token-to-fiat exchange rates\n * for tokens stored in the TokensController\n */\nexport class TokenRatesController extends StaticIntervalPollingController<TokenRatesPollingInput>()<\n typeof controllerName,\n TokenRatesControllerState,\n TokenRatesControllerMessenger\n> {\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n #disabled: boolean;\n\n #allTokens: TokensControllerState['allTokens'];\n\n #allDetectedTokens: TokensControllerState['allDetectedTokens'];\n\n /**\n * Creates a TokenRatesController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The polling interval in ms\n * @param options.disabled - Boolean to track if network requests are blocked\n * @param options.tokenPricesService - An object in charge of retrieving token price\n * @param options.messenger - The messenger instance for communication\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = false,\n tokenPricesService,\n messenger,\n state,\n }: {\n interval?: number;\n disabled?: boolean;\n tokenPricesService: AbstractTokenPricesService;\n messenger: TokenRatesControllerMessenger;\n state?: Partial<TokenRatesControllerState>;\n }) {\n super({\n name: controllerName,\n messenger,\n state: { ...getDefaultTokenRatesControllerState(), ...state },\n metadata: tokenRatesControllerMetadata,\n });\n\n this.setIntervalLength(interval);\n this.#tokenPricesService = tokenPricesService;\n this.#disabled = disabled;\n\n const { allTokens, allDetectedTokens } = this.#getTokensControllerState();\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n // Set native asset identifiers from NetworkEnablementController for CAIP-19 native token lookups\n this.#initNativeAssetIdentifiers();\n\n this.#subscribeToTokensStateChange();\n\n this.#subscribeToNetworkStateChange();\n }\n\n #subscribeToTokensStateChange() {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ allTokens, allDetectedTokens }) => {\n if (this.#disabled) {\n return;\n }\n\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIds = [\n ...new Set([\n ...Object.keys(allTokens),\n ...Object.keys(allDetectedTokens),\n ]),\n ] as Hex[];\n\n const chainIdsToUpdate = chainIds.filter(\n (chainId) =>\n !isEqual(this.#allTokens[chainId], allTokens[chainId]) ||\n !isEqual(\n this.#allDetectedTokens[chainId],\n allDetectedTokens[chainId],\n ),\n );\n\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n const chainIdAndNativeCurrency = chainIdsToUpdate.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n },\n ({ allTokens, allDetectedTokens }) => {\n return { allTokens, allDetectedTokens };\n },\n );\n }\n\n #subscribeToNetworkStateChange() {\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n (_state, patches) => {\n // Remove state for deleted networks\n for (const patch of patches) {\n if (\n patch.op === 'remove' &&\n patch.path[0] === 'networkConfigurationsByChainId'\n ) {\n const removedChainId = patch.path[1] as Hex;\n this.update((state) => {\n delete state.marketData[removedChainId];\n });\n }\n }\n },\n );\n }\n\n /**\n * Initialize the native asset identifiers from NetworkEnablementController.\n * This provides CAIP-19 native asset IDs for the token prices service.\n */\n #initNativeAssetIdentifiers(): void {\n if (this.#tokenPricesService.setNativeAssetIdentifiers) {\n const { nativeAssetIdentifiers } = this.messenger.call(\n 'NetworkEnablementController:getState',\n );\n this.#tokenPricesService.setNativeAssetIdentifiers(\n nativeAssetIdentifiers,\n );\n }\n }\n\n /**\n * Get the tokens for the given chain.\n *\n * @param chainId - The chain ID.\n * @returns The list of tokens addresses for the current chain\n */\n #getTokenAddresses(chainId: Hex): Hex[] {\n const getTokens = (allTokens: Record<Hex, { address: string }[]>) =>\n Object.values(allTokens ?? {}).flatMap((tokens) =>\n tokens.map(({ address }) => toChecksumHexAddress(address) as Hex),\n );\n\n const tokenAddresses = getTokens(this.#allTokens[chainId]);\n const detectedTokenAddresses = getTokens(this.#allDetectedTokens[chainId]);\n\n return [\n ...new Set([\n ...tokenAddresses,\n ...detectedTokenAddresses,\n getNativeTokenAddress(chainId),\n ]),\n ].sort();\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable(): void {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable(): void {\n this.#disabled = true;\n }\n\n #getTokensControllerState(): {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n } {\n const { allTokens, allDetectedTokens } = this.messenger.call(\n 'TokensController:getState',\n );\n\n return {\n allTokens,\n allDetectedTokens,\n };\n }\n\n /**\n * Updates exchange rates for all tokens.\n *\n * @param chainIdAndNativeCurrency - The chain ID and native currency.\n */\n async updateExchangeRates(\n chainIdAndNativeCurrency: ChainIdAndNativeCurrency[],\n ): Promise<void> {\n if (this.#disabled) {\n return;\n }\n\n const marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {};\n const assetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n const unsupportedAssetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n for (const { chainId, nativeCurrency } of chainIdAndNativeCurrency) {\n if (this.#tokenPricesService.validateChainIdSupported(chainId)) {\n for (const tokenAddress of this.#getTokenAddresses(chainId)) {\n if (\n this.#tokenPricesService.validateCurrencySupported(nativeCurrency)\n ) {\n (assetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n } else {\n (unsupportedAssetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n }\n }\n }\n }\n\n const promises = [\n ...Object.entries(assetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ...Object.entries(unsupportedAssetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ];\n\n await Promise.allSettled(promises);\n\n const chainIds = new Set(\n Object.values(chainIdAndNativeCurrency).map((chain) => chain.chainId),\n );\n\n for (const chainId of chainIds) {\n if (!marketData[chainId]) {\n marketData[chainId] = {};\n }\n }\n\n if (Object.keys(marketData).length > 0) {\n this.update((state) => {\n state.marketData = {\n ...state.marketData,\n ...marketData,\n };\n });\n }\n }\n\n async #fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {},\n ) {\n return await reduceInBatchesSerially<\n { chainId: Hex; tokenAddress: Hex },\n Record<Hex, Record<Hex, MarketDataDetails>>\n >({\n values: assets,\n batchSize: TOKEN_PRICES_BATCH_SIZE,\n eachBatch: async (partialMarketData, assetsBatch) => {\n const batchMarketData = await this.#tokenPricesService.fetchTokenPrices(\n {\n assets: assetsBatch,\n currency,\n },\n );\n\n for (const tokenPrice of batchMarketData) {\n (partialMarketData[tokenPrice.chainId] ??= {})[\n tokenPrice.tokenAddress\n ] = tokenPrice;\n }\n\n return partialMarketData;\n },\n initialResult: marketData,\n });\n }\n\n async #fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>,\n ) {\n // Step -1: Then fetch all tracked tokens priced in USD\n const marketDataInUSD =\n await this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n 'usd', // Fallback currency when the native currency is not supported\n );\n\n // Formula: price_in_native = token_usd / native_usd\n const convertUSDToNative = (\n valueInUSD: number,\n nativeTokenPriceInUSD: number,\n ) => valueInUSD / nativeTokenPriceInUSD;\n\n // Step -2: Convert USD prices to native currency\n for (const [chainId, marketDataByTokenAddress] of Object.entries(\n marketDataInUSD,\n ) as [Hex, Record<Hex, MarketDataDetails>][]) {\n const nativeTokenPriceInUSD =\n marketDataByTokenAddress[getNativeTokenAddress(chainId)]?.price;\n\n // Return here if it's null, undefined or 0\n if (!nativeTokenPriceInUSD) {\n continue;\n }\n\n for (const [tokenAddress, tokenData] of Object.entries(\n marketDataByTokenAddress,\n ) as [Hex, MarketDataDetails][]) {\n (marketData[chainId] ??= {})[tokenAddress] = {\n ...tokenData,\n currency,\n price: convertUSDToNative(tokenData.price, nativeTokenPriceInUSD),\n marketCap: convertUSDToNative(\n tokenData.marketCap,\n nativeTokenPriceInUSD,\n ),\n allTimeHigh: convertUSDToNative(\n tokenData.allTimeHigh,\n nativeTokenPriceInUSD,\n ),\n allTimeLow: convertUSDToNative(\n tokenData.allTimeLow,\n nativeTokenPriceInUSD,\n ),\n totalVolume: convertUSDToNative(\n tokenData.totalVolume,\n nativeTokenPriceInUSD,\n ),\n high1d: convertUSDToNative(tokenData.high1d, nativeTokenPriceInUSD),\n low1d: convertUSDToNative(tokenData.low1d, nativeTokenPriceInUSD),\n dilutedMarketCap: convertUSDToNative(\n tokenData.dilutedMarketCap,\n nativeTokenPriceInUSD,\n ),\n };\n }\n }\n }\n\n /**\n * Updates token rates for the given networkClientId\n *\n * @param input - The input for the poll.\n * @param input.chainIds - The chain ids to poll token rates on.\n */\n async _executePoll({ chainIds }: TokenRatesPollingInput): Promise<void> {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIdAndNativeCurrency = chainIds.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n }\n\n /**\n * Reset the controller state to the default state.\n */\n resetState() {\n this.update(() => {\n return getDefaultTokenRatesControllerState();\n });\n }\n}\n\nexport default TokenRatesController;\n"]}
@@ -1,6 +1,7 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
2
  import type { Messenger } from "@metamask/messenger";
3
3
  import type { NetworkControllerGetStateAction, NetworkControllerStateChangeEvent } from "@metamask/network-controller";
4
+ import type { NetworkEnablementControllerGetStateAction } from "@metamask/network-enablement-controller";
4
5
  import type { Hex } from "@metamask/utils";
5
6
  import type { AbstractTokenPricesService } from "./token-prices-service/abstract-token-prices-service.cjs";
6
7
  import { TokenRwaData } from "./token-service.cjs";
@@ -66,7 +67,7 @@ type ChainIdAndNativeCurrency = {
66
67
  /**
67
68
  * The external actions available to the {@link TokenRatesController}.
68
69
  */
69
- export type AllowedActions = TokensControllerGetStateAction | NetworkControllerGetStateAction;
70
+ export type AllowedActions = TokensControllerGetStateAction | NetworkControllerGetStateAction | NetworkEnablementControllerGetStateAction;
70
71
  /**
71
72
  * The external events available to the {@link TokenRatesController}.
72
73
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TokenRatesController.d.cts","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenRatesController.d.cts","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
2
  import type { Messenger } from "@metamask/messenger";
3
3
  import type { NetworkControllerGetStateAction, NetworkControllerStateChangeEvent } from "@metamask/network-controller";
4
+ import type { NetworkEnablementControllerGetStateAction } from "@metamask/network-enablement-controller";
4
5
  import type { Hex } from "@metamask/utils";
5
6
  import type { AbstractTokenPricesService } from "./token-prices-service/abstract-token-prices-service.mjs";
6
7
  import { TokenRwaData } from "./token-service.mjs";
@@ -66,7 +67,7 @@ type ChainIdAndNativeCurrency = {
66
67
  /**
67
68
  * The external actions available to the {@link TokenRatesController}.
68
69
  */
69
- export type AllowedActions = TokensControllerGetStateAction | NetworkControllerGetStateAction;
70
+ export type AllowedActions = TokensControllerGetStateAction | NetworkControllerGetStateAction | NetworkEnablementControllerGetStateAction;
70
71
  /**
71
72
  * The external events available to the {@link TokenRatesController}.
72
73
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TokenRatesController.d.mts","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenRatesController.d.mts","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _TokenRatesController_instances, _TokenRatesController_tokenPricesService, _TokenRatesController_disabled, _TokenRatesController_allTokens, _TokenRatesController_allDetectedTokens, _TokenRatesController_subscribeToTokensStateChange, _TokenRatesController_subscribeToNetworkStateChange, _TokenRatesController_getTokenAddresses, _TokenRatesController_getTokensControllerState, _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency, _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency;
12
+ var _TokenRatesController_instances, _TokenRatesController_tokenPricesService, _TokenRatesController_disabled, _TokenRatesController_allTokens, _TokenRatesController_allDetectedTokens, _TokenRatesController_subscribeToTokensStateChange, _TokenRatesController_subscribeToNetworkStateChange, _TokenRatesController_initNativeAssetIdentifiers, _TokenRatesController_getTokenAddresses, _TokenRatesController_getTokensControllerState, _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency, _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency;
13
13
  import { toChecksumHexAddress } from "@metamask/controller-utils";
14
14
  import { StaticIntervalPollingController } from "@metamask/polling-controller";
15
15
  import $lodash from "lodash";
@@ -72,6 +72,8 @@ export class TokenRatesController extends StaticIntervalPollingController() {
72
72
  const { allTokens, allDetectedTokens } = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokensControllerState).call(this);
73
73
  __classPrivateFieldSet(this, _TokenRatesController_allTokens, allTokens, "f");
74
74
  __classPrivateFieldSet(this, _TokenRatesController_allDetectedTokens, allDetectedTokens, "f");
75
+ // Set native asset identifiers from NetworkEnablementController for CAIP-19 native token lookups
76
+ __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_initNativeAssetIdentifiers).call(this);
75
77
  __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_subscribeToTokensStateChange).call(this);
76
78
  __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_subscribeToNetworkStateChange).call(this);
77
79
  }
@@ -216,6 +218,11 @@ _TokenRatesController_tokenPricesService = new WeakMap(), _TokenRatesController_
216
218
  }
217
219
  }
218
220
  });
221
+ }, _TokenRatesController_initNativeAssetIdentifiers = function _TokenRatesController_initNativeAssetIdentifiers() {
222
+ if (__classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").setNativeAssetIdentifiers) {
223
+ const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
224
+ __classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").setNativeAssetIdentifiers(nativeAssetIdentifiers);
225
+ }
219
226
  }, _TokenRatesController_getTokenAddresses = function _TokenRatesController_getTokenAddresses(chainId) {
220
227
  const getTokens = (allTokens) => Object.values(allTokens ?? {}).flatMap((tokens) => tokens.map(({ address }) => toChecksumHexAddress(address)));
221
228
  const tokenAddresses = getTokens(__classPrivateFieldGet(this, _TokenRatesController_allTokens, "f")[chainId]);
@@ -1 +1 @@
1
- {"version":3,"file":"TokenRatesController.mjs","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { reduceInBatchesSerially, TOKEN_PRICES_BATCH_SIZE } from './assetsUtil';\nimport type { AbstractTokenPricesService } from './token-prices-service/abstract-token-prices-service';\nimport { getNativeTokenAddress } from './token-prices-service/codefi-v2';\nimport { TokenRwaData } from './token-service';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerStateChangeEvent,\n TokensControllerState,\n} from './TokensController';\n\n/**\n * @type Token\n *\n * Token representation\n *\n * @property address - Hex address of the token contract\n * @property decimals - Number of decimals the token uses\n * @property symbol - Symbol of the token\n * @property aggregators - An array containing the token's aggregators\n * @property image - Image of the token, url or bit32 image\n * @property hasBalanceError - 'true' if there is an error while updating the token balance\n * @property isERC721 - 'true' if the token is a ERC721 token\n * @property name - Name of the token\n */\nexport type Token = {\n address: string;\n decimals: number;\n symbol: string;\n aggregators?: string[];\n image?: string;\n hasBalanceError?: boolean;\n isERC721?: boolean;\n name?: string;\n rwaData?: TokenRwaData;\n};\n\nconst DEFAULT_INTERVAL = 180000;\n\nexport type ContractExchangeRates = {\n [address: string]: number | undefined;\n};\n\nexport type MarketDataDetails = {\n tokenAddress: `0x${string}`;\n currency: string;\n allTimeHigh: number;\n allTimeLow: number;\n circulatingSupply: number;\n dilutedMarketCap: number;\n high1d: number;\n low1d: number;\n marketCap: number;\n marketCapPercentChange1d: number;\n price: number;\n priceChange1d: number;\n pricePercentChange1d: number;\n pricePercentChange1h: number;\n pricePercentChange1y: number;\n pricePercentChange7d: number;\n pricePercentChange14d: number;\n pricePercentChange30d: number;\n pricePercentChange200d: number;\n totalVolume: number;\n};\n\n/**\n * Represents a mapping of token contract addresses to their market data.\n */\nexport type ContractMarketData = Record<Hex, MarketDataDetails>;\n\ntype ChainIdAndNativeCurrency = {\n chainId: Hex;\n nativeCurrency: string;\n};\n\n/**\n * The external actions available to the {@link TokenRatesController}.\n */\nexport type AllowedActions =\n | TokensControllerGetStateAction\n | NetworkControllerGetStateAction;\n\n/**\n * The external events available to the {@link TokenRatesController}.\n */\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The name of the {@link TokenRatesController}.\n */\nexport const controllerName = 'TokenRatesController';\n\n/**\n * @type TokenRatesState\n *\n * Token rates controller state\n *\n * @property marketData - Market data for tokens, keyed by chain ID and then token contract address.\n */\nexport type TokenRatesControllerState = {\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>;\n};\n\n/**\n * The action that can be performed to get the state of the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerActions = TokenRatesControllerGetStateAction;\n\n/**\n * The event that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The events that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerEvents = TokenRatesControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link TokenRatesController} for communication.\n */\nexport type TokenRatesControllerMessenger = Messenger<\n typeof controllerName,\n TokenRatesControllerActions | AllowedActions,\n TokenRatesControllerEvents | AllowedEvents\n>;\n\nconst tokenRatesControllerMetadata: StateMetadata<TokenRatesControllerState> = {\n marketData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n/**\n * Get the default {@link TokenRatesController} state.\n *\n * @returns The default {@link TokenRatesController} state.\n */\nexport const getDefaultTokenRatesControllerState =\n (): TokenRatesControllerState => {\n return {\n marketData: {},\n };\n };\n\n/** The input to start polling for the {@link TokenRatesController} */\nexport type TokenRatesPollingInput = {\n chainIds: Hex[];\n};\n\n/**\n * Controller that passively polls on a set interval for token-to-fiat exchange rates\n * for tokens stored in the TokensController\n */\nexport class TokenRatesController extends StaticIntervalPollingController<TokenRatesPollingInput>()<\n typeof controllerName,\n TokenRatesControllerState,\n TokenRatesControllerMessenger\n> {\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n #disabled: boolean;\n\n #allTokens: TokensControllerState['allTokens'];\n\n #allDetectedTokens: TokensControllerState['allDetectedTokens'];\n\n /**\n * Creates a TokenRatesController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The polling interval in ms\n * @param options.disabled - Boolean to track if network requests are blocked\n * @param options.tokenPricesService - An object in charge of retrieving token price\n * @param options.messenger - The messenger instance for communication\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = false,\n tokenPricesService,\n messenger,\n state,\n }: {\n interval?: number;\n disabled?: boolean;\n tokenPricesService: AbstractTokenPricesService;\n messenger: TokenRatesControllerMessenger;\n state?: Partial<TokenRatesControllerState>;\n }) {\n super({\n name: controllerName,\n messenger,\n state: { ...getDefaultTokenRatesControllerState(), ...state },\n metadata: tokenRatesControllerMetadata,\n });\n\n this.setIntervalLength(interval);\n this.#tokenPricesService = tokenPricesService;\n this.#disabled = disabled;\n\n const { allTokens, allDetectedTokens } = this.#getTokensControllerState();\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n this.#subscribeToTokensStateChange();\n\n this.#subscribeToNetworkStateChange();\n }\n\n #subscribeToTokensStateChange() {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ allTokens, allDetectedTokens }) => {\n if (this.#disabled) {\n return;\n }\n\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIds = [\n ...new Set([\n ...Object.keys(allTokens),\n ...Object.keys(allDetectedTokens),\n ]),\n ] as Hex[];\n\n const chainIdsToUpdate = chainIds.filter(\n (chainId) =>\n !isEqual(this.#allTokens[chainId], allTokens[chainId]) ||\n !isEqual(\n this.#allDetectedTokens[chainId],\n allDetectedTokens[chainId],\n ),\n );\n\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n const chainIdAndNativeCurrency = chainIdsToUpdate.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n },\n ({ allTokens, allDetectedTokens }) => {\n return { allTokens, allDetectedTokens };\n },\n );\n }\n\n #subscribeToNetworkStateChange() {\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n (_state, patches) => {\n // Remove state for deleted networks\n for (const patch of patches) {\n if (\n patch.op === 'remove' &&\n patch.path[0] === 'networkConfigurationsByChainId'\n ) {\n const removedChainId = patch.path[1] as Hex;\n this.update((state) => {\n delete state.marketData[removedChainId];\n });\n }\n }\n },\n );\n }\n\n /**\n * Get the tokens for the given chain.\n *\n * @param chainId - The chain ID.\n * @returns The list of tokens addresses for the current chain\n */\n #getTokenAddresses(chainId: Hex): Hex[] {\n const getTokens = (allTokens: Record<Hex, { address: string }[]>) =>\n Object.values(allTokens ?? {}).flatMap((tokens) =>\n tokens.map(({ address }) => toChecksumHexAddress(address) as Hex),\n );\n\n const tokenAddresses = getTokens(this.#allTokens[chainId]);\n const detectedTokenAddresses = getTokens(this.#allDetectedTokens[chainId]);\n\n return [\n ...new Set([\n ...tokenAddresses,\n ...detectedTokenAddresses,\n getNativeTokenAddress(chainId),\n ]),\n ].sort();\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable(): void {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable(): void {\n this.#disabled = true;\n }\n\n #getTokensControllerState(): {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n } {\n const { allTokens, allDetectedTokens } = this.messenger.call(\n 'TokensController:getState',\n );\n\n return {\n allTokens,\n allDetectedTokens,\n };\n }\n\n /**\n * Updates exchange rates for all tokens.\n *\n * @param chainIdAndNativeCurrency - The chain ID and native currency.\n */\n async updateExchangeRates(\n chainIdAndNativeCurrency: ChainIdAndNativeCurrency[],\n ): Promise<void> {\n if (this.#disabled) {\n return;\n }\n\n const marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {};\n const assetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n const unsupportedAssetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n for (const { chainId, nativeCurrency } of chainIdAndNativeCurrency) {\n if (this.#tokenPricesService.validateChainIdSupported(chainId)) {\n for (const tokenAddress of this.#getTokenAddresses(chainId)) {\n if (\n this.#tokenPricesService.validateCurrencySupported(nativeCurrency)\n ) {\n (assetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n } else {\n (unsupportedAssetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n }\n }\n }\n }\n\n const promises = [\n ...Object.entries(assetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ...Object.entries(unsupportedAssetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ];\n\n await Promise.allSettled(promises);\n\n const chainIds = new Set(\n Object.values(chainIdAndNativeCurrency).map((chain) => chain.chainId),\n );\n\n for (const chainId of chainIds) {\n if (!marketData[chainId]) {\n marketData[chainId] = {};\n }\n }\n\n if (Object.keys(marketData).length > 0) {\n this.update((state) => {\n state.marketData = {\n ...state.marketData,\n ...marketData,\n };\n });\n }\n }\n\n async #fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {},\n ) {\n return await reduceInBatchesSerially<\n { chainId: Hex; tokenAddress: Hex },\n Record<Hex, Record<Hex, MarketDataDetails>>\n >({\n values: assets,\n batchSize: TOKEN_PRICES_BATCH_SIZE,\n eachBatch: async (partialMarketData, assetsBatch) => {\n const batchMarketData = await this.#tokenPricesService.fetchTokenPrices(\n {\n assets: assetsBatch,\n currency,\n },\n );\n\n for (const tokenPrice of batchMarketData) {\n (partialMarketData[tokenPrice.chainId] ??= {})[\n tokenPrice.tokenAddress\n ] = tokenPrice;\n }\n\n return partialMarketData;\n },\n initialResult: marketData,\n });\n }\n\n async #fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>,\n ) {\n // Step -1: Then fetch all tracked tokens priced in USD\n const marketDataInUSD =\n await this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n 'usd', // Fallback currency when the native currency is not supported\n );\n\n // Formula: price_in_native = token_usd / native_usd\n const convertUSDToNative = (\n valueInUSD: number,\n nativeTokenPriceInUSD: number,\n ) => valueInUSD / nativeTokenPriceInUSD;\n\n // Step -2: Convert USD prices to native currency\n for (const [chainId, marketDataByTokenAddress] of Object.entries(\n marketDataInUSD,\n ) as [Hex, Record<Hex, MarketDataDetails>][]) {\n const nativeTokenPriceInUSD =\n marketDataByTokenAddress[getNativeTokenAddress(chainId)]?.price;\n\n // Return here if it's null, undefined or 0\n if (!nativeTokenPriceInUSD) {\n continue;\n }\n\n for (const [tokenAddress, tokenData] of Object.entries(\n marketDataByTokenAddress,\n ) as [Hex, MarketDataDetails][]) {\n (marketData[chainId] ??= {})[tokenAddress] = {\n ...tokenData,\n currency,\n price: convertUSDToNative(tokenData.price, nativeTokenPriceInUSD),\n marketCap: convertUSDToNative(\n tokenData.marketCap,\n nativeTokenPriceInUSD,\n ),\n allTimeHigh: convertUSDToNative(\n tokenData.allTimeHigh,\n nativeTokenPriceInUSD,\n ),\n allTimeLow: convertUSDToNative(\n tokenData.allTimeLow,\n nativeTokenPriceInUSD,\n ),\n totalVolume: convertUSDToNative(\n tokenData.totalVolume,\n nativeTokenPriceInUSD,\n ),\n high1d: convertUSDToNative(tokenData.high1d, nativeTokenPriceInUSD),\n low1d: convertUSDToNative(tokenData.low1d, nativeTokenPriceInUSD),\n dilutedMarketCap: convertUSDToNative(\n tokenData.dilutedMarketCap,\n nativeTokenPriceInUSD,\n ),\n };\n }\n }\n }\n\n /**\n * Updates token rates for the given networkClientId\n *\n * @param input - The input for the poll.\n * @param input.chainIds - The chain ids to poll token rates on.\n */\n async _executePoll({ chainIds }: TokenRatesPollingInput): Promise<void> {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIdAndNativeCurrency = chainIds.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n }\n\n /**\n * Reset the controller state to the default state.\n */\n resetState() {\n this.update(() => {\n return getDefaultTokenRatesControllerState();\n });\n }\n}\n\nexport default TokenRatesController;\n"]}
1
+ {"version":3,"file":"TokenRatesController.mjs","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { toChecksumHexAddress } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type { NetworkEnablementControllerGetStateAction } from '@metamask/network-enablement-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { reduceInBatchesSerially, TOKEN_PRICES_BATCH_SIZE } from './assetsUtil';\nimport type { AbstractTokenPricesService } from './token-prices-service/abstract-token-prices-service';\nimport { getNativeTokenAddress } from './token-prices-service/codefi-v2';\nimport { TokenRwaData } from './token-service';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerStateChangeEvent,\n TokensControllerState,\n} from './TokensController';\n\n/**\n * @type Token\n *\n * Token representation\n *\n * @property address - Hex address of the token contract\n * @property decimals - Number of decimals the token uses\n * @property symbol - Symbol of the token\n * @property aggregators - An array containing the token's aggregators\n * @property image - Image of the token, url or bit32 image\n * @property hasBalanceError - 'true' if there is an error while updating the token balance\n * @property isERC721 - 'true' if the token is a ERC721 token\n * @property name - Name of the token\n */\nexport type Token = {\n address: string;\n decimals: number;\n symbol: string;\n aggregators?: string[];\n image?: string;\n hasBalanceError?: boolean;\n isERC721?: boolean;\n name?: string;\n rwaData?: TokenRwaData;\n};\n\nconst DEFAULT_INTERVAL = 180000;\n\nexport type ContractExchangeRates = {\n [address: string]: number | undefined;\n};\n\nexport type MarketDataDetails = {\n tokenAddress: `0x${string}`;\n currency: string;\n allTimeHigh: number;\n allTimeLow: number;\n circulatingSupply: number;\n dilutedMarketCap: number;\n high1d: number;\n low1d: number;\n marketCap: number;\n marketCapPercentChange1d: number;\n price: number;\n priceChange1d: number;\n pricePercentChange1d: number;\n pricePercentChange1h: number;\n pricePercentChange1y: number;\n pricePercentChange7d: number;\n pricePercentChange14d: number;\n pricePercentChange30d: number;\n pricePercentChange200d: number;\n totalVolume: number;\n};\n\n/**\n * Represents a mapping of token contract addresses to their market data.\n */\nexport type ContractMarketData = Record<Hex, MarketDataDetails>;\n\ntype ChainIdAndNativeCurrency = {\n chainId: Hex;\n nativeCurrency: string;\n};\n\n/**\n * The external actions available to the {@link TokenRatesController}.\n */\nexport type AllowedActions =\n | TokensControllerGetStateAction\n | NetworkControllerGetStateAction\n | NetworkEnablementControllerGetStateAction;\n\n/**\n * The external events available to the {@link TokenRatesController}.\n */\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The name of the {@link TokenRatesController}.\n */\nexport const controllerName = 'TokenRatesController';\n\n/**\n * @type TokenRatesState\n *\n * Token rates controller state\n *\n * @property marketData - Market data for tokens, keyed by chain ID and then token contract address.\n */\nexport type TokenRatesControllerState = {\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>;\n};\n\n/**\n * The action that can be performed to get the state of the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link TokenRatesController}.\n */\nexport type TokenRatesControllerActions = TokenRatesControllerGetStateAction;\n\n/**\n * The event that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n TokenRatesControllerState\n>;\n\n/**\n * The events that {@link TokenRatesController} can emit.\n */\nexport type TokenRatesControllerEvents = TokenRatesControllerStateChangeEvent;\n\n/**\n * The messenger of the {@link TokenRatesController} for communication.\n */\nexport type TokenRatesControllerMessenger = Messenger<\n typeof controllerName,\n TokenRatesControllerActions | AllowedActions,\n TokenRatesControllerEvents | AllowedEvents\n>;\n\nconst tokenRatesControllerMetadata: StateMetadata<TokenRatesControllerState> = {\n marketData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n/**\n * Get the default {@link TokenRatesController} state.\n *\n * @returns The default {@link TokenRatesController} state.\n */\nexport const getDefaultTokenRatesControllerState =\n (): TokenRatesControllerState => {\n return {\n marketData: {},\n };\n };\n\n/** The input to start polling for the {@link TokenRatesController} */\nexport type TokenRatesPollingInput = {\n chainIds: Hex[];\n};\n\n/**\n * Controller that passively polls on a set interval for token-to-fiat exchange rates\n * for tokens stored in the TokensController\n */\nexport class TokenRatesController extends StaticIntervalPollingController<TokenRatesPollingInput>()<\n typeof controllerName,\n TokenRatesControllerState,\n TokenRatesControllerMessenger\n> {\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n #disabled: boolean;\n\n #allTokens: TokensControllerState['allTokens'];\n\n #allDetectedTokens: TokensControllerState['allDetectedTokens'];\n\n /**\n * Creates a TokenRatesController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The polling interval in ms\n * @param options.disabled - Boolean to track if network requests are blocked\n * @param options.tokenPricesService - An object in charge of retrieving token price\n * @param options.messenger - The messenger instance for communication\n * @param options.state - Initial state to set on this controller\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = false,\n tokenPricesService,\n messenger,\n state,\n }: {\n interval?: number;\n disabled?: boolean;\n tokenPricesService: AbstractTokenPricesService;\n messenger: TokenRatesControllerMessenger;\n state?: Partial<TokenRatesControllerState>;\n }) {\n super({\n name: controllerName,\n messenger,\n state: { ...getDefaultTokenRatesControllerState(), ...state },\n metadata: tokenRatesControllerMetadata,\n });\n\n this.setIntervalLength(interval);\n this.#tokenPricesService = tokenPricesService;\n this.#disabled = disabled;\n\n const { allTokens, allDetectedTokens } = this.#getTokensControllerState();\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n // Set native asset identifiers from NetworkEnablementController for CAIP-19 native token lookups\n this.#initNativeAssetIdentifiers();\n\n this.#subscribeToTokensStateChange();\n\n this.#subscribeToNetworkStateChange();\n }\n\n #subscribeToTokensStateChange() {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async ({ allTokens, allDetectedTokens }) => {\n if (this.#disabled) {\n return;\n }\n\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIds = [\n ...new Set([\n ...Object.keys(allTokens),\n ...Object.keys(allDetectedTokens),\n ]),\n ] as Hex[];\n\n const chainIdsToUpdate = chainIds.filter(\n (chainId) =>\n !isEqual(this.#allTokens[chainId], allTokens[chainId]) ||\n !isEqual(\n this.#allDetectedTokens[chainId],\n allDetectedTokens[chainId],\n ),\n );\n\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n const chainIdAndNativeCurrency = chainIdsToUpdate.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n },\n ({ allTokens, allDetectedTokens }) => {\n return { allTokens, allDetectedTokens };\n },\n );\n }\n\n #subscribeToNetworkStateChange() {\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n (_state, patches) => {\n // Remove state for deleted networks\n for (const patch of patches) {\n if (\n patch.op === 'remove' &&\n patch.path[0] === 'networkConfigurationsByChainId'\n ) {\n const removedChainId = patch.path[1] as Hex;\n this.update((state) => {\n delete state.marketData[removedChainId];\n });\n }\n }\n },\n );\n }\n\n /**\n * Initialize the native asset identifiers from NetworkEnablementController.\n * This provides CAIP-19 native asset IDs for the token prices service.\n */\n #initNativeAssetIdentifiers(): void {\n if (this.#tokenPricesService.setNativeAssetIdentifiers) {\n const { nativeAssetIdentifiers } = this.messenger.call(\n 'NetworkEnablementController:getState',\n );\n this.#tokenPricesService.setNativeAssetIdentifiers(\n nativeAssetIdentifiers,\n );\n }\n }\n\n /**\n * Get the tokens for the given chain.\n *\n * @param chainId - The chain ID.\n * @returns The list of tokens addresses for the current chain\n */\n #getTokenAddresses(chainId: Hex): Hex[] {\n const getTokens = (allTokens: Record<Hex, { address: string }[]>) =>\n Object.values(allTokens ?? {}).flatMap((tokens) =>\n tokens.map(({ address }) => toChecksumHexAddress(address) as Hex),\n );\n\n const tokenAddresses = getTokens(this.#allTokens[chainId]);\n const detectedTokenAddresses = getTokens(this.#allDetectedTokens[chainId]);\n\n return [\n ...new Set([\n ...tokenAddresses,\n ...detectedTokenAddresses,\n getNativeTokenAddress(chainId),\n ]),\n ].sort();\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable(): void {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable(): void {\n this.#disabled = true;\n }\n\n #getTokensControllerState(): {\n allTokens: TokensControllerState['allTokens'];\n allDetectedTokens: TokensControllerState['allDetectedTokens'];\n } {\n const { allTokens, allDetectedTokens } = this.messenger.call(\n 'TokensController:getState',\n );\n\n return {\n allTokens,\n allDetectedTokens,\n };\n }\n\n /**\n * Updates exchange rates for all tokens.\n *\n * @param chainIdAndNativeCurrency - The chain ID and native currency.\n */\n async updateExchangeRates(\n chainIdAndNativeCurrency: ChainIdAndNativeCurrency[],\n ): Promise<void> {\n if (this.#disabled) {\n return;\n }\n\n const marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {};\n const assetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n const unsupportedAssetsByNativeCurrency: Record<\n string,\n {\n chainId: Hex;\n tokenAddress: Hex;\n }[]\n > = {};\n for (const { chainId, nativeCurrency } of chainIdAndNativeCurrency) {\n if (this.#tokenPricesService.validateChainIdSupported(chainId)) {\n for (const tokenAddress of this.#getTokenAddresses(chainId)) {\n if (\n this.#tokenPricesService.validateCurrencySupported(nativeCurrency)\n ) {\n (assetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n } else {\n (unsupportedAssetsByNativeCurrency[nativeCurrency] ??= []).push({\n chainId,\n tokenAddress,\n });\n }\n }\n }\n }\n\n const promises = [\n ...Object.entries(assetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ...Object.entries(unsupportedAssetsByNativeCurrency).map(\n ([nativeCurrency, assets]) =>\n this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets,\n nativeCurrency,\n marketData,\n ),\n ),\n ];\n\n await Promise.allSettled(promises);\n\n const chainIds = new Set(\n Object.values(chainIdAndNativeCurrency).map((chain) => chain.chainId),\n );\n\n for (const chainId of chainIds) {\n if (!marketData[chainId]) {\n marketData[chainId] = {};\n }\n }\n\n if (Object.keys(marketData).length > 0) {\n this.update((state) => {\n state.marketData = {\n ...state.marketData,\n ...marketData,\n };\n });\n }\n }\n\n async #fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>> = {},\n ) {\n return await reduceInBatchesSerially<\n { chainId: Hex; tokenAddress: Hex },\n Record<Hex, Record<Hex, MarketDataDetails>>\n >({\n values: assets,\n batchSize: TOKEN_PRICES_BATCH_SIZE,\n eachBatch: async (partialMarketData, assetsBatch) => {\n const batchMarketData = await this.#tokenPricesService.fetchTokenPrices(\n {\n assets: assetsBatch,\n currency,\n },\n );\n\n for (const tokenPrice of batchMarketData) {\n (partialMarketData[tokenPrice.chainId] ??= {})[\n tokenPrice.tokenAddress\n ] = tokenPrice;\n }\n\n return partialMarketData;\n },\n initialResult: marketData,\n });\n }\n\n async #fetchAndMapExchangeRatesForUnsupportedNativeCurrency(\n assets: {\n chainId: Hex;\n tokenAddress: Hex;\n }[],\n currency: string,\n marketData: Record<Hex, Record<Hex, MarketDataDetails>>,\n ) {\n // Step -1: Then fetch all tracked tokens priced in USD\n const marketDataInUSD =\n await this.#fetchAndMapExchangeRatesForSupportedNativeCurrency(\n assets,\n 'usd', // Fallback currency when the native currency is not supported\n );\n\n // Formula: price_in_native = token_usd / native_usd\n const convertUSDToNative = (\n valueInUSD: number,\n nativeTokenPriceInUSD: number,\n ) => valueInUSD / nativeTokenPriceInUSD;\n\n // Step -2: Convert USD prices to native currency\n for (const [chainId, marketDataByTokenAddress] of Object.entries(\n marketDataInUSD,\n ) as [Hex, Record<Hex, MarketDataDetails>][]) {\n const nativeTokenPriceInUSD =\n marketDataByTokenAddress[getNativeTokenAddress(chainId)]?.price;\n\n // Return here if it's null, undefined or 0\n if (!nativeTokenPriceInUSD) {\n continue;\n }\n\n for (const [tokenAddress, tokenData] of Object.entries(\n marketDataByTokenAddress,\n ) as [Hex, MarketDataDetails][]) {\n (marketData[chainId] ??= {})[tokenAddress] = {\n ...tokenData,\n currency,\n price: convertUSDToNative(tokenData.price, nativeTokenPriceInUSD),\n marketCap: convertUSDToNative(\n tokenData.marketCap,\n nativeTokenPriceInUSD,\n ),\n allTimeHigh: convertUSDToNative(\n tokenData.allTimeHigh,\n nativeTokenPriceInUSD,\n ),\n allTimeLow: convertUSDToNative(\n tokenData.allTimeLow,\n nativeTokenPriceInUSD,\n ),\n totalVolume: convertUSDToNative(\n tokenData.totalVolume,\n nativeTokenPriceInUSD,\n ),\n high1d: convertUSDToNative(tokenData.high1d, nativeTokenPriceInUSD),\n low1d: convertUSDToNative(tokenData.low1d, nativeTokenPriceInUSD),\n dilutedMarketCap: convertUSDToNative(\n tokenData.dilutedMarketCap,\n nativeTokenPriceInUSD,\n ),\n };\n }\n }\n }\n\n /**\n * Updates token rates for the given networkClientId\n *\n * @param input - The input for the poll.\n * @param input.chainIds - The chain ids to poll token rates on.\n */\n async _executePoll({ chainIds }: TokenRatesPollingInput): Promise<void> {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIdAndNativeCurrency = chainIds.reduce<\n { chainId: Hex; nativeCurrency: string }[]\n >((acc, chainId) => {\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n console.error(\n `TokenRatesController: No network configuration found for chainId ${chainId}`,\n );\n return acc;\n }\n acc.push({\n chainId,\n nativeCurrency: networkConfiguration.nativeCurrency,\n });\n return acc;\n }, []);\n\n await this.updateExchangeRates(chainIdAndNativeCurrency);\n }\n\n /**\n * Reset the controller state to the default state.\n */\n resetState() {\n this.update(() => {\n return getDefaultTokenRatesControllerState();\n });\n }\n}\n\nexport default TokenRatesController;\n"]}
@@ -187,7 +187,7 @@ const selectAllMultichainAssets = createAssetListSelector([
187
187
  (_a = groupAssets[accountGroupId])[chainId] ?? (_a[chainId] = []);
188
188
  const groupChainAssets = groupAssets[accountGroupId][chainId];
189
189
  const balance = multichainBalances[accountId]?.[assetId];
190
- const decimals = assetMetadata.units.find((unit) => unit.name === assetMetadata.name &&
190
+ const decimals = assetMetadata.units?.find((unit) => unit.name === assetMetadata.name &&
191
191
  unit.symbol === assetMetadata.symbol)?.decimals;
192
192
  if (!balance || decimals === undefined) {
193
193
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"token-selectors.cjs","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport { TrxScope } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { hexToBigInt, parseCaipAssetType } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { createSelector, weakMapMemoize } from 'reselect';\nimport { TokenRwaData } from 'src/token-service';\n\nimport {\n parseBalanceWithDecimals,\n stringifyBalanceWithDecimals,\n} from './stringify-balance';\nimport type { CurrencyRateState } from '../CurrencyRateController';\nimport type { MultichainAssetsControllerState } from '../MultichainAssetsController';\nimport type { MultichainAssetsRatesControllerState } from '../MultichainAssetsRatesController';\nimport type { MultichainBalancesControllerState } from '../MultichainBalancesController';\nimport { getNativeTokenAddress } from '../token-prices-service/codefi-v2';\nimport type { TokenBalancesControllerState } from '../TokenBalancesController';\nimport type { Token, TokenRatesControllerState } from '../TokenRatesController';\nimport type { TokensControllerState } from '../TokensController';\n\n// Asset Tron Filters\nexport const TRON_RESOURCE = {\n ENERGY: 'energy',\n BANDWIDTH: 'bandwidth',\n MAX_ENERGY: 'max-energy',\n MAX_BANDWIDTH: 'max-bandwidth',\n STRX_ENERGY: 'strx-energy',\n STRX_BANDWIDTH: 'strx-bandwidth',\n} as const;\n\nexport type TronResourceSymbol =\n (typeof TRON_RESOURCE)[keyof typeof TRON_RESOURCE];\n\nexport const TRON_RESOURCE_SYMBOLS = Object.values(\n TRON_RESOURCE,\n) as readonly TronResourceSymbol[];\n\nexport const TRON_RESOURCE_SYMBOLS_SET: ReadonlySet<TronResourceSymbol> =\n new Set(TRON_RESOURCE_SYMBOLS);\n\nexport type AssetsByAccountGroup = {\n [accountGroupId: AccountGroupId]: AccountGroupAssets;\n};\n\nexport type AccountGroupAssets = {\n [network: string]: Asset[];\n};\n\ntype EvmAccountType = Extract<InternalAccount['type'], `eip155:${string}`>;\ntype MultichainAccountType = Exclude<\n InternalAccount['type'],\n `eip155:${string}`\n>;\n\nexport type Asset = (\n | {\n accountType: EvmAccountType;\n assetId: Hex; // This is also the address for EVM tokens\n address: Hex;\n chainId: Hex;\n }\n | {\n accountType: MultichainAccountType;\n assetId: `${string}:${string}/${string}:${string}`;\n chainId: `${string}:${string}`;\n }\n) & {\n accountId: string;\n image: string;\n name: string;\n symbol: string;\n decimals: number;\n isNative: boolean;\n rawBalance: Hex;\n balance: string;\n fiat:\n | {\n balance: number;\n currency: string;\n conversionRate: number;\n }\n | undefined;\n rwaData?: TokenRwaData;\n};\n\nexport type AssetListState = {\n accountTree: AccountTreeControllerState['accountTree'];\n internalAccounts: AccountsControllerState['internalAccounts'];\n allTokens: TokensControllerState['allTokens'];\n allIgnoredTokens: TokensControllerState['allIgnoredTokens'];\n tokenBalances: TokenBalancesControllerState['tokenBalances'];\n marketData: TokenRatesControllerState['marketData'];\n currencyRates: CurrencyRateState['currencyRates'];\n accountsAssets: MultichainAssetsControllerState['accountsAssets'];\n allIgnoredAssets: MultichainAssetsControllerState['allIgnoredAssets'];\n assetsMetadata: MultichainAssetsControllerState['assetsMetadata'];\n balances: MultichainBalancesControllerState['balances'];\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currentCurrency: CurrencyRateState['currentCurrency'];\n networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];\n // This is the state from AccountTrackerController. The state is different on mobile and extension\n // accountsByChainId with a balance is the only field that both clients have in common\n // This field could be removed once TokenBalancesController returns native balances\n accountsByChainId: Record<\n Hex,\n Record<\n Hex,\n {\n balance: Hex | null;\n }\n >\n >;\n};\n\nconst createAssetListSelector = createSelector.withTypes<AssetListState>();\n\nconst selectAccountsToGroupIdMap = createAssetListSelector(\n [(state) => state.accountTree, (state) => state.internalAccounts],\n (accountTree, internalAccounts) => {\n const accountsMap: Record<\n string,\n {\n accountGroupId: AccountGroupId;\n type: InternalAccount['type'];\n accountId: string;\n }\n > = {};\n for (const { groups } of Object.values(accountTree.wallets)) {\n for (const { id: accountGroupId, accounts } of Object.values(groups)) {\n for (const accountId of accounts) {\n const internalAccount = internalAccounts.accounts[accountId];\n\n accountsMap[\n // TODO: We would not need internalAccounts if evmTokens state had the accountId\n internalAccount.type.startsWith('eip155')\n ? internalAccount.address\n : accountId\n ] = { accountGroupId, type: internalAccount.type, accountId };\n }\n }\n }\n\n return accountsMap;\n },\n);\n\n// TODO: This selector will not be needed once the native balances are part of the evm tokens state\nconst selectAllEvmAccountNativeBalances = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsByChainId,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n (state) => state.networkConfigurationsByChainId,\n ],\n (\n accountsMap,\n accountsByChainId,\n marketData,\n currencyRates,\n currentCurrency,\n networkConfigurationsByChainId,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainAccounts] of Object.entries(\n accountsByChainId,\n ) as [Hex, Record<Hex, { balance: Hex | null }>][]) {\n for (const [accountAddress, accountBalance] of Object.entries(\n chainAccounts,\n )) {\n const account = accountsMap[accountAddress.toLowerCase()];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n // If a native balance is missing, we still want to show it as 0\n const rawBalance = accountBalance.balance || '0x0';\n\n const nativeCurrency =\n networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';\n\n const nativeToken = {\n address: getNativeTokenAddress(chainId),\n decimals: 18,\n name: nativeCurrency === 'ETH' ? 'Ethereum' : nativeCurrency,\n symbol: nativeCurrency,\n // This field need to be filled at client level for now\n image: '',\n };\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n nativeToken.decimals,\n marketData,\n currencyRates,\n chainId,\n nativeToken.address,\n nativeCurrency, // Pass native currency symbol for fallback when market data is missing\n );\n\n groupChainAssets.push({\n accountType: type as EvmAccountType,\n assetId: nativeToken.address,\n isNative: true,\n address: nativeToken.address,\n image: nativeToken.image,\n name: nativeToken.name,\n symbol: nativeToken.symbol,\n accountId,\n decimals: nativeToken.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n nativeToken.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllEvmAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.allTokens,\n (state) => state.allIgnoredTokens,\n (state) => state.tokenBalances,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n evmTokens,\n ignoredEvmTokens,\n tokenBalances,\n marketData,\n currencyRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainTokens] of Object.entries(evmTokens) as [\n Hex,\n { [key: string]: Token[] },\n ][]) {\n for (const [accountAddress, addressTokens] of Object.entries(\n chainTokens,\n ) as [Hex, Token[]][]) {\n for (const token of addressTokens) {\n const tokenAddress = token.address as Hex;\n const account = accountsMap[accountAddress];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n if (\n ignoredEvmTokens[chainId]?.[accountAddress]?.includes(tokenAddress)\n ) {\n continue;\n }\n\n const rawBalance =\n tokenBalances[accountAddress]?.[chainId]?.[tokenAddress];\n\n if (!rawBalance) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n token.decimals,\n marketData,\n currencyRates,\n chainId,\n tokenAddress,\n );\n\n groupChainAssets.push({\n accountType: type as EvmAccountType,\n assetId: tokenAddress,\n isNative: false,\n address: tokenAddress,\n image: token.image ?? '',\n name: token.name ?? token.symbol,\n symbol: token.symbol,\n accountId,\n decimals: token.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n token.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n ...(token.rwaData && { rwaData: token.rwaData }),\n });\n }\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllMultichainAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsAssets,\n (state) => state.allIgnoredAssets,\n (state) => state.assetsMetadata,\n (state) => state.balances,\n (state) => state.conversionRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n multichainTokens,\n ignoredMultichainAssets,\n multichainAssetsMetadata,\n multichainBalances,\n multichainConversionRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [accountId, accountAssets] of Object.entries(multichainTokens)) {\n for (const assetId of accountAssets) {\n let caipAsset: ReturnType<typeof parseCaipAssetType>;\n try {\n caipAsset = parseCaipAssetType(assetId);\n } catch {\n // TODO: We should log this error when we have the ability to inject a logger from the client\n continue;\n }\n\n const { chainId } = caipAsset;\n const asset = `${caipAsset.assetNamespace}:${caipAsset.assetReference}`;\n\n const account = accountsMap[accountId];\n const assetMetadata = multichainAssetsMetadata[assetId];\n if (!account || !assetMetadata) {\n continue;\n }\n\n const { accountGroupId, type } = account;\n\n if (ignoredMultichainAssets?.[accountId]?.includes(assetId)) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const balance:\n | {\n amount: string;\n unit: string;\n }\n | undefined = multichainBalances[accountId]?.[assetId];\n\n const decimals = assetMetadata.units.find(\n (unit) =>\n unit.name === assetMetadata.name &&\n unit.symbol === assetMetadata.symbol,\n )?.decimals;\n\n if (!balance || decimals === undefined) {\n continue;\n }\n\n const rawBalance = parseBalanceWithDecimals(balance.amount, decimals);\n\n if (!rawBalance) {\n continue;\n }\n\n const fiatData = getFiatBalanceForMultichainAsset(\n balance,\n multichainConversionRates,\n assetId,\n );\n\n // TODO: We shouldn't have to rely on fallbacks for name and symbol, they should not be optional\n groupChainAssets.push({\n accountType: type as MultichainAccountType,\n assetId,\n isNative: caipAsset.assetNamespace === 'slip44',\n image: assetMetadata.iconUrl,\n name: assetMetadata.name ?? assetMetadata.symbol ?? asset,\n symbol: assetMetadata.symbol ?? asset,\n accountId,\n decimals,\n rawBalance,\n balance: balance.amount,\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nexport const selectAllAssets = createAssetListSelector(\n [\n selectAllEvmAssets,\n selectAllMultichainAssets,\n selectAllEvmAccountNativeBalances,\n ],\n (evmAssets, multichainAssets, evmAccountNativeBalances) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n mergeAssets(groupAssets, evmAssets);\n\n mergeAssets(groupAssets, multichainAssets);\n\n mergeAssets(groupAssets, evmAccountNativeBalances);\n\n return groupAssets;\n },\n);\n\nexport type SelectAccountGroupAssetOpts = {\n filterTronStakedTokens: boolean;\n};\n\nconst defaultSelectAccountGroupAssetOpts: SelectAccountGroupAssetOpts = {\n filterTronStakedTokens: true,\n};\n\nconst filterTronStakedTokens = (assetsByAccountGroup: AccountGroupAssets) => {\n const newAssetsByAccountGroup = { ...assetsByAccountGroup };\n\n Object.values(TrxScope).forEach((tronChainId) => {\n if (!newAssetsByAccountGroup[tronChainId]) {\n return;\n }\n\n newAssetsByAccountGroup[tronChainId] = newAssetsByAccountGroup[\n tronChainId\n ].filter((asset: Asset) => {\n if (\n asset.chainId.startsWith('tron:') &&\n TRON_RESOURCE_SYMBOLS_SET.has(\n asset.symbol?.toLowerCase() as TronResourceSymbol,\n )\n ) {\n return false;\n }\n return true;\n });\n });\n\n return newAssetsByAccountGroup;\n};\n\nexport const selectAssetsBySelectedAccountGroup = createAssetListSelector(\n [\n selectAllAssets,\n (state) => state.accountTree,\n (\n _state,\n opts: SelectAccountGroupAssetOpts = defaultSelectAccountGroupAssetOpts,\n ) => opts,\n ],\n (groupAssets, accountTree, opts) => {\n const { selectedAccountGroup } = accountTree;\n if (!selectedAccountGroup) {\n return {};\n }\n\n let result = groupAssets[selectedAccountGroup] || {};\n\n if (opts.filterTronStakedTokens) {\n result = filterTronStakedTokens(result);\n }\n\n return result;\n },\n {\n memoize: weakMapMemoize,\n argsMemoize: weakMapMemoize,\n },\n);\n\n// TODO: Once native assets are part of the evm tokens state, this function can be simplified as chains will always be unique\n/**\n * Merges the new assets into the existing assets\n *\n * @param existingAssets - The existing assets\n * @param newAssets - The new assets\n */\nfunction mergeAssets(\n existingAssets: AssetsByAccountGroup,\n newAssets: AssetsByAccountGroup,\n) {\n for (const [accountGroupId, accountAssets] of Object.entries(newAssets) as [\n AccountGroupId,\n AccountGroupAssets,\n ][]) {\n const existingAccountGroupAssets = existingAssets[accountGroupId];\n\n if (!existingAccountGroupAssets) {\n existingAssets[accountGroupId] = {};\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAssets[accountGroupId][network] = [...chainAssets];\n }\n } else {\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAccountGroupAssets[network] ??= [];\n existingAccountGroupAssets[network].push(...chainAssets);\n }\n }\n }\n}\n\n/**\n * @param rawBalance - The balance of the token\n * @param decimals - The decimals of the token\n * @param marketData - The market data for the token\n * @param currencyRates - The currency rates for the token\n * @param chainId - The chain id of the token\n * @param tokenAddress - The address of the token\n * @param nativeCurrencySymbol - The native currency symbol (e.g., 'ETH', 'BNB') - used for fallback when market data is missing for native tokens\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the market data or currency rates.\n */\nfunction getFiatBalanceForEvmToken(\n rawBalance: Hex,\n decimals: number,\n marketData: TokenRatesControllerState['marketData'],\n currencyRates: CurrencyRateState['currencyRates'],\n chainId: Hex,\n tokenAddress: Hex,\n nativeCurrencySymbol?: string,\n) {\n const tokenMarketData = marketData[chainId]?.[tokenAddress];\n\n // For native tokens: if no market data exists, use price=1 and look up currency rate directly\n // This is because native tokens are priced in themselves (1 ETH = 1 ETH)\n if (!tokenMarketData && nativeCurrencySymbol) {\n const currencyRate = currencyRates[nativeCurrencySymbol];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n }\n\n if (!tokenMarketData) {\n return undefined;\n }\n\n const currencyRate = currencyRates[tokenMarketData.currency];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n tokenMarketData.price *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n}\n\n/**\n * @param balance - The balance of the asset, in the format { amount: string; unit: string }\n * @param balance.amount - The amount of the balance\n * @param balance.unit - The unit of the balance\n * @param multichainConversionRates - The conversion rates for the multichain asset\n * @param assetId - The asset id of the asset\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the conversion rates.\n */\nfunction getFiatBalanceForMultichainAsset(\n balance: { amount: string; unit: string },\n multichainConversionRates: MultichainAssetsRatesControllerState['conversionRates'],\n assetId: `${string}:${string}/${string}:${string}`,\n) {\n const assetMarketData = multichainConversionRates[assetId];\n\n if (!assetMarketData?.rate) {\n return undefined;\n }\n\n return {\n balance: Number(balance.amount) * Number(assetMarketData.rate),\n conversionRate: Number(assetMarketData.rate),\n };\n}\n"]}
1
+ {"version":3,"file":"token-selectors.cjs","sourceRoot":"","sources":["../../src/selectors/token-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId } from '@metamask/account-api';\nimport type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport type { AccountsControllerState } from '@metamask/accounts-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport { TrxScope } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { hexToBigInt, parseCaipAssetType } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { createSelector, weakMapMemoize } from 'reselect';\nimport { TokenRwaData } from 'src/token-service';\n\nimport {\n parseBalanceWithDecimals,\n stringifyBalanceWithDecimals,\n} from './stringify-balance';\nimport type { CurrencyRateState } from '../CurrencyRateController';\nimport type { MultichainAssetsControllerState } from '../MultichainAssetsController';\nimport type { MultichainAssetsRatesControllerState } from '../MultichainAssetsRatesController';\nimport type { MultichainBalancesControllerState } from '../MultichainBalancesController';\nimport { getNativeTokenAddress } from '../token-prices-service/codefi-v2';\nimport type { TokenBalancesControllerState } from '../TokenBalancesController';\nimport type { Token, TokenRatesControllerState } from '../TokenRatesController';\nimport type { TokensControllerState } from '../TokensController';\n\n// Asset Tron Filters\nexport const TRON_RESOURCE = {\n ENERGY: 'energy',\n BANDWIDTH: 'bandwidth',\n MAX_ENERGY: 'max-energy',\n MAX_BANDWIDTH: 'max-bandwidth',\n STRX_ENERGY: 'strx-energy',\n STRX_BANDWIDTH: 'strx-bandwidth',\n} as const;\n\nexport type TronResourceSymbol =\n (typeof TRON_RESOURCE)[keyof typeof TRON_RESOURCE];\n\nexport const TRON_RESOURCE_SYMBOLS = Object.values(\n TRON_RESOURCE,\n) as readonly TronResourceSymbol[];\n\nexport const TRON_RESOURCE_SYMBOLS_SET: ReadonlySet<TronResourceSymbol> =\n new Set(TRON_RESOURCE_SYMBOLS);\n\nexport type AssetsByAccountGroup = {\n [accountGroupId: AccountGroupId]: AccountGroupAssets;\n};\n\nexport type AccountGroupAssets = {\n [network: string]: Asset[];\n};\n\ntype EvmAccountType = Extract<InternalAccount['type'], `eip155:${string}`>;\ntype MultichainAccountType = Exclude<\n InternalAccount['type'],\n `eip155:${string}`\n>;\n\nexport type Asset = (\n | {\n accountType: EvmAccountType;\n assetId: Hex; // This is also the address for EVM tokens\n address: Hex;\n chainId: Hex;\n }\n | {\n accountType: MultichainAccountType;\n assetId: `${string}:${string}/${string}:${string}`;\n chainId: `${string}:${string}`;\n }\n) & {\n accountId: string;\n image: string;\n name: string;\n symbol: string;\n decimals: number;\n isNative: boolean;\n rawBalance: Hex;\n balance: string;\n fiat:\n | {\n balance: number;\n currency: string;\n conversionRate: number;\n }\n | undefined;\n rwaData?: TokenRwaData;\n};\n\nexport type AssetListState = {\n accountTree: AccountTreeControllerState['accountTree'];\n internalAccounts: AccountsControllerState['internalAccounts'];\n allTokens: TokensControllerState['allTokens'];\n allIgnoredTokens: TokensControllerState['allIgnoredTokens'];\n tokenBalances: TokenBalancesControllerState['tokenBalances'];\n marketData: TokenRatesControllerState['marketData'];\n currencyRates: CurrencyRateState['currencyRates'];\n accountsAssets: MultichainAssetsControllerState['accountsAssets'];\n allIgnoredAssets: MultichainAssetsControllerState['allIgnoredAssets'];\n assetsMetadata: MultichainAssetsControllerState['assetsMetadata'];\n balances: MultichainBalancesControllerState['balances'];\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currentCurrency: CurrencyRateState['currentCurrency'];\n networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];\n // This is the state from AccountTrackerController. The state is different on mobile and extension\n // accountsByChainId with a balance is the only field that both clients have in common\n // This field could be removed once TokenBalancesController returns native balances\n accountsByChainId: Record<\n Hex,\n Record<\n Hex,\n {\n balance: Hex | null;\n }\n >\n >;\n};\n\nconst createAssetListSelector = createSelector.withTypes<AssetListState>();\n\nconst selectAccountsToGroupIdMap = createAssetListSelector(\n [(state) => state.accountTree, (state) => state.internalAccounts],\n (accountTree, internalAccounts) => {\n const accountsMap: Record<\n string,\n {\n accountGroupId: AccountGroupId;\n type: InternalAccount['type'];\n accountId: string;\n }\n > = {};\n for (const { groups } of Object.values(accountTree.wallets)) {\n for (const { id: accountGroupId, accounts } of Object.values(groups)) {\n for (const accountId of accounts) {\n const internalAccount = internalAccounts.accounts[accountId];\n\n accountsMap[\n // TODO: We would not need internalAccounts if evmTokens state had the accountId\n internalAccount.type.startsWith('eip155')\n ? internalAccount.address\n : accountId\n ] = { accountGroupId, type: internalAccount.type, accountId };\n }\n }\n }\n\n return accountsMap;\n },\n);\n\n// TODO: This selector will not be needed once the native balances are part of the evm tokens state\nconst selectAllEvmAccountNativeBalances = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsByChainId,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n (state) => state.networkConfigurationsByChainId,\n ],\n (\n accountsMap,\n accountsByChainId,\n marketData,\n currencyRates,\n currentCurrency,\n networkConfigurationsByChainId,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainAccounts] of Object.entries(\n accountsByChainId,\n ) as [Hex, Record<Hex, { balance: Hex | null }>][]) {\n for (const [accountAddress, accountBalance] of Object.entries(\n chainAccounts,\n )) {\n const account = accountsMap[accountAddress.toLowerCase()];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n // If a native balance is missing, we still want to show it as 0\n const rawBalance = accountBalance.balance || '0x0';\n\n const nativeCurrency =\n networkConfigurationsByChainId[chainId]?.nativeCurrency || 'NATIVE';\n\n const nativeToken = {\n address: getNativeTokenAddress(chainId),\n decimals: 18,\n name: nativeCurrency === 'ETH' ? 'Ethereum' : nativeCurrency,\n symbol: nativeCurrency,\n // This field need to be filled at client level for now\n image: '',\n };\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n nativeToken.decimals,\n marketData,\n currencyRates,\n chainId,\n nativeToken.address,\n nativeCurrency, // Pass native currency symbol for fallback when market data is missing\n );\n\n groupChainAssets.push({\n accountType: type as EvmAccountType,\n assetId: nativeToken.address,\n isNative: true,\n address: nativeToken.address,\n image: nativeToken.image,\n name: nativeToken.name,\n symbol: nativeToken.symbol,\n accountId,\n decimals: nativeToken.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n nativeToken.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllEvmAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.allTokens,\n (state) => state.allIgnoredTokens,\n (state) => state.tokenBalances,\n (state) => state.marketData,\n (state) => state.currencyRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n evmTokens,\n ignoredEvmTokens,\n tokenBalances,\n marketData,\n currencyRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [chainId, chainTokens] of Object.entries(evmTokens) as [\n Hex,\n { [key: string]: Token[] },\n ][]) {\n for (const [accountAddress, addressTokens] of Object.entries(\n chainTokens,\n ) as [Hex, Token[]][]) {\n for (const token of addressTokens) {\n const tokenAddress = token.address as Hex;\n const account = accountsMap[accountAddress];\n if (!account) {\n continue;\n }\n\n const { accountGroupId, type, accountId } = account;\n\n if (\n ignoredEvmTokens[chainId]?.[accountAddress]?.includes(tokenAddress)\n ) {\n continue;\n }\n\n const rawBalance =\n tokenBalances[accountAddress]?.[chainId]?.[tokenAddress];\n\n if (!rawBalance) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const fiatData = getFiatBalanceForEvmToken(\n rawBalance,\n token.decimals,\n marketData,\n currencyRates,\n chainId,\n tokenAddress,\n );\n\n groupChainAssets.push({\n accountType: type as EvmAccountType,\n assetId: tokenAddress,\n isNative: false,\n address: tokenAddress,\n image: token.image ?? '',\n name: token.name ?? token.symbol,\n symbol: token.symbol,\n accountId,\n decimals: token.decimals,\n rawBalance,\n balance: stringifyBalanceWithDecimals(\n hexToBigInt(rawBalance),\n token.decimals,\n ),\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n ...(token.rwaData && { rwaData: token.rwaData }),\n });\n }\n }\n }\n\n return groupAssets;\n },\n);\n\nconst selectAllMultichainAssets = createAssetListSelector(\n [\n selectAccountsToGroupIdMap,\n (state) => state.accountsAssets,\n (state) => state.allIgnoredAssets,\n (state) => state.assetsMetadata,\n (state) => state.balances,\n (state) => state.conversionRates,\n (state) => state.currentCurrency,\n ],\n (\n accountsMap,\n multichainTokens,\n ignoredMultichainAssets,\n multichainAssetsMetadata,\n multichainBalances,\n multichainConversionRates,\n currentCurrency,\n ) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n for (const [accountId, accountAssets] of Object.entries(multichainTokens)) {\n for (const assetId of accountAssets) {\n let caipAsset: ReturnType<typeof parseCaipAssetType>;\n try {\n caipAsset = parseCaipAssetType(assetId);\n } catch {\n // TODO: We should log this error when we have the ability to inject a logger from the client\n continue;\n }\n\n const { chainId } = caipAsset;\n const asset = `${caipAsset.assetNamespace}:${caipAsset.assetReference}`;\n\n const account = accountsMap[accountId];\n const assetMetadata = multichainAssetsMetadata[assetId];\n if (!account || !assetMetadata) {\n continue;\n }\n\n const { accountGroupId, type } = account;\n\n if (ignoredMultichainAssets?.[accountId]?.includes(assetId)) {\n continue;\n }\n\n groupAssets[accountGroupId] ??= {};\n groupAssets[accountGroupId][chainId] ??= [];\n const groupChainAssets = groupAssets[accountGroupId][chainId];\n\n const balance:\n | {\n amount: string;\n unit: string;\n }\n | undefined = multichainBalances[accountId]?.[assetId];\n\n const decimals = assetMetadata.units?.find(\n (unit) =>\n unit.name === assetMetadata.name &&\n unit.symbol === assetMetadata.symbol,\n )?.decimals;\n\n if (!balance || decimals === undefined) {\n continue;\n }\n\n const rawBalance = parseBalanceWithDecimals(balance.amount, decimals);\n\n if (!rawBalance) {\n continue;\n }\n\n const fiatData = getFiatBalanceForMultichainAsset(\n balance,\n multichainConversionRates,\n assetId,\n );\n\n // TODO: We shouldn't have to rely on fallbacks for name and symbol, they should not be optional\n groupChainAssets.push({\n accountType: type as MultichainAccountType,\n assetId,\n isNative: caipAsset.assetNamespace === 'slip44',\n image: assetMetadata.iconUrl,\n name: assetMetadata.name ?? assetMetadata.symbol ?? asset,\n symbol: assetMetadata.symbol ?? asset,\n accountId,\n decimals,\n rawBalance,\n balance: balance.amount,\n fiat: fiatData\n ? {\n balance: fiatData.balance,\n currency: currentCurrency,\n conversionRate: fiatData.conversionRate,\n }\n : undefined,\n chainId,\n });\n }\n }\n\n return groupAssets;\n },\n);\n\nexport const selectAllAssets = createAssetListSelector(\n [\n selectAllEvmAssets,\n selectAllMultichainAssets,\n selectAllEvmAccountNativeBalances,\n ],\n (evmAssets, multichainAssets, evmAccountNativeBalances) => {\n const groupAssets: AssetsByAccountGroup = {};\n\n mergeAssets(groupAssets, evmAssets);\n\n mergeAssets(groupAssets, multichainAssets);\n\n mergeAssets(groupAssets, evmAccountNativeBalances);\n\n return groupAssets;\n },\n);\n\nexport type SelectAccountGroupAssetOpts = {\n filterTronStakedTokens: boolean;\n};\n\nconst defaultSelectAccountGroupAssetOpts: SelectAccountGroupAssetOpts = {\n filterTronStakedTokens: true,\n};\n\nconst filterTronStakedTokens = (assetsByAccountGroup: AccountGroupAssets) => {\n const newAssetsByAccountGroup = { ...assetsByAccountGroup };\n\n Object.values(TrxScope).forEach((tronChainId) => {\n if (!newAssetsByAccountGroup[tronChainId]) {\n return;\n }\n\n newAssetsByAccountGroup[tronChainId] = newAssetsByAccountGroup[\n tronChainId\n ].filter((asset: Asset) => {\n if (\n asset.chainId.startsWith('tron:') &&\n TRON_RESOURCE_SYMBOLS_SET.has(\n asset.symbol?.toLowerCase() as TronResourceSymbol,\n )\n ) {\n return false;\n }\n return true;\n });\n });\n\n return newAssetsByAccountGroup;\n};\n\nexport const selectAssetsBySelectedAccountGroup = createAssetListSelector(\n [\n selectAllAssets,\n (state) => state.accountTree,\n (\n _state,\n opts: SelectAccountGroupAssetOpts = defaultSelectAccountGroupAssetOpts,\n ) => opts,\n ],\n (groupAssets, accountTree, opts) => {\n const { selectedAccountGroup } = accountTree;\n if (!selectedAccountGroup) {\n return {};\n }\n\n let result = groupAssets[selectedAccountGroup] || {};\n\n if (opts.filterTronStakedTokens) {\n result = filterTronStakedTokens(result);\n }\n\n return result;\n },\n {\n memoize: weakMapMemoize,\n argsMemoize: weakMapMemoize,\n },\n);\n\n// TODO: Once native assets are part of the evm tokens state, this function can be simplified as chains will always be unique\n/**\n * Merges the new assets into the existing assets\n *\n * @param existingAssets - The existing assets\n * @param newAssets - The new assets\n */\nfunction mergeAssets(\n existingAssets: AssetsByAccountGroup,\n newAssets: AssetsByAccountGroup,\n) {\n for (const [accountGroupId, accountAssets] of Object.entries(newAssets) as [\n AccountGroupId,\n AccountGroupAssets,\n ][]) {\n const existingAccountGroupAssets = existingAssets[accountGroupId];\n\n if (!existingAccountGroupAssets) {\n existingAssets[accountGroupId] = {};\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAssets[accountGroupId][network] = [...chainAssets];\n }\n } else {\n for (const [network, chainAssets] of Object.entries(accountAssets)) {\n existingAccountGroupAssets[network] ??= [];\n existingAccountGroupAssets[network].push(...chainAssets);\n }\n }\n }\n}\n\n/**\n * @param rawBalance - The balance of the token\n * @param decimals - The decimals of the token\n * @param marketData - The market data for the token\n * @param currencyRates - The currency rates for the token\n * @param chainId - The chain id of the token\n * @param tokenAddress - The address of the token\n * @param nativeCurrencySymbol - The native currency symbol (e.g., 'ETH', 'BNB') - used for fallback when market data is missing for native tokens\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the market data or currency rates.\n */\nfunction getFiatBalanceForEvmToken(\n rawBalance: Hex,\n decimals: number,\n marketData: TokenRatesControllerState['marketData'],\n currencyRates: CurrencyRateState['currencyRates'],\n chainId: Hex,\n tokenAddress: Hex,\n nativeCurrencySymbol?: string,\n) {\n const tokenMarketData = marketData[chainId]?.[tokenAddress];\n\n // For native tokens: if no market data exists, use price=1 and look up currency rate directly\n // This is because native tokens are priced in themselves (1 ETH = 1 ETH)\n if (!tokenMarketData && nativeCurrencySymbol) {\n const currencyRate = currencyRates[nativeCurrencySymbol];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n }\n\n if (!tokenMarketData) {\n return undefined;\n }\n\n const currencyRate = currencyRates[tokenMarketData.currency];\n\n if (!currencyRate?.conversionRate) {\n return undefined;\n }\n\n const fiatBalance =\n (convertHexToDecimal(rawBalance) / 10 ** decimals) *\n tokenMarketData.price *\n currencyRate.conversionRate;\n\n return {\n balance: fiatBalance,\n conversionRate: currencyRate.conversionRate,\n };\n}\n\n/**\n * @param balance - The balance of the asset, in the format { amount: string; unit: string }\n * @param balance.amount - The amount of the balance\n * @param balance.unit - The unit of the balance\n * @param multichainConversionRates - The conversion rates for the multichain asset\n * @param assetId - The asset id of the asset\n * @returns The price and currency of the token in the current currency. Returns undefined if the asset is not found in the conversion rates.\n */\nfunction getFiatBalanceForMultichainAsset(\n balance: { amount: string; unit: string },\n multichainConversionRates: MultichainAssetsRatesControllerState['conversionRates'],\n assetId: `${string}:${string}/${string}:${string}`,\n) {\n const assetMarketData = multichainConversionRates[assetId];\n\n if (!assetMarketData?.rate) {\n return undefined;\n }\n\n return {\n balance: Number(balance.amount) * Number(assetMarketData.rate),\n conversionRate: Number(assetMarketData.rate),\n };\n}\n"]}
@@ -184,7 +184,7 @@ const selectAllMultichainAssets = createAssetListSelector([
184
184
  (_a = groupAssets[accountGroupId])[chainId] ?? (_a[chainId] = []);
185
185
  const groupChainAssets = groupAssets[accountGroupId][chainId];
186
186
  const balance = multichainBalances[accountId]?.[assetId];
187
- const decimals = assetMetadata.units.find((unit) => unit.name === assetMetadata.name &&
187
+ const decimals = assetMetadata.units?.find((unit) => unit.name === assetMetadata.name &&
188
188
  unit.symbol === assetMetadata.symbol)?.decimals;
189
189
  if (!balance || decimals === undefined) {
190
190
  continue;