@metamask/assets-controllers 100.0.3 → 100.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -1
- package/dist/AccountTrackerController.cjs +25 -4
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts +5 -2
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts +5 -2
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +26 -5
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/MultichainAssetsRatesController/index.cjs +3 -1
- package/dist/MultichainAssetsRatesController/index.cjs.map +1 -1
- package/dist/MultichainAssetsRatesController/index.d.cts +1 -0
- package/dist/MultichainAssetsRatesController/index.d.cts.map +1 -1
- package/dist/MultichainAssetsRatesController/index.d.mts +1 -0
- package/dist/MultichainAssetsRatesController/index.d.mts.map +1 -1
- package/dist/MultichainAssetsRatesController/index.mjs +1 -0
- package/dist/MultichainAssetsRatesController/index.mjs.map +1 -1
- package/dist/NftController.cjs +198 -150
- package/dist/NftController.cjs.map +1 -1
- package/dist/NftController.d.cts.map +1 -1
- package/dist/NftController.d.mts.map +1 -1
- package/dist/NftController.mjs +198 -150
- package/dist/NftController.mjs.map +1 -1
- package/dist/TokenBalancesController.cjs +51 -12
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts +1 -1
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts +1 -1
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +51 -12
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/TokenDetectionController.cjs +0 -2
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts +1 -1
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts +1 -1
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +0 -2
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/dist/TokenListController.cjs +38 -5
- package/dist/TokenListController.cjs.map +1 -1
- package/dist/TokenListController.d.cts.map +1 -1
- package/dist/TokenListController.d.mts.map +1 -1
- package/dist/TokenListController.mjs +38 -5
- package/dist/TokenListController.mjs.map +1 -1
- package/dist/balances.cjs +46 -12
- package/dist/balances.cjs.map +1 -1
- package/dist/balances.d.cts +14 -3
- package/dist/balances.d.cts.map +1 -1
- package/dist/balances.d.mts +14 -3
- package/dist/balances.d.mts.map +1 -1
- package/dist/balances.mjs +46 -12
- package/dist/balances.mjs.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs +37 -11
- package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs.map +1 -1
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.cts +10 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.cts.map +1 -1
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.mts +10 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.mts.map +1 -1
- package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs +37 -11
- package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.cjs +99 -58
- package/dist/rpc-service/rpc-balance-fetcher.cjs.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.d.cts +4 -1
- package/dist/rpc-service/rpc-balance-fetcher.d.cts.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.d.mts +4 -1
- package/dist/rpc-service/rpc-balance-fetcher.d.mts.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.mjs +99 -58
- package/dist/rpc-service/rpc-balance-fetcher.mjs.map +1 -1
- package/dist/token-service.cjs +76 -3
- package/dist/token-service.cjs.map +1 -1
- package/dist/token-service.d.cts +102 -2
- package/dist/token-service.d.cts.map +1 -1
- package/dist/token-service.d.mts +102 -2
- package/dist/token-service.d.mts.map +1 -1
- package/dist/token-service.mjs +74 -2
- package/dist/token-service.mjs.map +1 -1
- package/package.json +8 -8
|
@@ -290,11 +290,17 @@ export class TokenBalancesController extends StaticIntervalPollingController() {
|
|
|
290
290
|
__classPrivateFieldSet(this, _TokenBalancesController_chainPollingConfig, { ...chainPollingIntervals }, "f");
|
|
291
291
|
// Always include AccountsApiFetcher - it dynamically checks allowExternalServices() in supports()
|
|
292
292
|
__classPrivateFieldSet(this, _TokenBalancesController_balanceFetchers, [
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
293
|
+
{
|
|
294
|
+
fetcher: __classPrivateFieldGet(this, _TokenBalancesController_createAccountsApiFetcher, "f").call(this),
|
|
295
|
+
name: 'AccountsApiFetcher',
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
fetcher: new RpcBalanceFetcher(__classPrivateFieldGet(this, _TokenBalancesController_getProvider, "f"), __classPrivateFieldGet(this, _TokenBalancesController_getNetworkClient, "f"), () => ({
|
|
299
|
+
allTokens: __classPrivateFieldGet(this, _TokenBalancesController_allTokens, "f"),
|
|
300
|
+
allDetectedTokens: __classPrivateFieldGet(this, _TokenBalancesController_detectedTokens, "f"),
|
|
301
|
+
})),
|
|
302
|
+
name: 'RpcFetcher',
|
|
303
|
+
},
|
|
298
304
|
], "f");
|
|
299
305
|
this.setIntervalLength(interval);
|
|
300
306
|
const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messenger.call('TokensController:getState');
|
|
@@ -534,7 +540,9 @@ _TokenBalancesController_platform = new WeakMap(), _TokenBalancesController_quer
|
|
|
534
540
|
}, _TokenBalancesController_fetchAllBalances = async function _TokenBalancesController_fetchAllBalances({ targetChains, selectedAccount, allAccounts, jwtToken, queryAllAccounts, }) {
|
|
535
541
|
const aggregated = [];
|
|
536
542
|
let remainingChains = [...targetChains];
|
|
537
|
-
|
|
543
|
+
let previousUnprocessedTokens;
|
|
544
|
+
let previousFetcherName;
|
|
545
|
+
for (const { fetcher, name: fetcherName } of __classPrivateFieldGet(this, _TokenBalancesController_balanceFetchers, "f")) {
|
|
538
546
|
const supportedChains = remainingChains.filter((chain) => fetcher.supports(chain));
|
|
539
547
|
if (!supportedChains.length) {
|
|
540
548
|
continue;
|
|
@@ -546,26 +554,57 @@ _TokenBalancesController_platform = new WeakMap(), _TokenBalancesController_quer
|
|
|
546
554
|
selectedAccount,
|
|
547
555
|
allAccounts,
|
|
548
556
|
jwtToken,
|
|
557
|
+
unprocessedTokens: previousUnprocessedTokens,
|
|
549
558
|
});
|
|
559
|
+
// Add balances, and removed processed chains
|
|
550
560
|
if (result.balances?.length) {
|
|
551
561
|
aggregated.push(...result.balances);
|
|
552
562
|
const processed = new Set(result.balances.map((b) => b.chainId));
|
|
553
563
|
remainingChains = remainingChains.filter((chain) => !processed.has(chain));
|
|
554
564
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
565
|
+
// Add unprocessed chains (from missing chains or missing tokens)
|
|
566
|
+
if (result.unprocessedChainIds || result.unprocessedTokens) {
|
|
567
|
+
const resultUnprocessedChains = result.unprocessedChainIds ?? [];
|
|
568
|
+
const resultUnsupportedTokenChains = Object.entries(result.unprocessedTokens ?? {}).flatMap(([_account, chainMap]) => Object.keys(chainMap));
|
|
569
|
+
const unprocessedChainIds = Array.from(new Set([
|
|
570
|
+
...resultUnprocessedChains,
|
|
571
|
+
...resultUnsupportedTokenChains,
|
|
572
|
+
]));
|
|
573
|
+
remainingChains = Array.from(new Set([...remainingChains, ...unprocessedChainIds]));
|
|
560
574
|
this.messenger
|
|
561
575
|
.call('TokenDetectionController:detectTokens', {
|
|
562
|
-
chainIds:
|
|
576
|
+
chainIds: unprocessedChainIds,
|
|
563
577
|
forceRpc: true,
|
|
564
578
|
})
|
|
565
579
|
.catch(() => {
|
|
566
580
|
// Silently handle token detection errors
|
|
567
581
|
});
|
|
568
582
|
}
|
|
583
|
+
// Balance Error Reporting - for unprocessed tokens from last fetcher, if balances are retrieved
|
|
584
|
+
const unprocessedTokensForReporting = previousUnprocessedTokens;
|
|
585
|
+
if (unprocessedTokensForReporting && result.balances?.length) {
|
|
586
|
+
const confirmedUnprocessedTokens = [];
|
|
587
|
+
// Capture balances that were found (> 0 balance), and was unprocessed
|
|
588
|
+
result.balances.forEach((bal) => {
|
|
589
|
+
const lowercaseAccount = bal.account.toLowerCase();
|
|
590
|
+
const lowercaseTokenAddress = bal.token.toLowerCase();
|
|
591
|
+
const hasResultBalance = bal.success && bal.token && bal.value && !bal.value.isZero();
|
|
592
|
+
const isUnprocessed = unprocessedTokensForReporting?.[lowercaseAccount]?.[bal.chainId]?.includes(lowercaseTokenAddress);
|
|
593
|
+
if (hasResultBalance && isUnprocessed) {
|
|
594
|
+
confirmedUnprocessedTokens.push({
|
|
595
|
+
chainId: bal.chainId,
|
|
596
|
+
tokenAddress: lowercaseTokenAddress,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
const confirmedUnprocessedTokenStrings = confirmedUnprocessedTokens.map((token) => `${token.chainId}:${token.tokenAddress}`);
|
|
601
|
+
if (confirmedUnprocessedTokens.length) {
|
|
602
|
+
console.warn(`TokenBalanceController: fetcher ${previousFetcherName} did not process tokens (instead handled by fetcher ${fetcherName}): ${confirmedUnprocessedTokenStrings.join(', ')}`);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// Set new previous fields
|
|
606
|
+
previousUnprocessedTokens = result.unprocessedTokens;
|
|
607
|
+
previousFetcherName = fetcherName;
|
|
569
608
|
}
|
|
570
609
|
catch (error) {
|
|
571
610
|
console.warn(`Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`);
|
|
@@ -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 /** Whether the user has completed onboarding. If false, balance updates are skipped. */\n isOnboarded?: () => boolean;\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 #isOnboarded: () => 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 isOnboarded = (): boolean => true,\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.#isOnboarded = isOnboarded;\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 and user is onboarded).\n * When locked or not onboarded, balance updates should be skipped.\n *\n * @returns Whether the controller should perform balance updates.\n */\n get isActive(): boolean {\n return this.#isUnlocked && this.#isOnboarded();\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 () => this.state.tokenBalances, // list of existing user tokens\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?.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 UnprocessedTokens,\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.AuthenticationControllerGetBearerTokenAction;\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 /** Whether the user has completed onboarding. If false, balance updates are skipped. */\n isOnboarded?: () => boolean;\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 #isOnboarded: () => boolean;\n\n readonly #balanceFetchers: { fetcher: BalanceFetcher; name: string }[];\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 isOnboarded = (): boolean => true,\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.#isOnboarded = isOnboarded;\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 {\n fetcher: this.#createAccountsApiFetcher(),\n name: 'AccountsApiFetcher',\n },\n {\n fetcher: new RpcBalanceFetcher(\n this.#getProvider,\n this.#getNetworkClient,\n () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n }),\n ),\n name: 'RpcFetcher',\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 and user is onboarded).\n * When locked or not onboarded, balance updates should be skipped.\n *\n * @returns Whether the controller should perform balance updates.\n */\n get isActive(): boolean {\n return this.#isUnlocked && this.#isOnboarded();\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 () => this.state.tokenBalances, // list of existing user tokens\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 let previousUnprocessedTokens: UnprocessedTokens | undefined;\n let previousFetcherName: string | undefined;\n\n for (const { fetcher, name: fetcherName } 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 unprocessedTokens: previousUnprocessedTokens,\n });\n\n // Add balances, and removed processed chains\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 // Add unprocessed chains (from missing chains or missing tokens)\n if (result.unprocessedChainIds || result.unprocessedTokens) {\n const resultUnprocessedChains = result.unprocessedChainIds ?? [];\n const resultUnsupportedTokenChains = Object.entries(\n result.unprocessedTokens ?? {},\n ).flatMap(([_account, chainMap]) => Object.keys(chainMap)) as Hex[];\n const unprocessedChainIds = Array.from(\n new Set([\n ...resultUnprocessedChains,\n ...resultUnsupportedTokenChains,\n ]),\n );\n\n remainingChains = Array.from(\n new Set([...remainingChains, ...unprocessedChainIds]),\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: unprocessedChainIds,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n // Balance Error Reporting - for unprocessed tokens from last fetcher, if balances are retrieved\n const unprocessedTokensForReporting = previousUnprocessedTokens;\n if (unprocessedTokensForReporting && result.balances?.length) {\n const confirmedUnprocessedTokens: {\n chainId: string;\n tokenAddress: string;\n }[] = [];\n\n // Capture balances that were found (> 0 balance), and was unprocessed\n result.balances.forEach((bal) => {\n const lowercaseAccount = bal.account.toLowerCase();\n const lowercaseTokenAddress = bal.token.toLowerCase();\n\n const hasResultBalance =\n bal.success && bal.token && bal.value && !bal.value.isZero();\n const isUnprocessed = unprocessedTokensForReporting?.[\n lowercaseAccount\n ]?.[bal.chainId]?.includes(lowercaseTokenAddress);\n\n if (hasResultBalance && isUnprocessed) {\n confirmedUnprocessedTokens.push({\n chainId: bal.chainId,\n tokenAddress: lowercaseTokenAddress,\n });\n }\n });\n\n const confirmedUnprocessedTokenStrings =\n confirmedUnprocessedTokens.map(\n (token) => `${token.chainId}:${token.tokenAddress}`,\n );\n if (confirmedUnprocessedTokens.length) {\n console.warn(\n `TokenBalanceController: fetcher ${previousFetcherName} did not process tokens (instead handled by fetcher ${fetcherName}): ${confirmedUnprocessedTokenStrings.join(', ')}`,\n );\n }\n }\n\n // Set new previous fields\n previousUnprocessedTokens = result.unprocessedTokens;\n previousFetcherName = fetcherName;\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?.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"]}
|
|
@@ -230,7 +230,6 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
230
230
|
// Check map of validated tokens (cache keys are lowercase)
|
|
231
231
|
const tokenData = __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId]?.data?.[lowercaseTokenAddress];
|
|
232
232
|
if (!tokenData) {
|
|
233
|
-
console.warn(`Token metadata not found in cache for ${tokenAddress} on chain ${chainId}`);
|
|
234
233
|
continue;
|
|
235
234
|
}
|
|
236
235
|
const { decimals, symbol, aggregators, iconUrl, name, rwaData } = tokenData;
|
|
@@ -310,7 +309,6 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
310
309
|
// Check map of validated tokens (cache keys are lowercase)
|
|
311
310
|
const tokenData = __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f")[chainId]?.data?.[lowercaseTokenAddress];
|
|
312
311
|
if (!tokenData) {
|
|
313
|
-
console.warn(`Token metadata not found in cache for ${tokenAddress} on chain ${chainId}`);
|
|
314
312
|
continue;
|
|
315
313
|
}
|
|
316
314
|
const { decimals, symbol, aggregators, iconUrl, name, rwaData } = tokenData;
|