@metamask/assets-controllers 47.0.0 → 48.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 (162) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/dist/AccountTrackerController.cjs.map +1 -1
  3. package/dist/AccountTrackerController.d.cts +8 -3
  4. package/dist/AccountTrackerController.d.cts.map +1 -1
  5. package/dist/AccountTrackerController.d.mts +8 -3
  6. package/dist/AccountTrackerController.d.mts.map +1 -1
  7. package/dist/AccountTrackerController.mjs.map +1 -1
  8. package/dist/AssetsContractController.cjs +3 -3
  9. package/dist/AssetsContractController.cjs.map +1 -1
  10. package/dist/AssetsContractController.d.cts +3 -3
  11. package/dist/AssetsContractController.d.cts.map +1 -1
  12. package/dist/AssetsContractController.d.mts +3 -3
  13. package/dist/AssetsContractController.d.mts.map +1 -1
  14. package/dist/AssetsContractController.mjs +3 -3
  15. package/dist/AssetsContractController.mjs.map +1 -1
  16. package/dist/CurrencyRateController.cjs.map +1 -1
  17. package/dist/CurrencyRateController.d.cts +2 -2
  18. package/dist/CurrencyRateController.d.cts.map +1 -1
  19. package/dist/CurrencyRateController.d.mts +2 -2
  20. package/dist/CurrencyRateController.d.mts.map +1 -1
  21. package/dist/CurrencyRateController.mjs.map +1 -1
  22. package/dist/MultichainAssetsController/MultichainAssetsController.cjs +324 -0
  23. package/dist/MultichainAssetsController/MultichainAssetsController.cjs.map +1 -0
  24. package/dist/MultichainAssetsController/MultichainAssetsController.d.cts +66 -0
  25. package/dist/MultichainAssetsController/MultichainAssetsController.d.cts.map +1 -0
  26. package/dist/MultichainAssetsController/MultichainAssetsController.d.mts +66 -0
  27. package/dist/MultichainAssetsController/MultichainAssetsController.d.mts.map +1 -0
  28. package/dist/MultichainAssetsController/MultichainAssetsController.mjs +319 -0
  29. package/dist/MultichainAssetsController/MultichainAssetsController.mjs.map +1 -0
  30. package/dist/MultichainAssetsController/index.cjs +7 -0
  31. package/dist/MultichainAssetsController/index.cjs.map +1 -0
  32. package/dist/MultichainAssetsController/index.d.cts +3 -0
  33. package/dist/MultichainAssetsController/index.d.cts.map +1 -0
  34. package/dist/MultichainAssetsController/index.d.mts +3 -0
  35. package/dist/MultichainAssetsController/index.d.mts.map +1 -0
  36. package/dist/MultichainAssetsController/index.mjs +2 -0
  37. package/dist/MultichainAssetsController/index.mjs.map +1 -0
  38. package/dist/MultichainAssetsController/utils.cjs +26 -0
  39. package/dist/MultichainAssetsController/utils.cjs.map +1 -0
  40. package/dist/MultichainAssetsController/utils.d.cts +13 -0
  41. package/dist/MultichainAssetsController/utils.d.cts.map +1 -0
  42. package/dist/MultichainAssetsController/utils.d.mts +13 -0
  43. package/dist/MultichainAssetsController/utils.d.mts.map +1 -0
  44. package/dist/MultichainAssetsController/utils.mjs +22 -0
  45. package/dist/MultichainAssetsController/utils.mjs.map +1 -0
  46. package/dist/MultichainBalancesController/MultichainBalancesController.cjs +30 -65
  47. package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
  48. package/dist/MultichainBalancesController/MultichainBalancesController.d.cts +5 -25
  49. package/dist/MultichainBalancesController/MultichainBalancesController.d.cts.map +1 -1
  50. package/dist/MultichainBalancesController/MultichainBalancesController.d.mts +5 -25
  51. package/dist/MultichainBalancesController/MultichainBalancesController.d.mts.map +1 -1
  52. package/dist/MultichainBalancesController/MultichainBalancesController.mjs +32 -67
  53. package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
  54. package/dist/MultichainBalancesController/constants.cjs +1 -10
  55. package/dist/MultichainBalancesController/constants.cjs.map +1 -1
  56. package/dist/MultichainBalancesController/constants.d.cts +0 -4
  57. package/dist/MultichainBalancesController/constants.d.cts.map +1 -1
  58. package/dist/MultichainBalancesController/constants.d.mts +0 -4
  59. package/dist/MultichainBalancesController/constants.d.mts.map +1 -1
  60. package/dist/MultichainBalancesController/constants.mjs +0 -9
  61. package/dist/MultichainBalancesController/constants.mjs.map +1 -1
  62. package/dist/MultichainBalancesController/index.cjs +1 -4
  63. package/dist/MultichainBalancesController/index.cjs.map +1 -1
  64. package/dist/MultichainBalancesController/index.d.cts +2 -3
  65. package/dist/MultichainBalancesController/index.d.cts.map +1 -1
  66. package/dist/MultichainBalancesController/index.d.mts +2 -3
  67. package/dist/MultichainBalancesController/index.d.mts.map +1 -1
  68. package/dist/MultichainBalancesController/index.mjs +1 -2
  69. package/dist/MultichainBalancesController/index.mjs.map +1 -1
  70. package/dist/MultichainBalancesController/utils.cjs +1 -14
  71. package/dist/MultichainBalancesController/utils.cjs.map +1 -1
  72. package/dist/MultichainBalancesController/utils.d.cts +0 -7
  73. package/dist/MultichainBalancesController/utils.d.cts.map +1 -1
  74. package/dist/MultichainBalancesController/utils.d.mts +0 -7
  75. package/dist/MultichainBalancesController/utils.d.mts.map +1 -1
  76. package/dist/MultichainBalancesController/utils.mjs +1 -13
  77. package/dist/MultichainBalancesController/utils.mjs.map +1 -1
  78. package/dist/NftController.cjs +1 -1
  79. package/dist/NftController.cjs.map +1 -1
  80. package/dist/NftController.d.cts +3 -3
  81. package/dist/NftController.d.cts.map +1 -1
  82. package/dist/NftController.d.mts +3 -3
  83. package/dist/NftController.d.mts.map +1 -1
  84. package/dist/NftController.mjs +1 -1
  85. package/dist/NftController.mjs.map +1 -1
  86. package/dist/NftDetectionController.cjs.map +1 -1
  87. package/dist/NftDetectionController.d.cts +2 -2
  88. package/dist/NftDetectionController.d.cts.map +1 -1
  89. package/dist/NftDetectionController.d.mts +2 -2
  90. package/dist/NftDetectionController.d.mts.map +1 -1
  91. package/dist/NftDetectionController.mjs.map +1 -1
  92. package/dist/RatesController/types.cjs.map +1 -1
  93. package/dist/RatesController/types.d.cts +2 -2
  94. package/dist/RatesController/types.d.cts.map +1 -1
  95. package/dist/RatesController/types.d.mts +2 -2
  96. package/dist/RatesController/types.d.mts.map +1 -1
  97. package/dist/RatesController/types.mjs.map +1 -1
  98. package/dist/TokenBalancesController.cjs.map +1 -1
  99. package/dist/TokenBalancesController.d.cts +6 -4
  100. package/dist/TokenBalancesController.d.cts.map +1 -1
  101. package/dist/TokenBalancesController.d.mts +6 -4
  102. package/dist/TokenBalancesController.d.mts.map +1 -1
  103. package/dist/TokenBalancesController.mjs.map +1 -1
  104. package/dist/TokenDetectionController.cjs +1 -1
  105. package/dist/TokenDetectionController.cjs.map +1 -1
  106. package/dist/TokenDetectionController.d.cts +2 -2
  107. package/dist/TokenDetectionController.d.cts.map +1 -1
  108. package/dist/TokenDetectionController.d.mts +2 -2
  109. package/dist/TokenDetectionController.d.mts.map +1 -1
  110. package/dist/TokenDetectionController.mjs +1 -1
  111. package/dist/TokenDetectionController.mjs.map +1 -1
  112. package/dist/TokenListController.cjs +1 -1
  113. package/dist/TokenListController.cjs.map +1 -1
  114. package/dist/TokenListController.d.cts +3 -3
  115. package/dist/TokenListController.d.cts.map +1 -1
  116. package/dist/TokenListController.d.mts +3 -3
  117. package/dist/TokenListController.d.mts.map +1 -1
  118. package/dist/TokenListController.mjs +1 -1
  119. package/dist/TokenListController.mjs.map +1 -1
  120. package/dist/TokenRatesController.cjs +1 -1
  121. package/dist/TokenRatesController.cjs.map +1 -1
  122. package/dist/TokenRatesController.d.cts +3 -3
  123. package/dist/TokenRatesController.d.cts.map +1 -1
  124. package/dist/TokenRatesController.d.mts +3 -3
  125. package/dist/TokenRatesController.d.mts.map +1 -1
  126. package/dist/TokenRatesController.mjs +1 -1
  127. package/dist/TokenRatesController.mjs.map +1 -1
  128. package/dist/TokensController.cjs +9 -6
  129. package/dist/TokensController.cjs.map +1 -1
  130. package/dist/TokensController.d.cts +3 -3
  131. package/dist/TokensController.d.cts.map +1 -1
  132. package/dist/TokensController.d.mts +3 -3
  133. package/dist/TokensController.d.mts.map +1 -1
  134. package/dist/TokensController.mjs +9 -6
  135. package/dist/TokensController.mjs.map +1 -1
  136. package/dist/index.cjs +4 -3
  137. package/dist/index.cjs.map +1 -1
  138. package/dist/index.d.cts +4 -2
  139. package/dist/index.d.cts.map +1 -1
  140. package/dist/index.d.mts +4 -2
  141. package/dist/index.d.mts.map +1 -1
  142. package/dist/index.mjs +3 -2
  143. package/dist/index.mjs.map +1 -1
  144. package/dist/token-prices-service/codefi-v2.d.cts +1 -1
  145. package/dist/token-prices-service/codefi-v2.d.mts +1 -1
  146. package/package.json +14 -11
  147. package/dist/MultichainBalancesController/BalancesTracker.cjs +0 -122
  148. package/dist/MultichainBalancesController/BalancesTracker.cjs.map +0 -1
  149. package/dist/MultichainBalancesController/BalancesTracker.d.cts +0 -54
  150. package/dist/MultichainBalancesController/BalancesTracker.d.cts.map +0 -1
  151. package/dist/MultichainBalancesController/BalancesTracker.d.mts +0 -54
  152. package/dist/MultichainBalancesController/BalancesTracker.d.mts.map +0 -1
  153. package/dist/MultichainBalancesController/BalancesTracker.mjs +0 -118
  154. package/dist/MultichainBalancesController/BalancesTracker.mjs.map +0 -1
  155. package/dist/MultichainBalancesController/Poller.cjs +0 -45
  156. package/dist/MultichainBalancesController/Poller.cjs.map +0 -1
  157. package/dist/MultichainBalancesController/Poller.d.cts +0 -7
  158. package/dist/MultichainBalancesController/Poller.d.cts.map +0 -1
  159. package/dist/MultichainBalancesController/Poller.d.mts +0 -7
  160. package/dist/MultichainBalancesController/Poller.d.mts.map +0 -1
  161. package/dist/MultichainBalancesController/Poller.mjs +0 -41
  162. package/dist/MultichainBalancesController/Poller.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import type { AccountsControllerGetSelectedAccountAction, AccountsControllerGetAccountAction, AccountsControllerSelectedEvmAccountChangeEvent } from "@metamask/accounts-controller";
