@metamask-previews/assets-controllers 94.0.0-preview-102c9cee → 94.0.0-preview-6c59381c
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 +9 -0
- package/dist/TokenBalancesController.cjs +9 -6
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +9 -6
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/TokenDetectionController.cjs +8 -0
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +8 -0
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenBalancesController.mjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport {\n BNToHex,\n isValidHexAddress,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type {\n BalanceUpdate,\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n} from '@metamask/core-backend';\nimport type {\n KeyringControllerAccountRemovedEvent,\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport type {\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerTransactionConfirmedEvent,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport {\n isCaipAssetType,\n isCaipChainId,\n isStrictHexString,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type {\n AccountTrackerControllerGetStateAction,\n AccountTrackerUpdateNativeBalancesAction,\n AccountTrackerUpdateStakedBalancesAction,\n} from './AccountTrackerController';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport { AccountsApiBalanceFetcher } from './multi-chain-accounts-service/api-balance-fetcher';\nimport type {\n BalanceFetcher,\n ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\nimport type {\n TokenDetectionControllerAddDetectedTokensViaPollingAction,\n TokenDetectionControllerAddDetectedTokensViaWsAction,\n TokenDetectionControllerDetectTokensAction,\n} from './TokenDetectionController';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerState,\n TokensControllerStateChangeEvent,\n} from './TokensController';\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nconst CONTROLLER = 'TokenBalancesController' as const;\nconst DEFAULT_INTERVAL_MS = 30_000; // 30 seconds\nconst DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS = 300_000; // 5 minutes\n\nconst metadata: StateMetadata<TokenBalancesControllerState> = {\n tokenBalances: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n// account → chain → token → balance\nexport type TokenBalances = Record<\n ChecksumAddress,\n Record<ChainIdHex, Record<ChecksumAddress, Hex>>\n>;\n\nexport type TokenBalancesControllerState = {\n tokenBalances: TokenBalances;\n};\n\nexport type TokenBalancesControllerGetStateAction = ControllerGetStateAction<\n typeof CONTROLLER,\n TokenBalancesControllerState\n>;\n\nexport type TokenBalancesControllerUpdateChainPollingConfigsAction = {\n type: `TokenBalancesController:updateChainPollingConfigs`;\n handler: TokenBalancesController['updateChainPollingConfigs'];\n};\n\nexport type TokenBalancesControllerGetChainPollingConfigAction = {\n type: `TokenBalancesController:getChainPollingConfig`;\n handler: TokenBalancesController['getChainPollingConfig'];\n};\n\nexport type TokenBalancesControllerActions =\n | TokenBalancesControllerGetStateAction\n | TokenBalancesControllerUpdateChainPollingConfigsAction\n | TokenBalancesControllerGetChainPollingConfigAction;\n\nexport type TokenBalancesControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof CONTROLLER, TokenBalancesControllerState>;\n\nexport type NativeBalanceEvent = {\n type: `${typeof CONTROLLER}:updatedNativeBalance`;\n payload: unknown[];\n};\n\nexport type TokenBalancesControllerEvents =\n | TokenBalancesControllerStateChangeEvent\n | NativeBalanceEvent;\n\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | TokensControllerGetStateAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerDetectTokensAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerControllerGetStateAction\n | AccountTrackerUpdateNativeBalancesAction\n | AccountTrackerUpdateStakedBalancesAction\n | KeyringControllerGetStateAction\n | AuthenticationController.AuthenticationControllerGetBearerToken;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | TransactionControllerTransactionConfirmedEvent\n | TransactionControllerIncomingTransactionsReceivedEvent;\n\nexport type TokenBalancesControllerMessenger = Messenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents\n>;\n\nexport type ChainPollingConfig = {\n /** Polling interval in milliseconds for this chain */\n interval: number;\n};\n\nexport type UpdateChainPollingConfigsOptions = {\n /** Whether to immediately fetch balances after updating configs (default: true) */\n immediateUpdate?: boolean;\n};\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n /** Default interval for chains not specified in chainPollingIntervals */\n interval?: number;\n /** Per-chain polling configuration */\n chainPollingIntervals?: Record<ChainIdHex, ChainPollingConfig>;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Array of chainIds that should use Accounts-API strategy (if supported by API). */\n accountsApiChainIds?: () => ChainIdHex[];\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n platform?: 'extension' | 'mobile';\n /** Polling interval when WebSocket is active and providing real-time updates */\n websocketActivePollingInterval?: number;\n};\n\nconst draft = <State>(base: State, fn: (draftState: State) => void): State =>\n produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\n/**\n * Convert CAIP chain ID or hex chain ID to hex chain ID.\n *\n * @param chainId - CAIP chain ID or hex chain ID.\n * @returns Hex chain ID.\n */\nexport const caipChainIdToHex = (chainId: string): ChainIdHex => {\n if (isStrictHexString(chainId)) {\n return chainId;\n }\n\n if (isCaipChainId(chainId)) {\n return toHex(parseCaipChainId(chainId).reference);\n }\n\n throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');\n};\n\n/**\n * Extract token address from asset type.\n *\n * @param assetType - Asset type string.\n * @returns Tuple of [tokenAddress, isNativeToken] or null if invalid.\n */\nexport const parseAssetType = (assetType: string): [string, boolean] | null => {\n if (!isCaipAssetType(assetType)) {\n return null;\n }\n\n const parsed = parseCaipAssetType(assetType);\n\n if (parsed.assetNamespace === 'erc20') {\n return [parsed.assetReference, false];\n }\n\n if (parsed.assetNamespace === 'slip44') {\n return [ZERO_ADDRESS, true];\n }\n\n return null;\n};\n\ntype NativeBalanceUpdate = { address: string; chainId: Hex; balance: Hex };\ntype StakedBalanceUpdate = {\n address: string;\n chainId: Hex;\n stakedBalance: Hex;\n};\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #platform: 'extension' | 'mobile';\n\n readonly #queryAllAccounts: boolean;\n\n readonly #accountsApiChainIds: () => ChainIdHex[];\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n #allIgnoredTokens: TokensControllerState['allIgnoredTokens'] = {};\n\n /** Default polling interval for chains without specific configuration */\n readonly #defaultInterval: number;\n\n /** Polling interval when WebSocket is active and providing real-time updates */\n readonly #websocketActivePollingInterval: number;\n\n /** Per-chain polling configuration */\n readonly #chainPollingConfig: Record<ChainIdHex, ChainPollingConfig>;\n\n /** Active polling timers grouped by interval */\n readonly #intervalPollingTimers: Map<number, NodeJS.Timeout> = new Map();\n\n /** Track if controller-level polling is active */\n #isControllerPollingActive = false;\n\n /** Track if the keyring is unlocked */\n #isUnlocked = false;\n\n /** Store original chainIds from startPolling to preserve intent */\n #requestedChainIds: ChainIdHex[] = [];\n\n /** Debouncing for rapid status changes to prevent excessive HTTP calls */\n readonly #statusChangeDebouncer: {\n timer: NodeJS.Timeout | null;\n pendingChanges: Map<string, 'up' | 'down'>;\n } = {\n timer: null,\n pendingChanges: new Map(),\n };\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n websocketActivePollingInterval = DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS,\n chainPollingIntervals = {},\n state = {},\n queryMultipleAccounts = true,\n accountsApiChainIds = (): ChainIdHex[] => [],\n allowExternalServices = (): boolean => true,\n platform,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#normalizeAccountAddresses();\n\n this.#platform = platform ?? 'extension';\n this.#queryAllAccounts = queryMultipleAccounts;\n this.#accountsApiChainIds = accountsApiChainIds;\n this.#defaultInterval = interval;\n this.#websocketActivePollingInterval = websocketActivePollingInterval;\n this.#chainPollingConfig = { ...chainPollingIntervals };\n\n this.#balanceFetchers = [\n ...(accountsApiChainIds().length > 0 && allowExternalServices()\n ? [this.#createAccountsApiFetcher()]\n : []),\n new RpcBalanceFetcher(this.#getProvider, this.#getNetworkClient, () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n })),\n ];\n\n this.setIntervalLength(interval);\n\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messenger.call('TokensController:getState');\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n this.#allIgnoredTokens = allIgnoredTokens;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.#subscribeToControllers();\n this.#registerActions();\n }\n\n #subscribeToControllers(): void {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n (tokensState: TokensControllerState) => {\n this.#onTokensChanged(tokensState).catch((error) => {\n console.warn('Error handling token state change:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n\n this.messenger.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\n );\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n this.#onAccountChanged,\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:balanceUpdated',\n (event) => {\n this.#onAccountActivityBalanceUpdate(event).catch((error) => {\n console.warn('Error handling balance update:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged.bind(this),\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta) => {\n this.updateBalances({\n chainIds: [transactionMeta.chainId],\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:incomingTransactionsReceived',\n (incomingTransactions) => {\n this.updateBalances({\n chainIds: incomingTransactions.map((tx) => tx.chainId),\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n }\n\n #registerActions(): void {\n this.messenger.registerActionHandler(\n `TokenBalancesController:updateChainPollingConfigs`,\n this.updateChainPollingConfigs.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `TokenBalancesController:getChainPollingConfig`,\n this.getChainPollingConfig.bind(this),\n );\n }\n\n /**\n * Whether the controller is active (keyring is unlocked).\n * When locked, balance updates should be skipped.\n *\n * @returns Whether the keyring is unlocked.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Normalize all account addresses to lowercase and merge duplicates\n * Handles migration from old state where addresses might be checksummed.\n */\n #normalizeAccountAddresses(): void {\n const currentState = this.state.tokenBalances;\n const normalizedBalances: TokenBalances = {};\n\n for (const address of Object.keys(currentState)) {\n const lowercaseAddress = address.toLowerCase() as ChecksumAddress;\n const accountBalances = currentState[address as ChecksumAddress];\n\n if (!accountBalances) {\n continue;\n }\n\n normalizedBalances[lowercaseAddress] ??= {};\n\n for (const chainId of Object.keys(accountBalances)) {\n const chainIdKey = chainId as ChainIdHex;\n normalizedBalances[lowercaseAddress][chainIdKey] ??= {};\n\n Object.assign(\n normalizedBalances[lowercaseAddress][chainIdKey],\n accountBalances[chainIdKey],\n );\n }\n }\n\n if (\n Object.keys(currentState).length !==\n Object.keys(normalizedBalances).length ||\n Object.keys(currentState).some((addr) => addr !== addr.toLowerCase())\n ) {\n this.update(() => ({ tokenBalances: normalizedBalances }));\n }\n }\n\n #chainIdsWithTokens(): ChainIdHex[] {\n return [\n ...new Set([\n ...Object.keys(this.#allTokens),\n ...Object.keys(this.#detectedTokens),\n ]),\n ] as ChainIdHex[];\n }\n\n readonly #getProvider = (chainId: ChainIdHex): Web3Provider => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n const client = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (\n chainId: ChainIdHex,\n ): ReturnType<NetworkControllerGetNetworkClientByIdAction['handler']> => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n return this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n readonly #createAccountsApiFetcher = (): BalanceFetcher => {\n const originalFetcher = new AccountsApiBalanceFetcher(\n this.#platform,\n this.#getProvider,\n );\n\n return {\n supports: (chainId: ChainIdHex): boolean =>\n this.#accountsApiChainIds().includes(chainId) &&\n originalFetcher.supports(chainId),\n fetch: originalFetcher.fetch.bind(originalFetcher),\n };\n };\n\n override _startPolling({ chainIds }: { chainIds: ChainIdHex[] }): void {\n this.#requestedChainIds = [...chainIds];\n this.#isControllerPollingActive = true;\n this.#startIntervalGroupPolling(chainIds, true);\n }\n\n #startIntervalGroupPolling(chainIds: ChainIdHex[], immediate = true): void {\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n const intervalGroups = new Map<number, ChainIdHex[]>();\n\n for (const chainId of chainIds) {\n const config = this.getChainPollingConfig(chainId);\n const group = intervalGroups.get(config.interval) ?? [];\n group.push(chainId);\n intervalGroups.set(config.interval, group);\n }\n\n for (const [interval, chainIdsGroup] of intervalGroups) {\n this.#startPollingForInterval(interval, chainIdsGroup, immediate);\n }\n }\n\n #startPollingForInterval(\n interval: number,\n chainIds: ChainIdHex[],\n immediate = true,\n ): void {\n const pollFunction = async (): Promise<void> => {\n if (!this.#isControllerPollingActive) {\n return;\n }\n\n try {\n await this._executePoll({ chainIds });\n } catch (error) {\n console.warn(\n `Polling failed for chains ${chainIds.join(', ')} with interval ${interval}:`,\n error,\n );\n }\n };\n\n if (immediate) {\n pollFunction().catch((error) => {\n console.warn(\n `Immediate polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }\n\n this.#setPollingTimer(interval, chainIds, pollFunction);\n }\n\n #setPollingTimer(\n interval: number,\n chainIds: ChainIdHex[],\n pollFunction: () => Promise<void>,\n ): void {\n const timer = setInterval(() => {\n pollFunction().catch((error) => {\n console.warn(\n `Interval polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }, interval);\n\n this.#intervalPollingTimers.set(interval, timer);\n }\n\n override _stopPollingByPollingTokenSetId(tokenSetId: string): void {\n let chainsToStop: ChainIdHex[] = [];\n\n try {\n const parsedTokenSetId = JSON.parse(tokenSetId);\n chainsToStop = parsedTokenSetId.chainIds ?? [];\n } catch (error) {\n console.warn('Failed to parse tokenSetId, stopping all polling:', error);\n this.#stopAllPolling();\n return;\n }\n\n const currentChainsSet = new Set(this.#requestedChainIds);\n const stopChainsSet = new Set(chainsToStop);\n\n const isCurrentSession =\n currentChainsSet.size === stopChainsSet.size &&\n [...currentChainsSet].every((chain) => stopChainsSet.has(chain));\n\n if (isCurrentSession) {\n this.#stopAllPolling();\n }\n }\n\n #stopAllPolling(): void {\n this.#isControllerPollingActive = false;\n this.#requestedChainIds = [];\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n }\n\n getChainPollingConfig(chainId: ChainIdHex): ChainPollingConfig {\n return (\n this.#chainPollingConfig[chainId] ?? {\n interval: this.#defaultInterval,\n }\n );\n }\n\n override async _executePoll({\n chainIds,\n queryAllAccounts = false,\n }: {\n chainIds: ChainIdHex[];\n queryAllAccounts?: boolean;\n }): Promise<void> {\n await this.updateBalances({ chainIds, queryAllAccounts });\n }\n\n updateChainPollingConfigs(\n configs: Record<ChainIdHex, ChainPollingConfig>,\n options: UpdateChainPollingConfigsOptions = { immediateUpdate: true },\n ): void {\n Object.assign(this.#chainPollingConfig, configs);\n\n if (this.#isControllerPollingActive) {\n this.#startIntervalGroupPolling(\n this.#requestedChainIds,\n options.immediateUpdate,\n );\n }\n }\n\n async updateBalances({\n chainIds,\n tokenAddresses,\n queryAllAccounts = false,\n }: {\n chainIds?: ChainIdHex[];\n tokenAddresses?: string[];\n queryAllAccounts?: boolean;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const targetChains = this.#getTargetChains(chainIds);\n if (!targetChains.length) {\n return;\n }\n\n const { selectedAccount, allAccounts, jwtToken } =\n await this.#getAccountsAndJwt();\n\n const aggregatedBalances = await this.#fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts: queryAllAccounts ?? this.#queryAllAccounts,\n });\n\n const filteredAggregated = this.#filterByTokenAddresses(\n aggregatedBalances,\n tokenAddresses,\n );\n\n const accountsToProcess = this.#getAccountsToProcess(\n queryAllAccounts,\n allAccounts,\n selectedAccount,\n );\n\n const prev = this.state;\n const next = this.#applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances: filteredAggregated,\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const accountTrackerState = this.messenger.call(\n 'AccountTrackerController:getState',\n );\n\n const nativeUpdates = this.#buildNativeBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (nativeUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeUpdates,\n );\n }\n\n const stakedUpdates = this.#buildStakedBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (stakedUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedUpdates,\n );\n }\n }\n\n await this.#importUntrackedTokens(filteredAggregated);\n }\n\n #getTargetChains(chainIds?: ChainIdHex[]): ChainIdHex[] {\n return chainIds?.length ? chainIds : this.#chainIdsWithTokens();\n }\n\n async #getAccountsAndJwt(): Promise<{\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken: string | undefined;\n }> {\n const { address: selected } = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messenger.call('AccountsController:listAccounts');\n\n const jwtToken = await safelyExecuteWithTimeout<string | undefined>(\n () => {\n return this.messenger.call('AuthenticationController:getBearerToken');\n },\n false,\n 5000,\n );\n\n return {\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n jwtToken,\n };\n }\n\n async #fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts,\n }: {\n targetChains: ChainIdHex[];\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken?: string;\n queryAllAccounts: boolean;\n }): Promise<ProcessedBalance[]> {\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((chain) =>\n fetcher.supports(chain),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const result = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n jwtToken,\n });\n\n if (result.balances?.length) {\n aggregated.push(...result.balances);\n\n const processed = new Set(result.balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processed.has(chain),\n );\n }\n\n if (result.unprocessedChainIds?.length) {\n const currentRemaining = [...remainingChains];\n const chainsToAdd = result.unprocessedChainIds.filter(\n (chainId) =>\n supportedChains.includes(chainId) &&\n !currentRemaining.includes(chainId),\n );\n remainingChains.push(...chainsToAdd);\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: result.unprocessedChainIds,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: supportedChains,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n if (!remainingChains.length) {\n break;\n }\n }\n\n return aggregated;\n }\n\n #filterByTokenAddresses(\n balances: ProcessedBalance[],\n tokenAddresses?: string[],\n ): ProcessedBalance[] {\n if (!tokenAddresses?.length) {\n return balances;\n }\n\n const lowered = tokenAddresses.map((a) => a.toLowerCase());\n return balances.filter((balance) =>\n lowered.includes(balance.token.toLowerCase()),\n );\n }\n\n #getAccountsToProcess(\n queryAllAccountsParam: boolean | undefined,\n allAccounts: InternalAccount[],\n selectedAccount: ChecksumAddress,\n ): ChecksumAddress[] {\n const effectiveQueryAll =\n queryAllAccountsParam ?? this.#queryAllAccounts ?? false;\n\n if (!effectiveQueryAll) {\n return [selectedAccount];\n }\n\n return allAccounts.map((account) => account.address as ChecksumAddress);\n }\n\n #applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances,\n }: {\n prev: TokenBalancesControllerState;\n targetChains: ChainIdHex[];\n accountsToProcess: ChecksumAddress[];\n balances: ProcessedBalance[];\n }): TokenBalancesControllerState {\n return draft(prev, (draftState) => {\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n draftState.tokenBalances[account] ??= {};\n draftState.tokenBalances[account][chainId] ??= {};\n\n const chainTokens = this.#allTokens[chainId];\n if (chainTokens?.[account]) {\n Object.values(chainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n\n const detectedChainTokens = this.#detectedTokens[chainId];\n if (detectedChainTokens?.[account]) {\n Object.values(detectedChainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n }\n }\n\n balances.forEach(({ success, value, account, token, chainId }) => {\n if (!success || value === undefined) {\n return;\n }\n\n const lowerCaseAccount = account.toLowerCase() as ChecksumAddress;\n const newBalance = toHex(value);\n const tokenAddress = checksum(token);\n\n const currentBalance =\n draftState.tokenBalances[lowerCaseAccount]?.[chainId]?.[tokenAddress];\n\n if (currentBalance !== newBalance) {\n ((draftState.tokenBalances[lowerCaseAccount] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = newBalance;\n }\n });\n });\n }\n\n #buildNativeBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): NativeBalanceUpdate[] {\n const nativeBalances = balances.filter(\n (balance) => balance.success && balance.token === ZERO_ADDRESS,\n );\n\n if (!nativeBalances.length) {\n return [];\n }\n\n return nativeBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value ? BNToHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.balance;\n return currentBalance !== update.balance;\n });\n }\n\n #buildStakedBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): StakedBalanceUpdate[] {\n const stakedBalances = balances.filter((balance) => {\n if (!balance.success || balance.token === ZERO_ADDRESS) {\n return false;\n }\n\n const stakingContractAddress =\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[balance.chainId];\n return (\n stakingContractAddress &&\n stakingContractAddress.toLowerCase() === balance.token.toLowerCase()\n );\n });\n\n if (!stakedBalances.length) {\n return [];\n }\n\n return stakedBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentStakedBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.stakedBalance;\n return currentStakedBalance !== update.stakedBalance;\n });\n }\n\n /**\n * Import untracked tokens that have non-zero balances.\n * This mirrors the v2 behavior where only tokens with actual balances are added.\n * Delegates to TokenDetectionController:addDetectedTokensViaPolling which handles:\n * - Checking if useTokenDetection preference is enabled\n * - Filtering tokens already in allTokens or allIgnoredTokens\n * - Token metadata lookup and addition via TokensController\n *\n * @param balances - Array of processed balance results from fetchers\n */\n async #importUntrackedTokens(balances: ProcessedBalance[]): Promise<void> {\n const tokensByChain = new Map<ChainIdHex, string[]>();\n\n for (const balance of balances) {\n // Skip failed fetches, native tokens, and zero balances (like v2 did)\n if (\n !balance.success ||\n balance.token === ZERO_ADDRESS ||\n !balance.value ||\n balance.value.isZero()\n ) {\n continue;\n }\n\n const tokenAddress = checksum(balance.token);\n const existing = tokensByChain.get(balance.chainId) ?? [];\n if (!existing.includes(tokenAddress)) {\n existing.push(tokenAddress);\n tokensByChain.set(balance.chainId, existing);\n }\n }\n\n // Add detected tokens via TokenDetectionController (handles preference check,\n // filtering of allTokens/allIgnoredTokens, and metadata lookup)\n for (const [chainId, tokenAddresses] of tokensByChain) {\n if (tokenAddresses.length) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaPolling',\n {\n tokensSlice: tokenAddresses,\n chainId,\n },\n );\n }\n }\n }\n\n resetState(): void {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n #isTokenTracked(\n tokenAddress: string,\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): boolean {\n const normalizedAccount = account.toLowerCase();\n\n if (\n this.#allTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token.address === tokenAddress,\n )\n ) {\n return true;\n }\n\n if (\n this.#allIgnoredTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token === tokenAddress,\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n readonly #onTokensChanged = async (\n state: TokensControllerState,\n ): Promise<void> => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n const relevantChainIds = Array.from(incomingChainIds).filter((chainId) => {\n const id = chainId as ChainIdHex;\n\n const hasTokensNow =\n (state.allTokens[id] && Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] && Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (!relevantChainIds.length) {\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n this.update((currentState) => {\n for (const chainId of relevantChainIds) {\n const id = chainId as ChainIdHex;\n const hasTokensNow =\n (state.allTokens[id] &&\n Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] &&\n Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const tokensChanged =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n if (!tokensChanged) {\n continue;\n }\n\n if (hasTokensNow) {\n changed.push(id);\n } else if (hadTokensBefore) {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (currentState.tokenBalances[addressKey]?.[id]) {\n currentState.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n this.#allIgnoredTokens = state.allIgnoredTokens;\n\n if (changed.length && !hasChanges) {\n this.updateBalances({ chainIds: changed }).catch((error) => {\n console.warn('Error updating balances after token change:', error);\n });\n }\n };\n\n readonly #onNetworkChanged = (state: NetworkState): void => {\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n const networksWithBalances = new Set<string>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const network of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n networksWithBalances.add(network);\n }\n }\n\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (!removedNetworks.length) {\n return;\n }\n\n this.update((currentState) => {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (currentState.tokenBalances[addressKey]?.[networkKey]) {\n delete currentState.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n };\n\n readonly #onAccountRemoved = (addr: string): void => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((currentState) => {\n delete currentState.tokenBalances[addr];\n });\n };\n\n readonly #onAccountChanged = (): void => {\n const chainIds = this.#chainIdsWithTokens();\n if (!chainIds.length) {\n return;\n }\n\n this.updateBalances({ chainIds }).catch(() => {\n // Silently handle polling errors\n });\n };\n\n #prepareBalanceUpdates(\n updates: BalanceUpdate[],\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): {\n tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[];\n newTokens: string[];\n nativeBalanceUpdates: NativeBalanceUpdate[];\n } {\n const tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[] = [];\n const newTokens: string[] = [];\n const nativeBalanceUpdates: NativeBalanceUpdate[] = [];\n\n for (const update of updates) {\n const { asset, postBalance } = update;\n\n if (postBalance.error) {\n throw new Error('Balance update has error');\n }\n\n const parsed = parseAssetType(asset.type);\n if (!parsed) {\n throw new Error('Failed to parse asset type');\n }\n\n const [tokenAddress, isNativeToken] = parsed;\n\n if (\n !isStrictHexString(tokenAddress) ||\n !isValidHexAddress(tokenAddress)\n ) {\n throw new Error('Invalid token address');\n }\n\n const checksumTokenAddress = checksum(tokenAddress);\n const isTracked = this.#isTokenTracked(\n checksumTokenAddress,\n account,\n chainId,\n );\n\n const balanceHex = postBalance.amount as Hex;\n\n tokenBalances.push({\n tokenAddress: checksumTokenAddress,\n balance: balanceHex,\n });\n\n if (isNativeToken) {\n nativeBalanceUpdates.push({\n address: account,\n chainId,\n balance: balanceHex,\n });\n }\n\n if (!isNativeToken && !isTracked) {\n newTokens.push(checksumTokenAddress);\n }\n }\n\n return { tokenBalances, newTokens, nativeBalanceUpdates };\n }\n\n readonly #onAccountActivityBalanceUpdate = async ({\n address,\n chain,\n updates,\n }: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }): Promise<void> => {\n const chainId = caipChainIdToHex(chain);\n const checksummedAccount = checksum(address);\n\n try {\n const { tokenBalances, newTokens, nativeBalanceUpdates } =\n this.#prepareBalanceUpdates(updates, checksummedAccount, chainId);\n\n if (tokenBalances.length > 0) {\n this.update((state) => {\n const lowercaseAccount =\n checksummedAccount.toLowerCase() as ChecksumAddress;\n state.tokenBalances[lowercaseAccount] ??= {};\n state.tokenBalances[lowercaseAccount][chainId] ??= {};\n\n for (const { tokenAddress, balance } of tokenBalances) {\n state.tokenBalances[lowercaseAccount][chainId][tokenAddress] =\n balance;\n }\n });\n }\n\n if (nativeBalanceUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeBalanceUpdates,\n );\n }\n\n if (newTokens.length > 0) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaWs',\n {\n tokensSlice: newTokens,\n chainId,\n },\n );\n }\n } catch (error) {\n console.warn(\n `Error updating balances from AccountActivityService for chain ${chain}, account ${address}:`,\n error,\n );\n console.warn('Balance update data:', JSON.stringify(updates, null, 2));\n\n await this.updateBalances({ chainIds: [chainId] }).catch(() => {\n // Silently handle polling errors\n });\n }\n };\n\n readonly #onAccountActivityStatusChanged = ({\n chainIds,\n status,\n }: {\n chainIds: string[];\n status: 'up' | 'down';\n }): void => {\n for (const chainId of chainIds) {\n this.#statusChangeDebouncer.pendingChanges.set(chainId, status);\n }\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n }\n\n this.#statusChangeDebouncer.timer = setTimeout(() => {\n this.#processAccumulatedStatusChanges();\n }, 5000);\n };\n\n #processAccumulatedStatusChanges(): void {\n const changes = Array.from(\n this.#statusChangeDebouncer.pendingChanges.entries(),\n );\n this.#statusChangeDebouncer.pendingChanges.clear();\n this.#statusChangeDebouncer.timer = null;\n\n if (!changes.length) {\n return;\n }\n\n const chainConfigs: Record<ChainIdHex, { interval: number }> = {};\n\n for (const [chainId, status] of changes) {\n const hexChainId = caipChainIdToHex(chainId);\n\n chainConfigs[hexChainId] =\n status === 'down'\n ? { interval: this.#defaultInterval }\n : { interval: this.#websocketActivePollingInterval };\n }\n\n const jitterDelay = Math.random() * this.#defaultInterval;\n\n setTimeout(() => {\n this.updateChainPollingConfigs(chainConfigs, { immediateUpdate: true });\n }, jitterDelay);\n }\n\n override destroy(): void {\n this.#isControllerPollingActive = false;\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n this.#statusChangeDebouncer.timer = null;\n }\n\n this.messenger.unregisterActionHandler(\n `TokenBalancesController:updateChainPollingConfigs`,\n );\n this.messenger.unregisterActionHandler(\n `TokenBalancesController:getChainPollingConfig`,\n );\n\n super.destroy();\n }\n}\n\nexport default TokenBalancesController;\n"]}
|
|
1
|
+
{"version":3,"file":"TokenBalancesController.mjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport {\n BNToHex,\n isValidHexAddress,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type {\n BalanceUpdate,\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n} from '@metamask/core-backend';\nimport type {\n KeyringControllerAccountRemovedEvent,\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport type {\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerTransactionConfirmedEvent,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport {\n isCaipAssetType,\n isCaipChainId,\n isStrictHexString,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type {\n AccountTrackerControllerGetStateAction,\n AccountTrackerUpdateNativeBalancesAction,\n AccountTrackerUpdateStakedBalancesAction,\n} from './AccountTrackerController';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport { AccountsApiBalanceFetcher } from './multi-chain-accounts-service/api-balance-fetcher';\nimport type {\n BalanceFetcher,\n ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\nimport type {\n TokenDetectionControllerAddDetectedTokensViaPollingAction,\n TokenDetectionControllerAddDetectedTokensViaWsAction,\n TokenDetectionControllerDetectTokensAction,\n} from './TokenDetectionController';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerState,\n TokensControllerStateChangeEvent,\n} from './TokensController';\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nconst CONTROLLER = 'TokenBalancesController' as const;\nconst DEFAULT_INTERVAL_MS = 30_000; // 30 seconds\nconst DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS = 300_000; // 5 minutes\n\nconst metadata: StateMetadata<TokenBalancesControllerState> = {\n tokenBalances: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n// account → chain → token → balance\nexport type TokenBalances = Record<\n ChecksumAddress,\n Record<ChainIdHex, Record<ChecksumAddress, Hex>>\n>;\n\nexport type TokenBalancesControllerState = {\n tokenBalances: TokenBalances;\n};\n\nexport type TokenBalancesControllerGetStateAction = ControllerGetStateAction<\n typeof CONTROLLER,\n TokenBalancesControllerState\n>;\n\nexport type TokenBalancesControllerUpdateChainPollingConfigsAction = {\n type: `TokenBalancesController:updateChainPollingConfigs`;\n handler: TokenBalancesController['updateChainPollingConfigs'];\n};\n\nexport type TokenBalancesControllerGetChainPollingConfigAction = {\n type: `TokenBalancesController:getChainPollingConfig`;\n handler: TokenBalancesController['getChainPollingConfig'];\n};\n\nexport type TokenBalancesControllerActions =\n | TokenBalancesControllerGetStateAction\n | TokenBalancesControllerUpdateChainPollingConfigsAction\n | TokenBalancesControllerGetChainPollingConfigAction;\n\nexport type TokenBalancesControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof CONTROLLER, TokenBalancesControllerState>;\n\nexport type NativeBalanceEvent = {\n type: `${typeof CONTROLLER}:updatedNativeBalance`;\n payload: unknown[];\n};\n\nexport type TokenBalancesControllerEvents =\n | TokenBalancesControllerStateChangeEvent\n | NativeBalanceEvent;\n\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | TokensControllerGetStateAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerDetectTokensAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerControllerGetStateAction\n | AccountTrackerUpdateNativeBalancesAction\n | AccountTrackerUpdateStakedBalancesAction\n | KeyringControllerGetStateAction\n | AuthenticationController.AuthenticationControllerGetBearerToken;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | TransactionControllerTransactionConfirmedEvent\n | TransactionControllerIncomingTransactionsReceivedEvent;\n\nexport type TokenBalancesControllerMessenger = Messenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents\n>;\n\nexport type ChainPollingConfig = {\n /** Polling interval in milliseconds for this chain */\n interval: number;\n};\n\nexport type UpdateChainPollingConfigsOptions = {\n /** Whether to immediately fetch balances after updating configs (default: true) */\n immediateUpdate?: boolean;\n};\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n /** Default interval for chains not specified in chainPollingIntervals */\n interval?: number;\n /** Per-chain polling configuration */\n chainPollingIntervals?: Record<ChainIdHex, ChainPollingConfig>;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Array of chainIds that should use Accounts-API strategy (if supported by API). */\n accountsApiChainIds?: () => ChainIdHex[];\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n platform?: 'extension' | 'mobile';\n /** Polling interval when WebSocket is active and providing real-time updates */\n websocketActivePollingInterval?: number;\n};\n\nconst draft = <State>(base: State, fn: (draftState: State) => void): State =>\n produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\n/**\n * Convert CAIP chain ID or hex chain ID to hex chain ID.\n *\n * @param chainId - CAIP chain ID or hex chain ID.\n * @returns Hex chain ID.\n */\nexport const caipChainIdToHex = (chainId: string): ChainIdHex => {\n if (isStrictHexString(chainId)) {\n return chainId;\n }\n\n if (isCaipChainId(chainId)) {\n return toHex(parseCaipChainId(chainId).reference);\n }\n\n throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');\n};\n\n/**\n * Extract token address from asset type.\n *\n * @param assetType - Asset type string.\n * @returns Tuple of [tokenAddress, isNativeToken] or null if invalid.\n */\nexport const parseAssetType = (assetType: string): [string, boolean] | null => {\n if (!isCaipAssetType(assetType)) {\n return null;\n }\n\n const parsed = parseCaipAssetType(assetType);\n\n if (parsed.assetNamespace === 'erc20') {\n return [parsed.assetReference, false];\n }\n\n if (parsed.assetNamespace === 'slip44') {\n return [ZERO_ADDRESS, true];\n }\n\n return null;\n};\n\ntype NativeBalanceUpdate = { address: string; chainId: Hex; balance: Hex };\ntype StakedBalanceUpdate = {\n address: string;\n chainId: Hex;\n stakedBalance: Hex;\n};\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #platform: 'extension' | 'mobile';\n\n readonly #queryAllAccounts: boolean;\n\n readonly #accountsApiChainIds: () => ChainIdHex[];\n\n readonly #allowExternalServices: () => boolean;\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n #allIgnoredTokens: TokensControllerState['allIgnoredTokens'] = {};\n\n /** Default polling interval for chains without specific configuration */\n readonly #defaultInterval: number;\n\n /** Polling interval when WebSocket is active and providing real-time updates */\n readonly #websocketActivePollingInterval: number;\n\n /** Per-chain polling configuration */\n readonly #chainPollingConfig: Record<ChainIdHex, ChainPollingConfig>;\n\n /** Active polling timers grouped by interval */\n readonly #intervalPollingTimers: Map<number, NodeJS.Timeout> = new Map();\n\n /** Track if controller-level polling is active */\n #isControllerPollingActive = false;\n\n /** Track if the keyring is unlocked */\n #isUnlocked = false;\n\n /** Store original chainIds from startPolling to preserve intent */\n #requestedChainIds: ChainIdHex[] = [];\n\n /** Debouncing for rapid status changes to prevent excessive HTTP calls */\n readonly #statusChangeDebouncer: {\n timer: NodeJS.Timeout | null;\n pendingChanges: Map<string, 'up' | 'down'>;\n } = {\n timer: null,\n pendingChanges: new Map(),\n };\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n websocketActivePollingInterval = DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS,\n chainPollingIntervals = {},\n state = {},\n queryMultipleAccounts = true,\n accountsApiChainIds = (): ChainIdHex[] => [],\n allowExternalServices = (): boolean => true,\n platform,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#normalizeAccountAddresses();\n\n this.#platform = platform ?? 'extension';\n this.#queryAllAccounts = queryMultipleAccounts;\n this.#accountsApiChainIds = accountsApiChainIds;\n this.#allowExternalServices = allowExternalServices;\n this.#defaultInterval = interval;\n this.#websocketActivePollingInterval = websocketActivePollingInterval;\n this.#chainPollingConfig = { ...chainPollingIntervals };\n\n // Always include AccountsApiFetcher - it dynamically checks allowExternalServices() in supports()\n this.#balanceFetchers = [\n this.#createAccountsApiFetcher(),\n new RpcBalanceFetcher(this.#getProvider, this.#getNetworkClient, () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n })),\n ];\n\n this.setIntervalLength(interval);\n\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messenger.call('TokensController:getState');\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n this.#allIgnoredTokens = allIgnoredTokens;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.#subscribeToControllers();\n this.#registerActions();\n }\n\n #subscribeToControllers(): void {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n (tokensState: TokensControllerState) => {\n this.#onTokensChanged(tokensState).catch((error) => {\n console.warn('Error handling token state change:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n\n this.messenger.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\n );\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n this.#onAccountChanged,\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:balanceUpdated',\n (event) => {\n this.#onAccountActivityBalanceUpdate(event).catch((error) => {\n console.warn('Error handling balance update:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged.bind(this),\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta) => {\n this.updateBalances({\n chainIds: [transactionMeta.chainId],\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:incomingTransactionsReceived',\n (incomingTransactions) => {\n this.updateBalances({\n chainIds: incomingTransactions.map((tx) => tx.chainId),\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n }\n\n #registerActions(): void {\n this.messenger.registerActionHandler(\n `TokenBalancesController:updateChainPollingConfigs`,\n this.updateChainPollingConfigs.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `TokenBalancesController:getChainPollingConfig`,\n this.getChainPollingConfig.bind(this),\n );\n }\n\n /**\n * Whether the controller is active (keyring is unlocked).\n * When locked, balance updates should be skipped.\n *\n * @returns Whether the keyring is unlocked.\n */\n get isActive(): boolean {\n return this.#isUnlocked;\n }\n\n /**\n * Normalize all account addresses to lowercase and merge duplicates\n * Handles migration from old state where addresses might be checksummed.\n */\n #normalizeAccountAddresses(): void {\n const currentState = this.state.tokenBalances;\n const normalizedBalances: TokenBalances = {};\n\n for (const address of Object.keys(currentState)) {\n const lowercaseAddress = address.toLowerCase() as ChecksumAddress;\n const accountBalances = currentState[address as ChecksumAddress];\n\n if (!accountBalances) {\n continue;\n }\n\n normalizedBalances[lowercaseAddress] ??= {};\n\n for (const chainId of Object.keys(accountBalances)) {\n const chainIdKey = chainId as ChainIdHex;\n normalizedBalances[lowercaseAddress][chainIdKey] ??= {};\n\n Object.assign(\n normalizedBalances[lowercaseAddress][chainIdKey],\n accountBalances[chainIdKey],\n );\n }\n }\n\n if (\n Object.keys(currentState).length !==\n Object.keys(normalizedBalances).length ||\n Object.keys(currentState).some((addr) => addr !== addr.toLowerCase())\n ) {\n this.update(() => ({ tokenBalances: normalizedBalances }));\n }\n }\n\n #chainIdsWithTokens(): ChainIdHex[] {\n return [\n ...new Set([\n ...Object.keys(this.#allTokens),\n ...Object.keys(this.#detectedTokens),\n ]),\n ] as ChainIdHex[];\n }\n\n readonly #getProvider = (chainId: ChainIdHex): Web3Provider => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n const client = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (\n chainId: ChainIdHex,\n ): ReturnType<NetworkControllerGetNetworkClientByIdAction['handler']> => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n return this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n readonly #createAccountsApiFetcher = (): BalanceFetcher => {\n const originalFetcher = new AccountsApiBalanceFetcher(\n this.#platform,\n this.#getProvider,\n );\n\n return {\n // Dynamically check allowExternalServices() at call time, not just at construction time\n supports: (chainId: ChainIdHex): boolean =>\n this.#allowExternalServices() &&\n this.#accountsApiChainIds().includes(chainId) &&\n originalFetcher.supports(chainId),\n fetch: originalFetcher.fetch.bind(originalFetcher),\n };\n };\n\n override _startPolling({ chainIds }: { chainIds: ChainIdHex[] }): void {\n this.#requestedChainIds = [...chainIds];\n this.#isControllerPollingActive = true;\n this.#startIntervalGroupPolling(chainIds, true);\n }\n\n #startIntervalGroupPolling(chainIds: ChainIdHex[], immediate = true): void {\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n const intervalGroups = new Map<number, ChainIdHex[]>();\n\n for (const chainId of chainIds) {\n const config = this.getChainPollingConfig(chainId);\n const group = intervalGroups.get(config.interval) ?? [];\n group.push(chainId);\n intervalGroups.set(config.interval, group);\n }\n\n for (const [interval, chainIdsGroup] of intervalGroups) {\n this.#startPollingForInterval(interval, chainIdsGroup, immediate);\n }\n }\n\n #startPollingForInterval(\n interval: number,\n chainIds: ChainIdHex[],\n immediate = true,\n ): void {\n const pollFunction = async (): Promise<void> => {\n if (!this.#isControllerPollingActive) {\n return;\n }\n\n try {\n await this._executePoll({ chainIds });\n } catch (error) {\n console.warn(\n `Polling failed for chains ${chainIds.join(', ')} with interval ${interval}:`,\n error,\n );\n }\n };\n\n if (immediate) {\n pollFunction().catch((error) => {\n console.warn(\n `Immediate polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }\n\n this.#setPollingTimer(interval, chainIds, pollFunction);\n }\n\n #setPollingTimer(\n interval: number,\n chainIds: ChainIdHex[],\n pollFunction: () => Promise<void>,\n ): void {\n const timer = setInterval(() => {\n pollFunction().catch((error) => {\n console.warn(\n `Interval polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }, interval);\n\n this.#intervalPollingTimers.set(interval, timer);\n }\n\n override _stopPollingByPollingTokenSetId(tokenSetId: string): void {\n let chainsToStop: ChainIdHex[] = [];\n\n try {\n const parsedTokenSetId = JSON.parse(tokenSetId);\n chainsToStop = parsedTokenSetId.chainIds ?? [];\n } catch (error) {\n console.warn('Failed to parse tokenSetId, stopping all polling:', error);\n this.#stopAllPolling();\n return;\n }\n\n const currentChainsSet = new Set(this.#requestedChainIds);\n const stopChainsSet = new Set(chainsToStop);\n\n const isCurrentSession =\n currentChainsSet.size === stopChainsSet.size &&\n [...currentChainsSet].every((chain) => stopChainsSet.has(chain));\n\n if (isCurrentSession) {\n this.#stopAllPolling();\n }\n }\n\n #stopAllPolling(): void {\n this.#isControllerPollingActive = false;\n this.#requestedChainIds = [];\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n }\n\n getChainPollingConfig(chainId: ChainIdHex): ChainPollingConfig {\n return (\n this.#chainPollingConfig[chainId] ?? {\n interval: this.#defaultInterval,\n }\n );\n }\n\n override async _executePoll({\n chainIds,\n queryAllAccounts = false,\n }: {\n chainIds: ChainIdHex[];\n queryAllAccounts?: boolean;\n }): Promise<void> {\n await this.updateBalances({ chainIds, queryAllAccounts });\n }\n\n updateChainPollingConfigs(\n configs: Record<ChainIdHex, ChainPollingConfig>,\n options: UpdateChainPollingConfigsOptions = { immediateUpdate: true },\n ): void {\n Object.assign(this.#chainPollingConfig, configs);\n\n if (this.#isControllerPollingActive) {\n this.#startIntervalGroupPolling(\n this.#requestedChainIds,\n options.immediateUpdate,\n );\n }\n }\n\n async updateBalances({\n chainIds,\n tokenAddresses,\n queryAllAccounts = false,\n }: {\n chainIds?: ChainIdHex[];\n tokenAddresses?: string[];\n queryAllAccounts?: boolean;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const targetChains = this.#getTargetChains(chainIds);\n if (!targetChains.length) {\n return;\n }\n\n const { selectedAccount, allAccounts, jwtToken } =\n await this.#getAccountsAndJwt();\n\n const aggregatedBalances = await this.#fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts: queryAllAccounts ?? this.#queryAllAccounts,\n });\n\n const filteredAggregated = this.#filterByTokenAddresses(\n aggregatedBalances,\n tokenAddresses,\n );\n\n const accountsToProcess = this.#getAccountsToProcess(\n queryAllAccounts,\n allAccounts,\n selectedAccount,\n );\n\n const prev = this.state;\n const next = this.#applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances: filteredAggregated,\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const accountTrackerState = this.messenger.call(\n 'AccountTrackerController:getState',\n );\n\n const nativeUpdates = this.#buildNativeBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (nativeUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeUpdates,\n );\n }\n\n const stakedUpdates = this.#buildStakedBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (stakedUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedUpdates,\n );\n }\n }\n\n await this.#importUntrackedTokens(filteredAggregated);\n }\n\n #getTargetChains(chainIds?: ChainIdHex[]): ChainIdHex[] {\n return chainIds?.length ? chainIds : this.#chainIdsWithTokens();\n }\n\n async #getAccountsAndJwt(): Promise<{\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken: string | undefined;\n }> {\n const { address: selected } = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messenger.call('AccountsController:listAccounts');\n\n const jwtToken = await safelyExecuteWithTimeout<string | undefined>(\n () => {\n return this.messenger.call('AuthenticationController:getBearerToken');\n },\n false,\n 5000,\n );\n\n return {\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n jwtToken,\n };\n }\n\n async #fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts,\n }: {\n targetChains: ChainIdHex[];\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken?: string;\n queryAllAccounts: boolean;\n }): Promise<ProcessedBalance[]> {\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((chain) =>\n fetcher.supports(chain),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const result = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n jwtToken,\n });\n\n if (result.balances?.length) {\n aggregated.push(...result.balances);\n\n const processed = new Set(result.balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processed.has(chain),\n );\n }\n\n if (result.unprocessedChainIds?.length) {\n const currentRemaining = [...remainingChains];\n const chainsToAdd = result.unprocessedChainIds.filter(\n (chainId) =>\n supportedChains.includes(chainId) &&\n !currentRemaining.includes(chainId),\n );\n remainingChains.push(...chainsToAdd);\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: result.unprocessedChainIds,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: supportedChains,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n if (!remainingChains.length) {\n break;\n }\n }\n\n return aggregated;\n }\n\n #filterByTokenAddresses(\n balances: ProcessedBalance[],\n tokenAddresses?: string[],\n ): ProcessedBalance[] {\n if (!tokenAddresses?.length) {\n return balances;\n }\n\n const lowered = tokenAddresses.map((a) => a.toLowerCase());\n return balances.filter((balance) =>\n lowered.includes(balance.token.toLowerCase()),\n );\n }\n\n #getAccountsToProcess(\n queryAllAccountsParam: boolean | undefined,\n allAccounts: InternalAccount[],\n selectedAccount: ChecksumAddress,\n ): ChecksumAddress[] {\n const effectiveQueryAll =\n queryAllAccountsParam ?? this.#queryAllAccounts ?? false;\n\n if (!effectiveQueryAll) {\n return [selectedAccount];\n }\n\n return allAccounts.map((account) => account.address as ChecksumAddress);\n }\n\n #applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances,\n }: {\n prev: TokenBalancesControllerState;\n targetChains: ChainIdHex[];\n accountsToProcess: ChecksumAddress[];\n balances: ProcessedBalance[];\n }): TokenBalancesControllerState {\n return draft(prev, (draftState) => {\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n draftState.tokenBalances[account] ??= {};\n draftState.tokenBalances[account][chainId] ??= {};\n\n const chainTokens = this.#allTokens[chainId];\n if (chainTokens?.[account]) {\n Object.values(chainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n\n const detectedChainTokens = this.#detectedTokens[chainId];\n if (detectedChainTokens?.[account]) {\n Object.values(detectedChainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n }\n }\n\n balances.forEach(({ success, value, account, token, chainId }) => {\n if (!success || value === undefined) {\n return;\n }\n\n const lowerCaseAccount = account.toLowerCase() as ChecksumAddress;\n const newBalance = toHex(value);\n const tokenAddress = checksum(token);\n\n const currentBalance =\n draftState.tokenBalances[lowerCaseAccount]?.[chainId]?.[tokenAddress];\n\n if (currentBalance !== newBalance) {\n ((draftState.tokenBalances[lowerCaseAccount] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = newBalance;\n }\n });\n });\n }\n\n #buildNativeBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): NativeBalanceUpdate[] {\n const nativeBalances = balances.filter(\n (balance) => balance.success && balance.token === ZERO_ADDRESS,\n );\n\n if (!nativeBalances.length) {\n return [];\n }\n\n return nativeBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value ? BNToHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.balance;\n return currentBalance !== update.balance;\n });\n }\n\n #buildStakedBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): StakedBalanceUpdate[] {\n const stakedBalances = balances.filter((balance) => {\n if (!balance.success || balance.token === ZERO_ADDRESS) {\n return false;\n }\n\n const stakingContractAddress =\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[balance.chainId];\n return (\n stakingContractAddress &&\n stakingContractAddress.toLowerCase() === balance.token.toLowerCase()\n );\n });\n\n if (!stakedBalances.length) {\n return [];\n }\n\n return stakedBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentStakedBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.stakedBalance;\n return currentStakedBalance !== update.stakedBalance;\n });\n }\n\n /**\n * Import untracked tokens that have non-zero balances.\n * This mirrors the v2 behavior where only tokens with actual balances are added.\n * Delegates to TokenDetectionController:addDetectedTokensViaPolling which handles:\n * - Checking if useTokenDetection preference is enabled\n * - Filtering tokens already in allTokens or allIgnoredTokens\n * - Token metadata lookup and addition via TokensController\n *\n * @param balances - Array of processed balance results from fetchers\n */\n async #importUntrackedTokens(balances: ProcessedBalance[]): Promise<void> {\n const tokensByChain = new Map<ChainIdHex, string[]>();\n\n for (const balance of balances) {\n // Skip failed fetches, native tokens, and zero balances (like v2 did)\n if (\n !balance.success ||\n balance.token === ZERO_ADDRESS ||\n !balance.value ||\n balance.value.isZero()\n ) {\n continue;\n }\n\n const tokenAddress = checksum(balance.token);\n const existing = tokensByChain.get(balance.chainId) ?? [];\n if (!existing.includes(tokenAddress)) {\n existing.push(tokenAddress);\n tokensByChain.set(balance.chainId, existing);\n }\n }\n\n // Add detected tokens via TokenDetectionController (handles preference check,\n // filtering of allTokens/allIgnoredTokens, and metadata lookup)\n for (const [chainId, tokenAddresses] of tokensByChain) {\n if (tokenAddresses.length) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaPolling',\n {\n tokensSlice: tokenAddresses,\n chainId,\n },\n );\n }\n }\n }\n\n resetState(): void {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n #isTokenTracked(\n tokenAddress: string,\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): boolean {\n const normalizedAccount = account.toLowerCase();\n\n if (\n this.#allTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token.address === tokenAddress,\n )\n ) {\n return true;\n }\n\n if (\n this.#allIgnoredTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token === tokenAddress,\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n readonly #onTokensChanged = async (\n state: TokensControllerState,\n ): Promise<void> => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n const relevantChainIds = Array.from(incomingChainIds).filter((chainId) => {\n const id = chainId as ChainIdHex;\n\n const hasTokensNow =\n (state.allTokens[id] && Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] && Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (!relevantChainIds.length) {\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n this.update((currentState) => {\n for (const chainId of relevantChainIds) {\n const id = chainId as ChainIdHex;\n const hasTokensNow =\n (state.allTokens[id] &&\n Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] &&\n Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const tokensChanged =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n if (!tokensChanged) {\n continue;\n }\n\n if (hasTokensNow) {\n changed.push(id);\n } else if (hadTokensBefore) {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (currentState.tokenBalances[addressKey]?.[id]) {\n currentState.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n this.#allIgnoredTokens = state.allIgnoredTokens;\n\n if (changed.length && !hasChanges) {\n this.updateBalances({ chainIds: changed }).catch((error) => {\n console.warn('Error updating balances after token change:', error);\n });\n }\n };\n\n readonly #onNetworkChanged = (state: NetworkState): void => {\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n const networksWithBalances = new Set<string>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const network of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n networksWithBalances.add(network);\n }\n }\n\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (!removedNetworks.length) {\n return;\n }\n\n this.update((currentState) => {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (currentState.tokenBalances[addressKey]?.[networkKey]) {\n delete currentState.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n };\n\n readonly #onAccountRemoved = (addr: string): void => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((currentState) => {\n delete currentState.tokenBalances[addr];\n });\n };\n\n readonly #onAccountChanged = (): void => {\n const chainIds = this.#chainIdsWithTokens();\n if (!chainIds.length) {\n return;\n }\n\n this.updateBalances({ chainIds }).catch(() => {\n // Silently handle polling errors\n });\n };\n\n #prepareBalanceUpdates(\n updates: BalanceUpdate[],\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): {\n tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[];\n newTokens: string[];\n nativeBalanceUpdates: NativeBalanceUpdate[];\n } {\n const tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[] = [];\n const newTokens: string[] = [];\n const nativeBalanceUpdates: NativeBalanceUpdate[] = [];\n\n for (const update of updates) {\n const { asset, postBalance } = update;\n\n if (postBalance.error) {\n throw new Error('Balance update has error');\n }\n\n const parsed = parseAssetType(asset.type);\n if (!parsed) {\n throw new Error('Failed to parse asset type');\n }\n\n const [tokenAddress, isNativeToken] = parsed;\n\n if (\n !isStrictHexString(tokenAddress) ||\n !isValidHexAddress(tokenAddress)\n ) {\n throw new Error('Invalid token address');\n }\n\n const checksumTokenAddress = checksum(tokenAddress);\n const isTracked = this.#isTokenTracked(\n checksumTokenAddress,\n account,\n chainId,\n );\n\n const balanceHex = postBalance.amount as Hex;\n\n tokenBalances.push({\n tokenAddress: checksumTokenAddress,\n balance: balanceHex,\n });\n\n if (isNativeToken) {\n nativeBalanceUpdates.push({\n address: account,\n chainId,\n balance: balanceHex,\n });\n }\n\n if (!isNativeToken && !isTracked) {\n newTokens.push(checksumTokenAddress);\n }\n }\n\n return { tokenBalances, newTokens, nativeBalanceUpdates };\n }\n\n readonly #onAccountActivityBalanceUpdate = async ({\n address,\n chain,\n updates,\n }: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }): Promise<void> => {\n const chainId = caipChainIdToHex(chain);\n const checksummedAccount = checksum(address);\n\n try {\n const { tokenBalances, newTokens, nativeBalanceUpdates } =\n this.#prepareBalanceUpdates(updates, checksummedAccount, chainId);\n\n if (tokenBalances.length > 0) {\n this.update((state) => {\n const lowercaseAccount =\n checksummedAccount.toLowerCase() as ChecksumAddress;\n state.tokenBalances[lowercaseAccount] ??= {};\n state.tokenBalances[lowercaseAccount][chainId] ??= {};\n\n for (const { tokenAddress, balance } of tokenBalances) {\n state.tokenBalances[lowercaseAccount][chainId][tokenAddress] =\n balance;\n }\n });\n }\n\n if (nativeBalanceUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeBalanceUpdates,\n );\n }\n\n if (newTokens.length > 0) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaWs',\n {\n tokensSlice: newTokens,\n chainId,\n },\n );\n }\n } catch (error) {\n console.warn(\n `Error updating balances from AccountActivityService for chain ${chain}, account ${address}:`,\n error,\n );\n console.warn('Balance update data:', JSON.stringify(updates, null, 2));\n\n await this.updateBalances({ chainIds: [chainId] }).catch(() => {\n // Silently handle polling errors\n });\n }\n };\n\n readonly #onAccountActivityStatusChanged = ({\n chainIds,\n status,\n }: {\n chainIds: string[];\n status: 'up' | 'down';\n }): void => {\n for (const chainId of chainIds) {\n this.#statusChangeDebouncer.pendingChanges.set(chainId, status);\n }\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n }\n\n this.#statusChangeDebouncer.timer = setTimeout(() => {\n this.#processAccumulatedStatusChanges();\n }, 5000);\n };\n\n #processAccumulatedStatusChanges(): void {\n const changes = Array.from(\n this.#statusChangeDebouncer.pendingChanges.entries(),\n );\n this.#statusChangeDebouncer.pendingChanges.clear();\n this.#statusChangeDebouncer.timer = null;\n\n if (!changes.length) {\n return;\n }\n\n const chainConfigs: Record<ChainIdHex, { interval: number }> = {};\n\n for (const [chainId, status] of changes) {\n const hexChainId = caipChainIdToHex(chainId);\n\n chainConfigs[hexChainId] =\n status === 'down'\n ? { interval: this.#defaultInterval }\n : { interval: this.#websocketActivePollingInterval };\n }\n\n const jitterDelay = Math.random() * this.#defaultInterval;\n\n setTimeout(() => {\n this.updateChainPollingConfigs(chainConfigs, { immediateUpdate: true });\n }, jitterDelay);\n }\n\n override destroy(): void {\n this.#isControllerPollingActive = false;\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n this.#statusChangeDebouncer.timer = null;\n }\n\n this.messenger.unregisterActionHandler(\n `TokenBalancesController:updateChainPollingConfigs`,\n );\n this.messenger.unregisterActionHandler(\n `TokenBalancesController:getChainPollingConfig`,\n );\n\n super.destroy();\n }\n}\n\nexport default TokenBalancesController;\n"]}
|
|
@@ -217,6 +217,10 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
217
217
|
if (!__classPrivateFieldGet(this, _TokenDetectionController_useExternalServices, "f").call(this)) {
|
|
218
218
|
return;
|
|
219
219
|
}
|
|
220
|
+
// Refresh the token cache to ensure we have the latest token metadata
|
|
221
|
+
// This fixes a bug where the cache from construction time could be stale/empty
|
|
222
|
+
const { tokensChainsCache } = this.messenger.call('TokenListController:getState');
|
|
223
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache ?? {}, "f");
|
|
220
224
|
const tokensWithBalance = [];
|
|
221
225
|
const eventTokensDetails = [];
|
|
222
226
|
for (const tokenAddress of tokensSlice) {
|
|
@@ -280,6 +284,10 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
280
284
|
if (!__classPrivateFieldGet(this, _TokenDetectionController_useExternalServices, "f").call(this)) {
|
|
281
285
|
return;
|
|
282
286
|
}
|
|
287
|
+
// Refresh the token cache to ensure we have the latest token metadata
|
|
288
|
+
// This fixes a bug where the cache from construction time could be stale/empty
|
|
289
|
+
const { tokensChainsCache } = this.messenger.call('TokenListController:getState');
|
|
290
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache ?? {}, "f");
|
|
283
291
|
const selectedAddress = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSelectedAddress).call(this);
|
|
284
292
|
// Get current token states to filter out already tracked/ignored tokens
|
|
285
293
|
const { allTokens, allIgnoredTokens } = this.messenger.call('TokensController:getState');
|