@metamask/assets-controllers 40.0.0 → 42.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/dist/AccountTrackerController.d.cts +4 -4
  3. package/dist/AccountTrackerController.d.mts +4 -4
  4. package/dist/CurrencyRateController.cjs +40 -58
  5. package/dist/CurrencyRateController.cjs.map +1 -1
  6. package/dist/CurrencyRateController.d.cts +15 -15
  7. package/dist/CurrencyRateController.d.cts.map +1 -1
  8. package/dist/CurrencyRateController.d.mts +15 -15
  9. package/dist/CurrencyRateController.d.mts.map +1 -1
  10. package/dist/CurrencyRateController.mjs +41 -59
  11. package/dist/CurrencyRateController.mjs.map +1 -1
  12. package/dist/NftController.cjs +8 -0
  13. package/dist/NftController.cjs.map +1 -1
  14. package/dist/NftController.d.cts +4 -0
  15. package/dist/NftController.d.cts.map +1 -1
  16. package/dist/NftController.d.mts +4 -0
  17. package/dist/NftController.d.mts.map +1 -1
  18. package/dist/NftController.mjs +8 -0
  19. package/dist/NftController.mjs.map +1 -1
  20. package/dist/RatesController/RatesController.cjs +1 -1
  21. package/dist/RatesController/RatesController.cjs.map +1 -1
  22. package/dist/RatesController/RatesController.mjs +1 -1
  23. package/dist/RatesController/RatesController.mjs.map +1 -1
  24. package/dist/RatesController/types.cjs.map +1 -1
  25. package/dist/RatesController/types.d.cts +6 -7
  26. package/dist/RatesController/types.d.cts.map +1 -1
  27. package/dist/RatesController/types.d.mts +6 -7
  28. package/dist/RatesController/types.d.mts.map +1 -1
  29. package/dist/RatesController/types.mjs.map +1 -1
  30. package/dist/TokenBalancesController.cjs +8 -0
  31. package/dist/TokenBalancesController.cjs.map +1 -1
  32. package/dist/TokenBalancesController.d.cts +4 -0
  33. package/dist/TokenBalancesController.d.cts.map +1 -1
  34. package/dist/TokenBalancesController.d.mts +4 -0
  35. package/dist/TokenBalancesController.d.mts.map +1 -1
  36. package/dist/TokenBalancesController.mjs +8 -0
  37. package/dist/TokenBalancesController.mjs.map +1 -1
  38. package/dist/TokenDetectionController.cjs +58 -16
  39. package/dist/TokenDetectionController.cjs.map +1 -1
  40. package/dist/TokenDetectionController.d.cts +7 -5
  41. package/dist/TokenDetectionController.d.cts.map +1 -1
  42. package/dist/TokenDetectionController.d.mts +7 -5
  43. package/dist/TokenDetectionController.d.mts.map +1 -1
  44. package/dist/TokenDetectionController.mjs +59 -16
  45. package/dist/TokenDetectionController.mjs.map +1 -1
  46. package/dist/TokenListController.cjs.map +1 -1
  47. package/dist/TokenListController.d.cts +5 -5
  48. package/dist/TokenListController.d.cts.map +1 -1
  49. package/dist/TokenListController.d.mts +5 -5
  50. package/dist/TokenListController.d.mts.map +1 -1
  51. package/dist/TokenListController.mjs.map +1 -1
  52. package/dist/TokenRatesController.cjs +43 -13
  53. package/dist/TokenRatesController.cjs.map +1 -1
  54. package/dist/TokenRatesController.d.cts +12 -8
  55. package/dist/TokenRatesController.d.cts.map +1 -1
  56. package/dist/TokenRatesController.d.mts +12 -8
  57. package/dist/TokenRatesController.d.mts.map +1 -1
  58. package/dist/TokenRatesController.mjs +43 -13
  59. package/dist/TokenRatesController.mjs.map +1 -1
  60. package/dist/TokensController.cjs +8 -0
  61. package/dist/TokensController.cjs.map +1 -1
  62. package/dist/TokensController.d.cts +4 -0
  63. package/dist/TokensController.d.cts.map +1 -1
  64. package/dist/TokensController.d.mts +4 -0
  65. package/dist/TokensController.d.mts.map +1 -1
  66. package/dist/TokensController.mjs +8 -0
  67. package/dist/TokensController.mjs.map +1 -1
  68. package/dist/crypto-compare-service/crypto-compare.cjs +8 -6
  69. package/dist/crypto-compare-service/crypto-compare.cjs.map +1 -1
  70. package/dist/crypto-compare-service/crypto-compare.d.cts +1 -1
  71. package/dist/crypto-compare-service/crypto-compare.d.cts.map +1 -1
  72. package/dist/crypto-compare-service/crypto-compare.d.mts +1 -1
  73. package/dist/crypto-compare-service/crypto-compare.d.mts.map +1 -1
  74. package/dist/crypto-compare-service/crypto-compare.mjs +8 -6
  75. package/dist/crypto-compare-service/crypto-compare.mjs.map +1 -1
  76. package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs +7 -2
  77. package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs.map +1 -1
  78. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.cts +3 -2
  79. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.cts.map +1 -1
  80. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.mts +3 -2
  81. package/dist/multi-chain-accounts-service/multi-chain-accounts.d.mts.map +1 -1
  82. package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs +7 -2
  83. package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs.map +1 -1
  84. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.mjs","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerGetAccountAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n RestrictedControllerMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport contractMap from '@metamask/contract-metadata';\nimport {\n ASSET_TYPES,\n ChainId,\n ERC20,\n safelyExecute,\n isEqualCaseInsensitive,\n} from '@metamask/controller-utils';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetNetworkConfigurationByNetworkClientId,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkDidChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\nimport { hexToNumber } from '@metamask/utils';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport { isTokenDetectionSupportedForNetwork } from './assetsUtil';\nimport {\n fetchMultiChainBalances,\n fetchSupportedNetworks,\n} from './multi-chain-accounts-service';\nimport type {\n GetTokenListState,\n TokenListMap,\n TokenListStateChange,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\nimport type {\n TokensControllerAddDetectedTokensAction,\n TokensControllerGetStateAction,\n} from './TokensController';\n\nconst DEFAULT_INTERVAL = 180000;\n\ntype LegacyToken = {\n name: string;\n logo: `${string}.svg`;\n symbol: string;\n decimals: number;\n erc20?: boolean;\n erc721?: boolean;\n};\n\ntype TokenDetectionMap = {\n [P in keyof TokenListMap]: Omit<TokenListMap[P], 'occurrences'>;\n};\n\nexport const STATIC_MAINNET_TOKEN_LIST = Object.entries<LegacyToken>(\n contractMap,\n).reduce<TokenDetectionMap>((acc, [base, contract]) => {\n const { logo, erc20, erc721, ...tokenMetadata } = contract;\n return {\n ...acc,\n [base.toLowerCase()]: {\n ...tokenMetadata,\n address: base.toLowerCase(),\n iconUrl: `images/contract/${logo}`,\n aggregators: [],\n },\n };\n}, {});\n\nexport const controllerName = 'TokenDetectionController';\n\nexport type TokenDetectionState = Record<never, never>;\n\nexport type TokenDetectionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenDetectionState\n>;\n\nexport type TokenDetectionControllerActions =\n TokenDetectionControllerGetStateAction;\n\nexport type AllowedActions =\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetAccountAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetNetworkConfigurationByNetworkClientId\n | NetworkControllerGetStateAction\n | GetTokenListState\n | KeyringControllerGetStateAction\n | PreferencesControllerGetStateAction\n | TokensControllerGetStateAction\n | TokensControllerAddDetectedTokensAction;\n\nexport type TokenDetectionControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;\n\nexport type TokenDetectionControllerEvents =\n TokenDetectionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | NetworkControllerNetworkDidChangeEvent\n | TokenListStateChange\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent;\n\nexport type TokenDetectionControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n TokenDetectionControllerActions | AllowedActions,\n TokenDetectionControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/** The input to start polling for the {@link TokenDetectionController} */\ntype TokenDetectionPollingInput = {\n networkClientId: NetworkClientId;\n address: string;\n};\n\n/**\n * Controller that passively polls on a set interval for Tokens auto detection\n * @property intervalId - Polling interval used to fetch new token rates\n * @property selectedAddress - Vault selected address\n * @property networkClientId - The network client ID of the current selected network\n * @property disabled - Boolean to track if network requests are blocked\n * @property isUnlocked - Boolean to track if the keyring state is unlocked\n * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network\n */\nexport class TokenDetectionController extends StaticIntervalPollingController<TokenDetectionPollingInput>()<\n typeof controllerName,\n TokenDetectionState,\n TokenDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #selectedAccountId: string;\n\n #networkClientId: NetworkClientId;\n\n #tokenList: TokenDetectionMap = {};\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n #isDetectionEnabledForNetwork: boolean;\n\n readonly #getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n\n readonly #trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n\n #accountsAPI = {\n isAccountsAPIEnabled: true,\n supportedNetworksCache: null as number[] | null,\n async getSupportedNetworks() {\n /* istanbul ignore next */\n if (!this.isAccountsAPIEnabled) {\n throw new Error('Accounts API Feature Switch is disabled');\n }\n\n /* istanbul ignore next */\n if (this.supportedNetworksCache) {\n return this.supportedNetworksCache;\n }\n\n const result = await fetchSupportedNetworks().catch(() => null);\n this.supportedNetworksCache = result;\n return result;\n },\n\n async getMultiChainBalances(address: string, chainId: Hex) {\n if (!this.isAccountsAPIEnabled) {\n throw new Error('Accounts API Feature Switch is disabled');\n }\n\n const chainIdNumber = hexToNumber(chainId);\n const supportedNetworks = await this.getSupportedNetworks();\n\n if (!supportedNetworks || !supportedNetworks.includes(chainIdNumber)) {\n const supportedNetworksErrStr = (supportedNetworks ?? []).toString();\n throw new Error(\n `Unsupported Network: supported networks ${supportedNetworksErrStr}, network: ${chainIdNumber}`,\n );\n }\n\n const result = await fetchMultiChainBalances(address, {\n networks: [chainIdNumber],\n });\n\n return result.balances;\n },\n };\n\n /**\n * Creates a TokenDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The controller messaging system.\n * @param options.disabled - If set to true, all network requests are blocked.\n * @param options.interval - Polling interval used to fetch new token rates\n * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.\n * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.\n * @param options.useAccountsAPI - Feature Switch for using the accounts API when detecting tokens (default: true)\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = true,\n getBalancesInSingleCall,\n trackMetaMetricsEvent,\n messenger,\n useAccountsAPI = true,\n }: {\n interval?: number;\n disabled?: boolean;\n getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n messenger: TokenDetectionControllerMessenger;\n useAccountsAPI?: boolean;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {},\n metadata: {},\n });\n\n this.#disabled = disabled;\n this.setIntervalLength(interval);\n\n this.#selectedAccountId = this.#getSelectedAccount().id;\n\n const { chainId, networkClientId } =\n this.#getCorrectChainIdAndNetworkClientId();\n this.#networkClientId = networkClientId;\n\n const { useTokenDetection: defaultUseTokenDetection } =\n this.messagingSystem.call('PreferencesController:getState');\n this.#isDetectionEnabledFromPreferences = defaultUseTokenDetection;\n this.#isDetectionEnabledForNetwork =\n isTokenDetectionSupportedForNetwork(chainId);\n\n this.#getBalancesInSingleCall = getBalancesInSingleCall;\n\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n const { isUnlocked } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n this.#isUnlocked = isUnlocked;\n\n this.#accountsAPI.isAccountsAPIEnabled = useAccountsAPI;\n\n this.#registerEventListeners();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system subscriptions to controller events.\n */\n #registerEventListeners() {\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 this.messagingSystem.subscribe('KeyringController:unlock', async () => {\n this.#isUnlocked = true;\n await this.#restartTokenDetection();\n });\n\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n this.#stopPolling();\n });\n\n this.messagingSystem.subscribe(\n 'TokenListController: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 ({ tokenList }) => {\n const hasTokens = Object.keys(tokenList).length;\n\n if (hasTokens) {\n await this.#restartTokenDetection();\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'PreferencesController: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 ({ useTokenDetection }) => {\n const selectedAccount = this.#getSelectedAccount();\n const isDetectionChangedFromPreferences =\n this.#isDetectionEnabledFromPreferences !== useTokenDetection;\n\n this.#isDetectionEnabledFromPreferences = useTokenDetection;\n\n if (isDetectionChangedFromPreferences) {\n await this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\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 (selectedAccount) => {\n const isSelectedAccountIdChanged =\n this.#selectedAccountId !== selectedAccount.id;\n if (isSelectedAccountIdChanged) {\n this.#selectedAccountId = selectedAccount.id;\n await this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'NetworkController:networkDidChange',\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 ({ selectedNetworkClientId }) => {\n const isNetworkClientIdChanged =\n this.#networkClientId !== selectedNetworkClientId;\n\n const { chainId: newChainId } =\n this.#getCorrectChainIdAndNetworkClientId(selectedNetworkClientId);\n this.#isDetectionEnabledForNetwork =\n isTokenDetectionSupportedForNetwork(newChainId);\n\n if (isNetworkClientIdChanged && this.#isDetectionEnabledForNetwork) {\n this.#networkClientId = selectedNetworkClientId;\n await this.#restartTokenDetection({\n networkClientId: this.#networkClientId,\n });\n }\n },\n );\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 /**\n * Internal isActive state\n * @type {boolean}\n */\n get isActive(): boolean {\n return !this.#disabled && this.#isUnlocked;\n }\n\n /**\n * Start polling for detected tokens.\n */\n async start(): Promise<void> {\n this.enable();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for detected tokens.\n */\n stop(): void {\n this.disable();\n this.#stopPolling();\n }\n\n #stopPolling(): void {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n if (!this.isActive) {\n return;\n }\n this.#stopPolling();\n await this.detectTokens();\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 this.#intervalId = setInterval(async () => {\n await this.detectTokens();\n }, this.getIntervalLength());\n }\n\n #getCorrectChainIdAndNetworkClientId(networkClientId?: NetworkClientId): {\n chainId: Hex;\n networkClientId: NetworkClientId;\n } {\n if (networkClientId) {\n const networkConfiguration = this.messagingSystem.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n networkClientId,\n );\n if (networkConfiguration) {\n return {\n chainId: networkConfiguration.chainId,\n networkClientId,\n };\n }\n }\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return {\n chainId,\n networkClientId: selectedNetworkClientId,\n };\n }\n\n async _executePoll({\n networkClientId,\n address,\n }: TokenDetectionPollingInput): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n networkClientId,\n selectedAddress: address,\n });\n }\n\n /**\n * Restart token detection polling period and call detectNewTokens\n * in case of address change or user session initialization.\n *\n * @param options - Options for restart token detection.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances\n * @param options.networkClientId - The ID of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n networkClientId,\n }: {\n selectedAddress?: string;\n networkClientId?: NetworkClientId;\n } = {}): Promise<void> {\n await this.detectTokens({\n networkClientId,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n /**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.networkClientId - The ID of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n */\n async detectTokens({\n networkClientId,\n selectedAddress,\n }: {\n networkClientId?: NetworkClientId;\n selectedAddress?: string;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const addressAgainstWhichToDetect =\n selectedAddress ?? this.#getSelectedAddress();\n const { chainId, networkClientId: selectedNetworkClientId } =\n this.#getCorrectChainIdAndNetworkClientId(networkClientId);\n const chainIdAgainstWhichToDetect = chainId;\n const networkClientIdAgainstWhichToDetect = selectedNetworkClientId;\n\n if (!isTokenDetectionSupportedForNetwork(chainIdAgainstWhichToDetect)) {\n return;\n }\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainIdAgainstWhichToDetect !== ChainId.mainnet\n ) {\n return;\n }\n const isTokenDetectionInactiveInMainnet =\n !this.#isDetectionEnabledFromPreferences &&\n chainIdAgainstWhichToDetect === ChainId.mainnet;\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokenList = isTokenDetectionInactiveInMainnet\n ? STATIC_MAINNET_TOKEN_LIST\n : tokensChainsCache[chainIdAgainstWhichToDetect]?.data ?? {};\n\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId: chainIdAgainstWhichToDetect,\n selectedAddress: addressAgainstWhichToDetect,\n });\n\n // Attempt Accounts API Detection\n const accountAPIResult = await this.#addDetectedTokensViaAPI({\n chainId: chainIdAgainstWhichToDetect,\n selectedAddress: addressAgainstWhichToDetect,\n tokenCandidateSlices,\n });\n if (accountAPIResult?.result === 'success') {\n return;\n }\n\n // Attempt RPC Detection\n const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) =>\n this.#addDetectedTokens({\n tokensSlice,\n selectedAddress: addressAgainstWhichToDetect,\n networkClientId: networkClientIdAgainstWhichToDetect,\n chainId: chainIdAgainstWhichToDetect,\n }),\n );\n\n await Promise.all(tokenDetectionPromises);\n }\n\n #getSlicesOfTokensToDetect({\n chainId,\n selectedAddress,\n }: {\n chainId: Hex;\n selectedAddress: string;\n }): string[][] {\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messagingSystem.call('TokensController:getState');\n const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [\n allTokens,\n allDetectedTokens,\n allIgnoredTokens,\n ].map((tokens) =>\n (tokens[chainId]?.[selectedAddress] ?? []).map((value) =>\n typeof value === 'string' ? value : value.address,\n ),\n );\n\n const tokensToDetect: string[] = [];\n for (const tokenAddress of Object.keys(this.#tokenList)) {\n if (\n [\n tokensAddresses,\n detectedTokensAddresses,\n ignoredTokensAddresses,\n ].every(\n (addresses) =>\n !addresses.find((address) =>\n isEqualCaseInsensitive(address, tokenAddress),\n ),\n )\n ) {\n tokensToDetect.push(tokenAddress);\n }\n }\n\n const slicesOfTokensToDetect = [];\n for (let i = 0, size = 1000; i < tokensToDetect.length; i += size) {\n slicesOfTokensToDetect.push(tokensToDetect.slice(i, i + size));\n }\n\n return slicesOfTokensToDetect;\n }\n\n /**\n * This adds detected tokens from the Accounts API, avoiding the multi-call RPC calls for balances\n * @param options - method arguments\n * @param options.selectedAddress - address to check against\n * @param options.chainId - chainId to check tokens for\n * @param options.tokenCandidateSlices - these are tokens we know a user does not have (by checking the tokens controller).\n * We will use these these token candidates to determine if a token found from the API is valid to be added on the users wallet.\n * It will also prevent us to adding tokens a user already has\n * @returns a success or failed object\n */\n async #addDetectedTokensViaAPI({\n selectedAddress,\n chainId,\n tokenCandidateSlices,\n }: {\n selectedAddress: string;\n chainId: Hex;\n tokenCandidateSlices: string[][];\n }) {\n return await safelyExecute(async () => {\n const tokenBalances = await this.#accountsAPI\n .getMultiChainBalances(selectedAddress, chainId)\n .catch(() => null);\n\n if (!tokenBalances || tokenBalances.length === 0) {\n return { result: 'failed' } as const;\n }\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n\n const tokenCandidateSet = new Set<string>(tokenCandidateSlices.flat());\n\n tokenBalances.forEach((token) => {\n const tokenAddress = token.address;\n\n // Make sure that the token to add is in our candidate list\n // Ensures we don't add tokens we already own\n if (!tokenCandidateSet.has(token.address)) {\n return;\n }\n\n // We need specific data from tokenList to correctly create a token\n // So even if we have a token that was detected correctly by the API, if its missing data we cannot safely add it.\n if (!this.#tokenList[token.address]) {\n return;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name } =\n this.#tokenList[token.address];\n eventTokensDetails.push(`${symbol} - ${tokenAddress}`);\n tokensWithBalance.push({\n address: tokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n });\n });\n\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: ERC20,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n await this.messagingSystem.call(\n 'TokensController:addDetectedTokens',\n tokensWithBalance,\n {\n selectedAddress,\n chainId,\n },\n );\n }\n\n return { result: 'success' } as const;\n });\n }\n\n async #addDetectedTokens({\n tokensSlice,\n selectedAddress,\n networkClientId,\n chainId,\n }: {\n tokensSlice: string[];\n selectedAddress: string;\n networkClientId: NetworkClientId;\n chainId: Hex;\n }): Promise<void> {\n await safelyExecute(async () => {\n const balances = await this.#getBalancesInSingleCall(\n selectedAddress,\n tokensSlice,\n networkClientId,\n );\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n for (const nonZeroTokenAddress of Object.keys(balances)) {\n const { decimals, symbol, aggregators, iconUrl, name } =\n this.#tokenList[nonZeroTokenAddress];\n eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);\n tokensWithBalance.push({\n address: nonZeroTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n });\n }\n\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: ERC20,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n await this.messagingSystem.call(\n 'TokensController:addDetectedTokens',\n tokensWithBalance,\n {\n selectedAddress,\n chainId,\n },\n );\n }\n });\n }\n\n #getSelectedAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getSelectedAddress() {\n // If the address is not defined (or empty), we fallback to the currently selected account's address\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n this.#selectedAccountId,\n );\n return account?.address || '';\n }\n}\n\nexport default TokenDetectionController;\n"]}
1
+ {"version":3,"file":"TokenDetectionController.mjs","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerGetAccountAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n RestrictedControllerMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport contractMap from '@metamask/contract-metadata';\nimport {\n ASSET_TYPES,\n ChainId,\n ERC20,\n safelyExecute,\n isEqualCaseInsensitive,\n} from '@metamask/controller-utils';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetNetworkConfigurationByNetworkClientId,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkDidChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\nimport { hexToNumber } from '@metamask/utils';\nimport { isEqual, mapValues, isObject, get } from 'lodash';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport { isTokenDetectionSupportedForNetwork } from './assetsUtil';\nimport {\n fetchMultiChainBalances,\n fetchSupportedNetworks,\n} from './multi-chain-accounts-service';\nimport type {\n GetTokenListState,\n TokenListMap,\n TokenListStateChange,\n TokensChainsCache,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\nimport type {\n TokensControllerAddDetectedTokensAction,\n TokensControllerGetStateAction,\n} from './TokensController';\n\nconst DEFAULT_INTERVAL = 180000;\n\ntype LegacyToken = {\n name: string;\n logo: `${string}.svg`;\n symbol: string;\n decimals: number;\n erc20?: boolean;\n erc721?: boolean;\n};\n\ntype TokenDetectionMap = {\n [P in keyof TokenListMap]: Omit<TokenListMap[P], 'occurrences'>;\n};\n\nexport const STATIC_MAINNET_TOKEN_LIST = Object.entries<LegacyToken>(\n contractMap,\n).reduce<TokenDetectionMap>((acc, [base, contract]) => {\n const { logo, erc20, erc721, ...tokenMetadata } = contract;\n return {\n ...acc,\n [base.toLowerCase()]: {\n ...tokenMetadata,\n address: base.toLowerCase(),\n iconUrl: `images/contract/${logo}`,\n aggregators: [],\n },\n };\n}, {});\n\n/**\n * Function that takes a TokensChainsCache object and maps chainId with TokenListMap.\n * @param tokensChainsCache - TokensChainsCache input object\n * @returns returns the map of chainId with TokenListMap\n */\nfunction mapChainIdWithTokenListMap(tokensChainsCache: TokensChainsCache) {\n return mapValues(tokensChainsCache, (value) => {\n if (isObject(value) && 'data' in value) {\n return get(value, ['data']);\n }\n return value;\n });\n}\n\nexport const controllerName = 'TokenDetectionController';\n\nexport type TokenDetectionState = Record<never, never>;\n\nexport type TokenDetectionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenDetectionState\n>;\n\nexport type TokenDetectionControllerActions =\n TokenDetectionControllerGetStateAction;\n\nexport type AllowedActions =\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetAccountAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetNetworkConfigurationByNetworkClientId\n | NetworkControllerGetStateAction\n | GetTokenListState\n | KeyringControllerGetStateAction\n | PreferencesControllerGetStateAction\n | TokensControllerGetStateAction\n | TokensControllerAddDetectedTokensAction;\n\nexport type TokenDetectionControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;\n\nexport type TokenDetectionControllerEvents =\n TokenDetectionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | NetworkControllerNetworkDidChangeEvent\n | TokenListStateChange\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent;\n\nexport type TokenDetectionControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n TokenDetectionControllerActions | AllowedActions,\n TokenDetectionControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/** The input to start polling for the {@link TokenDetectionController} */\ntype TokenDetectionPollingInput = {\n networkClientId: NetworkClientId;\n address: string;\n};\n\n/**\n * Controller that passively polls on a set interval for Tokens auto detection\n * @property intervalId - Polling interval used to fetch new token rates\n * @property selectedAddress - Vault selected address\n * @property networkClientId - The network client ID of the current selected network\n * @property disabled - Boolean to track if network requests are blocked\n * @property isUnlocked - Boolean to track if the keyring state is unlocked\n * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network\n */\nexport class TokenDetectionController extends StaticIntervalPollingController<TokenDetectionPollingInput>()<\n typeof controllerName,\n TokenDetectionState,\n TokenDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #selectedAccountId: string;\n\n #networkClientId: NetworkClientId;\n\n #tokensChainsCache: TokensChainsCache = {};\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n #isDetectionEnabledForNetwork: boolean;\n\n readonly #getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n\n readonly #trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n\n #accountsAPI = {\n isAccountsAPIEnabled: true,\n supportedNetworksCache: null as number[] | null,\n platform: '' as 'extension' | 'mobile',\n\n async getSupportedNetworks() {\n /* istanbul ignore next */\n if (!this.isAccountsAPIEnabled) {\n throw new Error('Accounts API Feature Switch is disabled');\n }\n\n /* istanbul ignore next */\n if (this.supportedNetworksCache) {\n return this.supportedNetworksCache;\n }\n\n const result = await fetchSupportedNetworks().catch(() => null);\n this.supportedNetworksCache = result;\n return result;\n },\n\n async getMultiChainBalances(address: string, chainId: Hex) {\n if (!this.isAccountsAPIEnabled) {\n throw new Error('Accounts API Feature Switch is disabled');\n }\n\n const chainIdNumber = hexToNumber(chainId);\n const supportedNetworks = await this.getSupportedNetworks();\n\n if (!supportedNetworks || !supportedNetworks.includes(chainIdNumber)) {\n const supportedNetworksErrStr = (supportedNetworks ?? []).toString();\n throw new Error(\n `Unsupported Network: supported networks ${supportedNetworksErrStr}, network: ${chainIdNumber}`,\n );\n }\n\n const result = await fetchMultiChainBalances(\n address,\n {\n networks: [chainIdNumber],\n },\n this.platform,\n );\n\n return result.balances;\n },\n };\n\n /**\n * Creates a TokenDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The controller messaging system.\n * @param options.disabled - If set to true, all network requests are blocked.\n * @param options.interval - Polling interval used to fetch new token rates\n * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.\n * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.\n * @param options.useAccountsAPI - Feature Switch for using the accounts API when detecting tokens (default: true)\n * @param options.platform - Indicates whether the platform is extension or mobile\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = true,\n getBalancesInSingleCall,\n trackMetaMetricsEvent,\n messenger,\n useAccountsAPI = true,\n platform,\n }: {\n interval?: number;\n disabled?: boolean;\n getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n messenger: TokenDetectionControllerMessenger;\n useAccountsAPI?: boolean;\n platform: 'extension' | 'mobile';\n }) {\n super({\n name: controllerName,\n messenger,\n state: {},\n metadata: {},\n });\n\n this.#disabled = disabled;\n this.setIntervalLength(interval);\n\n this.#selectedAccountId = this.#getSelectedAccount().id;\n\n const { chainId, networkClientId } =\n this.#getCorrectChainIdAndNetworkClientId();\n this.#networkClientId = networkClientId;\n\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache;\n\n const { useTokenDetection: defaultUseTokenDetection } =\n this.messagingSystem.call('PreferencesController:getState');\n this.#isDetectionEnabledFromPreferences = defaultUseTokenDetection;\n this.#isDetectionEnabledForNetwork =\n isTokenDetectionSupportedForNetwork(chainId);\n\n this.#getBalancesInSingleCall = getBalancesInSingleCall;\n\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n const { isUnlocked } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n this.#isUnlocked = isUnlocked;\n\n this.#accountsAPI.isAccountsAPIEnabled = useAccountsAPI;\n this.#accountsAPI.platform = platform;\n\n this.#registerEventListeners();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system subscriptions to controller events.\n */\n #registerEventListeners() {\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 this.messagingSystem.subscribe('KeyringController:unlock', async () => {\n this.#isUnlocked = true;\n await this.#restartTokenDetection();\n });\n\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n this.#stopPolling();\n });\n\n this.messagingSystem.subscribe(\n 'TokenListController: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 ({ tokensChainsCache }) => {\n const isEqualValues = this.#compareTokensChainsCache(\n tokensChainsCache,\n this.#tokensChainsCache,\n );\n if (!isEqualValues) {\n await this.#restartTokenDetection();\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'PreferencesController: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 ({ useTokenDetection }) => {\n const selectedAccount = this.#getSelectedAccount();\n const isDetectionChangedFromPreferences =\n this.#isDetectionEnabledFromPreferences !== useTokenDetection;\n\n this.#isDetectionEnabledFromPreferences = useTokenDetection;\n\n if (isDetectionChangedFromPreferences) {\n await this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\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 (selectedAccount) => {\n const isSelectedAccountIdChanged =\n this.#selectedAccountId !== selectedAccount.id;\n if (isSelectedAccountIdChanged) {\n this.#selectedAccountId = selectedAccount.id;\n await this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'NetworkController:networkDidChange',\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 ({ selectedNetworkClientId }) => {\n const isNetworkClientIdChanged =\n this.#networkClientId !== selectedNetworkClientId;\n\n const { chainId: newChainId } =\n this.#getCorrectChainIdAndNetworkClientId(selectedNetworkClientId);\n this.#isDetectionEnabledForNetwork =\n isTokenDetectionSupportedForNetwork(newChainId);\n\n if (isNetworkClientIdChanged && this.#isDetectionEnabledForNetwork) {\n this.#networkClientId = selectedNetworkClientId;\n await this.#restartTokenDetection({\n networkClientId: this.#networkClientId,\n });\n }\n },\n );\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 /**\n * Internal isActive state\n * @type {boolean}\n */\n get isActive(): boolean {\n return !this.#disabled && this.#isUnlocked;\n }\n\n /**\n * Start polling for detected tokens.\n */\n async start(): Promise<void> {\n this.enable();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for detected tokens.\n */\n stop(): void {\n this.disable();\n this.#stopPolling();\n }\n\n #stopPolling(): void {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n if (!this.isActive) {\n return;\n }\n this.#stopPolling();\n await this.detectTokens();\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 this.#intervalId = setInterval(async () => {\n await this.detectTokens();\n }, this.getIntervalLength());\n }\n\n /**\n * Compares current and previous tokensChainsCache object focusing only on the data object.\n * @param tokensChainsCache - current tokensChainsCache input object\n * @param previousTokensChainsCache - previous tokensChainsCache input object\n * @returns boolean indicating if the two objects are equal\n */\n\n #compareTokensChainsCache(\n tokensChainsCache: TokensChainsCache,\n previousTokensChainsCache: TokensChainsCache,\n ): boolean {\n const cleanPreviousTokensChainsCache = mapChainIdWithTokenListMap(\n previousTokensChainsCache,\n );\n const cleanTokensChainsCache =\n mapChainIdWithTokenListMap(tokensChainsCache);\n const isEqualValues = isEqual(\n cleanTokensChainsCache,\n cleanPreviousTokensChainsCache,\n );\n return isEqualValues;\n }\n\n #getCorrectChainIdAndNetworkClientId(networkClientId?: NetworkClientId): {\n chainId: Hex;\n networkClientId: NetworkClientId;\n } {\n if (networkClientId) {\n const networkConfiguration = this.messagingSystem.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n networkClientId,\n );\n if (networkConfiguration) {\n return {\n chainId: networkConfiguration.chainId,\n networkClientId,\n };\n }\n }\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return {\n chainId,\n networkClientId: selectedNetworkClientId,\n };\n }\n\n async _executePoll({\n networkClientId,\n address,\n }: TokenDetectionPollingInput): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n networkClientId,\n selectedAddress: address,\n });\n }\n\n /**\n * Restart token detection polling period and call detectNewTokens\n * in case of address change or user session initialization.\n *\n * @param options - Options for restart token detection.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances\n * @param options.networkClientId - The ID of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n networkClientId,\n }: {\n selectedAddress?: string;\n networkClientId?: NetworkClientId;\n } = {}): Promise<void> {\n await this.detectTokens({\n networkClientId,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n /**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.networkClientId - The ID of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n */\n async detectTokens({\n networkClientId,\n selectedAddress,\n }: {\n networkClientId?: NetworkClientId;\n selectedAddress?: string;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const addressAgainstWhichToDetect =\n selectedAddress ?? this.#getSelectedAddress();\n const { chainId, networkClientId: selectedNetworkClientId } =\n this.#getCorrectChainIdAndNetworkClientId(networkClientId);\n const chainIdAgainstWhichToDetect = chainId;\n const networkClientIdAgainstWhichToDetect = selectedNetworkClientId;\n\n if (!isTokenDetectionSupportedForNetwork(chainIdAgainstWhichToDetect)) {\n return;\n }\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainIdAgainstWhichToDetect !== ChainId.mainnet\n ) {\n return;\n }\n const isTokenDetectionInactiveInMainnet =\n !this.#isDetectionEnabledFromPreferences &&\n chainIdAgainstWhichToDetect === ChainId.mainnet;\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = isTokenDetectionInactiveInMainnet\n ? this.#getConvertedStaticMainnetTokenList()\n : tokensChainsCache ?? {};\n\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId: chainIdAgainstWhichToDetect,\n selectedAddress: addressAgainstWhichToDetect,\n });\n\n // Attempt Accounts API Detection\n const accountAPIResult = await this.#addDetectedTokensViaAPI({\n chainId: chainIdAgainstWhichToDetect,\n selectedAddress: addressAgainstWhichToDetect,\n tokenCandidateSlices,\n });\n if (accountAPIResult?.result === 'success') {\n return;\n }\n\n // Attempt RPC Detection\n const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) =>\n this.#addDetectedTokens({\n tokensSlice,\n selectedAddress: addressAgainstWhichToDetect,\n networkClientId: networkClientIdAgainstWhichToDetect,\n chainId: chainIdAgainstWhichToDetect,\n }),\n );\n\n await Promise.all(tokenDetectionPromises);\n }\n\n #getSlicesOfTokensToDetect({\n chainId,\n selectedAddress,\n }: {\n chainId: Hex;\n selectedAddress: string;\n }): string[][] {\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messagingSystem.call('TokensController:getState');\n const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [\n allTokens,\n allDetectedTokens,\n allIgnoredTokens,\n ].map((tokens) =>\n (tokens[chainId]?.[selectedAddress] ?? []).map((value) =>\n typeof value === 'string' ? value : value.address,\n ),\n );\n\n const tokensToDetect: string[] = [];\n for (const tokenAddress of Object.keys(\n this.#tokensChainsCache?.[chainId]?.data || {},\n )) {\n if (\n [\n tokensAddresses,\n detectedTokensAddresses,\n ignoredTokensAddresses,\n ].every(\n (addresses) =>\n !addresses.find((address) =>\n isEqualCaseInsensitive(address, tokenAddress),\n ),\n )\n ) {\n tokensToDetect.push(tokenAddress);\n }\n }\n\n const slicesOfTokensToDetect = [];\n for (let i = 0, size = 1000; i < tokensToDetect.length; i += size) {\n slicesOfTokensToDetect.push(tokensToDetect.slice(i, i + size));\n }\n\n return slicesOfTokensToDetect;\n }\n\n #getConvertedStaticMainnetTokenList(): TokensChainsCache {\n const data: TokenListMap = Object.entries(STATIC_MAINNET_TOKEN_LIST).reduce(\n (acc, [key, value]) => ({\n ...acc,\n [key]: {\n name: value.name,\n symbol: value.symbol,\n decimals: value.decimals,\n address: value.address,\n aggregators: [],\n iconUrl: value?.iconUrl,\n },\n }),\n {},\n );\n return {\n '0x1': {\n data,\n timestamp: 0,\n },\n };\n }\n\n /**\n * This adds detected tokens from the Accounts API, avoiding the multi-call RPC calls for balances\n * @param options - method arguments\n * @param options.selectedAddress - address to check against\n * @param options.chainId - chainId to check tokens for\n * @param options.tokenCandidateSlices - these are tokens we know a user does not have (by checking the tokens controller).\n * We will use these these token candidates to determine if a token found from the API is valid to be added on the users wallet.\n * It will also prevent us to adding tokens a user already has\n * @returns a success or failed object\n */\n async #addDetectedTokensViaAPI({\n selectedAddress,\n chainId,\n tokenCandidateSlices,\n }: {\n selectedAddress: string;\n chainId: Hex;\n tokenCandidateSlices: string[][];\n }) {\n return await safelyExecute(async () => {\n const tokenBalances = await this.#accountsAPI\n .getMultiChainBalances(selectedAddress, chainId)\n .catch(() => null);\n\n if (!tokenBalances || tokenBalances.length === 0) {\n return { result: 'failed' } as const;\n }\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n\n const tokenCandidateSet = new Set<string>(tokenCandidateSlices.flat());\n\n tokenBalances.forEach((token) => {\n const tokenAddress = token.address;\n\n // Make sure that the token to add is in our candidate list\n // Ensures we don't add tokens we already own\n if (!tokenCandidateSet.has(token.address)) {\n return;\n }\n\n // We need specific data from tokensChainsCache to correctly create a token\n // So even if we have a token that was detected correctly by the API, if its missing data we cannot safely add it.\n if (!this.#tokensChainsCache[chainId].data[token.address]) {\n return;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name } =\n this.#tokensChainsCache[chainId].data[token.address];\n eventTokensDetails.push(`${symbol} - ${tokenAddress}`);\n tokensWithBalance.push({\n address: tokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n });\n });\n\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: ERC20,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n await this.messagingSystem.call(\n 'TokensController:addDetectedTokens',\n tokensWithBalance,\n {\n selectedAddress,\n chainId,\n },\n );\n }\n\n return { result: 'success' } as const;\n });\n }\n\n async #addDetectedTokens({\n tokensSlice,\n selectedAddress,\n networkClientId,\n chainId,\n }: {\n tokensSlice: string[];\n selectedAddress: string;\n networkClientId: NetworkClientId;\n chainId: Hex;\n }): Promise<void> {\n await safelyExecute(async () => {\n const balances = await this.#getBalancesInSingleCall(\n selectedAddress,\n tokensSlice,\n networkClientId,\n );\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n for (const nonZeroTokenAddress of Object.keys(balances)) {\n const { decimals, symbol, aggregators, iconUrl, name } =\n this.#tokensChainsCache[chainId].data[nonZeroTokenAddress];\n eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);\n tokensWithBalance.push({\n address: nonZeroTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n });\n }\n\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: ERC20,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n await this.messagingSystem.call(\n 'TokensController:addDetectedTokens',\n tokensWithBalance,\n {\n selectedAddress,\n chainId,\n },\n );\n }\n });\n }\n\n #getSelectedAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getSelectedAddress() {\n // If the address is not defined (or empty), we fallback to the currently selected account's address\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n this.#selectedAccountId,\n );\n return account?.address || '';\n }\n}\n\nexport default TokenDetectionController;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenListController.cjs","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkControllerGetNetworkClientByIdAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenListByChainId } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\ntype TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = ControllerStateChangeEvent<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerEvents = TokenListStateChange;\n\nexport type GetTokenListState = ControllerGetStateAction<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerActions = GetTokenListState;\n\ntype AllowedActions = NetworkControllerGetNetworkClientByIdAction;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\nexport type TokenListControllerMessenger = RestrictedControllerMessenger<\n typeof name,\n TokenListControllerActions | AllowedActions,\n TokenListControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nexport const getDefaultTokenListState = (): TokenListState => {\n return {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n };\n};\n\n/** The input to start polling for the {@link TokenListController} */\ntype TokenListPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends StaticIntervalPollingController<TokenListPollingInput>()<\n typeof name,\n TokenListState,\n TokenListControllerMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListControllerMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...getDefaultTokenListState(), ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\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 onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController: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 (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n const selectedNetworkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkControllerState.selectedNetworkClientId,\n );\n const { chainId } = selectedNetworkClient.configuration;\n\n if (this.chainId !== chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\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 this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param input - The input for the poll.\n * @param input.networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({\n networkClientId,\n }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(networkClientId);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @param networkClientId - The ID of the network client triggering the fetch.\n */\n async fetchTokenList(networkClientId?: NetworkClientId): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n let networkClient;\n if (networkClientId) {\n networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n }\n const chainId = networkClient?.configuration.chainId ?? this.chainId;\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens = await safelyExecute(() =>\n this.#fetchFromCache(chainId),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n for (const token of tokensFromAPI) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n * @param chainId - The chain ID of the network for which to fetch the cache.\n * @returns The cached data, or `null` if the cache was expired.\n */\n async #fetchFromCache(chainId: Hex): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
1
+ {"version":3,"file":"TokenListController.cjs","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkControllerGetNetworkClientByIdAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenListByChainId } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\nexport type TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = ControllerStateChangeEvent<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerEvents = TokenListStateChange;\n\nexport type GetTokenListState = ControllerGetStateAction<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerActions = GetTokenListState;\n\ntype AllowedActions = NetworkControllerGetNetworkClientByIdAction;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\nexport type TokenListControllerMessenger = RestrictedControllerMessenger<\n typeof name,\n TokenListControllerActions | AllowedActions,\n TokenListControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nexport const getDefaultTokenListState = (): TokenListState => {\n return {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n };\n};\n\n/** The input to start polling for the {@link TokenListController} */\ntype TokenListPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends StaticIntervalPollingController<TokenListPollingInput>()<\n typeof name,\n TokenListState,\n TokenListControllerMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListControllerMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...getDefaultTokenListState(), ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\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 onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController: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 (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n const selectedNetworkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkControllerState.selectedNetworkClientId,\n );\n const { chainId } = selectedNetworkClient.configuration;\n\n if (this.chainId !== chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\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 this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param input - The input for the poll.\n * @param input.networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({\n networkClientId,\n }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(networkClientId);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @param networkClientId - The ID of the network client triggering the fetch.\n */\n async fetchTokenList(networkClientId?: NetworkClientId): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n let networkClient;\n if (networkClientId) {\n networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n }\n const chainId = networkClient?.configuration.chainId ?? this.chainId;\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens = await safelyExecute(() =>\n this.#fetchFromCache(chainId),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n for (const token of tokensFromAPI) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n * @param chainId - The chain ID of the network for which to fetch the cache.\n * @returns The cached data, or `null` if the cache was expired.\n */\n async #fetchFromCache(chainId: Hex): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
@@ -16,7 +16,7 @@ type DataCache = {
16
16
  timestamp: number;
17
17
  data: TokenListMap;
18
18
  };
19
- type TokensChainsCache = {
19
+ export type TokensChainsCache = {
20
20
  [chainId: Hex]: DataCache;
21
21
  };
22
22
  export type TokenListState = {
@@ -37,14 +37,14 @@ type TokenListPollingInput = {
37
37
  networkClientId: NetworkClientId;
38
38
  };
39
39
  declare const TokenListController_base: (abstract new (...args: any[]) => {
40
- readonly "__#787852@#intervalIds": Record<string, NodeJS.Timeout>;
41
- "__#787852@#intervalLength": number | undefined;
40
+ readonly "__#787890@#intervalIds": Record<string, NodeJS.Timeout>;
41
+ "__#787890@#intervalLength": number | undefined;
42
42
  setIntervalLength(intervalLength: number): void;
43
43
  getIntervalLength(): number | undefined;
44
44
  _startPolling(input: TokenListPollingInput): void;
45
45
  _stopPollingByPollingTokenSetId(key: string): void;
46
- readonly "__#787844@#pollingTokenSets": Map<string, Set<string>>;
47
- "__#787844@#callbacks": Map<string, Set<(input: TokenListPollingInput) => void>>;
46
+ readonly "__#787882@#pollingTokenSets": Map<string, Set<string>>;
47
+ "__#787882@#callbacks": Map<string, Set<(input: TokenListPollingInput) => void>>;
48
48
  _executePoll(input: TokenListPollingInput): Promise<void>;
49
49
  startPolling(input: TokenListPollingInput): string;
50
50
  stopAllPolling(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"TokenListController.d.cts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenListController.d.cts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ type DataCache = {
16
16
  timestamp: number;
17
17
  data: TokenListMap;
18
18
  };
19
- type TokensChainsCache = {
19
+ export type TokensChainsCache = {
20
20
  [chainId: Hex]: DataCache;
21
21
  };
22
22
  export type TokenListState = {
@@ -37,14 +37,14 @@ type TokenListPollingInput = {
37
37
  networkClientId: NetworkClientId;
38
38
  };
39
39
  declare const TokenListController_base: (abstract new (...args: any[]) => {
40
- readonly "__#787852@#intervalIds": Record<string, NodeJS.Timeout>;
41
- "__#787852@#intervalLength": number | undefined;
40
+ readonly "__#787890@#intervalIds": Record<string, NodeJS.Timeout>;
41
+ "__#787890@#intervalLength": number | undefined;
42
42
  setIntervalLength(intervalLength: number): void;
43
43
  getIntervalLength(): number | undefined;
44
44
  _startPolling(input: TokenListPollingInput): void;
45
45
  _stopPollingByPollingTokenSetId(key: string): void;
46
- readonly "__#787844@#pollingTokenSets": Map<string, Set<string>>;
47
- "__#787844@#callbacks": Map<string, Set<(input: TokenListPollingInput) => void>>;
46
+ readonly "__#787882@#pollingTokenSets": Map<string, Set<string>>;
47
+ "__#787882@#callbacks": Map<string, Set<(input: TokenListPollingInput) => void>>;
48
48
  _executePoll(input: TokenListPollingInput): Promise<void>;
49
49
  startPolling(input: TokenListPollingInput): string;
50
50
  stopAllPolling(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"TokenListController.d.mts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenListController.d.mts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenListController.mjs","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkControllerGetNetworkClientByIdAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenListByChainId } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\ntype TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = ControllerStateChangeEvent<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerEvents = TokenListStateChange;\n\nexport type GetTokenListState = ControllerGetStateAction<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerActions = GetTokenListState;\n\ntype AllowedActions = NetworkControllerGetNetworkClientByIdAction;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\nexport type TokenListControllerMessenger = RestrictedControllerMessenger<\n typeof name,\n TokenListControllerActions | AllowedActions,\n TokenListControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nexport const getDefaultTokenListState = (): TokenListState => {\n return {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n };\n};\n\n/** The input to start polling for the {@link TokenListController} */\ntype TokenListPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends StaticIntervalPollingController<TokenListPollingInput>()<\n typeof name,\n TokenListState,\n TokenListControllerMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListControllerMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...getDefaultTokenListState(), ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\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 onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController: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 (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n const selectedNetworkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkControllerState.selectedNetworkClientId,\n );\n const { chainId } = selectedNetworkClient.configuration;\n\n if (this.chainId !== chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\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 this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param input - The input for the poll.\n * @param input.networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({\n networkClientId,\n }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(networkClientId);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @param networkClientId - The ID of the network client triggering the fetch.\n */\n async fetchTokenList(networkClientId?: NetworkClientId): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n let networkClient;\n if (networkClientId) {\n networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n }\n const chainId = networkClient?.configuration.chainId ?? this.chainId;\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens = await safelyExecute(() =>\n this.#fetchFromCache(chainId),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n for (const token of tokensFromAPI) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n * @param chainId - The chain ID of the network for which to fetch the cache.\n * @returns The cached data, or `null` if the cache was expired.\n */\n async #fetchFromCache(chainId: Hex): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
1
+ {"version":3,"file":"TokenListController.mjs","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkControllerGetNetworkClientByIdAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenListByChainId } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\nexport type TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = ControllerStateChangeEvent<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerEvents = TokenListStateChange;\n\nexport type GetTokenListState = ControllerGetStateAction<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerActions = GetTokenListState;\n\ntype AllowedActions = NetworkControllerGetNetworkClientByIdAction;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\nexport type TokenListControllerMessenger = RestrictedControllerMessenger<\n typeof name,\n TokenListControllerActions | AllowedActions,\n TokenListControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nexport const getDefaultTokenListState = (): TokenListState => {\n return {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n };\n};\n\n/** The input to start polling for the {@link TokenListController} */\ntype TokenListPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends StaticIntervalPollingController<TokenListPollingInput>()<\n typeof name,\n TokenListState,\n TokenListControllerMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListControllerMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...getDefaultTokenListState(), ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\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 onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController: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 (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n const selectedNetworkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkControllerState.selectedNetworkClientId,\n );\n const { chainId } = selectedNetworkClient.configuration;\n\n if (this.chainId !== chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\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 this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param input - The input for the poll.\n * @param input.networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({\n networkClientId,\n }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(networkClientId);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @param networkClientId - The ID of the network client triggering the fetch.\n */\n async fetchTokenList(networkClientId?: NetworkClientId): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n let networkClient;\n if (networkClientId) {\n networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n }\n const chainId = networkClient?.configuration.chainId ?? this.chainId;\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens = await safelyExecute(() =>\n this.#fetchFromCache(chainId),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n for (const token of tokensFromAPI) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n * @param chainId - The chain ID of the network for which to fetch the cache.\n * @returns The cached data, or `null` if the cache was expired.\n */\n async #fetchFromCache(chainId: Hex): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
@@ -206,13 +206,26 @@ class TokenRatesController extends (0, polling_controller_1.StaticIntervalPollin
206
206
  * Updates token rates for the given networkClientId
207
207
  *
208
208
  * @param input - The input for the poll.
209
- * @param input.networkClientId - The network client ID used to get a ticker value.
209
+ * @param input.chainId - The chain id to poll token rates on.
210
210
  */
211
- async _executePoll({ networkClientId, }) {
212
- const networkClient = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
211
+ async _executePoll({ chainId }) {
212
+ const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
213
+ const networkConfiguration = networkConfigurationsByChainId[chainId];
214
+ if (!networkConfiguration) {
215
+ console.error(`TokenRatesController: No network configuration found for chainId ${chainId}`);
216
+ return;
217
+ }
213
218
  await this.updateExchangeRatesByChainId({
214
- chainId: networkClient.configuration.chainId,
215
- nativeCurrency: networkClient.configuration.ticker,
219
+ chainId,
220
+ nativeCurrency: networkConfiguration.nativeCurrency,
221
+ });
222
+ }
223
+ /**
224
+ * Reset the controller state to the default state.
225
+ */
226
+ resetState() {
227
+ this.update(() => {
228
+ return (0, exports.getDefaultTokenRatesControllerState)();
216
229
  });
217
230
  }
218
231
  }
@@ -222,14 +235,29 @@ _TokenRatesController_handle = new WeakMap(), _TokenRatesController_pollState =
222
235
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
223
236
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
224
237
  async ({ allTokens, allDetectedTokens }) => {
225
- const previousTokenAddresses = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokenAddresses).call(this, __classPrivateFieldGet(this, _TokenRatesController_chainId, "f"));
238
+ if (__classPrivateFieldGet(this, _TokenRatesController_disabled, "f")) {
239
+ return;
240
+ }
241
+ const chainIds = [
242
+ ...new Set([
243
+ ...Object.keys(allTokens),
244
+ ...Object.keys(allDetectedTokens),
245
+ ]),
246
+ ];
247
+ const chainIdsToUpdate = chainIds.filter((chainId) => !(0, lodash_1.isEqual)(__classPrivateFieldGet(this, _TokenRatesController_allTokens, "f")[chainId], allTokens[chainId]) ||
248
+ !(0, lodash_1.isEqual)(__classPrivateFieldGet(this, _TokenRatesController_allDetectedTokens, "f")[chainId], allDetectedTokens[chainId]));
226
249
  __classPrivateFieldSet(this, _TokenRatesController_allTokens, allTokens, "f");
227
250
  __classPrivateFieldSet(this, _TokenRatesController_allDetectedTokens, allDetectedTokens, "f");
228
- const newTokenAddresses = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokenAddresses).call(this, __classPrivateFieldGet(this, _TokenRatesController_chainId, "f"));
229
- if (!(0, lodash_1.isEqual)(previousTokenAddresses, newTokenAddresses) &&
230
- __classPrivateFieldGet(this, _TokenRatesController_pollState, "f") === PollState.Active) {
231
- await this.updateExchangeRates();
232
- }
251
+ const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
252
+ await Promise.allSettled(chainIdsToUpdate.map(async (chainId) => {
253
+ const nativeCurrency = networkConfigurationsByChainId[chainId]?.nativeCurrency;
254
+ if (nativeCurrency) {
255
+ await this.updateExchangeRatesByChainId({
256
+ chainId: chainId,
257
+ nativeCurrency,
258
+ });
259
+ }
260
+ }));
233
261
  }, ({ allTokens, allDetectedTokens }) => {
234
262
  return { allTokens, allDetectedTokens };
235
263
  });
@@ -324,6 +352,7 @@ async function _TokenRatesController_fetchAndMapExchangeRates({ tokenAddresses,
324
352
  });
325
353
  }
326
354
  return await __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency).call(this, {
355
+ chainId,
327
356
  tokenAddresses,
328
357
  nativeCurrency,
329
358
  });
@@ -387,17 +416,18 @@ async function _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeC
387
416
  * API, then convert the prices to our desired native currency.
388
417
  *
389
418
  * @param args - The arguments to this function.
419
+ * @param args.chainId - The chain id to fetch prices for.
390
420
  * @param args.tokenAddresses - Addresses for tokens.
391
421
  * @param args.nativeCurrency - The native currency in which to request
392
422
  * prices.
393
423
  * @returns A map of the token addresses (as checksums) to their prices in the
394
424
  * native currency.
395
425
  */
396
- async function _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency({ tokenAddresses, nativeCurrency, }) {
426
+ async function _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency({ chainId, tokenAddresses, nativeCurrency, }) {
397
427
  const [contractExchangeInformations, fallbackCurrencyToNativeCurrencyConversionRate,] = await Promise.all([
398
428
  __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency).call(this, {
399
429
  tokenAddresses,
400
- chainId: __classPrivateFieldGet(this, _TokenRatesController_chainId, "f"),
430
+ chainId,
401
431
  nativeCurrency: controller_utils_1.FALL_BACK_VS_CURRENCY,
402
432
  }),
403
433
  getCurrencyConversionRate({