2
- import type { RestrictedControllerMessenger, ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
+ import type { RestrictedMessenger, ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
3
  import type { KeyringControllerGetStateAction, KeyringControllerLockEvent, KeyringControllerUnlockEvent } from "@metamask/keyring-controller";
4
4
  import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetNetworkConfigurationByNetworkClientId, NetworkControllerGetStateAction, NetworkControllerNetworkDidChangeEvent } from "@metamask/network-controller";
5
5
  import type { PreferencesControllerGetStateAction, PreferencesControllerStateChangeEvent } from "@metamask/preferences-controller";
@@ -27,7 +27,7 @@ export type AllowedActions = AccountsControllerGetSelectedAccountAction | Accoun
27
27
  export type TokenDetectionControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;
28
28
  export type TokenDetectionControllerEvents = TokenDetectionControllerStateChangeEvent;
29
29
  export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent | TokenListStateChange | KeyringControllerLockEvent | KeyringControllerUnlockEvent | PreferencesControllerStateChangeEvent;
30
- export type TokenDetectionControllerMessenger = RestrictedControllerMessenger<typeof controllerName, TokenDetectionControllerActions | AllowedActions, TokenDetectionControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
30
+ export type TokenDetectionControllerMessenger = RestrictedMessenger<typeof controllerName, TokenDetectionControllerActions | AllowedActions, TokenDetectionControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
31
31
  /** The input to start polling for the {@link TokenDetectionController} */
32
32
  type TokenDetectionPollingInput = {
33
33
  chainIds: Hex[];
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.d.mts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenDetectionController.d.mts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
@@ -456,7 +456,7 @@ async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddre
456
456
  const { tokensChainsCache } = this.messagingSystem.call('TokenListController:getState');
457
457
  __classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, isTokenDetectionInactiveInMainnet
458
458
  ? __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this)
459
- : tokensChainsCache ?? {}, "f");
459
+ : (tokensChainsCache ?? {}), "f");
460
460
  // Generate token candidates based on chainId and selectedAddress
