@metamask/assets-controllers 74.3.0 → 74.3.2
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 +19 -1
- package/dist/AccountTrackerController.cjs +57 -144
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts +2 -2
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts +2 -2
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +58 -147
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/TokenBalancesController.cjs +1 -1
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +2 -2
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/multicall.cjs +4 -5
- package/dist/multicall.cjs.map +1 -1
- package/dist/multicall.d.cts.map +1 -1
- package/dist/multicall.d.mts.map +1 -1
- package/dist/multicall.mjs +4 -5
- package/dist/multicall.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenBalancesController.cjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n isValidHexAddress,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type { KeyringControllerAccountRemovedEvent } from '@metamask/keyring-controller';\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 { Hex } from '@metamask/utils';\nimport { isStrictHexString } from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type {\n AccountTrackerUpdateNativeBalancesAction,\n AccountTrackerUpdateStakedBalancesAction,\n} from './AccountTrackerController';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport {\n AccountsApiBalanceFetcher,\n type BalanceFetcher,\n type ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\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 = 180_000; // 3 minutes\n\nconst metadata = {\n tokenBalances: { persist: true, anonymous: false },\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 TokenBalancesControllerActions =\n TokenBalancesControllerGetStateAction;\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 | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerUpdateNativeBalancesAction\n | AccountTrackerUpdateStakedBalancesAction;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent;\n\nexport type TokenBalancesControllerMessenger = RestrictedMessenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n interval?: number;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Enable Accounts‑API strategy (if supported chain). */\n useAccountsAPI?: boolean;\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n};\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Helper utilities\nconst draft = <T>(base: T, fn: (d: T) => void): T => produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Main controller\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #queryAllAccounts: boolean;\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n state = {},\n queryMultipleAccounts = true,\n useAccountsAPI = false,\n allowExternalServices = () => true,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#queryAllAccounts = queryMultipleAccounts;\n\n // Strategy order: API first, then RPC fallback\n this.#balanceFetchers = [\n ...(useAccountsAPI && allowExternalServices()\n ? [new AccountsApiBalanceFetcher('extension', this.#getProvider)]\n : []),\n new RpcBalanceFetcher(this.#getProvider, this.#getNetworkClient, () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n })),\n ];\n\n this.setIntervalLength(interval);\n\n // initial token state & subscriptions\n const { allTokens, allDetectedTokens } = this.messagingSystem.call(\n 'TokensController:getState',\n );\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n\n this.messagingSystem.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 this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n this.messagingSystem.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\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.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n const client = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (chainId: ChainIdHex) => {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n return this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n async _executePoll({ chainIds }: { chainIds: ChainIdHex[] }) {\n await this.updateBalances({ chainIds });\n }\n\n async updateBalances({ chainIds }: { chainIds?: ChainIdHex[] } = {}) {\n const targetChains = chainIds ?? this.#chainIdsWithTokens();\n if (!targetChains.length) {\n return;\n }\n\n const { address: selected } = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messagingSystem.call(\n 'AccountsController:listAccounts',\n );\n\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n\n // Try each fetcher in order, removing successfully processed chains\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((c) =>\n fetcher.supports(c),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const balances = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts: this.#queryAllAccounts,\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n });\n\n if (balances && balances.length > 0) {\n aggregated.push(...balances);\n // Remove chains that were successfully processed\n const processedChains = new Set(balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processedChains.has(chain),\n );\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n // Continue to next fetcher (fallback)\n }\n\n // If all chains have been processed, break early\n if (remainingChains.length === 0) {\n break;\n }\n }\n\n // Determine which accounts to process\n const accountsToProcess = this.#queryAllAccounts\n ? allAccounts.map((a) => a.address as ChecksumAddress)\n : [selected as ChecksumAddress];\n\n const prev = this.state;\n const next = draft(prev, (d) => {\n // First, initialize all tokens from allTokens state with balance 0\n // for the accounts and chains we're processing\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n // Initialize tokens from allTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n\n // Initialize tokens from allDetectedTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n }\n }\n\n // Then update with actual fetched balances where available\n aggregated.forEach(({ success, value, account, token, chainId }) => {\n if (success && value !== undefined) {\n ((d.tokenBalances[account] ??= {})[chainId] ??= {})[checksum(token)] =\n toHex(value);\n }\n });\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const nativeBalances = aggregated.filter(\n (r) => r.success && r.token === ZERO_ADDRESS,\n );\n\n // Update native token balances in a single batch operation for better performance\n if (nativeBalances.length > 0) {\n const balanceUpdates = nativeBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value?.toString() ?? '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateNativeBalances',\n balanceUpdates,\n );\n }\n\n // Get staking contract addresses for filtering\n const stakingContractAddresses = Object.values(\n STAKING_CONTRACT_ADDRESS_BY_CHAINID,\n ).map((addr) => addr.toLowerCase());\n\n // Filter and update staked balances in a single batch operation for better performance\n const stakedBalances = aggregated.filter((r) => {\n return (\n r.success &&\n r.token !== ZERO_ADDRESS &&\n stakingContractAddresses.includes(r.token.toLowerCase())\n );\n });\n\n if (stakedBalances.length > 0) {\n const stakedBalanceUpdates = stakedBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedBalanceUpdates,\n );\n }\n }\n }\n\n resetState() {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n readonly #onTokensChanged = async (state: TokensControllerState) => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n // Get chains that have existing balances\n const chainsWithBalances = new Set<ChainIdHex>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const chainId of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n chainsWithBalances.add(chainId as ChainIdHex);\n }\n }\n\n // Only process chains that are explicitly mentioned in the incoming state change\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n // Only proceed if there are actual changes to chains that have balances or are being added\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 // Check if there's an actual change in token state\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n // Process chains that have actual changes OR are new chains getting tokens\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (relevantChainIds.length === 0) {\n // No relevant changes, just update internal state\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n // Handle both cleanup and updates in a single state update\n this.update((s) => {\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 if (\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id])\n ) {\n if (hasTokensNow) {\n // Chain still has tokens - mark for async balance update\n changed.push(id);\n } else if (hadTokensBefore) {\n // Chain had tokens before but doesn't now - clean up balances immediately\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (s.tokenBalances[addressKey]?.[id]) {\n s.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n\n // Only update balances for chains that still have tokens (and only if we haven't already updated state)\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) => {\n // Check if any networks were removed by comparing with previous state\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n // Get all networks that currently have balances\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 // Find networks that were removed\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (removedNetworks.length > 0) {\n this.update((s) => {\n // Remove balances for all accounts on the deleted networks\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (s.tokenBalances[addressKey]?.[networkKey]) {\n delete s.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n }\n };\n\n readonly #onAccountRemoved = (addr: string) => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((s) => {\n delete s.tokenBalances[addr as ChecksumAddress];\n });\n };\n}\n\nexport default TokenBalancesController;\n"]}
|
|
1
|
+
{"version":3,"file":"TokenBalancesController.cjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n BNToHex,\n isValidHexAddress,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type { KeyringControllerAccountRemovedEvent } from '@metamask/keyring-controller';\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 { Hex } from '@metamask/utils';\nimport { isStrictHexString } from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type {\n AccountTrackerUpdateNativeBalancesAction,\n AccountTrackerUpdateStakedBalancesAction,\n} from './AccountTrackerController';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport {\n AccountsApiBalanceFetcher,\n type BalanceFetcher,\n type ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\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 = 180_000; // 3 minutes\n\nconst metadata = {\n tokenBalances: { persist: true, anonymous: false },\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 TokenBalancesControllerActions =\n TokenBalancesControllerGetStateAction;\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 | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerUpdateNativeBalancesAction\n | AccountTrackerUpdateStakedBalancesAction;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent;\n\nexport type TokenBalancesControllerMessenger = RestrictedMessenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n interval?: number;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Enable Accounts‑API strategy (if supported chain). */\n useAccountsAPI?: boolean;\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n};\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Helper utilities\nconst draft = <T>(base: T, fn: (d: T) => void): T => produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Main controller\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #queryAllAccounts: boolean;\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n state = {},\n queryMultipleAccounts = true,\n useAccountsAPI = false,\n allowExternalServices = () => true,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#queryAllAccounts = queryMultipleAccounts;\n\n // Strategy order: API first, then RPC fallback\n this.#balanceFetchers = [\n ...(useAccountsAPI && allowExternalServices()\n ? [new AccountsApiBalanceFetcher('extension', this.#getProvider)]\n : []),\n new RpcBalanceFetcher(this.#getProvider, this.#getNetworkClient, () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n })),\n ];\n\n this.setIntervalLength(interval);\n\n // initial token state & subscriptions\n const { allTokens, allDetectedTokens } = this.messagingSystem.call(\n 'TokensController:getState',\n );\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n\n this.messagingSystem.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 this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n this.messagingSystem.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\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.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n const client = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (chainId: ChainIdHex) => {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n return this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n async _executePoll({ chainIds }: { chainIds: ChainIdHex[] }) {\n await this.updateBalances({ chainIds });\n }\n\n async updateBalances({ chainIds }: { chainIds?: ChainIdHex[] } = {}) {\n const targetChains = chainIds ?? this.#chainIdsWithTokens();\n if (!targetChains.length) {\n return;\n }\n\n const { address: selected } = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messagingSystem.call(\n 'AccountsController:listAccounts',\n );\n\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n\n // Try each fetcher in order, removing successfully processed chains\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((c) =>\n fetcher.supports(c),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const balances = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts: this.#queryAllAccounts,\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n });\n\n if (balances && balances.length > 0) {\n aggregated.push(...balances);\n // Remove chains that were successfully processed\n const processedChains = new Set(balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processedChains.has(chain),\n );\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n // Continue to next fetcher (fallback)\n }\n\n // If all chains have been processed, break early\n if (remainingChains.length === 0) {\n break;\n }\n }\n\n // Determine which accounts to process\n const accountsToProcess = this.#queryAllAccounts\n ? allAccounts.map((a) => a.address as ChecksumAddress)\n : [selected as ChecksumAddress];\n\n const prev = this.state;\n const next = draft(prev, (d) => {\n // First, initialize all tokens from allTokens state with balance 0\n // for the accounts and chains we're processing\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n // Initialize tokens from allTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n\n // Initialize tokens from allDetectedTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n }\n }\n\n // Then update with actual fetched balances where available\n aggregated.forEach(({ success, value, account, token, chainId }) => {\n if (success && value !== undefined) {\n ((d.tokenBalances[account] ??= {})[chainId] ??= {})[checksum(token)] =\n toHex(value);\n }\n });\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const nativeBalances = aggregated.filter(\n (r) => r.success && r.token === ZERO_ADDRESS,\n );\n\n // Update native token balances in a single batch operation for better performance\n if (nativeBalances.length > 0) {\n const balanceUpdates = nativeBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value ? BNToHex(balance.value) : '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateNativeBalances',\n balanceUpdates,\n );\n }\n\n // Get staking contract addresses for filtering\n const stakingContractAddresses = Object.values(\n STAKING_CONTRACT_ADDRESS_BY_CHAINID,\n ).map((addr) => addr.toLowerCase());\n\n // Filter and update staked balances in a single batch operation for better performance\n const stakedBalances = aggregated.filter((r) => {\n return (\n r.success &&\n r.token !== ZERO_ADDRESS &&\n stakingContractAddresses.includes(r.token.toLowerCase())\n );\n });\n\n if (stakedBalances.length > 0) {\n const stakedBalanceUpdates = stakedBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedBalanceUpdates,\n );\n }\n }\n }\n\n resetState() {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n readonly #onTokensChanged = async (state: TokensControllerState) => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n // Get chains that have existing balances\n const chainsWithBalances = new Set<ChainIdHex>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const chainId of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n chainsWithBalances.add(chainId as ChainIdHex);\n }\n }\n\n // Only process chains that are explicitly mentioned in the incoming state change\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n // Only proceed if there are actual changes to chains that have balances or are being added\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 // Check if there's an actual change in token state\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n // Process chains that have actual changes OR are new chains getting tokens\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (relevantChainIds.length === 0) {\n // No relevant changes, just update internal state\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n // Handle both cleanup and updates in a single state update\n this.update((s) => {\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 if (\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id])\n ) {\n if (hasTokensNow) {\n // Chain still has tokens - mark for async balance update\n changed.push(id);\n } else if (hadTokensBefore) {\n // Chain had tokens before but doesn't now - clean up balances immediately\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (s.tokenBalances[addressKey]?.[id]) {\n s.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n\n // Only update balances for chains that still have tokens (and only if we haven't already updated state)\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) => {\n // Check if any networks were removed by comparing with previous state\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n // Get all networks that currently have balances\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 // Find networks that were removed\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (removedNetworks.length > 0) {\n this.update((s) => {\n // Remove balances for all accounts on the deleted networks\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (s.tokenBalances[addressKey]?.[networkKey]) {\n delete s.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n }\n };\n\n readonly #onAccountRemoved = (addr: string) => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((s) => {\n delete s.tokenBalances[addr as ChecksumAddress];\n });\n };\n}\n\nexport default TokenBalancesController;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenBalancesController.d.cts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0CAA0C,EAC1C,oCAAoC,EACrC,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;
|
|
1
|
+
{"version":3,"file":"TokenBalancesController.d.cts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenBalancesController.d.mts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0CAA0C,EAC1C,oCAAoC,EACrC,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACpB,kCAAkC;
|
|
1
|
+
{"version":3,"file":"TokenBalancesController.d.mts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _TokenBalancesController_instances, _TokenBalancesController_queryAllAccounts, _TokenBalancesController_balanceFetchers, _TokenBalancesController_allTokens, _TokenBalancesController_detectedTokens, _TokenBalancesController_chainIdsWithTokens, _TokenBalancesController_getProvider, _TokenBalancesController_getNetworkClient, _TokenBalancesController_onTokensChanged, _TokenBalancesController_onNetworkChanged, _TokenBalancesController_onAccountRemoved;
|
|
13
13
|
import { Web3Provider } from "@ethersproject/providers";
|
|
14
|
-
import { isValidHexAddress, toChecksumHexAddress, toHex } from "@metamask/controller-utils";
|
|
14
|
+
import { BNToHex, isValidHexAddress, toChecksumHexAddress, toHex } from "@metamask/controller-utils";
|
|
15
15
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
16
16
|
import { isStrictHexString } from "@metamask/utils";
|
|
17
17
|
import { produce } from "immer";
|
|
@@ -285,7 +285,7 @@ export class TokenBalancesController extends StaticIntervalPollingController() {
|
|
|
285
285
|
const balanceUpdates = nativeBalances.map((balance) => ({
|
|
286
286
|
address: balance.account,
|
|
287
287
|
chainId: balance.chainId,
|
|
288
|
-
balance: balance.value
|
|
288
|
+
balance: balance.value ? BNToHex(balance.value) : '0x0',
|
|
289
289
|
}));
|
|
290
290
|
this.messagingSystem.call('AccountTrackerController:updateNativeBalances', balanceUpdates);
|
|
291
291
|
}
|
|
@@ -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} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n isValidHexAddress,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type { KeyringControllerAccountRemovedEvent } from '@metamask/keyring-controller';\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 { Hex } from '@metamask/utils';\nimport { isStrictHexString } from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type {\n AccountTrackerUpdateNativeBalancesAction,\n AccountTrackerUpdateStakedBalancesAction,\n} from './AccountTrackerController';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport {\n AccountsApiBalanceFetcher,\n type BalanceFetcher,\n type ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\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 = 180_000; // 3 minutes\n\nconst metadata = {\n tokenBalances: { persist: true, anonymous: false },\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 TokenBalancesControllerActions =\n TokenBalancesControllerGetStateAction;\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 | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerUpdateNativeBalancesAction\n | AccountTrackerUpdateStakedBalancesAction;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent;\n\nexport type TokenBalancesControllerMessenger = RestrictedMessenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n interval?: number;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Enable Accounts‑API strategy (if supported chain). */\n useAccountsAPI?: boolean;\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n};\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Helper utilities\nconst draft = <T>(base: T, fn: (d: T) => void): T => produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Main controller\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #queryAllAccounts: boolean;\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n state = {},\n queryMultipleAccounts = true,\n useAccountsAPI = false,\n allowExternalServices = () => true,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#queryAllAccounts = queryMultipleAccounts;\n\n // Strategy order: API first, then RPC fallback\n this.#balanceFetchers = [\n ...(useAccountsAPI && allowExternalServices()\n ? [new AccountsApiBalanceFetcher('extension', this.#getProvider)]\n : []),\n new RpcBalanceFetcher(this.#getProvider, this.#getNetworkClient, () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n })),\n ];\n\n this.setIntervalLength(interval);\n\n // initial token state & subscriptions\n const { allTokens, allDetectedTokens } = this.messagingSystem.call(\n 'TokensController:getState',\n );\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n\n this.messagingSystem.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 this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n this.messagingSystem.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\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.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n const client = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (chainId: ChainIdHex) => {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n return this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n async _executePoll({ chainIds }: { chainIds: ChainIdHex[] }) {\n await this.updateBalances({ chainIds });\n }\n\n async updateBalances({ chainIds }: { chainIds?: ChainIdHex[] } = {}) {\n const targetChains = chainIds ?? this.#chainIdsWithTokens();\n if (!targetChains.length) {\n return;\n }\n\n const { address: selected } = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messagingSystem.call(\n 'AccountsController:listAccounts',\n );\n\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n\n // Try each fetcher in order, removing successfully processed chains\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((c) =>\n fetcher.supports(c),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const balances = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts: this.#queryAllAccounts,\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n });\n\n if (balances && balances.length > 0) {\n aggregated.push(...balances);\n // Remove chains that were successfully processed\n const processedChains = new Set(balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processedChains.has(chain),\n );\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n // Continue to next fetcher (fallback)\n }\n\n // If all chains have been processed, break early\n if (remainingChains.length === 0) {\n break;\n }\n }\n\n // Determine which accounts to process\n const accountsToProcess = this.#queryAllAccounts\n ? allAccounts.map((a) => a.address as ChecksumAddress)\n : [selected as ChecksumAddress];\n\n const prev = this.state;\n const next = draft(prev, (d) => {\n // First, initialize all tokens from allTokens state with balance 0\n // for the accounts and chains we're processing\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n // Initialize tokens from allTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n\n // Initialize tokens from allDetectedTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n }\n }\n\n // Then update with actual fetched balances where available\n aggregated.forEach(({ success, value, account, token, chainId }) => {\n if (success && value !== undefined) {\n ((d.tokenBalances[account] ??= {})[chainId] ??= {})[checksum(token)] =\n toHex(value);\n }\n });\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const nativeBalances = aggregated.filter(\n (r) => r.success && r.token === ZERO_ADDRESS,\n );\n\n // Update native token balances in a single batch operation for better performance\n if (nativeBalances.length > 0) {\n const balanceUpdates = nativeBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value?.toString() ?? '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateNativeBalances',\n balanceUpdates,\n );\n }\n\n // Get staking contract addresses for filtering\n const stakingContractAddresses = Object.values(\n STAKING_CONTRACT_ADDRESS_BY_CHAINID,\n ).map((addr) => addr.toLowerCase());\n\n // Filter and update staked balances in a single batch operation for better performance\n const stakedBalances = aggregated.filter((r) => {\n return (\n r.success &&\n r.token !== ZERO_ADDRESS &&\n stakingContractAddresses.includes(r.token.toLowerCase())\n );\n });\n\n if (stakedBalances.length > 0) {\n const stakedBalanceUpdates = stakedBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedBalanceUpdates,\n );\n }\n }\n }\n\n resetState() {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n readonly #onTokensChanged = async (state: TokensControllerState) => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n // Get chains that have existing balances\n const chainsWithBalances = new Set<ChainIdHex>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const chainId of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n chainsWithBalances.add(chainId as ChainIdHex);\n }\n }\n\n // Only process chains that are explicitly mentioned in the incoming state change\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n // Only proceed if there are actual changes to chains that have balances or are being added\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 // Check if there's an actual change in token state\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n // Process chains that have actual changes OR are new chains getting tokens\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (relevantChainIds.length === 0) {\n // No relevant changes, just update internal state\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n // Handle both cleanup and updates in a single state update\n this.update((s) => {\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 if (\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id])\n ) {\n if (hasTokensNow) {\n // Chain still has tokens - mark for async balance update\n changed.push(id);\n } else if (hadTokensBefore) {\n // Chain had tokens before but doesn't now - clean up balances immediately\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (s.tokenBalances[addressKey]?.[id]) {\n s.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n\n // Only update balances for chains that still have tokens (and only if we haven't already updated state)\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) => {\n // Check if any networks were removed by comparing with previous state\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n // Get all networks that currently have balances\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 // Find networks that were removed\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (removedNetworks.length > 0) {\n this.update((s) => {\n // Remove balances for all accounts on the deleted networks\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (s.tokenBalances[addressKey]?.[networkKey]) {\n delete s.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n }\n };\n\n readonly #onAccountRemoved = (addr: string) => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((s) => {\n delete s.tokenBalances[addr as ChecksumAddress];\n });\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} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n BNToHex,\n isValidHexAddress,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type { KeyringControllerAccountRemovedEvent } from '@metamask/keyring-controller';\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 { Hex } from '@metamask/utils';\nimport { isStrictHexString } from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type {\n AccountTrackerUpdateNativeBalancesAction,\n AccountTrackerUpdateStakedBalancesAction,\n} from './AccountTrackerController';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport {\n AccountsApiBalanceFetcher,\n type BalanceFetcher,\n type ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\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 = 180_000; // 3 minutes\n\nconst metadata = {\n tokenBalances: { persist: true, anonymous: false },\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 TokenBalancesControllerActions =\n TokenBalancesControllerGetStateAction;\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 | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerUpdateNativeBalancesAction\n | AccountTrackerUpdateStakedBalancesAction;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent;\n\nexport type TokenBalancesControllerMessenger = RestrictedMessenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n interval?: number;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Enable Accounts‑API strategy (if supported chain). */\n useAccountsAPI?: boolean;\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n};\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Helper utilities\nconst draft = <T>(base: T, fn: (d: T) => void): T => produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n// endregion\n\n// ────────────────────────────────────────────────────────────────────────────\n// region: Main controller\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #queryAllAccounts: boolean;\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n state = {},\n queryMultipleAccounts = true,\n useAccountsAPI = false,\n allowExternalServices = () => true,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#queryAllAccounts = queryMultipleAccounts;\n\n // Strategy order: API first, then RPC fallback\n this.#balanceFetchers = [\n ...(useAccountsAPI && allowExternalServices()\n ? [new AccountsApiBalanceFetcher('extension', this.#getProvider)]\n : []),\n new RpcBalanceFetcher(this.#getProvider, this.#getNetworkClient, () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n })),\n ];\n\n this.setIntervalLength(interval);\n\n // initial token state & subscriptions\n const { allTokens, allDetectedTokens } = this.messagingSystem.call(\n 'TokensController:getState',\n );\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n\n this.messagingSystem.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 this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n this.messagingSystem.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\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.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n const client = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (chainId: ChainIdHex) => {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const cfg = networkConfigurationsByChainId[chainId];\n const { networkClientId } = cfg.rpcEndpoints[cfg.defaultRpcEndpointIndex];\n return this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n async _executePoll({ chainIds }: { chainIds: ChainIdHex[] }) {\n await this.updateBalances({ chainIds });\n }\n\n async updateBalances({ chainIds }: { chainIds?: ChainIdHex[] } = {}) {\n const targetChains = chainIds ?? this.#chainIdsWithTokens();\n if (!targetChains.length) {\n return;\n }\n\n const { address: selected } = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messagingSystem.call(\n 'AccountsController:listAccounts',\n );\n\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n\n // Try each fetcher in order, removing successfully processed chains\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((c) =>\n fetcher.supports(c),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const balances = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts: this.#queryAllAccounts,\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n });\n\n if (balances && balances.length > 0) {\n aggregated.push(...balances);\n // Remove chains that were successfully processed\n const processedChains = new Set(balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processedChains.has(chain),\n );\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n // Continue to next fetcher (fallback)\n }\n\n // If all chains have been processed, break early\n if (remainingChains.length === 0) {\n break;\n }\n }\n\n // Determine which accounts to process\n const accountsToProcess = this.#queryAllAccounts\n ? allAccounts.map((a) => a.address as ChecksumAddress)\n : [selected as ChecksumAddress];\n\n const prev = this.state;\n const next = draft(prev, (d) => {\n // First, initialize all tokens from allTokens state with balance 0\n // for the accounts and chains we're processing\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n // Initialize tokens from allTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n\n // Initialize tokens from allDetectedTokens\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 ((d.tokenBalances[account] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = '0x0';\n },\n );\n }\n }\n }\n\n // Then update with actual fetched balances where available\n aggregated.forEach(({ success, value, account, token, chainId }) => {\n if (success && value !== undefined) {\n ((d.tokenBalances[account] ??= {})[chainId] ??= {})[checksum(token)] =\n toHex(value);\n }\n });\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const nativeBalances = aggregated.filter(\n (r) => r.success && r.token === ZERO_ADDRESS,\n );\n\n // Update native token balances in a single batch operation for better performance\n if (nativeBalances.length > 0) {\n const balanceUpdates = nativeBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value ? BNToHex(balance.value) : '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateNativeBalances',\n balanceUpdates,\n );\n }\n\n // Get staking contract addresses for filtering\n const stakingContractAddresses = Object.values(\n STAKING_CONTRACT_ADDRESS_BY_CHAINID,\n ).map((addr) => addr.toLowerCase());\n\n // Filter and update staked balances in a single batch operation for better performance\n const stakedBalances = aggregated.filter((r) => {\n return (\n r.success &&\n r.token !== ZERO_ADDRESS &&\n stakingContractAddresses.includes(r.token.toLowerCase())\n );\n });\n\n if (stakedBalances.length > 0) {\n const stakedBalanceUpdates = stakedBalances.map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }));\n\n this.messagingSystem.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedBalanceUpdates,\n );\n }\n }\n }\n\n resetState() {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n readonly #onTokensChanged = async (state: TokensControllerState) => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n // Get chains that have existing balances\n const chainsWithBalances = new Set<ChainIdHex>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const chainId of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n chainsWithBalances.add(chainId as ChainIdHex);\n }\n }\n\n // Only process chains that are explicitly mentioned in the incoming state change\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n // Only proceed if there are actual changes to chains that have balances or are being added\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 // Check if there's an actual change in token state\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n // Process chains that have actual changes OR are new chains getting tokens\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (relevantChainIds.length === 0) {\n // No relevant changes, just update internal state\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n // Handle both cleanup and updates in a single state update\n this.update((s) => {\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 if (\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id])\n ) {\n if (hasTokensNow) {\n // Chain still has tokens - mark for async balance update\n changed.push(id);\n } else if (hadTokensBefore) {\n // Chain had tokens before but doesn't now - clean up balances immediately\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (s.tokenBalances[addressKey]?.[id]) {\n s.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n\n // Only update balances for chains that still have tokens (and only if we haven't already updated state)\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) => {\n // Check if any networks were removed by comparing with previous state\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n // Get all networks that currently have balances\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 // Find networks that were removed\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (removedNetworks.length > 0) {\n this.update((s) => {\n // Remove balances for all accounts on the deleted networks\n for (const address of Object.keys(s.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (s.tokenBalances[addressKey]?.[networkKey]) {\n delete s.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n }\n };\n\n readonly #onAccountRemoved = (addr: string) => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((s) => {\n delete s.tokenBalances[addr as ChecksumAddress];\n });\n };\n}\n\nexport default TokenBalancesController;\n"]}
|
package/dist/multicall.cjs
CHANGED
|
@@ -477,14 +477,13 @@ const processBalanceResults = (results, callMapping, chainId, provider, includeS
|
|
|
477
477
|
results.forEach((result, index) => {
|
|
478
478
|
if (result.success) {
|
|
479
479
|
const { tokenAddress, userAddress, callType } = callMapping[index];
|
|
480
|
-
let balance;
|
|
481
480
|
if (callType === 'native') {
|
|
482
481
|
// For native token, decode the getEthBalance result
|
|
483
|
-
|
|
482
|
+
const balanceRaw = multicall3Contract.interface.decodeFunctionResult(GET_ETH_BALANCE_FUNCTION, result.returnData)[0];
|
|
484
483
|
if (!balanceMap[tokenAddress]) {
|
|
485
484
|
balanceMap[tokenAddress] = {};
|
|
486
485
|
}
|
|
487
|
-
balanceMap[tokenAddress][userAddress] =
|
|
486
|
+
balanceMap[tokenAddress][userAddress] = new bn_js_1.default(balanceRaw.toString());
|
|
488
487
|
}
|
|
489
488
|
else if (callType === 'staking') {
|
|
490
489
|
// Staking is now handled separately in two-step process
|
|
@@ -493,11 +492,11 @@ const processBalanceResults = (results, callMapping, chainId, provider, includeS
|
|
|
493
492
|
}
|
|
494
493
|
else {
|
|
495
494
|
// For ERC20 tokens, decode the balanceOf result
|
|
496
|
-
|
|
495
|
+
const balanceRaw = erc20Contract.interface.decodeFunctionResult(BALANCE_OF_FUNCTION, result.returnData)[0];
|
|
497
496
|
if (!balanceMap[tokenAddress]) {
|
|
498
497
|
balanceMap[tokenAddress] = {};
|
|
499
498
|
}
|
|
500
|
-
balanceMap[tokenAddress][userAddress] =
|
|
499
|
+
balanceMap[tokenAddress][userAddress] = new bn_js_1.default(balanceRaw.toString());
|
|
501
500
|
}
|
|
502
501
|
}
|
|
503
502
|
});
|