@metamask-previews/assets-controllers 70.0.0-preview-d9822daf → 70.0.1-preview-988fbb56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,14 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
11
-
12
- - **BREAKING:** Add peer dependency `@metamask/profile-sync-controller`
13
- - **BREAKING:** Add `profileId`-based rate limiting support for Accounts API calls
14
- - Use `AuthenticationController:getBearerToken` in order to get a bearer token that gets attached to every request to the Accounts API
10
+ ## [70.0.1]
15
11
 
16
12
  ### Changed
17
13
 
14
+ - Bump `@metamask/controller-utils` from `^11.10.0` to `^11.11.0` ([#6069](https://github.com/MetaMask/core/pull/6069))
15
+ - This upgrade includes performance improvements to checksum hex address normalization
18
16
  - Bump `@metamask/utils` from `^11.2.0` to `^11.4.2` ([#6054](https://github.com/MetaMask/core/pull/6054))
19
17
 
20
18
  ## [70.0.0]
@@ -1755,7 +1753,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1755
1753
 
1756
1754
  - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
1757
1755
 
1758
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@70.0.0...HEAD
1756
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@70.0.1...HEAD
1757
+ [70.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@70.0.0...@metamask/assets-controllers@70.0.1
1759
1758
  [70.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@69.0.0...@metamask/assets-controllers@70.0.0
1760
1759
  [69.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@68.2.0...@metamask/assets-controllers@69.0.0
1761
1760
  [68.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@68.1.0...@metamask/assets-controllers@68.2.0
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAccountId, _TokenDetectionController_networkClientId, _TokenDetectionController_tokensChainsCache, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_accountsAPI, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_compareTokensChainsCache, _TokenDetectionController_getCorrectNetworkClientIdByChainId, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getChainsToDetect, _TokenDetectionController_attemptAccountAPIDetection, _TokenDetectionController_addChainsToRpcDetection, _TokenDetectionController_shouldDetectTokens, _TokenDetectionController_detectTokensUsingRpc, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_getConvertedStaticMainnetTokenList, _TokenDetectionController_addDetectedTokensViaAPI, _TokenDetectionController_filterAndBuildTokensWithBalance, _TokenDetectionController_addDetectedTokens, _TokenDetectionController_getSelectedAccount, _TokenDetectionController_getSelectedAddress, _TokenDetectionController_getAuthenticationControllerBearerToken;
16
+ var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAccountId, _TokenDetectionController_networkClientId, _TokenDetectionController_tokensChainsCache, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_accountsAPI, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_compareTokensChainsCache, _TokenDetectionController_getCorrectNetworkClientIdByChainId, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getChainsToDetect, _TokenDetectionController_attemptAccountAPIDetection, _TokenDetectionController_addChainsToRpcDetection, _TokenDetectionController_shouldDetectTokens, _TokenDetectionController_detectTokensUsingRpc, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_getConvertedStaticMainnetTokenList, _TokenDetectionController_addDetectedTokensViaAPI, _TokenDetectionController_filterAndBuildTokensWithBalance, _TokenDetectionController_addDetectedTokens, _TokenDetectionController_getSelectedAccount, _TokenDetectionController_getSelectedAddress;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.TokenDetectionController = exports.controllerName = exports.mapChainIdWithTokenListMap = exports.STATIC_MAINNET_TOKEN_LIST = void 0;
19
19
  const contract_metadata_1 = __importDefault(require("@metamask/contract-metadata"));
@@ -38,7 +38,6 @@ exports.STATIC_MAINNET_TOKEN_LIST = Object.entries(contract_metadata_1.default).
38
38
  }, {});
39
39
  /**
40
40
  * Function that takes a TokensChainsCache object and maps chainId with TokenListMap.
41
- *
42
41
  * @param tokensChainsCache - TokensChainsCache input object
43
42
  * @returns returns the map of chainId with TokenListMap
44
43
  */
@@ -54,20 +53,13 @@ exports.mapChainIdWithTokenListMap = mapChainIdWithTokenListMap;
54
53
  exports.controllerName = 'TokenDetectionController';
55
54
  /**
56
55
  * Controller that passively polls on a set interval for Tokens auto detection
57
- *
58
- * intervalId - Polling interval used to fetch new token rates
59
- *
60
- * selectedAddress - Vault selected address
61
- *
62
- * networkClientId - The network client ID of the current selected network
63
- *
64
- * disabled - Boolean to track if network requests are blocked
65
- *
66
- * isUnlocked - Boolean to track if the keyring state is unlocked
67
- *
68
- * isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController
69
- *
70
- * isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network
56
+ * @property intervalId - Polling interval used to fetch new token rates
57
+ * @property selectedAddress - Vault selected address
58
+ * @property networkClientId - The network client ID of the current selected network
59
+ * @property disabled - Boolean to track if network requests are blocked
60
+ * @property isUnlocked - Boolean to track if the keyring state is unlocked
61
+ * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController
62
+ * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network
71
63
  */
72
64
  class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPollingController)() {
73
65
  /**
@@ -104,7 +96,7 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
104
96
  isAccountsAPIEnabled: true,
105
97
  supportedNetworksCache: null,
106
98
  platform: '',
107
- async getSupportedNetworks(options) {
99
+ async getSupportedNetworks() {
108
100
  /* istanbul ignore next */
109
101
  if (!this.isAccountsAPIEnabled) {
110
102
  throw new Error('Accounts API Feature Switch is disabled');
@@ -113,15 +105,11 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
113
105
  if (this.supportedNetworksCache) {
114
106
  return this.supportedNetworksCache;
115
107
  }
116
- const { getAuthenticationControllerBearerToken } = options;
117
- const result = await (0, multi_chain_accounts_service_1.fetchSupportedNetworks)({
118
- getAuthenticationControllerBearerToken,
119
- }).catch(() => null);
108
+ const result = await (0, multi_chain_accounts_service_1.fetchSupportedNetworks)().catch(() => null);
120
109
  this.supportedNetworksCache = result;
121
110
  return result;
122
111
  },
123
- async getMultiNetworksBalances(address, chainIds, supportedNetworks, options) {
124
- const { getAuthenticationControllerBearerToken } = options;
112
+ async getMultiNetworksBalances(address, chainIds, supportedNetworks) {
125
113
  const chainIdNumbers = chainIds.map((chainId) => (0, utils_1.hexToNumber)(chainId));
126
114
  if (!supportedNetworks ||
127
115
  !chainIdNumbers.every((id) => supportedNetworks.includes(id))) {
@@ -130,7 +118,6 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
130
118
  }
131
119
  const result = await (0, multi_chain_accounts_service_1.fetchMultiChainBalances)(address, {
132
120
  networks: chainIdNumbers,
133
- getAuthenticationControllerBearerToken,
134
121
  }, this.platform);
135
122
  return result.balances;
136
123
  },
@@ -167,8 +154,7 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
167
154
  }
168
155
  /**
169
156
  * Internal isActive state
170
- *
171
- * @returns boolean indicating if the controller is active
157
+ * @type {boolean}
172
158
  */
173
159
  get isActive() {
174
160
  return !__classPrivateFieldGet(this, _TokenDetectionController_disabled, "f") && __classPrivateFieldGet(this, _TokenDetectionController_isUnlocked, "f");
@@ -212,9 +198,7 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
212
198
  const clientNetworks = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectNetworkClientIdByChainId).call(this, chainIds);
213
199
  let supportedNetworks;
214
200
  if (__classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f").isAccountsAPIEnabled) {
215
- supportedNetworks = await __classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f").getSupportedNetworks({
216
- getAuthenticationControllerBearerToken: __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getAuthenticationControllerBearerToken).bind(this),
217
- });
201
+ supportedNetworks = await __classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f").getSupportedNetworks();
218
202
  }
219
203
  const { chainsToDetectUsingRpc, chainsToDetectUsingAccountAPI } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getChainsToDetect).call(this, clientNetworks, supportedNetworks);
220
204
  // Try detecting tokens via Account API first if conditions allow
@@ -455,7 +439,6 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
455
439
  }, _TokenDetectionController_addDetectedTokensViaAPI =
456
440
  /**
457
441
  * This adds detected tokens from the Accounts API, avoiding the multi-call RPC calls for balances
458
- *
459
442
  * @param options - method arguments
460
443
  * @param options.selectedAddress - address to check against
461
444
  * @param options.chainIds - array of chainIds to check tokens for
@@ -466,9 +449,7 @@ async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddre
466
449
  return await (0, controller_utils_1.safelyExecute)(async () => {
467
450
  // Fetch balances for multiple chain IDs at once
468
451
  const tokenBalancesByChain = await __classPrivateFieldGet(this, _TokenDetectionController_accountsAPI, "f")
469
- .getMultiNetworksBalances(selectedAddress, chainIds, supportedNetworks, {
470
- getAuthenticationControllerBearerToken: __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getAuthenticationControllerBearerToken).bind(this),
471
- })
452
+ .getMultiNetworksBalances(selectedAddress, chainIds, supportedNetworks)
472
453
  .catch(() => null);
473
454
  if (tokenBalancesByChain === null) {
474
455
  return { result: 'failed' };
@@ -500,8 +481,10 @@ async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddre
500
481
  properties: {
501
482
  tokens: eventTokensDetails,
502
483
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
484
+ // eslint-disable-next-line @typescript-eslint/naming-convention
503
485
  token_standard: controller_utils_1.ERC20,
504
486
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
487
+ // eslint-disable-next-line @typescript-eslint/naming-convention
505
488
  asset_type: controller_utils_1.ASSET_TYPES.TOKEN,
506
489
  },
507
490
  });
@@ -568,8 +551,10 @@ async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddre
568
551
  properties: {
569
552
  tokens: eventTokensDetails,
570
553
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
554
+ // eslint-disable-next-line @typescript-eslint/naming-convention
571
555
  token_standard: controller_utils_1.ERC20,
572
556
  // TODO: Either fix this lint violation or explain why it's necessary to ignore.
557
+ // eslint-disable-next-line @typescript-eslint/naming-convention
573
558
  asset_type: controller_utils_1.ASSET_TYPES.TOKEN,
574
559
  },
575
560
  });
@@ -585,8 +570,6 @@ async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddre
585
570
  // If the address is not defined (or empty), we fallback to the currently selected account's address
586
571
  const account = this.messagingSystem.call('AccountsController:getAccount', __classPrivateFieldGet(this, _TokenDetectionController_selectedAccountId, "f"));
587
572
  return account?.address || '';
588
- }, _TokenDetectionController_getAuthenticationControllerBearerToken = async function _TokenDetectionController_getAuthenticationControllerBearerToken() {
589
- return await this.messagingSystem.call('AuthenticationController:getBearerToken');
590
573
  };
591
574
  exports.default = TokenDetectionController;
592
575
  //# sourceMappingURL=TokenDetectionController.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.cjs","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 { AuthenticationControllerGetBearerToken } from '@metamask/profile-sync-controller/auth';\nimport type { TransactionControllerTransactionConfirmedEvent } from '@metamask/transaction-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 *\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 | AuthenticationControllerGetBearerToken;\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 | TransactionControllerTransactionConfirmedEvent;\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 *\n * intervalId - Polling interval used to fetch new token rates\n *\n * selectedAddress - Vault selected address\n *\n * networkClientId - The network client ID of the current selected network\n *\n * disabled - Boolean to track if network requests are blocked\n *\n * isUnlocked - Boolean to track if the keyring state is unlocked\n *\n * isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n *\n * 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 readonly #networkClientId: NetworkClientId;\n\n #tokensChainsCache: TokensChainsCache = {};\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n readonly #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\n token_standard: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n\n asset_type: string;\n };\n }) => void;\n\n readonly #accountsAPI = {\n isAccountsAPIEnabled: true,\n supportedNetworksCache: null as number[] | null,\n platform: '' as 'extension' | 'mobile',\n\n async getSupportedNetworks(options: {\n getAuthenticationControllerBearerToken: () => ReturnType<\n AuthenticationControllerGetBearerToken['handler']\n >;\n }) {\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 { getAuthenticationControllerBearerToken } = options;\n\n const result = await fetchSupportedNetworks({\n getAuthenticationControllerBearerToken,\n }).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 options: {\n getAuthenticationControllerBearerToken: () => ReturnType<\n AuthenticationControllerGetBearerToken['handler']\n >;\n },\n ) {\n const { getAuthenticationControllerBearerToken } = options;\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 getAuthenticationControllerBearerToken,\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\n token_standard: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n\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 this.messagingSystem.subscribe(\n 'TransactionController:transactionConfirmed',\n async (transactionMeta) => {\n await this.detectTokens({\n chainIds: [transactionMeta.chainId],\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 *\n * @returns boolean indicating if the controller is active\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 *\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 getAuthenticationControllerBearerToken:\n this.#getAuthenticationControllerBearerToken.bind(this),\n });\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 *\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(\n selectedAddress,\n chainIds,\n supportedNetworks,\n {\n getAuthenticationControllerBearerToken:\n this.#getAuthenticationControllerBearerToken.bind(this),\n },\n )\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\n token_standard: ERC20,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n\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 *\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\n token_standard: ERC20,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n\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 async #getAuthenticationControllerBearerToken(): ReturnType<\n AuthenticationControllerGetBearerToken['handler']\n > {\n return await this.messagingSystem.call(\n 'AuthenticationController:getBearerToken',\n );\n }\n}\n\nexport default TokenDetectionController;\n"]}
1
+ {"version":3,"file":"TokenDetectionController.cjs","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 { TransactionControllerTransactionConfirmedEvent } from '@metamask/transaction-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 | TransactionControllerTransactionConfirmedEvent;\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 this.messagingSystem.subscribe(\n 'TransactionController:transactionConfirmed',\n async (transactionMeta) => {\n await this.detectTokens({\n chainIds: [transactionMeta.chainId],\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"]}
@@ -3,7 +3,6 @@ import type { RestrictedMessenger, ControllerGetStateAction, ControllerStateChan
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";
6
- import type { AuthenticationControllerGetBearerToken } from "@metamask/profile-sync-controller/auth";
7
6
  import type { TransactionControllerTransactionConfirmedEvent } from "@metamask/transaction-controller";
8
7
  import type { Hex } from "@metamask/utils";
9
8
  import type { AssetsContractController } from "./AssetsContractController.cjs";
@@ -15,7 +14,6 @@ type TokenDetectionMap = {
15
14
  export declare const STATIC_MAINNET_TOKEN_LIST: TokenDetectionMap;
16
15
  /**
17
16
  * Function that takes a TokensChainsCache object and maps chainId with TokenListMap.
18
- *
19
17
  * @param tokensChainsCache - TokensChainsCache input object
20
18
  * @returns returns the map of chainId with TokenListMap
21
19
  */
@@ -26,7 +24,7 @@ export declare const controllerName = "TokenDetectionController";
26
24
  export type TokenDetectionState = Record<never, never>;
27
25
  export type TokenDetectionControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenDetectionState>;
28
26
  export type TokenDetectionControllerActions = TokenDetectionControllerGetStateAction;
29
- export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction | GetTokenListState | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction | AuthenticationControllerGetBearerToken;
27
+ export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction | GetTokenListState | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction;
30
28
  export type TokenDetectionControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;
31
29
  export type TokenDetectionControllerEvents = TokenDetectionControllerStateChangeEvent;
32
30
  export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent | TokenListStateChange | KeyringControllerLockEvent | KeyringControllerUnlockEvent | PreferencesControllerStateChangeEvent | TransactionControllerTransactionConfirmedEvent;
@@ -53,20 +51,13 @@ declare const TokenDetectionController_base: (abstract new (...args: any[]) => {
53
51
  }) & typeof import("@metamask/base-controller").BaseController;
54
52
  /**
55
53
  * Controller that passively polls on a set interval for Tokens auto detection
56
- *
57
- * intervalId - Polling interval used to fetch new token rates
58
- *
59
- * selectedAddress - Vault selected address
60
- *
61
- * networkClientId - The network client ID of the current selected network
62
- *
63
- * disabled - Boolean to track if network requests are blocked
64
- *
65
- * isUnlocked - Boolean to track if the keyring state is unlocked
66
- *
67
- * isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController
68
- *
69
- * isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network
54
+ * @property intervalId - Polling interval used to fetch new token rates
55
+ * @property selectedAddress - Vault selected address
56
+ * @property networkClientId - The network client ID of the current selected network
57
+ * @property disabled - Boolean to track if network requests are blocked
58
+ * @property isUnlocked - Boolean to track if the keyring state is unlocked
59
+ * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController
60
+ * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network
70
61
  */
71
62
  export declare class TokenDetectionController extends TokenDetectionController_base<typeof controllerName, TokenDetectionState, TokenDetectionControllerMessenger> {
72
63
  #private;
@@ -109,8 +100,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
109
100
  disable(): void;
110
101
  /**
111
102
  * Internal isActive state
112
- *
113
- * @returns boolean indicating if the controller is active
103
+ * @type {boolean}
114
104
  */
115
105
  get isActive(): boolean;
116
106
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.d.cts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenDetectionController.d.cts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,6 @@ import type { RestrictedMessenger, ControllerGetStateAction, ControllerStateChan
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";
6
- import type { AuthenticationControllerGetBearerToken } from "@metamask/profile-sync-controller/auth";
7
6
  import type { TransactionControllerTransactionConfirmedEvent } from "@metamask/transaction-controller";
8
7
  import type { Hex } from "@metamask/utils";
9
8
  import type { AssetsContractController } from "./AssetsContractController.mjs";
@@ -15,7 +14,6 @@ type TokenDetectionMap = {
15
14
  export declare const STATIC_MAINNET_TOKEN_LIST: TokenDetectionMap;
16
15
  /**
17
16
  * Function that takes a TokensChainsCache object and maps chainId with TokenListMap.
18
- *
19
17
  * @param tokensChainsCache - TokensChainsCache input object
20
18
  * @returns returns the map of chainId with TokenListMap
21
19
  */
@@ -26,7 +24,7 @@ export declare const controllerName = "TokenDetectionController";
26
24
  export type TokenDetectionState = Record<never, never>;
27
25
  export type TokenDetectionControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenDetectionState>;
28
26
  export type TokenDetectionControllerActions = TokenDetectionControllerGetStateAction;
29
- export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction | GetTokenListState | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction | AuthenticationControllerGetBearerToken;
27
+ export type AllowedActions = AccountsControllerGetSelectedAccountAction | AccountsControllerGetAccountAction | NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetStateAction | GetTokenListState | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction;
30
28
  export type TokenDetectionControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;
31
29
  export type TokenDetectionControllerEvents = TokenDetectionControllerStateChangeEvent;
32
30
  export type AllowedEvents = AccountsControllerSelectedEvmAccountChangeEvent | NetworkControllerNetworkDidChangeEvent | TokenListStateChange | KeyringControllerLockEvent | KeyringControllerUnlockEvent | PreferencesControllerStateChangeEvent | TransactionControllerTransactionConfirmedEvent;
@@ -53,20 +51,13 @@ declare const TokenDetectionController_base: (abstract new (...args: any[]) => {
53
51
  }) & typeof import("@metamask/base-controller").BaseController;
54
52
  /**
55
53
  * Controller that passively polls on a set interval for Tokens auto detection
56
- *
57
- * intervalId - Polling interval used to fetch new token rates
58
- *
59
- * selectedAddress - Vault selected address
60
- *
61
- * networkClientId - The network client ID of the current selected network
62
- *
63
- * disabled - Boolean to track if network requests are blocked
64
- *
65
- * isUnlocked - Boolean to track if the keyring state is unlocked
66
- *
67
- * isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController
68
- *
69
- * isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network
54
+ * @property intervalId - Polling interval used to fetch new token rates
55
+ * @property selectedAddress - Vault selected address
56
+ * @property networkClientId - The network client ID of the current selected network
57
+ * @property disabled - Boolean to track if network requests are blocked
58
+ * @property isUnlocked - Boolean to track if the keyring state is unlocked
59
+ * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController
60
+ * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network
70
61
  */
71
62
  export declare class TokenDetectionController extends TokenDetectionController_base<typeof controllerName, TokenDetectionState, TokenDetectionControllerMessenger> {
72
63
  #private;
@@ -109,8 +100,7 @@ export declare class TokenDetectionController extends TokenDetectionController_b
109
100
  disable(): void;
110
101
  /**
111
102
  * Internal isActive state
112
- *
113
- * @returns boolean indicating if the controller is active
103
+ * @type {boolean}
114
104
  */
115
105
  get isActive(): boolean;
116
106
  /**
@@ -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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"}