461
461
  const tokenCandidateSlices = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSlicesOfTokensToDetect).call(this, {
462
462
  chainId,
@@ -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';\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\ntype NetworkClient = {\n chainId: Hex;\n networkClientId: string;\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 */\nexport function mapChainIdWithTokenListMap(\n tokensChainsCache: TokensChainsCache,\n) {\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 chainIds: Hex[];\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 getMultiNetworksBalances(\n address: string,\n chainIds: Hex[],\n supportedNetworks: number[] | null,\n ) {\n const chainIdNumbers = chainIds.map((chainId) => hexToNumber(chainId));\n\n if (\n !supportedNetworks ||\n !chainIdNumbers.every((id) => supportedNetworks.includes(id))\n ) {\n const supportedNetworksErrStr = (supportedNetworks ?? []).toString();\n throw new Error(\n `Unsupported Network: supported networks ${supportedNetworksErrStr}, requested networks: ${chainIdNumbers.toString()}`,\n );\n }\n\n const result = await fetchMultiChainBalances(\n address,\n {\n networks: chainIdNumbers,\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\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 { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n const chainIds = Object.keys(networkConfigurationsByChainId) as Hex[];\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 chainIds,\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 #getCorrectNetworkClientIdByChainId(\n chainIds: Hex[] | undefined,\n ): { chainId: Hex; networkClientId: NetworkClientId }[] {\n const { networkConfigurationsByChainId, selectedNetworkClientId } =\n this.messagingSystem.call('NetworkController:getState');\n\n if (!chainIds) {\n const networkConfiguration = this.messagingSystem.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n selectedNetworkClientId,\n );\n\n return [\n {\n chainId: networkConfiguration?.chainId ?? ChainId.mainnet,\n networkClientId: selectedNetworkClientId,\n },\n ];\n }\n\n return chainIds.map((chainId) => {\n const configuration = networkConfigurationsByChainId[chainId];\n return {\n chainId,\n networkClientId:\n configuration.rpcEndpoints[configuration.defaultRpcEndpointIndex]\n .networkClientId,\n };\n });\n }\n\n #getCorrectChainIdAndNetworkClientId() {\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 chainIds,\n address,\n }: TokenDetectionPollingInput): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n chainIds,\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.chainIds - The chain IDs of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n chainIds,\n }: {\n selectedAddress?: string;\n chainIds?: Hex[];\n } = {}): Promise<void> {\n await this.detectTokens({\n chainIds,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n #getChainsToDetect(\n clientNetworks: NetworkClient[],\n supportedNetworks: number[] | null | undefined,\n ) {\n const chainsToDetectUsingAccountAPI: Hex[] = [];\n const chainsToDetectUsingRpc: NetworkClient[] = [];\n\n clientNetworks.forEach(({ chainId, networkClientId }) => {\n if (supportedNetworks?.includes(hexToNumber(chainId))) {\n chainsToDetectUsingAccountAPI.push(chainId);\n } else {\n chainsToDetectUsingRpc.push({ chainId, networkClientId });\n }\n });\n\n return { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI };\n }\n\n async #attemptAccountAPIDetection(\n chainsToDetectUsingAccountAPI: Hex[],\n addressToDetect: string,\n supportedNetworks: number[] | null,\n ) {\n return await this.#addDetectedTokensViaAPI({\n chainIds: chainsToDetectUsingAccountAPI,\n selectedAddress: addressToDetect,\n supportedNetworks,\n });\n }\n\n #addChainsToRpcDetection(\n chainsToDetectUsingRpc: NetworkClient[],\n chainsToDetectUsingAccountAPI: Hex[],\n clientNetworks: NetworkClient[],\n ): void {\n chainsToDetectUsingAccountAPI.forEach((chainId) => {\n const networkEntry = clientNetworks.find(\n (network) => network.chainId === chainId,\n );\n if (networkEntry) {\n chainsToDetectUsingRpc.push({\n chainId: networkEntry.chainId,\n networkClientId: networkEntry.networkClientId,\n });\n }\n });\n }\n\n #shouldDetectTokens(chainId: Hex): boolean {\n if (!isTokenDetectionSupportedForNetwork(chainId)) {\n return false;\n }\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainId !== ChainId.mainnet\n ) {\n return false;\n }\n\n const isMainnetDetectionInactive =\n !this.#isDetectionEnabledFromPreferences && chainId === ChainId.mainnet;\n if (isMainnetDetectionInactive) {\n this.#tokensChainsCache = this.#getConvertedStaticMainnetTokenList();\n } else {\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n }\n\n return true;\n }\n\n async #detectTokensUsingRpc(\n chainsToDetectUsingRpc: NetworkClient[],\n addressToDetect: string,\n ): Promise<void> {\n for (const { chainId, networkClientId } of chainsToDetectUsingRpc) {\n if (!this.#shouldDetectTokens(chainId)) {\n continue;\n }\n\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId,\n selectedAddress: addressToDetect,\n });\n const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) =>\n this.#addDetectedTokens({\n tokensSlice,\n selectedAddress: addressToDetect,\n networkClientId,\n chainId,\n }),\n );\n\n await Promise.all(tokenDetectionPromises);\n }\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.chainIds - The chain IDs of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n */\n async detectTokens({\n chainIds,\n selectedAddress,\n }: {\n chainIds?: Hex[];\n selectedAddress?: string;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const addressToDetect = selectedAddress ?? this.#getSelectedAddress();\n const clientNetworks = this.#getCorrectNetworkClientIdByChainId(chainIds);\n\n let supportedNetworks;\n if (this.#accountsAPI.isAccountsAPIEnabled) {\n supportedNetworks = await this.#accountsAPI.getSupportedNetworks();\n }\n const { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI } =\n this.#getChainsToDetect(clientNetworks, supportedNetworks);\n\n // Try detecting tokens via Account API first if conditions allow\n if (supportedNetworks && chainsToDetectUsingAccountAPI.length > 0) {\n const apiResult = await this.#attemptAccountAPIDetection(\n chainsToDetectUsingAccountAPI,\n addressToDetect,\n supportedNetworks,\n );\n\n // If the account API call failed, have those chains fall back to RPC detection\n if (apiResult?.result === 'failed') {\n this.#addChainsToRpcDetection(\n chainsToDetectUsingRpc,\n chainsToDetectUsingAccountAPI,\n clientNetworks,\n );\n }\n }\n\n // Proceed with RPC detection if there are chains remaining in chainsToDetectUsingRpc\n if (chainsToDetectUsingRpc.length > 0) {\n await this.#detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect);\n }\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.chainIds - array of chainIds to check tokens for\n * @param options.supportedNetworks - array of chainIds to check tokens for\n * @returns a success or failed object\n */\n async #addDetectedTokensViaAPI({\n selectedAddress,\n chainIds,\n supportedNetworks,\n }: {\n selectedAddress: string;\n chainIds: Hex[];\n supportedNetworks: number[] | null;\n }) {\n return await safelyExecute(async () => {\n // Fetch balances for multiple chain IDs at once\n const tokenBalancesByChain = await this.#accountsAPI\n .getMultiNetworksBalances(selectedAddress, chainIds, supportedNetworks)\n .catch(() => null);\n\n if (tokenBalancesByChain === null) {\n return { result: 'failed' } as const;\n }\n\n // Process each chain ID individually\n for (const chainId of chainIds) {\n const isTokenDetectionInactiveInMainnet =\n !this.#isDetectionEnabledFromPreferences &&\n chainId === ChainId.mainnet;\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = isTokenDetectionInactiveInMainnet\n ? this.#getConvertedStaticMainnetTokenList()\n : tokensChainsCache ?? {};\n\n // Generate token candidates based on chainId and selectedAddress\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId,\n selectedAddress,\n });\n\n // Filter balances for the current chainId\n const tokenBalances = tokenBalancesByChain.filter(\n (balance) => balance.chainId === hexToNumber(chainId),\n );\n\n if (!tokenBalances || tokenBalances.length === 0) {\n continue;\n }\n\n // Use helper function to filter tokens with balance for this chainId\n const { tokensWithBalance, eventTokensDetails } =\n this.#filterAndBuildTokensWithBalance(\n tokenCandidateSlices,\n tokenBalances,\n chainId,\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 return { result: 'success' } as const;\n });\n }\n\n /**\n * Helper function to filter and build token data for detected tokens\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 * @param tokenBalances - Tokens balances fetched from API\n * @param chainId - The chain ID being processed\n * @returns an object containing tokensWithBalance and eventTokensDetails arrays\n */\n\n #filterAndBuildTokensWithBalance(\n tokenCandidateSlices: string[][],\n tokenBalances:\n | {\n object: string;\n type?: string;\n timestamp?: string;\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n chainId: number;\n balance: string;\n }[]\n | null,\n chainId: Hex,\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 the token to add is in our candidate list\n if (!tokenCandidateSet.has(tokenAddress)) {\n return;\n }\n\n // Retrieve token data from cache to safely add it\n const tokenData = this.#tokensChainsCache[chainId]?.data[tokenAddress];\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 (!tokenData) {\n return;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name } = tokenData;\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 return { tokensWithBalance, eventTokensDetails };\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
+ {"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 RestrictedMessenger,\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\ntype NetworkClient = {\n chainId: Hex;\n networkClientId: string;\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 */\nexport function mapChainIdWithTokenListMap(\n tokensChainsCache: TokensChainsCache,\n) {\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 = RestrictedMessenger<\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 chainIds: Hex[];\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 getMultiNetworksBalances(\n address: string,\n chainIds: Hex[],\n supportedNetworks: number[] | null,\n ) {\n const chainIdNumbers = chainIds.map((chainId) => hexToNumber(chainId));\n\n if (\n !supportedNetworks ||\n !chainIdNumbers.every((id) => supportedNetworks.includes(id))\n ) {\n const supportedNetworksErrStr = (supportedNetworks ?? []).toString();\n throw new Error(\n `Unsupported Network: supported networks ${supportedNetworksErrStr}, requested networks: ${chainIdNumbers.toString()}`,\n );\n }\n\n const result = await fetchMultiChainBalances(\n address,\n {\n networks: chainIdNumbers,\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\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 { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n const chainIds = Object.keys(networkConfigurationsByChainId) as Hex[];\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 chainIds,\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 #getCorrectNetworkClientIdByChainId(\n chainIds: Hex[] | undefined,\n ): { chainId: Hex; networkClientId: NetworkClientId }[] {\n const { networkConfigurationsByChainId, selectedNetworkClientId } =\n this.messagingSystem.call('NetworkController:getState');\n\n if (!chainIds) {\n const networkConfiguration = this.messagingSystem.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n selectedNetworkClientId,\n );\n\n return [\n {\n chainId: networkConfiguration?.chainId ?? ChainId.mainnet,\n networkClientId: selectedNetworkClientId,\n },\n ];\n }\n\n return chainIds.map((chainId) => {\n const configuration = networkConfigurationsByChainId[chainId];\n return {\n chainId,\n networkClientId:\n configuration.rpcEndpoints[configuration.defaultRpcEndpointIndex]\n .networkClientId,\n };\n });\n }\n\n #getCorrectChainIdAndNetworkClientId() {\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 chainIds,\n address,\n }: TokenDetectionPollingInput): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n chainIds,\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.chainIds - The chain IDs of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n chainIds,\n }: {\n selectedAddress?: string;\n chainIds?: Hex[];\n } = {}): Promise<void> {\n await this.detectTokens({\n chainIds,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n #getChainsToDetect(\n clientNetworks: NetworkClient[],\n supportedNetworks: number[] | null | undefined,\n ) {\n const chainsToDetectUsingAccountAPI: Hex[] = [];\n const chainsToDetectUsingRpc: NetworkClient[] = [];\n\n clientNetworks.forEach(({ chainId, networkClientId }) => {\n if (supportedNetworks?.includes(hexToNumber(chainId))) {\n chainsToDetectUsingAccountAPI.push(chainId);\n } else {\n chainsToDetectUsingRpc.push({ chainId, networkClientId });\n }\n });\n\n return { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI };\n }\n\n async #attemptAccountAPIDetection(\n chainsToDetectUsingAccountAPI: Hex[],\n addressToDetect: string,\n supportedNetworks: number[] | null,\n ) {\n return await this.#addDetectedTokensViaAPI({\n chainIds: chainsToDetectUsingAccountAPI,\n selectedAddress: addressToDetect,\n supportedNetworks,\n });\n }\n\n #addChainsToRpcDetection(\n chainsToDetectUsingRpc: NetworkClient[],\n chainsToDetectUsingAccountAPI: Hex[],\n clientNetworks: NetworkClient[],\n ): void {\n chainsToDetectUsingAccountAPI.forEach((chainId) => {\n const networkEntry = clientNetworks.find(\n (network) => network.chainId === chainId,\n );\n if (networkEntry) {\n chainsToDetectUsingRpc.push({\n chainId: networkEntry.chainId,\n networkClientId: networkEntry.networkClientId,\n });\n }\n });\n }\n\n #shouldDetectTokens(chainId: Hex): boolean {\n if (!isTokenDetectionSupportedForNetwork(chainId)) {\n return false;\n }\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainId !== ChainId.mainnet\n ) {\n return false;\n }\n\n const isMainnetDetectionInactive =\n !this.#isDetectionEnabledFromPreferences && chainId === ChainId.mainnet;\n if (isMainnetDetectionInactive) {\n this.#tokensChainsCache = this.#getConvertedStaticMainnetTokenList();\n } else {\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n }\n\n return true;\n }\n\n async #detectTokensUsingRpc(\n chainsToDetectUsingRpc: NetworkClient[],\n addressToDetect: string,\n ): Promise<void> {\n for (const { chainId, networkClientId } of chainsToDetectUsingRpc) {\n if (!this.#shouldDetectTokens(chainId)) {\n continue;\n }\n\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId,\n selectedAddress: addressToDetect,\n });\n const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) =>\n this.#addDetectedTokens({\n tokensSlice,\n selectedAddress: addressToDetect,\n networkClientId,\n chainId,\n }),\n );\n\n await Promise.all(tokenDetectionPromises);\n }\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.chainIds - The chain IDs of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n */\n async detectTokens({\n chainIds,\n selectedAddress,\n }: {\n chainIds?: Hex[];\n selectedAddress?: string;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const addressToDetect = selectedAddress ?? this.#getSelectedAddress();\n const clientNetworks = this.#getCorrectNetworkClientIdByChainId(chainIds);\n\n let supportedNetworks;\n if (this.#accountsAPI.isAccountsAPIEnabled) {\n supportedNetworks = await this.#accountsAPI.getSupportedNetworks();\n }\n const { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI } =\n this.#getChainsToDetect(clientNetworks, supportedNetworks);\n\n // Try detecting tokens via Account API first if conditions allow\n if (supportedNetworks && chainsToDetectUsingAccountAPI.length > 0) {\n const apiResult = await this.#attemptAccountAPIDetection(\n chainsToDetectUsingAccountAPI,\n addressToDetect,\n supportedNetworks,\n );\n\n // If the account API call failed, have those chains fall back to RPC detection\n if (apiResult?.result === 'failed') {\n this.#addChainsToRpcDetection(\n chainsToDetectUsingRpc,\n chainsToDetectUsingAccountAPI,\n clientNetworks,\n );\n }\n }\n\n // Proceed with RPC detection if there are chains remaining in chainsToDetectUsingRpc\n if (chainsToDetectUsingRpc.length > 0) {\n await this.#detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect);\n }\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.chainIds - array of chainIds to check tokens for\n * @param options.supportedNetworks - array of chainIds to check tokens for\n * @returns a success or failed object\n */\n async #addDetectedTokensViaAPI({\n selectedAddress,\n chainIds,\n supportedNetworks,\n }: {\n selectedAddress: string;\n chainIds: Hex[];\n supportedNetworks: number[] | null;\n }) {\n return await safelyExecute(async () => {\n // Fetch balances for multiple chain IDs at once\n const tokenBalancesByChain = await this.#accountsAPI\n .getMultiNetworksBalances(selectedAddress, chainIds, supportedNetworks)\n .catch(() => null);\n\n if (tokenBalancesByChain === null) {\n return { result: 'failed' } as const;\n }\n\n // Process each chain ID individually\n for (const chainId of chainIds) {\n const isTokenDetectionInactiveInMainnet =\n !this.#isDetectionEnabledFromPreferences &&\n chainId === ChainId.mainnet;\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = isTokenDetectionInactiveInMainnet\n ? this.#getConvertedStaticMainnetTokenList()\n : (tokensChainsCache ?? {});\n\n // Generate token candidates based on chainId and selectedAddress\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId,\n selectedAddress,\n });\n\n // Filter balances for the current chainId\n const tokenBalances = tokenBalancesByChain.filter(\n (balance) => balance.chainId === hexToNumber(chainId),\n );\n\n if (!tokenBalances || tokenBalances.length === 0) {\n continue;\n }\n\n // Use helper function to filter tokens with balance for this chainId\n const { tokensWithBalance, eventTokensDetails } =\n this.#filterAndBuildTokensWithBalance(\n tokenCandidateSlices,\n tokenBalances,\n chainId,\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 return { result: 'success' } as const;\n });\n }\n\n /**\n * Helper function to filter and build token data for detected tokens\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 * @param tokenBalances - Tokens balances fetched from API\n * @param chainId - The chain ID being processed\n * @returns an object containing tokensWithBalance and eventTokensDetails arrays\n */\n\n #filterAndBuildTokensWithBalance(\n tokenCandidateSlices: string[][],\n tokenBalances:\n | {\n object: string;\n type?: string;\n timestamp?: string;\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n chainId: number;\n balance: string;\n }[]\n | null,\n chainId: Hex,\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 the token to add is in our candidate list\n if (!tokenCandidateSet.has(tokenAddress)) {\n return;\n }\n\n // Retrieve token data from cache to safely add it\n const tokenData = this.#tokensChainsCache[chainId]?.data[tokenAddress];\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 (!tokenData) {\n return;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name } = tokenData;\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 return { tokensWithBalance, eventTokensDetails };\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"]}
@@ -40,7 +40,7 @@ class TokenListController extends (0, polling_controller_1.StaticIntervalPolling
40
40
  * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.
41
41
  * @param options.interval - The polling interval, in milliseconds.
42
42
  * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.
43
- * @param options.messenger - A restricted controller messenger.
43
+ * @param options.messenger - A restricted messenger.
44
44
  * @param options.state - Initial state to set on this controller.
45
45
  * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.
46
46
  */
@@ -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 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 chainId: Hex;\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.setIntervalLength(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 }\n }\n }\n\n // Eventually we want to remove start/restart/stop controls in favor of new _executePoll API\n // Maintaining these functions for now until we can safely deprecate them for backwards compatibility\n /**\n * Start polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Restart polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async restart() {\n this.stopPolling();\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Stop polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * This stops any active polling.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n /**\n * This stops any active polling intervals.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval for a given chainId (this should be deprecated in favor of _executePoll)\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async #startDeprecatedPolling(): Promise<void> {\n // renaming this to avoid collision with base class\n await safelyExecute(() => this.fetchTokenList(this.chainId));\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(this.chainId));\n }, this.intervalDelay);\n }\n\n /**\n * This starts a new polling loop for any given chain. Under the hood it is deduping polls\n *\n * @private\n * @param input - The input for the poll.\n * @param input.chainId - The chainId of the chain to trigger the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({ chainId }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(chainId);\n }\n\n /**\n * Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)\n *\n * @param chainId - The chainId of the current chain triggering the fetch.\n */\n async fetchTokenList(chainId: Hex): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n // Attempt to fetch cached tokens\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 from the API\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (tokensFromAPI) {\n // Format tokens from API (HTTP) and update tokenList\n tokenList = {};\n for (const token of tokensFromAPI) {\n tokenList[token.address] = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n }\n } else {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n }\n }\n\n // Update the state with a single update for both tokenList and tokenChainsCache\n this.update(() => {\n return {\n ...this.state,\n tokenList:\n this.chainId === chainId ? tokenList : this.state.tokenList,\n tokensChainsCache: {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n },\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 RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\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 = RestrictedMessenger<\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 chainId: Hex;\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 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.setIntervalLength(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 }\n }\n }\n\n // Eventually we want to remove start/restart/stop controls in favor of new _executePoll API\n // Maintaining these functions for now until we can safely deprecate them for backwards compatibility\n /**\n * Start polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Restart polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async restart() {\n this.stopPolling();\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Stop polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * This stops any active polling.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n /**\n * This stops any active polling intervals.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval for a given chainId (this should be deprecated in favor of _executePoll)\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async #startDeprecatedPolling(): Promise<void> {\n // renaming this to avoid collision with base class\n await safelyExecute(() => this.fetchTokenList(this.chainId));\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(this.chainId));\n }, this.intervalDelay);\n }\n\n /**\n * This starts a new polling loop for any given chain. Under the hood it is deduping polls\n *\n * @private\n * @param input - The input for the poll.\n * @param input.chainId - The chainId of the chain to trigger the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({ chainId }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(chainId);\n }\n\n /**\n * Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)\n *\n * @param chainId - The chainId of the current chain triggering the fetch.\n */\n async fetchTokenList(chainId: Hex): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n // Attempt to fetch cached tokens\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 from the API\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (tokensFromAPI) {\n // Format tokens from API (HTTP) and update tokenList\n tokenList = {};\n for (const token of tokensFromAPI) {\n tokenList[token.address] = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n }\n } else {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n }\n }\n\n // Update the state with a single update for both tokenList and tokenChainsCache\n this.update(() => {\n return {\n ...this.state,\n tokenList:\n this.chainId === chainId ? tokenList : this.state.tokenList,\n tokensChainsCache: {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n },\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,4 +1,4 @@
1
- import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedControllerMessenger } from "@metamask/base-controller";
1
+ import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
2
2
  import type { NetworkControllerStateChangeEvent, NetworkState, NetworkControllerGetNetworkClientByIdAction } from "@metamask/network-controller";
3
3
  import type { Hex } from "@metamask/utils";
4
4
  declare const name = "TokenListController";
@@ -30,7 +30,7 @@ export type GetTokenListState = ControllerGetStateAction<typeof name, TokenListS
30
30
  export type TokenListControllerActions = GetTokenListState;
31
31
  type AllowedActions = NetworkControllerGetNetworkClientByIdAction;
32
32
  type AllowedEvents = NetworkControllerStateChangeEvent;
33
- export type TokenListControllerMessenger = RestrictedControllerMessenger<typeof name, TokenListControllerActions | AllowedActions, TokenListControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
33
+ export type TokenListControllerMessenger = RestrictedMessenger<typeof name, TokenListControllerActions | AllowedActions, TokenListControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
34
34
  export declare const getDefaultTokenListState: () => TokenListState;
35
35
  /** The input to start polling for the {@link TokenListController} */
36
36
  type TokenListPollingInput = {
@@ -70,7 +70,7 @@ export declare class TokenListController extends TokenListController_base<typeof
70
70
  * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.
71
71
  * @param options.interval - The polling interval, in milliseconds.
72
72
  * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.
73
- * @param options.messenger - A restricted controller messenger.
73
+ * @param options.messenger - A restricted messenger.
74
74
  * @param options.state - Initial state to set on this controller.
75
75
  * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.
76
76
  */
@@ -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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"}
@@ -1,4 +1,4 @@
1
- import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedControllerMessenger } from "@metamask/base-controller";
1
+ import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
2
2
  import type { NetworkControllerStateChangeEvent, NetworkState, NetworkControllerGetNetworkClientByIdAction } from "@metamask/network-controller";
3
3
  import type { Hex } from "@metamask/utils";
4
4
  declare const name = "TokenListController";
@@ -30,7 +30,7 @@ export type GetTokenListState = ControllerGetStateAction<typeof name, TokenListS
30
30
  export type TokenListControllerActions = GetTokenListState;
31
31
  type AllowedActions = NetworkControllerGetNetworkClientByIdAction;
32
32
  type AllowedEvents = NetworkControllerStateChangeEvent;
33
- export type TokenListControllerMessenger = RestrictedControllerMessenger<typeof name, TokenListControllerActions | AllowedActions, TokenListControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
33
+ export type TokenListControllerMessenger = RestrictedMessenger<typeof name, TokenListControllerActions | AllowedActions, TokenListControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
34
34
  export declare const getDefaultTokenListState: () => TokenListState;
35
35
  /** The input to start polling for the {@link TokenListController} */
36
36
  type TokenListPollingInput = {
@@ -70,7 +70,7 @@ export declare class TokenListController extends TokenListController_base<typeof
70
70
  * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.
71
71
  * @param options.interval - The polling interval, in milliseconds.
72
72
  * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.
73
- * @param options.messenger - A restricted controller messenger.
73
+ * @param options.messenger - A restricted messenger.
74
74
  * @param options.state - Initial state to set on this controller.
75
75
  * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.
76
76
  */
@@ -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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"}
@@ -36,7 +36,7 @@ export class TokenListController extends StaticIntervalPollingController() {
36
36
  * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.
37
37
  * @param options.interval - The polling interval, in milliseconds.
38
38
  * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.
39
- * @param options.messenger - A restricted controller messenger.
39
+ * @param options.messenger - A restricted messenger.
40
40
  * @param options.state - Initial state to set on this controller.
41
41
  * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.
42
42
  */
@@ -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 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 chainId: Hex;\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.setIntervalLength(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 }\n }\n }\n\n // Eventually we want to remove start/restart/stop controls in favor of new _executePoll API\n // Maintaining these functions for now until we can safely deprecate them for backwards compatibility\n /**\n * Start polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Restart polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async restart() {\n this.stopPolling();\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Stop polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * This stops any active polling.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n /**\n * This stops any active polling intervals.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval for a given chainId (this should be deprecated in favor of _executePoll)\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async #startDeprecatedPolling(): Promise<void> {\n // renaming this to avoid collision with base class\n await safelyExecute(() => this.fetchTokenList(this.chainId));\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(this.chainId));\n }, this.intervalDelay);\n }\n\n /**\n * This starts a new polling loop for any given chain. Under the hood it is deduping polls\n *\n * @private\n * @param input - The input for the poll.\n * @param input.chainId - The chainId of the chain to trigger the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({ chainId }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(chainId);\n }\n\n /**\n * Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)\n *\n * @param chainId - The chainId of the current chain triggering the fetch.\n */\n async fetchTokenList(chainId: Hex): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n // Attempt to fetch cached tokens\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 from the API\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (tokensFromAPI) {\n // Format tokens from API (HTTP) and update tokenList\n tokenList = {};\n for (const token of tokensFromAPI) {\n tokenList[token.address] = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n }\n } else {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n }\n }\n\n // Update the state with a single update for both tokenList and tokenChainsCache\n this.update(() => {\n return {\n ...this.state,\n tokenList:\n this.chainId === chainId ? tokenList : this.state.tokenList,\n tokensChainsCache: {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n },\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 RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\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 = RestrictedMessenger<\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 chainId: Hex;\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 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.setIntervalLength(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 }\n }\n }\n\n // Eventually we want to remove start/restart/stop controls in favor of new _executePoll API\n // Maintaining these functions for now until we can safely deprecate them for backwards compatibility\n /**\n * Start polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Restart polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async restart() {\n this.stopPolling();\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Stop polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * This stops any active polling.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n /**\n * This stops any active polling intervals.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval for a given chainId (this should be deprecated in favor of _executePoll)\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async #startDeprecatedPolling(): Promise<void> {\n // renaming this to avoid collision with base class\n await safelyExecute(() => this.fetchTokenList(this.chainId));\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(this.chainId));\n }, this.intervalDelay);\n }\n\n /**\n * This starts a new polling loop for any given chain. Under the hood it is deduping polls\n *\n * @private\n * @param input - The input for the poll.\n * @param input.chainId - The chainId of the chain to trigger the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({ chainId }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(chainId);\n }\n\n /**\n * Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)\n *\n * @param chainId - The chainId of the current chain triggering the fetch.\n */\n async fetchTokenList(chainId: Hex): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n // Attempt to fetch cached tokens\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 from the API\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (tokensFromAPI) {\n // Format tokens from API (HTTP) and update tokenList\n tokenList = {};\n for (const token of tokensFromAPI) {\n tokenList[token.address] = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n }\n } else {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n }\n }\n\n // Update the state with a single update for both tokenList and tokenChainsCache\n this.update(() => {\n return {\n ...this.state,\n tokenList:\n this.chainId === chainId ? tokenList : this.state.tokenList,\n tokensChainsCache: {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n },\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"]}
@@ -81,7 +81,7 @@ class TokenRatesController extends (0, polling_controller_1.StaticIntervalPollin
81
81
  * @param options.interval - The polling interval in ms
82
82
  * @param options.disabled - Boolean to track if network requests are blocked
83
83
  * @param options.tokenPricesService - An object in charge of retrieving token price
84
- * @param options.messenger - The controller messenger instance for communication
84
+ * @param options.messenger - The messenger instance for communication
85
85
  * @param options.state - Initial state to set on this controller
86
86
  */
87
87
  constructor({ interval = DEFAULT_INTERVAL, disabled = false, tokenPricesService, messenger, state, }) {