@metamask-previews/assets-controller 20.0.0-preview-2068a48d2 → 20.0.0-preview-bbbbbb9f2
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsController.js","sourceRoot":"","sources":["../src/AssetsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountTreeControllerGetAccountsFromSelectedAccountGroupAction,\n AccountTreeControllerInitializedEvent,\n AccountTreeControllerIsInitializedAction,\n AccountTreeControllerSelectedAccountGroupChangeEvent,\n AccountTreeControllerUninitializedEvent,\n} from '@metamask/account-tree-controller';\nimport type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type {\n ClientControllerGetStateAction,\n ClientControllerStateChangeEvent,\n} from '@metamask/client-controller';\nimport { clientControllerSelectors } from '@metamask/client-controller';\nimport type { ConfigRegistryControllerGetNetworkConfigByCaip2ChainIdAction } from '@metamask/config-registry-controller';\nimport type { TraceCallback, TraceContext } from '@metamask/controller-utils';\nimport type {\n ApiPlatformClient,\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n SupportedCurrency,\n} from '@metamask/core-backend';\nimport type { Transaction as KeyringTransaction } from '@metamask/keyring-api';\nimport type {\n KeyringControllerIsUnlockedAction,\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 { MultichainTransactionsControllerTransactionConfirmedEvent } from '@metamask/multichain-transactions-controller';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkDidChangeEvent,\n NetworkControllerNetworkRemovedEvent,\n NetworkState,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type {\n NetworkEnablementControllerGetStateAction,\n NetworkEnablementControllerEvents,\n NetworkEnablementControllerState,\n} from '@metamask/network-enablement-controller';\nimport type {\n GetPermissions,\n PermissionControllerStateChange,\n} from '@metamask/permission-controller';\nimport { PhishingControllerBulkScanTokensAction } from '@metamask/phishing-controller';\nimport type { PreferencesControllerStateChangeEvent } from '@metamask/preferences-controller';\nimport type {\n RemoteFeatureFlagControllerGetStateAction,\n RemoteFeatureFlagControllerStateChangeEvent,\n} from '@metamask/remote-feature-flag-controller';\nimport type {\n SnapControllerGetRunnableSnapsAction,\n SnapControllerHandleRequestAction,\n SnapControllerSnapInstalledEvent,\n} from '@metamask/snaps-controllers';\nimport type {\n TransactionControllerTransactionConfirmedEvent,\n TransactionControllerUnapprovedTransactionAddedEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport {\n isCaipChainId,\n isStrictHexString,\n KnownCaipNamespace,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { BigNumber as BigNumberJS } from 'bignumber.js';\nimport { isEqual } from 'lodash-es';\n\nimport type { AssetsControllerMethodActions } from './AssetsController-method-action-types.js';\nimport type {\n AbstractDataSource,\n DataSourceState,\n SubscriptionRequest,\n} from './data-sources/AbstractDataSource.js';\nimport { AccountActivityDataSource } from './data-sources/AccountActivityDataSource.js';\nimport type { AccountsApiDataSourceConfig } from './data-sources/AccountsApiDataSource.js';\nimport { AccountsApiDataSource } from './data-sources/AccountsApiDataSource.js';\nimport { isStakingContractAssetId } from './data-sources/evm-rpc-services/index.js';\nimport { shouldSkipNativeForCaipChainId } from './data-sources/evm-rpc-services/utils/assets.js';\nimport type { PriceDataSourceConfig } from './data-sources/PriceDataSource.js';\nimport { PriceDataSource } from './data-sources/PriceDataSource.js';\nimport type { RpcDataSourceConfig } from './data-sources/RpcDataSource.js';\nimport { RpcDataSource } from './data-sources/RpcDataSource.js';\nimport type { AccountsControllerAccountBalancesUpdatedEvent } from './data-sources/SnapDataSource.js';\nimport { SnapDataSource } from './data-sources/SnapDataSource.js';\nimport type { StakedBalanceDataSourceConfig } from './data-sources/StakedBalanceDataSource.js';\nimport { StakedBalanceDataSource } from './data-sources/StakedBalanceDataSource.js';\nimport {\n CaipAssetNamespace,\n TokenDataSource,\n} from './data-sources/TokenDataSource.js';\nimport {\n CHAINS_WITH_DEFAULT_TRACKED_ASSETS,\n DEFAULT_TRACKED_ASSETS_BY_CHAIN,\n buildDefaultAssetsInfo,\n getDefaultAssetMetadata,\n} from './defaults.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport { CustomAssetGraduationMiddleware } from './middlewares/CustomAssetGraduationMiddleware.js';\nimport {\n createParallelBalanceMiddleware,\n createParallelMiddleware,\n} from './middlewares/ParallelMiddleware.js';\nimport { RpcFallbackMiddleware } from './middlewares/RpcFallbackMiddleware.js';\nimport { dropBalancesOutsideAccountScopes } from './migrations/dropBalancesOutsideAccountScopes.js';\nimport type { Assets3346MigrationState } from './migrations/healAssetsInfoMetadata.js';\nimport {\n cleanSpamAssets,\n isUnlockCleanupEnabled,\n tempHealAssetsInfoMetadata,\n} from './migrations/healAssetsInfoMetadata.js';\nimport {\n buildFastFetchSources,\n buildUpdateSources,\n buildWsUpdateSources,\n executeAssetsPipeline,\n} from './pipeline/index.js';\nimport { trackAssetsLoading } from './trackAssetsLoading.js';\nimport type {\n AccountId,\n AssetsControllerState,\n AssetsDataSource,\n AssetsUpdateMode,\n ChainId,\n Caip19AssetId,\n AssetMetadata,\n FungibleAssetMetadata,\n AssetPrice,\n AssetBalance,\n FungibleAssetBalance,\n AccountWithSupportedChains,\n AssetType,\n DataType,\n DataRequest,\n DataResponse,\n SubscriptionResponse,\n Asset,\n} from './types.js';\nimport type { AssetVisibility } from './utils/assetVisibility.js';\nimport { getAssetVisibility } from './utils/assetVisibility.js';\nimport {\n UNKNOWN_EVM_NATIVE_ASSET_REFERENCE,\n ZERO_ADDRESS,\n} from './utils/constants.js';\nimport { pickRpcCustomAssetsSupplement } from './utils/customAssetsRpcSupplement.js';\nimport {\n normalizeAmountString,\n normalizeAssetId,\n formatExchangeRatesForBridge,\n formatStateForTransactionPay,\n buildNativeAssetsFromConstant,\n buildNativeAssetsFromApi,\n getDefaultNativeAssetBalance,\n getZeroAssetBalance,\n} from './utils/index.js';\nimport type {\n BridgeExchangeRatesFormat,\n TransactionPayLegacyFormat,\n} from './utils/index.js';\nimport { emitTrace, withTrace } from './utils/trace.js';\nimport type { TraceSpanData } from './utils/trace.js';\n\nconst NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];\n\n/** Stable empty map so memoized formatters are not busted by `?? {}` identity churn. */\nconst EMPTY_NATIVE_ASSET_MAP: Record<ChainId, Caip19AssetId> = {};\n\n// ============================================================================\n// PENDING TOKEN METADATA (UI input format for addCustomAsset)\n// ============================================================================\n\n/**\n * Metadata format passed from the UI when adding a custom token.\n * Mirrors the \"pendingTokens\" shape used by the extension.\n */\nexport type PendingTokenMetadata = {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n iconUrl?: string;\n aggregators?: string[];\n occurrences?: number;\n chainId: string;\n unlisted?: boolean;\n};\n\n// ============================================================================\n// CONTROLLER CONSTANTS\n// ============================================================================\n\nconst CONTROLLER_NAME = 'AssetsController' as const;\n\n/** Method names exposed as messenger actions (AssetsController:getAssets, etc.) */\nconst MESSENGER_EXPOSED_METHODS = [\n 'getAssets',\n 'getAssetsBalance',\n 'getAssetMetadata',\n 'getAccountAssetByID',\n 'getAccountAssetsByIDs',\n 'getAccountAssetsByScope',\n 'getAssetsPrice',\n 'syncAssetsPrices',\n 'getExchangeRatesForBridge',\n 'getStateForTransactionPay',\n 'addCustomAsset',\n 'removeCustomAsset',\n 'getCustomAssets',\n 'hideAsset',\n 'unhideAsset',\n 'setSelectedCurrency',\n] as const;\n\n/** Default polling interval hint for data sources (30 seconds) */\nconst DEFAULT_POLLING_INTERVAL_MS = 30_000;\n\n// ============================================================================\n// TRACE NAMES — used in Sentry spans (search these strings in Discover)\n// ============================================================================\nconst TRACE_FIRST_INIT_FETCH = 'AssetsControllerFirstInitFetch';\nconst TRACE_FULL_FETCH = 'AssetsFullFetch';\n/** Parent span that nests per-source timings; dashboard charts {@link TRACE_FULL_FETCH}. */\nconst TRACE_FETCH_PIPELINE = 'AssetsFetchPipeline';\nconst TRACE_BACKGROUND_FETCH = 'AssetsBackgroundFetch';\nconst TRACE_UPDATE_PIPELINE = 'AssetsUpdatePipeline';\n/** Parent span that nests update enrichment; dashboard charts {@link TRACE_UPDATE_PIPELINE}. */\nconst TRACE_UPDATE_PARENT = 'AssetsUpdateEnrichment';\nconst TRACE_SUBSCRIPTION_ERROR = 'AssetsSubscriptionError';\nconst TRACE_STATE_SIZE = 'AssetsStateSize';\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// ============================================================================\n// STATE TYPES\n// ============================================================================\n\nexport type { AssetsControllerState };\n\n/**\n * Returns the default state for AssetsController.\n *\n * @returns The default AssetsController state. Balance, price, and custom\n * asset maps start empty; `assetsInfo` is pre-seeded for default tracked\n * assets (see {@link buildDefaultAssetsInfo}).\n */\nexport function getDefaultAssetsControllerState(): AssetsControllerState {\n return {\n // Pre-populate metadata for controller-managed default tracked assets\n // (e.g. mUSD on Ethereum mainnet, Linea, Monad) so they are\n // immediately renderable in the UI before any RPC poll completes.\n // Per-account zero-balance entries are filled into `assetsBalance`\n // by `#ensureDefaultTrackedAssetsSeeded` once accounts are known.\n assetsInfo: buildDefaultAssetsInfo(),\n assetsBalance: {},\n assetsPrice: {},\n customAssets: {},\n assetPreferences: {},\n selectedCurrency: 'usd',\n };\n}\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\nexport type AssetsControllerGetStateAction = ControllerGetStateAction<\n typeof CONTROLLER_NAME,\n AssetsControllerState\n>;\n\nexport type AssetsControllerActions =\n | AssetsControllerGetStateAction\n | AssetsControllerMethodActions;\n\nexport type AssetsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof CONTROLLER_NAME,\n AssetsControllerState\n>;\n\nexport type AssetsControllerBalanceChangedEvent = {\n type: `${typeof CONTROLLER_NAME}:balanceChanged`;\n payload: [\n {\n accountId: AccountId;\n assetId: Caip19AssetId;\n previousAmount: string;\n newAmount: string;\n },\n ];\n};\n\nexport type AssetsControllerPriceChangedEvent = {\n type: `${typeof CONTROLLER_NAME}:priceChanged`;\n payload: [{ prices: Record<Caip19AssetId, AssetPrice> }];\n};\n\nexport type AssetsControllerEvents =\n | AssetsControllerStateChangeEvent\n | AssetsControllerBalanceChangedEvent\n | AssetsControllerPriceChangedEvent;\n\ntype AllowedActions =\n // AssetsController\n | AccountsControllerGetSelectedAccountAction\n | AccountTreeControllerGetAccountsFromSelectedAccountGroupAction\n | AccountTreeControllerIsInitializedAction\n | ClientControllerGetStateAction\n | KeyringControllerIsUnlockedAction\n // RpcDataSource\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | ConfigRegistryControllerGetNetworkConfigByCaip2ChainIdAction\n // StakedBalanceDataSource\n | NetworkEnablementControllerGetStateAction\n // SnapDataSource\n | SnapControllerGetRunnableSnapsAction\n | SnapControllerHandleRequestAction\n | GetPermissions\n // PhishingController\n | PhishingControllerBulkScanTokensAction\n // AccountsApiDataSource (Accounts API v6 balances feature flag)\n | RemoteFeatureFlagControllerGetStateAction;\n\ntype AllowedEvents =\n // AssetsController — account tree lifecycle and group switches\n | AccountTreeControllerSelectedAccountGroupChangeEvent\n | AccountTreeControllerInitializedEvent\n | AccountTreeControllerUninitializedEvent\n | ClientControllerStateChangeEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent\n | TransactionControllerUnapprovedTransactionAddedEvent\n | TransactionControllerTransactionConfirmedEvent\n // AssetsController — non-EVM (Snap keyring) transaction confirmations\n | MultichainTransactionsControllerTransactionConfirmedEvent\n // RpcDataSource, StakedBalanceDataSource\n | NetworkControllerStateChangeEvent\n // AssetsController (default-asset seeding + cross-source asset refresh\n // whenever a network configuration is added to or removed from\n // NetworkController)\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkDidChangeEvent\n | NetworkControllerNetworkRemovedEvent\n // StakedBalanceDataSource\n | NetworkEnablementControllerEvents\n // SnapDataSource\n | AccountsControllerAccountBalancesUpdatedEvent\n | PermissionControllerStateChange\n | SnapControllerSnapInstalledEvent\n // AccountActivityService (real-time balance updates + chain status for unified assets)\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent\n // AccountsApiDataSource subscribes to react to Snaps → AssetsController\n // migration flag changes (which gate the chains it surfaces as active)\n | RemoteFeatureFlagControllerStateChangeEvent;\n\nexport type AssetsControllerMessenger = Messenger<\n typeof CONTROLLER_NAME,\n AssetsControllerActions | AllowedActions,\n AssetsControllerEvents | AllowedEvents\n>;\n\n// ============================================================================\n// CONTROLLER OPTIONS\n// ============================================================================\n\nexport type AssetsControllerOptions = {\n messenger: AssetsControllerMessenger;\n state?: Partial<AssetsControllerState>;\n /** Default polling interval hint passed to data sources (ms) */\n defaultUpdateInterval?: number;\n /** Function to determine if the controller is enabled. Defaults to true. */\n isEnabled?: () => boolean;\n /**\n * Getter for basic functionality (matches the \"Basic functionality\" setting in the UI).\n * When it returns true, internet services are on: token/price APIs are used for metadata, price,\n * and price subscription. When false, only RPC is used (no token/price APIs).\n * No value is stored; the getter is invoked when needed.\n * Defaults to () => true when not provided (APIs enabled).\n */\n isBasicFunctionality?: () => boolean;\n /**\n * Called by the controller with an onChange callback. The consumer subscribes to its own\n * basic-functionality source (e.g. PreferencesController:stateChange in extension, or a\n * different mechanism in mobile) and invokes onChange(isBasic) when the value changes.\n * The controller will then refresh its subscriptions. May return an unsubscribe function\n * called on controller destroy. Optional; when omitted, basic-functionality changes are not\n * subscribed to (e.g. host can notify via root messenger or another path).\n */\n subscribeToBasicFunctionalityChange?: (\n onChange: (isBasic: boolean) => void,\n ) => void | (() => void);\n /**\n * API client for balance/price/metadata. The controller instantiates data sources\n * and uses them directly when this is provided.\n */\n queryApiClient: ApiPlatformClient;\n /** Optional configuration for RpcDataSource. */\n rpcDataSourceConfig?: RpcDataSourceConfig;\n /**\n * Optional trace callback. When provided, the controller invokes it with a\n * trace request when the first init/fetch completes (e.g. after unlock).\n * Use this to report first init fetch duration to Sentry (e.g. via addBreadcrumb or setMeasurement).\n */\n trace?: TraceCallback;\n /**\n * Optional Sentry (or compatible) reporter for **issue** events. When data source middlewares\n * fail, the controller constructs an `AssetsDataSourceError` and passes it here so you can call\n * `Sentry.captureException`. Span-only trace callbacks do not create Issues;\n * wire this if you need Sentry alerts on middleware failures.\n */\n captureException?: (error: Error) => void;\n /** Optional configuration for AccountsApiDataSource. */\n accountsApiDataSourceConfig?: AccountsApiDataSourceConfig;\n /** Optional configuration for PriceDataSource. */\n priceDataSourceConfig?: PriceDataSourceConfig;\n /** Optional configuration for StakedBalanceDataSource. */\n stakedBalanceDataSourceConfig?: StakedBalanceDataSourceConfig;\n /**\n * Function returning whether onboarding is complete. When false,\n * RPC and staked balance data sources skip fetch and subscribe\n * (no on-chain calls until the user has finished onboarding).\n * Defaults to () => true.\n */\n isOnboarded?: () => boolean;\n\n /**\n * TEMPORARY — will be removed in a future release.\n * Issue: https://consensyssoftware.atlassian.net/browse/ASSETS-3346\n */\n tempMigrateAssetsInfoMetadataAssets3346?: () => Assets3346MigrationState;\n};\n\n// ============================================================================\n// STATE METADATA\n// ============================================================================\n\nconst stateMetadata: StateMetadata<AssetsControllerState> = {\n assetsInfo: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetsBalance: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetsPrice: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n customAssets: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetPreferences: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n selectedCurrency: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetsLoadingStatus: {\n persist: false,\n includeInStateLogs: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nfunction extractChainId(assetId: Caip19AssetId): ChainId {\n const parsed = parseCaipAssetType(assetId);\n return parsed.chainId;\n}\n\n/**\n * Normalizes all asset IDs in a DataResponse.\n * This is applied at the controller level to ensure consistent state\n * regardless of how data sources format their asset IDs.\n *\n * @param response - The DataResponse to normalize.\n * @returns The normalized DataResponse with checksummed EVM addresses.\n */\nfunction normalizeResponse(response: DataResponse): DataResponse {\n const normalized: DataResponse = {};\n\n if (response.assetsInfo) {\n normalized.assetsInfo = {};\n for (const [assetId, metadata] of Object.entries(response.assetsInfo)) {\n const normalizedId = normalizeAssetId(assetId as Caip19AssetId);\n normalized.assetsInfo[normalizedId] = metadata;\n }\n }\n\n if (response.assetsPrice) {\n normalized.assetsPrice = {};\n for (const [assetId, price] of Object.entries(response.assetsPrice)) {\n const normalizedId = normalizeAssetId(assetId as Caip19AssetId);\n normalized.assetsPrice[normalizedId] = price;\n }\n }\n\n if (response.assetsBalance) {\n normalized.assetsBalance = {};\n for (const [accountId, balances] of Object.entries(\n response.assetsBalance,\n )) {\n normalized.assetsBalance[accountId] = {};\n for (const [assetId, balance] of Object.entries(balances)) {\n const normalizedId = normalizeAssetId(assetId as Caip19AssetId);\n normalized.assetsBalance[accountId][normalizedId] = balance;\n }\n }\n }\n\n // Preserve errors (chain IDs don't need normalization)\n if (response.errors) {\n normalized.errors = { ...response.errors };\n }\n\n if (response.updateMode) {\n normalized.updateMode = response.updateMode;\n }\n\n if (response.replaceCoveredChainBalances) {\n normalized.replaceCoveredChainBalances = true;\n }\n\n return normalized;\n}\n\n/**\n * Compute the effective account balances from a data-source response and prior state.\n *\n * @param previousBalances - Balances already in state for this account.\n * @param accountBalances - Balances from the incoming response.\n * @param customAssetIds - Custom assets to preserve when replacing covered chains\n * on the Accounts API v5 path (`replaceCoveredChainBalances`).\n * @param replaceCoveredChains - When true (v5 force refresh), drop prior balances\n * on chains present in the response before applying it, then restore custom assets.\n * @returns The effective balance map for the account.\n */\nfunction effectiveAccountBalancesV5(\n previousBalances: Record<string, AssetBalance>,\n accountBalances: Record<string, AssetBalance>,\n customAssetIds: Caip19AssetId[],\n replaceCoveredChains: boolean,\n): Record<string, AssetBalance> {\n if (!replaceCoveredChains) {\n return { ...previousBalances, ...accountBalances };\n }\n\n const coveredChains = new Set(\n Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]),\n );\n\n const next: Record<string, AssetBalance> = {};\n for (const [assetId, balance] of Object.entries(previousBalances)) {\n if (!coveredChains.has(assetId.split('/')[0])) {\n next[assetId] = balance;\n }\n }\n\n Object.assign(next, accountBalances);\n\n for (const customId of customAssetIds) {\n if (!Object.prototype.hasOwnProperty.call(next, customId)) {\n const prev = previousBalances[customId];\n next[customId] = prev ?? getZeroAssetBalance(customId);\n }\n }\n\n // Staked vault balances are owned by StakedBalanceDataSource. When an\n // Accounts API (or other) chain-slice replace omits them, keep the prior\n // on-chain staked amount instead of clearing it to missing/0.\n for (const [assetId, balance] of Object.entries(previousBalances)) {\n if (\n isStakingContractAssetId(assetId) &&\n !Object.prototype.hasOwnProperty.call(next, assetId)\n ) {\n next[assetId] = balance;\n }\n }\n\n return next;\n}\n\n/**\n * Compute the effective account balances for an Accounts API v6 update.\n *\n * `merge` overlays the incoming balances on prior state (Account Activity,\n * Snap events, staking). `full` replaces each covered chain slice. v6 asks\n * for natives, pins, and default tracked assets through `includeAssetIds`\n * and either returns them (at zero when the account holds none) or names\n * them in `unprocessedIncludeAssetIds`. Assets the client tracks on purpose\n * survive a `full` replace even when the response omits them, so an upstream\n * gap cannot wipe them — see `shouldKeepAsset`.\n *\n * @param previousBalances - Balances already in state for this account.\n * @param updatedBalances - Balances from the incoming response.\n * @param undeletableAssetIds - Visible assets the client asked for (native,\n * pin, or default tracked). They survive a `full` replace if the response\n * omits them. Hidden assets are excluded from snapshots and dropped here;\n * unhide is expected to fetch a new snapshot.\n * @param updateMode - `'merge'` overlays incoming balances; `'full'` replaces\n * each updated chain slice except undeletable and staking assets.\n * @returns The effective balance map for the account.\n */\nfunction effectiveAccountBalancesV6(\n previousBalances: Record<string, AssetBalance>,\n updatedBalances: Record<string, AssetBalance>,\n undeletableAssetIds: Set<string>,\n updateMode: AssetsUpdateMode,\n): Record<string, AssetBalance> {\n if (updateMode === 'merge') {\n return { ...previousBalances, ...updatedBalances };\n }\n\n const updatedChains = new Set(\n Object.keys(updatedBalances).map((assetId) =>\n extractChainId(assetId as Caip19AssetId),\n ),\n );\n const shouldKeepAsset = (assetId: Caip19AssetId): boolean =>\n !updatedChains.has(extractChainId(assetId)) ||\n undeletableAssetIds.has(assetId.toLowerCase()) ||\n isStakingContractAssetId(assetId);\n\n const keptBalances: Record<string, AssetBalance> = {};\n for (const [assetId, balance] of Object.entries(previousBalances)) {\n if (shouldKeepAsset(assetId as Caip19AssetId)) {\n keptBalances[assetId] = balance;\n }\n }\n return { ...keptBalances, ...updatedBalances };\n}\n\n// ============================================================================\n// CONTROLLER IMPLEMENTATION\n// ============================================================================\n\n/**\n * AssetsController provides a unified interface for managing asset balances\n * across all blockchain networks (EVM and non-EVM) and all asset types.\n *\n * ## Core Responsibilities\n *\n * 1. **One-Time Fetch (Sync)**: For initial load, force refresh, or on-demand queries.\n * Uses `getAssets()`, `getAssetsBalance()`, etc. with `forceUpdate: true`.\n *\n * 2. **Async Subscriptions**: Subscribes to data sources for ongoing updates.\n * Data sources push updates via callbacks; the controller updates state.\n *\n * 3. **Dynamic Source Selection**: Routes requests to appropriate data sources\n * based on which chains they support. When active chains change, the controller\n * dynamically adjusts subscriptions.\n *\n * 4. **Client + Keyring Lifecycle**: Starts subscriptions only when both the UI is\n * open (ClientController) and the wallet is unlocked (KeyringController).\n * Stops when either the UI closes or the keyring locks. See client-controller\n * README for the combined pattern.\n *\n * ## Architecture\n *\n * - Data sources declare their supported chains (async, can change over time)\n * - Data sources are responsible for their own update mechanisms (WebSocket, polling, events)\n * - The controller does NOT manage polling - it simply receives pushed updates\n */\nexport class AssetsController extends BaseController<\n typeof CONTROLLER_NAME,\n AssetsControllerState,\n AssetsControllerMessenger\n> {\n /** Whether the controller is enabled */\n readonly #isEnabled: () => boolean;\n\n /** Getter for basic functionality (only balance fetch/subscribe use RPC; token/price API not used). No attribute stored. */\n readonly #isBasicFunctionality: () => boolean;\n\n /** Default update interval hint passed to data sources */\n readonly #defaultUpdateInterval: number;\n\n /** Optional trace callback for first init/fetch measurement (duration). */\n readonly #trace?: TraceCallback;\n\n /** Optional reporter for Issue-style errors (e.g. Sentry.captureException). */\n readonly #captureException?: (error: Error) => void;\n\n /** Whether we have already reported first init fetch for this session (reset on #stop). */\n #firstInitFetchReported = false;\n\n /** Whether we have already reported state size for this session (reset on #stop). */\n #stateSizeReported = false;\n\n /**\n * Emit a state-size trace once on app start (first state update after unlock).\n */\n #emitStateSizeTrace(): void {\n if (!this.#trace || this.#stateSizeReported) {\n return;\n }\n this.#stateSizeReported = true;\n\n const {\n assetsBalance: balances,\n customAssets,\n assetsInfo,\n assetsPrice,\n } = this.state;\n\n // Count balance entries and collect unique asset IDs / chain IDs in one pass.\n let balanceEntries = 0;\n const uniqueAssets = new Set<string>();\n const uniqueNetworks = new Set<string>();\n\n for (const acct of Object.values(balances)) {\n const assetIds = Object.keys(acct);\n balanceEntries += assetIds.length;\n for (const assetId of assetIds) {\n uniqueAssets.add(assetId);\n // CAIP-19 format: \"eip155:1/slip44:60\" — chainId is everything before \"/\"\n const slash = assetId.indexOf('/');\n if (slash > 0) {\n uniqueNetworks.add(assetId.slice(0, slash));\n }\n }\n }\n\n let customAssetEntries = 0;\n for (const ids of Object.values(customAssets)) {\n if (Array.isArray(ids)) {\n customAssetEntries += ids.length;\n }\n }\n\n emitTrace({\n name: TRACE_STATE_SIZE,\n trace: this.#trace,\n data: {\n balance_entries: balanceEntries,\n balance_accounts: Object.keys(balances).length,\n // `asset_count` matches the Assets Health dashboard widget field name.\n asset_count: uniqueAssets.size,\n unique_asset_count: uniqueAssets.size,\n network_count: uniqueNetworks.size,\n metadata_entries: Object.keys(assetsInfo).length,\n price_entries: Object.keys(assetsPrice).length,\n custom_asset_entries: customAssetEntries,\n },\n });\n }\n\n readonly #controllerMutex = new Mutex();\n\n /** Serializes account-switch fetch + subscribe to prevent overlapping races. */\n readonly #accountRefreshMutex = new Mutex();\n\n /**\n * Active balance subscriptions keyed by account ID.\n * Each account has one logical subscription that may span multiple data sources.\n * For example, if WebSocket covers chains A,B and RPC covers chain C,\n * the account subscribes to both data sources for its chains.\n */\n readonly #activeSubscriptions: Map<string, SubscriptionResponse> = new Map();\n\n /**\n * Guards against `#start()` re-entrancy. `#activeSubscriptions` only\n * becomes non-empty once `#runStartupRefresh()`'s forced `getAssets()`\n * call resolves, which can take many seconds for accounts with many\n * chains/snaps. `#start()` is invoked by `#updateActive()`, which is\n * wired to several independent events (e.g. keyring unlock, account tree\n * init, client state change). If a second such event fires before the\n * first `getAssets()` call resolves, the `#activeSubscriptions.size > 0`\n * guard alone doesn't catch it, and the whole startup refresh (including\n * its forced `getAssets()` call) runs a second time for the same accounts.\n */\n #startInFlight = false;\n\n /** Currently enabled chains from NetworkEnablementController */\n #enabledChains: Set<ChainId> = new Set();\n\n /**\n * Get the currently selected accounts from AccountTreeController.\n * This includes all accounts in the same group as the selected account\n * (EVM, Bitcoin, Solana, Tron, etc. that belong to the same logical account group).\n *\n * @returns Array of InternalAccount objects from the selected account group.\n */\n #getSelectedAccounts(): InternalAccount[] {\n const accounts = this.messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n );\n if (accounts.length > 0) {\n return accounts;\n }\n const selectedAccount = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n if (selectedAccount) {\n return [selectedAccount];\n }\n return [];\n }\n\n /**\n * Whether `AccountTreeController.init()` has completed and the tree is ready.\n *\n * @returns True when the account tree has been initialized.\n */\n #isAccountTreeInitialized(): boolean {\n return this.messenger.call('AccountTreeController:isInitialized');\n }\n\n /**\n * Whether the client (UI) is open, read from ClientController state.\n *\n * @returns True when the UI is open.\n */\n #isUiOpen(): boolean {\n return clientControllerSelectors.selectIsUiOpen(\n this.messenger.call('ClientController:getState'),\n );\n }\n\n /**\n * Whether the keyring is unlocked, read from KeyringController.\n *\n * @returns True when the wallet vault is unlocked.\n */\n #isKeyringUnlocked(): boolean {\n return this.messenger.call('KeyringController:isUnlocked');\n }\n\n readonly #accountActivityDataSource: AccountActivityDataSource;\n\n readonly #accountsApiDataSource: AccountsApiDataSource;\n\n readonly #snapDataSource: SnapDataSource;\n\n readonly #rpcDataSource: RpcDataSource;\n\n readonly #stakedBalanceDataSource: StakedBalanceDataSource;\n\n /**\n * All balance data sources in priority order for chain-claiming and cleanup.\n * Note: StakedBalanceDataSource is excluded because it provides supplementary\n * data and should not participate in chain-claiming.\n *\n * @returns The four balance data source instances in priority order.\n */\n get #allBalanceDataSources(): [\n AccountActivityDataSource,\n AccountsApiDataSource,\n SnapDataSource,\n RpcDataSource,\n ] {\n return [\n this.#accountActivityDataSource,\n this.#accountsApiDataSource,\n this.#snapDataSource,\n this.#rpcDataSource,\n ];\n }\n\n readonly #priceDataSource: PriceDataSource;\n\n readonly #customAssetGraduationMiddleware: CustomAssetGraduationMiddleware;\n\n readonly #rpcFallbackMiddleware: RpcFallbackMiddleware;\n\n readonly #tokenDataSource: TokenDataSource;\n\n #unsubscribeBasicFunctionality: (() => void) | null = null;\n\n readonly #queryApiClient: ApiPlatformClient;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n constructor({\n messenger,\n state = {},\n defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS,\n isEnabled = (): boolean => true,\n isBasicFunctionality,\n subscribeToBasicFunctionalityChange,\n queryApiClient,\n rpcDataSourceConfig,\n trace,\n captureException,\n accountsApiDataSourceConfig,\n priceDataSourceConfig,\n stakedBalanceDataSourceConfig,\n isOnboarded,\n tempMigrateAssetsInfoMetadataAssets3346,\n }: AssetsControllerOptions) {\n super({\n name: CONTROLLER_NAME,\n messenger,\n metadata: stateMetadata,\n state: {\n ...getDefaultAssetsControllerState(),\n ...state,\n },\n });\n\n this.#isEnabled = isEnabled;\n this.#isBasicFunctionality = isBasicFunctionality ?? ((): boolean => true);\n this.#defaultUpdateInterval = defaultUpdateInterval;\n this.#trace = trace;\n this.#captureException = captureException;\n this.#queryApiClient = queryApiClient;\n const rpcConfig = rpcDataSourceConfig ?? {};\n\n // TEMPORARY: heal assetsInfo metadata wiped by a prior defect\n // (see extension migration #215 / ASSETS-3346). Remove in a future release.\n if (tempMigrateAssetsInfoMetadataAssets3346) {\n this.update(() =>\n tempHealAssetsInfoMetadata({\n state: this.state,\n getMigrationState: tempMigrateAssetsInfoMetadataAssets3346,\n captureException,\n }),\n );\n }\n\n this.#initializeNativeAssetsMap(queryApiClient);\n\n this.#onActiveChainsUpdated = (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ): void => {\n try {\n this.#handleActiveChainsUpdate(dataSourceName, chains, previousChains);\n } catch (error) {\n log('Failed to handle active chains update', {\n dataSourceName,\n error,\n });\n }\n };\n\n this.#accountActivityDataSource = new AccountActivityDataSource({\n messenger: this.messenger,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n onAssetsUpdate: (response, request): Promise<void> =>\n this.handleAssetsUpdate(\n response,\n this.#accountActivityDataSource.getName(),\n request,\n ),\n });\n this.#accountsApiDataSource = new AccountsApiDataSource({\n messenger: this.messenger,\n queryApiClient,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n ...accountsApiDataSourceConfig,\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetsState: (): AssetsControllerState => this.state,\n getAssetVisibility: this.#getAssetVisibility.bind(this),\n });\n this.#snapDataSource = new SnapDataSource({\n messenger: this.messenger,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n onAssetsUpdate: (response): Promise<void> =>\n this.handleAssetsUpdate(response, 'SnapDataSource'),\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetVisibility: this.#getAssetVisibility.bind(this),\n getAssetsState: (): AssetsControllerState => this.state,\n });\n this.#rpcDataSource = new RpcDataSource({\n messenger: this.messenger,\n getAssetsState: (): AssetsControllerState => this.state,\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetVisibility: this.#getAssetVisibility.bind(this),\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n getNativeAssetForChain: (chainId: ChainId): Caip19AssetId | undefined =>\n this.#getNativeAssetForChain(chainId),\n queryApiClient,\n ...rpcConfig,\n isOnboarded: rpcConfig.isOnboarded ?? isOnboarded,\n getAssetType: (assetId: Caip19AssetId): 'native' | 'erc20' | 'spl' =>\n this.#getAssetType(assetId),\n });\n this.#stakedBalanceDataSource = new StakedBalanceDataSource({\n messenger: this.messenger,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n ...stakedBalanceDataSourceConfig,\n });\n this.#tokenDataSource = new TokenDataSource(this.messenger, {\n queryApiClient,\n getNativeAssetIds: (): Caip19AssetId[] => {\n return this.#getNativeAssetIdsForEnabledChains();\n },\n getAssetType: (assetId: Caip19AssetId): 'native' | 'erc20' | 'spl' =>\n this.#getAssetType(assetId),\n getAssetsState: (): AssetsControllerState => this.state,\n });\n this.#priceDataSource = new PriceDataSource({\n queryApiClient,\n getSelectedCurrency: (): SupportedCurrency => this.state.selectedCurrency,\n getAssetsState: (): AssetsControllerState => this.state,\n ...priceDataSourceConfig,\n });\n this.#customAssetGraduationMiddleware = new CustomAssetGraduationMiddleware(\n {\n getSelectedAccountId: (): AccountId | undefined => {\n try {\n return this.#getSelectedAccounts()[0]?.id;\n } catch {\n return undefined;\n }\n },\n removeCustomAsset: (accountId, assetId): void =>\n this.removeCustomAsset(accountId, assetId),\n getAssetsState: (): AssetsControllerState => this.state,\n },\n );\n this.#rpcFallbackMiddleware = new RpcFallbackMiddleware({\n rpcDataSource: this.#rpcDataSource,\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetsState: (): AssetsControllerState => this.state,\n });\n\n log('Initializing AssetsController', {\n defaultUpdateInterval: this.#defaultUpdateInterval,\n });\n\n this.#initializeState();\n this.#subscribeToEvents();\n this.#registerActionHandlers();\n // Subscriptions start only when both UI is open and keyring unlocked -> #updateActive().\n\n // Subscribe to basic-functionality changes after construction so a synchronous\n // onChange during subscribe cannot run before data sources are initialized.\n if (subscribeToBasicFunctionalityChange) {\n const unsubscribe = subscribeToBasicFunctionalityChange((isBasic) =>\n this.handleBasicFunctionalityChange(isBasic),\n );\n if (typeof unsubscribe === 'function') {\n this.#unsubscribeBasicFunctionality = unsubscribe;\n }\n }\n }\n\n // ============================================================================\n // INITIALIZATION\n // ============================================================================\n\n #initializeNativeAssetsMap(queryApiClient: ApiPlatformClient): void {\n queryApiClient.queryClient\n .fetchQuery({\n queryKey: NATIVE_ASSETS_QUERY_KEY,\n queryFn: buildNativeAssetsFromApi,\n staleTime: Infinity,\n gcTime: Infinity,\n })\n .catch((error) => {\n // Failure to populate native asset cache is non-fatal;\n // #isNativeAsset falls back to the seed data from buildNativeAssetsFromConstant.\n log(\n 'Failed to populate native asset cache, falling back to seed data',\n error,\n );\n });\n\n // Seed the cache synchronously so that synchronous consumers (e.g.\n // #isNativeAsset, #resolveNativeAssetIds) have data available immediately.\n // When fetchQuery resolves (currently instant, future: API), it overwrites\n // this with potentially fresher data.\n const initialNativeAssetMap = buildNativeAssetsFromConstant();\n queryApiClient.setCachedData(\n NATIVE_ASSETS_QUERY_KEY,\n initialNativeAssetMap,\n );\n }\n\n #initializeState(): void {\n const { enabledNetworkMap } = this.messenger.call(\n 'NetworkEnablementController:getState',\n );\n this.#enabledChains = this.#extractEnabledChains(enabledNetworkMap);\n\n log('Initialized state', {\n enabledNetworkMap,\n enabledChains: this.#enabledChains,\n });\n }\n\n /**\n * Extract enabled chains from enabledNetworkMap.\n * Returns CAIP-2 chain IDs for all enabled networks across all namespaces.\n *\n * Note: For EIP155 (EVM) chains, the reference is normalized to decimal format\n * to ensure consistency with CAIP-2 standard and API responses.\n *\n * @param enabledNetworkMap - The enabled network map from NetworkEnablementController.\n * @returns Set of CAIP-2 chain IDs for all enabled networks.\n */\n #extractEnabledChains(\n enabledNetworkMap: NetworkEnablementControllerState['enabledNetworkMap'],\n ): Set<ChainId> {\n const chains = new Set<ChainId>();\n\n for (const [namespace, networks] of Object.entries(enabledNetworkMap)) {\n for (const [reference, isEnabled] of Object.entries(networks)) {\n if (isEnabled) {\n // Check if reference is already a full CAIP-2 chain ID (contains colon)\n if (reference.includes(':')) {\n // Already a full chain ID, use as-is\n chains.add(reference as ChainId);\n } else {\n // Normalize EIP155 chain references from hex to decimal (CAIP-2 standard)\n const normalizedReference = this.#normalizeChainReference(\n namespace,\n reference,\n );\n chains.add(`${namespace}:${normalizedReference}`);\n }\n }\n }\n }\n return chains;\n }\n\n /**\n * Normalize chain reference to CAIP-2 standard format.\n * For EIP155, converts hex chain IDs to decimal.\n *\n * @param namespace - The chain namespace (e.g., \"eip155\").\n * @param reference - The chain reference (e.g., \"0x1\" or \"1\").\n * @returns The normalized chain reference in decimal format.\n */\n #normalizeChainReference(namespace: string, reference: string): string {\n if (namespace === 'eip155' && isStrictHexString(reference)) {\n // Convert hex to decimal for EIP155 chains\n return parseInt(reference, 16).toString();\n }\n return reference;\n }\n\n #subscribeToEvents(): void {\n this.messenger.subscribe(\n 'AccountTreeController:selectedAccountGroupChange',\n (groupId, previousGroupId) => {\n this.#handleAccountGroupChanged(groupId, previousGroupId).catch(\n console.error,\n );\n },\n );\n\n this.messenger.subscribe('AccountTreeController:initialized', () => {\n this.#updateActive();\n });\n this.messenger.subscribe('AccountTreeController:uninitialized', () => {\n this.#updateActive();\n });\n\n // Subscribe to network enablement changes (only enabledNetworkMap)\n this.messenger.subscribe(\n 'NetworkEnablementController:stateChange',\n ({ enabledNetworkMap }) => {\n this.#handleEnabledNetworksChanged(enabledNetworkMap).catch(\n console.error,\n );\n },\n );\n\n // When a network is added or removed from NetworkController, refresh\n // assets across every data source so balances, prices, and metadata\n // stay consistent. On add we also seed default tracked assets (e.g.\n // mUSD on Monad) when the chain is in our defaults registry, so the\n // entries appear immediately without waiting for it to also be\n // enabled in NetworkEnablementController.\n this.messenger.subscribe(\n 'NetworkController:networkAdded',\n (networkConfiguration) => {\n this.#handleNetworkAdded(networkConfiguration.chainId);\n this.#refreshAssetsAfterNetworkAdded(\n networkConfiguration.chainId,\n ).catch((error: unknown) => {\n log('Failed to refresh assets after network added', { error });\n });\n },\n );\n\n this.messenger.subscribe('NetworkController:networkRemoved', () => {\n this.#refreshAssetsAfterNetworkChange();\n });\n\n // Selected EVM network switch (network picker). Enablement changes are\n // handled separately via NetworkEnablementController:stateChange.\n this.messenger.subscribe(\n 'NetworkController:networkDidChange',\n (networkState) => {\n this.#handleNetworkDidChange(networkState).catch(console.error);\n },\n );\n\n // Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked\n this.messenger.subscribe(\n 'ClientController:stateChange',\n () => {\n this.#updateActive();\n },\n clientControllerSelectors.selectIsUiOpen,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.messenger.subscribe('KeyringController:unlock', async () => {\n try {\n this.#runOutOfScopeBalanceCleanup();\n } catch {\n /* Do nothing */\n }\n await this.#runSpamCleanup().catch(() => {\n /* Do nothing */\n });\n this.#updateActive();\n });\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#updateActive();\n });\n\n // Subscribe to unapproved transactions - TXs that need confirmation.\n // Ensures balances for the account making the transaction are updated\n // (e.g. for gas estimations), except on AccountActivity-active chains.\n this.messenger.subscribe(\n 'TransactionController:unapprovedTransactionAdded',\n (transactionMeta: TransactionMeta) => {\n this.#refreshAssetsForEVMTransaction(transactionMeta);\n },\n );\n\n // Post-tx refresh via the full fetch pipeline (Accounts API + RPC fallback).\n // Skipped for chains covered by AccountActivity (real-time WS updates).\n // RpcDataSource also listens for transactionConfirmed, but only refreshes\n // chains it owns via an active subscription.\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta: TransactionMeta) => {\n this.#refreshAssetsForEVMTransaction(transactionMeta);\n },\n );\n\n // Non-EVM equivalent of the above: Snap keyrings report transaction\n // lifecycle through MultichainTransactionsController. When the chain is\n // not covered by AccountActivity (WebSocket down / unsupported), refresh\n // via the Accounts API with the server cache bypassed.\n this.messenger.subscribe(\n 'MultichainTransactionsController:transactionConfirmed',\n (transaction: KeyringTransaction) => {\n this.#refreshAssetsForNonEvmTransaction(transaction);\n },\n );\n }\n\n /**\n * Force-refresh assets for the account/chain of an EVM transaction, unless\n * the chain is already covered by AccountActivity (real-time WebSocket\n * balances). Always bypasses the Accounts API's server-side cache so a\n * refresh cannot be answered with a stale pre-transaction snapshot.\n *\n * @param transactionMeta - The transaction that triggered the refresh.\n */\n #refreshAssetsForEVMTransaction(transactionMeta: TransactionMeta): void {\n const hexChainId = transactionMeta.chainId;\n if (!hexChainId) {\n return;\n }\n\n const caipChainId = `eip155:${parseInt(hexChainId, 16)}` as ChainId;\n\n const fromAddress = transactionMeta.txParams.from?.toLowerCase();\n if (!fromAddress) {\n return;\n }\n\n this.#refreshAssetsAfterConfirmed(\n caipChainId,\n (account) => account.address.toLowerCase() === fromAddress,\n );\n }\n\n /**\n * Non-EVM counterpart of `#refreshAssetsForEVMTransaction` for transactions\n * reported by Snap keyrings via\n * `MultichainTransactionsController`. The keyring `Transaction` already\n * carries a CAIP-2 `chain` and the internal `account` id, so no address\n * normalisation is needed.\n *\n * @param transaction - The confirmed keyring transaction.\n */\n #refreshAssetsForNonEvmTransaction(transaction: KeyringTransaction): void {\n const { chain, account: accountId } = transaction;\n if (!chain || !accountId || !isCaipChainId(chain)) {\n return;\n }\n\n this.#refreshAssetsAfterConfirmed(\n chain,\n (account) => account.id === accountId,\n );\n }\n\n /**\n * Shared post-transaction refresh: skip when AccountActivity already pushes\n * live balances for `caipChainId` (a force fetch would be redundant and can\n * race the WebSocket path); otherwise run a force `getAssets` for the first\n * selected account matching `matchAccount`, bypassing the Accounts API's\n * server-side cache.\n *\n * @param caipChainId - CAIP-2 chain the transaction was on.\n * @param matchAccount - Predicate selecting the originating account among\n * the currently selected accounts.\n */\n #refreshAssetsAfterConfirmed(\n caipChainId: ChainId,\n matchAccount: (account: InternalAccount) => boolean,\n ): void {\n if (\n this.#accountActivityDataSource\n .getActiveChainsSync()\n .includes(caipChainId)\n ) {\n return;\n }\n\n const matchedAccount = this.#getSelectedAccounts().find(matchAccount);\n if (!matchedAccount) {\n return;\n }\n\n this.getAssets([matchedAccount], {\n chainIds: [caipChainId],\n forceUpdate: true,\n bypassServerCache: true,\n }).catch((error: unknown) => {\n log('Failed to refresh assets after transaction event', { error });\n });\n }\n\n /**\n * One-time cleanup of balances a v5 update stamped onto accounts after a\n * group switch. Runs on unlock, the same point as spam cleanup, and only\n * touches the selected accounts (their scopes are what define ownership).\n */\n #runOutOfScopeBalanceCleanup(): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n this.update((state) => {\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n dropBalancesOutsideAccountScopes(balances, accounts);\n });\n }\n\n async #runSpamCleanup(): Promise<void> {\n try {\n const shouldRun =\n this.#isKeyringUnlocked() &&\n this.#isBasicFunctionality() &&\n isUnlockCleanupEnabled(\n this.messenger.call('RemoteFeatureFlagController:getState')\n ?.remoteFeatureFlags,\n );\n if (!shouldRun) {\n return;\n }\n } catch (error) {\n log('Failed to start spam cleanup', { error });\n return;\n }\n\n try {\n const originalState = this.state;\n const result = await cleanSpamAssets({\n state: originalState,\n apiClient: this.#queryApiClient,\n captureException: this.#captureException,\n });\n\n if (!result) {\n return;\n }\n\n this.update((state) => {\n result.applyPatch(\n /* oxlint-disable typescript/no-unnecessary-type-assertion */\n state as Pick<\n AssetsControllerState,\n 'assetsInfo' | 'assetsBalance' | 'assetsPrice'\n >,\n /* oxlint-enable typescript/no-unnecessary-type-assertion */\n {\n spamAssetIds: result.spamAssetIds,\n },\n );\n });\n } catch (error) {\n log('Failed to run spam cleanup', { error });\n }\n }\n\n /**\n * Start or stop asset tracking based on client (UI) open state, keyring\n * unlock state, and account-tree readiness. Only runs when the UI is open,\n * the keyring is unlocked, and the account tree has finished `init()`.\n */\n #updateActive(): void {\n const shouldRun =\n this.#isUiOpen() &&\n this.#isKeyringUnlocked() &&\n this.#isAccountTreeInitialized();\n if (shouldRun) {\n this.#start();\n } else {\n this.#stop();\n }\n }\n\n /**\n * Force-fetch balances then subscribe. Used on unlock / first startup.\n *\n * @param accounts - Selected accounts to refresh.\n */\n async #runStartupRefresh(accounts: InternalAccount[]): Promise<void> {\n const releaseLock = await this.#accountRefreshMutex.acquire();\n try {\n await this.getAssets(accounts, {\n chainIds: [...this.#enabledChains],\n forceUpdate: true,\n });\n // Seed before subscribe so the price poll / update fetch sees natives\n // and default tracked assets that were never returned by balance APIs.\n this.#ensureNativeBalancesDefaultZero();\n this.#ensureDefaultTrackedAssetsSeeded();\n // Balances were just force-fetched — skip AccountsApi's subscribe-time poll.\n this.#subscribeAssets({ skipInitialFetch: true });\n } catch (error) {\n log('Failed to fetch assets on startup', error);\n this.#ensureNativeBalancesDefaultZero();\n this.#ensureDefaultTrackedAssetsSeeded();\n this.#subscribeAssets({ skipInitialFetch: true });\n } finally {\n releaseLock();\n }\n }\n\n #registerActionHandlers(): void {\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n // ============================================================================\n // DATA SOURCE CHAIN MANAGEMENT\n // ============================================================================\n\n /**\n * Handle when a data source's supported chains change.\n * Used to refresh balance subscriptions and run a one-time fetch when a new chain is supported.\n *\n * - On any add/remove: re-subscribes to data sources so chain assignment stays correct.\n * - When chains are added: fetches balances for the new chains (for selected accounts on enabled networks).\n *\n * Controller does not store chains; sources report via this callback. previousChains is required for diff.\n *\n * @param dataSourceId - The identifier of the data source reporting the change.\n * @param activeChains - Currently active (supported and available) chain IDs for this source.\n * @param previousChains - Previous chains; used to compute added/removed.\n */\n #handleActiveChainsUpdate(\n dataSourceId: string,\n activeChains: ChainId[],\n previousChains: ChainId[],\n ): void {\n if (!this.#isUiOpen() || !this.#isKeyringUnlocked() || !this.#isEnabled()) {\n return;\n }\n log('Data source active chains changed', {\n dataSourceId,\n chainCount: activeChains.length,\n chains: activeChains,\n });\n\n const previous: ChainId[] = previousChains;\n\n const previousSet = new Set(previous);\n const addedChains = activeChains.filter((ch) => !previousSet.has(ch));\n const removedChains = previous.filter((ch) => !activeChains.includes(ch));\n\n // Refresh subscriptions to use updated data source availability.\n if (addedChains.length > 0 || removedChains.length > 0) {\n this.#subscribeAssets();\n }\n }\n\n /**\n * Returns the callback passed to data sources for reporting active chain updates.\n * Used by tests to simulate a data source reporting chain changes.\n *\n * @returns The onActiveChainsUpdated callback.\n */\n getOnActiveChainsUpdated(): (\n dataSourceId: string,\n activeChains: ChainId[],\n previousChains: ChainId[],\n ) => void {\n return this.#onActiveChainsUpdated;\n }\n\n // ============================================================================\n // MIDDLEWARE EXECUTION\n // ============================================================================\n\n /**\n * Execute middlewares with request/response context.\n * Returns response and exclusive duration per source (sum ≈ wall time).\n *\n * Thin wrapper over {@link executeAssetsPipeline} that supplies the\n * controller-owned exception reporter.\n *\n * @param params - Middleware execution options.\n * @param params.sources - Data sources or middlewares with getName() and assetsMiddleware.\n * @param params.request - The data request.\n * @param params.initialResponse - Optional initial response (for enriching existing data).\n * @param params.parentContext - Optional parent Sentry span; per-source timings nest under it.\n * @param params.trace - Optional trace callback; omit after unlock/first-init to skip spans.\n * @returns Response and durationByDataSource (exclusive ms per source name).\n */\n async #executeMiddlewares(params: {\n sources: AssetsDataSource[];\n request: DataRequest;\n initialResponse?: DataResponse;\n parentContext?: TraceContext;\n /** Omit after unlock/first-init so timing spans are not emitted. */\n trace?: TraceCallback;\n }): Promise<{\n response: DataResponse;\n durationByDataSource: Record<string, number>;\n }> {\n return executeAssetsPipeline({\n ...params,\n captureException: this.#captureException,\n });\n }\n\n // ============================================================================\n // PUBLIC API: QUERY METHODS\n // ============================================================================\n\n @trackAssetsLoading\n async getAssets(\n accounts: InternalAccount[],\n options?: {\n chainIds?: ChainId[];\n assetTypes?: AssetType[];\n forceUpdate?: boolean;\n /**\n * Also bypass server-side HTTP caches (e.g. the Accounts API's 60s\n * cache, via a random `bypassServerCache` query param). Only meaningful\n * together with `forceUpdate`. Use sparingly — e.g. right after a\n * transaction confirms, when the API's cached snapshot is known stale.\n */\n bypassServerCache?: boolean;\n dataTypes?: DataType[];\n },\n ): Promise<Record<AccountId, Record<Caip19AssetId, Asset>>> {\n const chainIds = options?.chainIds ?? [...this.#enabledChains];\n const assetTypes = options?.assetTypes ?? ['fungible'];\n const dataTypes = options?.dataTypes ?? ['balance', 'metadata', 'price'];\n\n if (accounts.length === 0 || chainIds.length === 0) {\n return this.#getAssetsFromState(accounts, chainIds, assetTypes);\n }\n\n if (options?.forceUpdate) {\n await this.#forceUpdateAssets({\n accounts,\n chainIds,\n requestOptions: {\n assetTypes,\n dataTypes,\n forceUpdate: true,\n bypassServerCache: options.bypassServerCache,\n },\n });\n }\n\n const result = this.#getAssetsFromState(accounts, chainIds, assetTypes);\n return result;\n }\n\n /**\n * Force-fetch spot prices for an explicit asset list.\n *\n * Calls `PriceDataSource` directly and merges the result into `assetsPrice`.\n * Prices are shared across accounts, so this does not take an account or\n * chain scope and does not run the balance pipeline.\n *\n * Returns without calling the Price API when basic functionality is off.\n * That matches the asset pipeline, which drops the price source in RPC-only\n * mode, and `setSelectedCurrency`, which skips its price refresh.\n *\n * @param assetIds - CAIP-19 asset IDs to sync.\n */\n async syncAssetsPrices(assetIds: Caip19AssetId[]): Promise<void> {\n if (!this.#isBasicFunctionality() || assetIds.length === 0) {\n return;\n }\n\n const assetsPrice = await this.#priceDataSource.fetchAssetPrices(assetIds);\n if (Object.keys(assetsPrice).length === 0) {\n return;\n }\n\n await this.#updateState({\n assetsPrice,\n updateMode: 'merge',\n });\n }\n\n /**\n * Run a forced fetch on the v5 or v6 pipeline.\n *\n * @param params - Accounts, chains, and request fields for this fetch.\n * @param params.accounts - Accounts in this fetch.\n * @param params.chainIds - Chains in this fetch.\n * @param params.requestOptions - Shared force-update request fields.\n */\n async #forceUpdateAssets({\n accounts,\n chainIds,\n requestOptions,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n requestOptions: {\n assetTypes: AssetType[];\n dataTypes: DataType[];\n forceUpdate: true;\n bypassServerCache?: boolean;\n };\n }): Promise<void> {\n const pipelineTrace = this.#firstInitFetchReported\n ? undefined\n : this.#trace;\n\n if (this.#isBalanceV6Enabled()) {\n await this.#forceUpdateAssetsV6({\n accounts,\n chainIds,\n request: this.#buildDataRequest(accounts, chainIds, requestOptions),\n pipelineTrace,\n });\n return;\n }\n\n await this.#forceUpdateAssetsV5({\n accounts,\n chainIds,\n request: this.#buildForceUpdateRequestV5(\n accounts,\n chainIds,\n requestOptions,\n ),\n pipelineTrace,\n });\n }\n\n /**\n * v5 force-update request: every pin of the requested accounts, unscoped.\n * Delete with the rest of the v5 path when `assetsAccountsApiV6` is the default.\n *\n * @param accounts - Accounts in this fetch.\n * @param chainIds - Chains in this fetch.\n * @param requestOptions - Shared force-update request fields.\n * @param requestOptions.assetTypes - Asset types to fetch.\n * @param requestOptions.dataTypes - Data types to fetch.\n * @param requestOptions.forceUpdate - Always `true` to bypass caches.\n * @param requestOptions.bypassServerCache - Also bypass server-side HTTP caches.\n * @returns The v5 data request.\n */\n #buildForceUpdateRequestV5(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n requestOptions: {\n assetTypes: AssetType[];\n dataTypes: DataType[];\n forceUpdate: true;\n bypassServerCache?: boolean;\n },\n ): DataRequest {\n const customAssets: Caip19AssetId[] = [];\n for (const account of accounts) {\n customAssets.push(...this.getCustomAssets(account.id));\n }\n\n return this.#buildDataRequest(accounts, chainIds, {\n ...requestOptions,\n customAssets: customAssets.length > 0 ? customAssets : undefined,\n });\n }\n\n async #forceUpdateAssetsV5({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n }): Promise<void> {\n const isBasicFunctionality = this.#isBasicFunctionality();\n const fastSources = buildFastFetchSources(\n {\n accountsApiDataSource: this.#accountsApiDataSource,\n customAssetGraduationMiddleware: this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n { isBasicFunctionality, includeCustomAssetGraduation: true },\n );\n\n const fastResponse = await this.#runFastFetchV5({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n });\n this.#firstInitFetchReported = true;\n\n this.#runBackgroundFetch({\n accounts,\n request,\n pipelineTrace,\n chainIds: this.#getSlowPipelineChainIds(chainIds, fastResponse),\n isBasicFunctionality,\n });\n }\n\n async #forceUpdateAssetsV6({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n }): Promise<void> {\n const isBasicFunctionality = this.#isBasicFunctionality();\n const fastSources = buildFastFetchSources(\n {\n accountsApiDataSource: this.#accountsApiDataSource,\n customAssetGraduationMiddleware: this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n {\n isBasicFunctionality,\n includeCustomAssetGraduation: false,\n },\n );\n\n const fastResponse = await this.#runFastFetchV6({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n });\n this.#firstInitFetchReported = true;\n\n this.#runBackgroundFetch({\n accounts,\n request,\n pipelineTrace,\n chainIds: this.#getSlowPipelineChainIds(chainIds, fastResponse),\n isBasicFunctionality,\n });\n }\n\n async #runFastFetchV5({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n fastSources: AssetsDataSource[];\n isBasicFunctionality: boolean;\n }): Promise<DataResponse> {\n const { response } = await withTrace({\n name: TRACE_FETCH_PIPELINE,\n trace: pipelineTrace,\n data: {\n chain_count: chainIds.length,\n account_count: accounts.length,\n basic_functionality: isBasicFunctionality,\n },\n fn: async (parentContext) => {\n const startTime = performance.now();\n const result = await this.#executeMiddlewares({\n sources: fastSources,\n request,\n parentContext,\n trace: pipelineTrace,\n });\n await this.#updateState({\n ...result.response,\n updateMode: 'merge',\n replaceCoveredChainBalances: true,\n });\n this.#emitFastFetchTraces({\n accounts,\n chainIds,\n result,\n durationMs: performance.now() - startTime,\n isBasicFunctionality,\n parentContext,\n pipelineTrace,\n });\n return result;\n },\n });\n return response;\n }\n\n async #runFastFetchV6({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n fastSources: AssetsDataSource[];\n isBasicFunctionality: boolean;\n }): Promise<DataResponse> {\n const { response } = await withTrace({\n name: TRACE_FETCH_PIPELINE,\n trace: pipelineTrace,\n data: {\n chain_count: chainIds.length,\n account_count: accounts.length,\n basic_functionality: isBasicFunctionality,\n },\n fn: async (parentContext) => {\n const startTime = performance.now();\n const result = await this.#executeMiddlewares({\n sources: fastSources,\n request,\n parentContext,\n trace: pipelineTrace,\n });\n await this.#updateState(result.response);\n this.#emitFastFetchTraces({\n accounts,\n chainIds,\n result,\n durationMs: performance.now() - startTime,\n isBasicFunctionality,\n parentContext,\n pipelineTrace,\n });\n return result;\n },\n });\n return response;\n }\n\n #runBackgroundFetch({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n isBasicFunctionality,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n isBasicFunctionality: boolean;\n }): void {\n if (chainIds.length === 0) {\n return;\n }\n const slowSources = isBasicFunctionality\n ? [this.#snapDataSource, this.#rpcDataSource]\n : [this.#rpcDataSource];\n const slowRequest = { ...request, chainIds };\n\n withTrace({\n name: TRACE_BACKGROUND_FETCH,\n trace: pipelineTrace,\n data: {\n chain_count: chainIds.length,\n account_count: accounts.length,\n },\n fn: async (parentContext) => {\n const { response } = await this.#executeMiddlewares({\n sources: [\n createParallelBalanceMiddleware(slowSources),\n ...(isBasicFunctionality\n ? [\n createParallelMiddleware([\n this.#tokenDataSource,\n this.#priceDataSource,\n ]),\n ]\n : []),\n ],\n request: slowRequest,\n parentContext,\n trace: pipelineTrace,\n });\n await this.#updateState(response);\n },\n }).catch((error: unknown) => log('Background pipeline failed', { error }));\n }\n\n #emitFastFetchTraces({\n accounts,\n chainIds,\n result,\n durationMs,\n isBasicFunctionality,\n parentContext,\n pipelineTrace,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n result: {\n response: DataResponse;\n durationByDataSource: Record<string, number>;\n };\n durationMs: number;\n isBasicFunctionality: boolean;\n parentContext?: TraceContext;\n pipelineTrace?: TraceCallback;\n }): void {\n emitTrace({\n name: TRACE_FULL_FETCH,\n trace: pipelineTrace,\n data: {\n duration_ms: durationMs,\n chain_count: chainIds.length,\n account_count: accounts.length,\n basic_functionality: isBasicFunctionality,\n asset_count: result.response.assetsBalance\n ? Object.values(result.response.assetsBalance).reduce(\n (sum, account) => sum + Object.keys(account).length,\n 0,\n )\n : 0,\n price_count: result.response.assetsPrice\n ? Object.keys(result.response.assetsPrice).length\n : 0,\n ...result.durationByDataSource,\n },\n parentContext,\n });\n emitTrace({\n name: TRACE_FIRST_INIT_FETCH,\n trace: pipelineTrace,\n data: {\n duration_ms: durationMs,\n chain_ids: JSON.stringify(chainIds),\n ...result.durationByDataSource,\n },\n parentContext,\n });\n }\n\n async getAssetsBalance(\n accounts: InternalAccount[],\n options?: {\n chainIds?: ChainId[];\n assetTypes?: AssetType[];\n forceUpdate?: boolean;\n },\n ): Promise<Record<AccountId, Record<Caip19AssetId, AssetBalance>>> {\n // Reuse getAssets with dataTypes: ['balance'] only\n const assets = await this.getAssets(accounts, {\n chainIds: options?.chainIds,\n assetTypes: options?.assetTypes,\n forceUpdate: options?.forceUpdate,\n dataTypes: ['balance', 'metadata'],\n });\n\n // Extract just the balance from each asset\n const result: Record<AccountId, Record<Caip19AssetId, AssetBalance>> = {};\n for (const [accountId, accountAssets] of Object.entries(assets)) {\n result[accountId] = {};\n for (const [assetId, asset] of Object.entries(accountAssets)) {\n if (asset.balance) {\n result[accountId][assetId as Caip19AssetId] = asset.balance;\n }\n }\n }\n\n return result;\n }\n\n getAssetMetadata(assetId: Caip19AssetId): AssetMetadata | undefined {\n return this.state.assetsInfo[assetId];\n }\n\n /**\n * Get a single combined asset (balance + metadata + price + computed\n * `fiatValue`) for an account directly from controller state.\n *\n * Reuses the same state-composition and filtering logic as `getAssets`\n * (balance and metadata are required, a missing price falls back to\n * `{ price: 0, lastUpdated: 0 }` with `fiatValue: 0`, and hidden or\n * otherwise filtered assets are excluded) so the returned shape never\n * drifts from `getAssets`. Reads from current state only and does not\n * trigger a data-source refresh.\n *\n * @param accountId - The account ID (`InternalAccount.id`, not an address).\n * @param assetId - The CAIP-19 asset ID including chain scope\n * (e.g. `eip155:1/erc20:0x...`).\n * @returns The combined `Asset`, or `undefined` when no complete\n * renderable asset (balance + metadata) exists for the account/asset pair.\n * @throws If `accountId` is empty or `assetId` is not a valid CAIP-19 asset ID.\n */\n getAccountAssetByID(\n accountId: AccountId,\n assetId: Caip19AssetId,\n ): Asset | undefined {\n this.#assertNonEmptyAccountId(accountId, 'getAccountAssetByID');\n\n const normalizedAssetId = this.#normalizeAssetIdOrThrow(\n assetId,\n 'getAccountAssetByID',\n );\n\n return this.#getAssetFromState(accountId, normalizedAssetId, {\n assetTypeSet: new Set(['fungible']),\n });\n }\n\n /**\n * Get multiple combined assets (balance + metadata + price + computed\n * `fiatValue`) for an account directly from controller state.\n *\n * Applies the same state-composition and filtering rules as\n * `getAccountAssetByID` to each requested asset ID. Asset IDs that do not\n * resolve to a complete renderable asset (missing balance/metadata, hidden,\n * or otherwise filtered out) are omitted from the result. Reads from\n * current state only and does not trigger a data-source refresh.\n *\n * @param accountId - The account ID (`InternalAccount.id`, not an address).\n * @param assetIds - The CAIP-19 asset IDs including chain scope\n * (e.g. `eip155:1/erc20:0x...`).\n * @returns A record of combined `Asset`s keyed by normalized CAIP-19 asset\n * ID, containing only the requested assets that resolved.\n * @throws If `accountId` is empty or any `assetIds` entry is not a valid\n * CAIP-19 asset ID.\n */\n getAccountAssetsByIDs(\n accountId: AccountId,\n assetIds: Caip19AssetId[],\n ): Record<Caip19AssetId, Asset> {\n this.#assertNonEmptyAccountId(accountId, 'getAccountAssetsByIDs');\n\n const result = Object.create(null) as Record<Caip19AssetId, Asset>;\n\n for (const assetId of assetIds) {\n const normalizedAssetId = this.#normalizeAssetIdOrThrow(\n assetId,\n 'getAccountAssetsByIDs',\n );\n\n const asset = this.#getAssetFromState(accountId, normalizedAssetId, {\n assetTypeSet: new Set(['fungible']),\n });\n\n if (asset) {\n result[normalizedAssetId] = asset;\n }\n }\n\n return result;\n }\n\n /**\n * Get all combined assets (balance + metadata + price + computed\n * `fiatValue`) an account holds on a given chain scope, directly from\n * controller state.\n *\n * Applies the same state-composition and filtering rules as\n * `getAccountAssetByID` (hidden or otherwise filtered assets are excluded).\n * Reads from current state only and does not trigger a data-source refresh.\n *\n * @param accountId - The account ID (`InternalAccount.id`, not an address).\n * @param scope - The CAIP-2 chain ID to filter by (e.g. `eip155:1`).\n * @returns A record of combined `Asset`s keyed by CAIP-19 asset ID,\n * containing only the account's assets on the given scope.\n * @throws If `accountId` is empty or `scope` is not a valid CAIP-2 chain ID.\n */\n getAccountAssetsByScope(\n accountId: AccountId,\n scope: ChainId,\n ): Record<Caip19AssetId, Asset> {\n this.#assertNonEmptyAccountId(accountId, 'getAccountAssetsByScope');\n\n if (!isCaipChainId(scope)) {\n throw new Error(\n `AssetsController.getAccountAssetsByScope: invalid CAIP-2 scope \"${String(\n scope,\n )}\"`,\n );\n }\n\n const result = Object.create(null) as Record<Caip19AssetId, Asset>;\n const chainIdSet = new Set<ChainId>([scope]);\n const assetTypeSet = new Set<AssetType>(['fungible']);\n const accountBalances = this.state.assetsBalance[accountId] ?? {};\n\n for (const assetId of Object.keys(accountBalances)) {\n const typedAssetId = assetId as Caip19AssetId;\n\n const asset = this.#getAssetFromState(accountId, typedAssetId, {\n chainIdSet,\n assetTypeSet,\n });\n\n if (asset) {\n result[typedAssetId] = asset;\n }\n }\n\n return result;\n }\n\n /**\n * Throws when the provided account ID is not a non-empty string.\n *\n * @param accountId - The account ID to validate.\n * @param methodName - The public method name used in the error message.\n */\n #assertNonEmptyAccountId(accountId: AccountId, methodName: string): void {\n if (typeof accountId !== 'string' || accountId.length === 0) {\n throw new Error(\n `AssetsController.${methodName}: accountId must be a non-empty string`,\n );\n }\n }\n\n /**\n * Normalizes a CAIP-19 asset ID, converting normalization failures into a\n * descriptive error.\n *\n * @param assetId - The CAIP-19 asset ID to normalize.\n * @param methodName - The public method name used in the error message.\n * @returns The normalized CAIP-19 asset ID.\n */\n #normalizeAssetIdOrThrow(\n assetId: Caip19AssetId,\n methodName: string,\n ): Caip19AssetId {\n try {\n return normalizeAssetId(assetId);\n } catch {\n throw new Error(\n `AssetsController.${methodName}: invalid CAIP-19 assetId \"${assetId}\"`,\n );\n }\n }\n\n async getAssetsPrice(\n accounts: InternalAccount[],\n options?: {\n chainIds?: ChainId[];\n assetTypes?: AssetType[];\n forceUpdate?: boolean;\n },\n ): Promise<Record<Caip19AssetId, AssetPrice>> {\n const assets = await this.getAssets(accounts, {\n chainIds: options?.chainIds,\n assetTypes: options?.assetTypes,\n forceUpdate: options?.forceUpdate,\n dataTypes: ['price'],\n });\n\n // Extract just the price from each asset (flattened across accounts)\n const result: Record<Caip19AssetId, AssetPrice> = {};\n for (const accountAssets of Object.values(assets)) {\n for (const [assetId, asset] of Object.entries(accountAssets)) {\n if (asset.price) {\n result[assetId as Caip19AssetId] = asset.price;\n }\n }\n }\n\n return result;\n }\n\n /**\n * Returns exchange rates in the format expected by the bridge controller\n * (conversionRates, currencyRates, marketData, currentCurrency) so that\n * when useAssetsControllerForRates is true the bridge can use a single\n * action instead of MultichainAssetsRatesController, TokenRatesController,\n * and CurrencyRateController.\n *\n * @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency.\n */\n getExchangeRatesForBridge(): BridgeExchangeRatesFormat {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n return formatExchangeRatesForBridge({\n assetsInfo: this.state.assetsInfo,\n assetsPrice: this.state.assetsPrice,\n selectedCurrency: this.state.selectedCurrency,\n nativeAssetIdentifiers: this.#getNativeAssetMap(),\n networkConfigurationsByChainId,\n });\n }\n\n /**\n * Returns state in the legacy format expected by transaction-pay-controller\n * (TokenBalancesController, AccountTrackerController, TokensController,\n * TokenRatesController, CurrencyRateController shapes) so that when\n * useAssetsController is true the transaction-pay-controller can use a\n * single action instead of five separate getState calls.\n *\n * @returns Legacy-compatible state for transaction-pay-controller.\n */\n getStateForTransactionPay(): TransactionPayLegacyFormat {\n const accounts = this.#getSelectedAccounts();\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n return formatStateForTransactionPay({\n assetsBalance: this.state.assetsBalance,\n assetsInfo: this.state.assetsInfo,\n assetsPrice: this.state.assetsPrice,\n selectedCurrency: this.state.selectedCurrency,\n accounts: accounts.map((a) => ({ id: a.id, address: a.address })),\n nativeAssetIdentifiers: this.#getNativeAssetMap(),\n networkConfigurationsByChainId,\n });\n }\n\n // ============================================================================\n // CUSTOM ASSETS MANAGEMENT\n // ============================================================================\n\n /**\n * Add a custom asset for an account.\n * Custom assets are included in subscription and fetch operations.\n * Adding a custom asset also unhides it if it was previously hidden,\n * and force-fetches that asset's chain (including every visible pin).\n *\n * When `pendingMetadata` is provided (e.g. from the extension's pending-tokens\n * flow), the token metadata is persisted immediately into `assetsInfo` so the\n * UI can render it without waiting for the next pipeline fetch.\n *\n * @param accountId - The account ID to add the custom asset for.\n * @param assetId - The CAIP-19 asset ID to add.\n * @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).\n */\n async addCustomAsset(\n accountId: AccountId,\n assetId: Caip19AssetId,\n pendingMetadata?: PendingTokenMetadata,\n ): Promise<void> {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Adding custom asset', { accountId, assetId: normalizedAssetId });\n\n this.update((state) => {\n const customAssets = state.customAssets as Record<string, string[]>;\n if (!customAssets[accountId]) {\n customAssets[accountId] = [];\n }\n\n // Only add if not already present\n if (!customAssets[accountId].includes(normalizedAssetId)) {\n customAssets[accountId].push(normalizedAssetId);\n }\n\n // Unhide the asset if it was hidden (via assetPreferences)\n const prefs = state.assetPreferences[normalizedAssetId];\n if (prefs?.hidden) {\n delete prefs.hidden;\n if (Object.keys(prefs).length === 0) {\n delete state.assetPreferences[normalizedAssetId];\n }\n }\n\n // Persist metadata from the UI so the token is immediately renderable\n if (pendingMetadata) {\n const parsed = parseCaipAssetType(normalizedAssetId);\n let tokenType: FungibleAssetMetadata['type'] = 'erc20';\n if (this.#isNativeAsset(normalizedAssetId)) {\n tokenType = 'native';\n } else if (\n parsed.chain.namespace === KnownCaipNamespace.Solana &&\n parsed.assetNamespace === CaipAssetNamespace.Token\n ) {\n tokenType = 'spl';\n }\n\n const assetMetadata: FungibleAssetMetadata = {\n type: tokenType,\n symbol: pendingMetadata.symbol,\n name: pendingMetadata.name,\n decimals: pendingMetadata.decimals,\n image: pendingMetadata.iconUrl,\n aggregators: pendingMetadata.aggregators,\n occurrences: pendingMetadata.occurrences,\n };\n\n (state.assetsInfo as Record<string, AssetMetadata>)[normalizedAssetId] =\n assetMetadata;\n }\n\n // Seed a zero balance so the UI can render the asset immediately,\n // before the next pipeline fetch returns the real amount.\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n balances[accountId] ??= {};\n balances[accountId][normalizedAssetId] ??=\n getZeroAssetBalance(normalizedAssetId);\n });\n\n const account = this.#getSelectedAccounts().find((a) => a.id === accountId);\n if (account) {\n await this.getAssets([account], {\n chainIds: [extractChainId(normalizedAssetId)],\n dataTypes: ['balance', 'metadata', 'price'],\n assetTypes: ['fungible'],\n forceUpdate: true,\n });\n }\n\n // Re-evaluate subscriptions so polls pick up the new pin.\n this.#subscribeAssets();\n }\n\n /**\n * Remove a custom asset from an account.\n *\n * @param accountId - The account ID to remove the custom asset from.\n * @param assetId - The CAIP-19 asset ID to remove.\n */\n removeCustomAsset(accountId: AccountId, assetId: Caip19AssetId): void {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Removing custom asset', { accountId, assetId: normalizedAssetId });\n\n this.update((state) => {\n if (state.customAssets[accountId]) {\n state.customAssets[accountId] = state.customAssets[accountId].filter(\n (id) => id !== normalizedAssetId,\n );\n\n // Clean up empty arrays\n if (state.customAssets[accountId].length === 0) {\n delete state.customAssets[accountId];\n }\n }\n });\n\n // Re-evaluate subscriptions so polls drop the removed pin.\n this.#subscribeAssets();\n }\n\n /**\n * Get all custom assets for an account.\n *\n * @param accountId - The account ID to get custom assets for.\n * @returns Array of CAIP-19 asset IDs for the account's custom assets.\n */\n getCustomAssets(accountId: AccountId): Caip19AssetId[] {\n return this.state.customAssets[accountId] ?? [];\n }\n\n // ============================================================================\n // HIDDEN ASSETS MANAGEMENT\n // ============================================================================\n\n /**\n * Hide an asset globally.\n * Hidden assets are excluded from the asset list returned by getAssets.\n * The hidden state is stored in assetPreferences.\n *\n * @param assetId - The CAIP-19 asset ID to hide.\n */\n hideAsset(assetId: Caip19AssetId): void {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Hiding asset', { assetId: normalizedAssetId });\n\n this.update((state) => {\n if (!state.assetPreferences[normalizedAssetId]) {\n state.assetPreferences[normalizedAssetId] = {};\n }\n state.assetPreferences[normalizedAssetId].hidden = true;\n });\n\n // Re-evaluate subscriptions so polls exclude the newly hidden asset.\n this.#subscribeAssets();\n }\n\n /**\n * Unhide an asset globally.\n * Force-fetches that asset's chain (including every visible pin) so a\n * `full` snapshot can restore the balance immediately, then re-evaluates\n * subscriptions so later polls stop excluding it.\n *\n * @param assetId - The CAIP-19 asset ID to unhide.\n */\n async unhideAsset(assetId: Caip19AssetId): Promise<void> {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Unhiding asset', { assetId: normalizedAssetId });\n\n this.update((state) => {\n const prefs = state.assetPreferences[normalizedAssetId];\n if (prefs) {\n delete prefs.hidden;\n if (Object.keys(prefs).length === 0) {\n delete state.assetPreferences[normalizedAssetId];\n }\n }\n });\n\n const chainId = extractChainId(normalizedAssetId);\n const account = this.#getSelectedAccounts().find((selectedAccount) =>\n this.#getEnabledChainsForAccount(selectedAccount).includes(chainId),\n );\n if (account) {\n await this.getAssets([account], {\n chainIds: [chainId],\n dataTypes: ['balance', 'metadata', 'price'],\n assetTypes: ['fungible'],\n forceUpdate: true,\n });\n }\n\n this.#subscribeAssets();\n }\n\n /**\n * Whether Accounts API v6 (and the v6 custom-asset path) is enabled.\n * Injected into AccountsApiDataSource and RpcFallbackMiddleware.\n *\n * `RemoteFeatureFlagController` resolves a threshold-scoped flag to the\n * selected group's `value`, so processed state is a boolean.\n *\n * @returns `true` when the v6 remote flag is on.\n */\n #isBalanceV6Enabled(): boolean {\n try {\n const { remoteFeatureFlags } = this.messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n return remoteFeatureFlags?.assetsAccountsApiV6 === true;\n } catch {\n return false;\n }\n }\n\n // ============================================================================\n // CURRENT CURRENCY MANAGEMENT\n // ============================================================================\n\n /**\n * Set the current currency.\n *\n * @param selectedCurrency - The ISO 4217 currency code to set.\n */\n setSelectedCurrency(selectedCurrency: SupportedCurrency): void {\n const previousCurrency = this.state.selectedCurrency;\n\n if (previousCurrency === selectedCurrency) {\n return;\n }\n\n this.update((state) => {\n state.selectedCurrency = selectedCurrency;\n });\n\n log('Current currency changed', {\n previousCurrency,\n selectedCurrency,\n });\n\n if (!this.#isBasicFunctionality()) {\n return;\n }\n\n // Currency changed — old cached prices are in the wrong currency.\n this.#priceDataSource.invalidatePriceCache();\n\n this.syncAssetsPrices(\n Object.values(this.state.assetsBalance).flatMap(\n (balances) => Object.keys(balances) as Caip19AssetId[],\n ),\n ).catch((error) => {\n log('Failed to fetch asset prices after current currency change', error);\n });\n }\n\n // ============================================================================\n // SUBSCRIPTIONS\n // ============================================================================\n\n /**\n * Subscribe to price updates for all assets held by the given accounts.\n * Polls PriceDataSource which fetches prices from balance state.\n *\n * @param accounts - Accounts to subscribe price updates for.\n * @param chainIds - Chain IDs to filter prices for.\n */\n subscribeAssetsPrice(accounts: InternalAccount[], chainIds: ChainId[]): void {\n if (!this.#isBasicFunctionality()) {\n return;\n }\n const subscriptionKey = 'ds:PriceDataSource';\n\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n const isUpdate = existingSubscription !== undefined;\n\n const request = this.#buildDataRequest(accounts, chainIds, {\n dataTypes: ['price'],\n });\n const subscribeReq: SubscriptionRequest = {\n request,\n subscriptionId: subscriptionKey,\n isUpdate,\n onAssetsUpdate: (response) =>\n this.handleAssetsUpdate(response, 'PriceDataSource'),\n };\n\n this.#priceDataSource.subscribe(subscribeReq).catch(console.error);\n\n // Track subscription\n const subscription: SubscriptionResponse = {\n chains: chainIds,\n accountId: subscriptionKey,\n assetTypes: ['fungible'],\n dataTypes: ['price'],\n unsubscribe: () => {\n this.#activeSubscriptions.delete(subscriptionKey);\n },\n };\n\n this.#activeSubscriptions.set(subscriptionKey, subscription);\n }\n\n /**\n * Unsubscribe from price updates.\n */\n unsubscribeAssetsPrice(): void {\n const subscriptionKey = 'ds:PriceDataSource';\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n\n if (!existingSubscription) {\n return;\n }\n this.#priceDataSource.unsubscribe(subscriptionKey).catch(console.error);\n existingSubscription.unsubscribe();\n }\n\n // ============================================================================\n // STATE MANAGEMENT\n // ============================================================================\n\n /**\n * Reads the native asset map (CAIP-2 chain ID -> CAIP-19 native asset ID)\n * from the QueryClient cache. Populated at construction via fetchQuery.\n *\n * @returns Cached map, or a stable empty object if not yet populated\n * (stable identity so downstream memoized formatters can cache-hit).\n */\n #getNativeAssetMap(): Record<ChainId, Caip19AssetId> {\n return (\n this.#queryApiClient.getCachedData<Record<ChainId, Caip19AssetId>>(\n NATIVE_ASSETS_QUERY_KEY,\n ) ?? EMPTY_NATIVE_ASSET_MAP\n );\n }\n\n /**\n * Canonical native CAIP-19 ID for a chain. Uses the native asset map when\n * the chain is registered. An unregistered EVM chain falls back to the\n * zero-address ERC-20 encoding used for EVM natives without a SLIP-44 id;\n * an unregistered non-EVM chain resolves no native at all — fabricating an\n * `erc20:` asset on a non-EVM namespace would produce an ID no data source\n * ever writes.\n *\n * @param chainId - CAIP-2 chain ID.\n * @returns The native asset ID for the chain, or `undefined` when the\n * chain is unregistered and non-EVM.\n */\n #getNativeAssetForChain(chainId: ChainId): Caip19AssetId | undefined {\n const registered = this.#getNativeAssetMap()[chainId];\n if (registered) {\n return registered;\n }\n if (parseCaipChainId(chainId).namespace === KnownCaipNamespace.Eip155) {\n return `${chainId}/${UNKNOWN_EVM_NATIVE_ASSET_REFERENCE}` as Caip19AssetId;\n }\n return undefined;\n }\n\n #getAssetVisibility(\n accountIds: AccountId[],\n chainIds: ChainId[],\n ): AssetVisibility {\n return getAssetVisibility({\n state: this.state,\n accountIds,\n chainIds,\n getNativeAssetForChain: (chainId) =>\n this.#getNativeAssetForChain(chainId),\n });\n }\n\n /**\n * Lowercased asset IDs a v6 `full` snapshot must keep for an account, even\n * when the response omits them: natives, pins, and default tracked assets\n * the client asked for. Hidden assets are sent as `excludeAssetIds` and are\n * dropped here; unhide is expected to fetch a new snapshot. Everything else\n * on a covered chain was discovered by the source, so its absence means the\n * balance is gone.\n *\n * @param state - State being updated (the in-flight draft, not `this.state`).\n * @param accountId - Account whose pins apply.\n * @param accountBalances - Incoming balances, which define the covered chains.\n * @returns Lowercased CAIP-19 IDs that must survive the replace.\n */\n #getUndeletableAssetIds(\n state: AssetsControllerState,\n accountId: AccountId,\n accountBalances: Record<string, AssetBalance>,\n ): Set<string> {\n const coveredChainIds = [\n ...new Set(\n Object.keys(accountBalances).map(\n (assetId) => assetId.split('/')[0] as ChainId,\n ),\n ),\n ];\n const { visibleAssetIds } = getAssetVisibility({\n state,\n accountIds: [accountId],\n chainIds: coveredChainIds,\n // Registered natives only: the unknown-native fallback is a fabricated\n // ID, so it must never shield a row from a `full` replace.\n getNativeAssetForChain: (chainId) => this.#getNativeAssetMap()[chainId],\n });\n\n return new Set(visibleAssetIds.map((assetId) => assetId.toLowerCase()));\n }\n\n /**\n * Checks whether the given CAIP-19 asset ID represents a native asset\n * according to the cached native asset map, the asset namespace, and the asset reference.\n *\n * @param assetId - The CAIP-19 asset ID to check (case-insensitive).\n * @returns True if the asset ID is a native asset.\n */\n #isNativeAsset(assetId: Caip19AssetId): boolean {\n const parsed = parseCaipAssetType(assetId);\n\n if (parsed.assetNamespace === 'slip44') {\n return true;\n }\n\n const lower = assetId.toLowerCase();\n const isInNativeAssetMap = Object.values(this.#getNativeAssetMap()).some(\n (id) => id.toLowerCase() === lower,\n );\n if (isInNativeAssetMap) {\n return true;\n }\n\n if (\n parsed.assetNamespace === 'erc20' &&\n parsed.assetReference === ZERO_ADDRESS\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Determines the asset type for a given CAIP-19 asset ID.\n *\n * @param assetId - The CAIP-19 asset ID.\n * @returns The asset type: 'native', 'erc20', or 'spl'.\n */\n #getAssetType(assetId: Caip19AssetId): 'native' | 'erc20' | 'spl' {\n const parsed = parseCaipAssetType(assetId);\n\n if (this.#isNativeAsset(assetId)) {\n return 'native';\n }\n\n if (\n parsed.chain.namespace === KnownCaipNamespace.Solana &&\n parsed.assetNamespace === CaipAssetNamespace.Token\n ) {\n return 'spl';\n }\n\n return 'erc20';\n }\n\n /**\n * Resolves native asset IDs (CAIP-19) for the given chains by looking them up\n * in the cached native asset map.\n * Chains without a registered native identifier are skipped.\n *\n * @param chains - The chain IDs to resolve native assets for.\n * @returns Array of native asset IDs for the chains that have a registered identifier.\n */\n #resolveNativeAssetIds(chains: Iterable<ChainId>): Caip19AssetId[] {\n const nativeAssetMap = this.#getNativeAssetMap();\n const ids: Caip19AssetId[] = [];\n for (const chainId of chains) {\n const nativeId = nativeAssetMap[chainId];\n if (nativeId) {\n ids.push(nativeId);\n }\n }\n return ids;\n }\n\n /**\n * Returns native asset IDs for all enabled chains.\n *\n * @returns Array of native asset IDs, one per enabled chain that has a registered identifier.\n */\n #getNativeAssetIdsForEnabledChains(): Caip19AssetId[] {\n return this.#resolveNativeAssetIds(this.#enabledChains);\n }\n\n /**\n * Returns native asset IDs for the chains that this account supports\n * (account scopes ∩ enabled chains).\n *\n * @param account - The account (scopes determine which chains apply).\n * @returns Array of native asset IDs, one per supported chain that has a registered identifier.\n */\n #getNativeAssetIdsForAccount(account: InternalAccount): Caip19AssetId[] {\n return this.#resolveNativeAssetIds(\n this.#getEnabledChainsForAccount(account),\n );\n }\n\n /**\n * Chains for the post-commit slow pipeline (Snap + RPC). Excludes chains the\n * fast Accounts API path already handled without error so stale RPC data cannot\n * overwrite fresh API zeros (e.g. after max send).\n *\n * @param chainIds - Chains requested by the caller.\n * @param fastResponse - Response committed by the fast pipeline.\n * @returns Chain IDs that still need the slow pipeline.\n */\n #getSlowPipelineChainIds(\n chainIds: ChainId[],\n fastResponse: DataResponse,\n ): ChainId[] {\n const accountsApiChains = new Set(\n this.#accountsApiDataSource.getActiveChainsSync(),\n );\n\n return chainIds.filter((chainId) => {\n if (fastResponse.errors?.[chainId]) {\n return true;\n }\n if (!accountsApiChains.has(chainId)) {\n return true;\n }\n return false;\n });\n }\n\n /**\n * Ensures assetsBalance has a 0 balance for each native token (from\n * NetworkEnablementController.nativeAssetIdentifiers) for each selected account.\n * Only adds natives for chains that the account supports (correct accountId ↔ chain mapping).\n */\n #ensureNativeBalancesDefaultZero(): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n this.update((state) => {\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n for (const account of accounts) {\n const accountId = account.id;\n const nativeAssetIds = this.#getNativeAssetIdsForAccount(account);\n if (nativeAssetIds.length === 0) {\n continue;\n }\n if (!balances[accountId]) {\n balances[accountId] = {};\n }\n for (const nativeAssetId of nativeAssetIds) {\n if (\n !Object.prototype.hasOwnProperty.call(\n balances[accountId],\n nativeAssetId,\n )\n ) {\n balances[accountId][nativeAssetId] =\n getDefaultNativeAssetBalance(nativeAssetId);\n }\n }\n }\n });\n }\n\n /**\n * Seed selected accounts with zero-balance entries for every\n * controller-managed default tracked asset (e.g. mUSD on mainnet,\n * Linea, Monad). Also re-asserts the metadata in `assetsInfo` so the\n * defaults survive a future state migration that strips them.\n *\n * `chainsToSeed` lets callers narrow the work to a specific subset\n * of chains — useful when reacting to a `NetworkEnablementController`\n * change to seed only the chain that was just added (e.g. when the\n * user finally turns on Monad). When `undefined`, every chain in the\n * default tracked assets registry is seeded.\n *\n * Existing entries are never clobbered.\n *\n * @param chainsToSeed - Optional subset of CAIP-2 chain ids to seed.\n * If omitted, all default tracked chains are seeded.\n */\n #ensureDefaultTrackedAssetsSeeded(chainsToSeed?: ChainId[]): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n // Default tracked assets are ERC-20s on EVM chains today. Restrict\n // seeding to accounts that have at least one EVM scope so we don't\n // pollute non-EVM accounts. The wildcard `eip155:0` scope counts.\n const evmAccounts = accounts.filter((account) =>\n (account.scopes ?? []).some((scope) => scope.startsWith('eip155:')),\n );\n if (evmAccounts.length === 0) {\n return;\n }\n\n // Gate seeding on whether the chain is currently enabled. This is\n // why mUSD appears on mainnet/Linea immediately (those are normally\n // enabled at startup) but only appears on Monad once the user\n // turns the Monad network on.\n const candidateChains = chainsToSeed ?? [...this.#enabledChains];\n const targetChains = candidateChains.filter((chainId) =>\n CHAINS_WITH_DEFAULT_TRACKED_ASSETS.has(chainId),\n );\n if (targetChains.length === 0) {\n return;\n }\n this.update((state) => {\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n const metadata = state.assetsInfo as Record<string, AssetMetadata>;\n\n for (const chainId of targetChains) {\n const defaultAssetIds =\n DEFAULT_TRACKED_ASSETS_BY_CHAIN.get(chainId) ?? [];\n for (const assetId of defaultAssetIds) {\n // Re-seed metadata if state was hydrated from a prior version\n // that didn't include defaults.\n if (!metadata[assetId]) {\n const seed = getDefaultAssetMetadata(assetId);\n if (seed) {\n metadata[assetId] = seed;\n }\n }\n\n for (const account of evmAccounts) {\n balances[account.id] ??= {};\n const accountBalances = balances[account.id];\n accountBalances[assetId] ??= { amount: '0' };\n }\n }\n }\n });\n }\n\n async #updateState(response: DataResponse): Promise<void> {\n const normalizedResponse = normalizeResponse(response);\n const mode: AssetsUpdateMode = normalizedResponse.updateMode ?? 'merge';\n const isBalanceV6Enabled = this.#isBalanceV6Enabled();\n\n const releaseLock = await this.#controllerMutex.acquire();\n\n try {\n const previousState = this.state;\n const previousPrices = { ...this.state.assetsPrice };\n\n // Track actual changes for logging\n const changedBalances: {\n accountId: string;\n assetId: string;\n oldAmount: string | undefined;\n newAmount: string;\n }[] = [];\n const changedMetadata: string[] = [];\n\n this.update((state) => {\n // Use type assertions to avoid deep type instantiation issues with Immer Draft types\n const metadata = state.assetsInfo as Record<string, AssetMetadata>;\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n const prices = state.assetsPrice as Record<string, AssetPrice>;\n\n if (normalizedResponse.assetsInfo) {\n for (const [key, value] of Object.entries(\n normalizedResponse.assetsInfo,\n )) {\n const existing = metadata[key] as FungibleAssetMetadata | undefined;\n const incoming = value as FungibleAssetMetadata;\n\n // When the API returns no symbol or name for this token, it has no\n // real knowledge of it (e.g. a user-deployed token not indexed by\n // the API). Preserve richer metadata already in state (e.g. from\n // pendingMetadata set by addCustomAsset) so that the correct\n // decimals/symbol/name/image are not overwritten with empty values.\n const nextValue =\n existing && !incoming.symbol && !incoming.name\n ? {\n ...existing,\n ...incoming,\n symbol: existing.symbol,\n name: existing.name,\n decimals: existing.decimals ?? incoming.decimals,\n image: existing.image ?? incoming.image,\n }\n : value;\n\n if (\n !isEqual(\n previousState.assetsInfo[key as Caip19AssetId],\n nextValue,\n )\n ) {\n metadata[key] = nextValue;\n changedMetadata.push(key);\n }\n }\n }\n\n // Reconcile & self-heal stale asset \"types\" (e.g. erc20 -> native)\n // using IDs from new response assetInfo and assetBalance\n const assetsInfoAssetIdsSet = new Set<Caip19AssetId>([\n ...Object.keys(normalizedResponse.assetsInfo ?? {}),\n ...Object.values(normalizedResponse.assetsBalance ?? {}).flatMap(\n (accountBalances) => Object.keys(accountBalances),\n ),\n ] as Caip19AssetId[]);\n for (const assetId of assetsInfoAssetIdsSet) {\n const entry = metadata[assetId] as FungibleAssetMetadata | undefined;\n if (!entry) {\n continue;\n }\n const correctType = this.#getAssetType(assetId);\n if (entry.type !== correctType) {\n metadata[assetId] = { ...entry, type: correctType };\n if (!changedMetadata.includes(assetId)) {\n changedMetadata.push(assetId);\n }\n }\n }\n\n if (normalizedResponse.assetsBalance) {\n const applyV5AccountBalanceUpdate = (\n accountId: string,\n accountBalances: Record<string, AssetBalance>,\n previousBalances: Record<string, AssetBalance>,\n ): void => {\n const customAssetIds =\n (state.customAssets as Record<string, Caip19AssetId[]>)[\n accountId\n ] ?? [];\n\n const replaceCoveredChains =\n mode === 'full' ||\n normalizedResponse.replaceCoveredChainBalances === true;\n\n const effectiveAccountBalances = effectiveAccountBalancesV5(\n previousBalances,\n accountBalances,\n customAssetIds,\n replaceCoveredChains,\n );\n\n // Ensure native tokens have an entry (0 if missing) for chains this account supports\n const account = this.#getSelectedAccounts().find(\n (a) => a.id === accountId,\n );\n const nativeAssetIdsForAccount = account\n ? this.#getNativeAssetIdsForAccount(account)\n : [];\n for (const nativeAssetId of nativeAssetIdsForAccount) {\n if (\n !Object.prototype.hasOwnProperty.call(\n effectiveAccountBalances,\n nativeAssetId,\n )\n ) {\n effectiveAccountBalances[nativeAssetId] =\n getDefaultNativeAssetBalance(nativeAssetId);\n }\n }\n\n for (const [assetId, balance] of Object.entries(\n effectiveAccountBalances,\n )) {\n const previousBalance = previousBalances[\n assetId as Caip19AssetId\n ] as AssetBalance | undefined;\n // Coerce amounts (e.g. \"1e-18\" from a data source stringifying\n // a JS Number) into a plain decimal so downstream BigInt()\n // consumers don't crash. Decimals are read from the freshest\n // merged metadata when available; when metadata is not yet\n // known, the amount is left at its natural precision (only\n // exponent form is rewritten) so balances arriving before\n // their metadata aren't lossily truncated.\n const assetDecimals = (\n metadata[assetId] as { decimals?: number } | undefined\n )?.decimals;\n const newAmount = normalizeAmountString(\n (balance as { amount: unknown }).amount,\n assetDecimals,\n );\n const newMetadata =\n (balance as FungibleAssetBalance).metadata ??\n (previousBalance as FungibleAssetBalance | undefined)?.metadata;\n effectiveAccountBalances[assetId] = {\n amount: newAmount,\n ...(newMetadata === undefined ? {} : { metadata: newMetadata }),\n };\n const oldAmount = previousBalance?.amount;\n const isNewSeededZero =\n oldAmount === undefined &&\n newAmount === '0' &&\n (nativeAssetIdsForAccount.includes(assetId as Caip19AssetId) ||\n getDefaultAssetMetadata(assetId as Caip19AssetId) !==\n undefined);\n if (oldAmount !== newAmount && !isNewSeededZero) {\n changedBalances.push({\n accountId,\n assetId,\n oldAmount,\n newAmount,\n });\n }\n }\n\n if (!isEqual(previousBalances, effectiveAccountBalances)) {\n balances[accountId] = effectiveAccountBalances;\n }\n };\n\n // Delete with the rest of the v6 path if `assetsAccountsApiV6` is\n // rolled back; v5 keeps using `applyV5AccountBalanceUpdate`.\n const applyV6AccountBalanceUpdate = (\n accountId: string,\n accountBalances: Record<string, AssetBalance>,\n previousBalances: Record<string, AssetBalance>,\n ): void => {\n const effectiveAccountBalances = effectiveAccountBalancesV6(\n previousBalances,\n accountBalances,\n this.#getUndeletableAssetIds(\n state as unknown as AssetsControllerState,\n accountId,\n accountBalances,\n ),\n mode,\n );\n\n for (const [assetId, balance] of Object.entries(\n effectiveAccountBalances,\n )) {\n const previousBalance = previousBalances[\n assetId as Caip19AssetId\n ] as AssetBalance | undefined;\n const assetDecimals = (\n metadata[assetId] as { decimals?: number } | undefined\n )?.decimals;\n const newAmount = normalizeAmountString(\n (balance as { amount: unknown }).amount,\n assetDecimals,\n );\n const newMetadata =\n (balance as FungibleAssetBalance).metadata ??\n (previousBalance as FungibleAssetBalance | undefined)?.metadata;\n effectiveAccountBalances[assetId] = {\n amount: newAmount,\n ...(newMetadata === undefined ? {} : { metadata: newMetadata }),\n };\n const oldAmount = previousBalance?.amount;\n // A v6 snapshot reports assets the account holds none of (its\n // `includeAssetIds`) at zero. Publishing those as a change would\n // emit `0 -> 0`, since a missing previous amount reads as '0'.\n const isNewZero = oldAmount === undefined && newAmount === '0';\n if (oldAmount !== newAmount && !isNewZero) {\n changedBalances.push({\n accountId,\n assetId,\n oldAmount,\n newAmount,\n });\n }\n }\n\n if (!isEqual(previousBalances, effectiveAccountBalances)) {\n balances[accountId] = effectiveAccountBalances;\n }\n };\n\n for (const [accountId, accountBalances] of Object.entries(\n normalizedResponse.assetsBalance,\n )) {\n const previousBalances =\n previousState.assetsBalance[accountId] ?? {};\n\n if (isBalanceV6Enabled) {\n applyV6AccountBalanceUpdate(\n accountId,\n accountBalances,\n previousBalances,\n );\n } else {\n applyV5AccountBalanceUpdate(\n accountId,\n accountBalances,\n previousBalances,\n );\n }\n }\n }\n\n if (normalizedResponse.assetsPrice) {\n for (const [key, value] of Object.entries(\n normalizedResponse.assetsPrice,\n )) {\n if (!isEqual(previousPrices[key as Caip19AssetId], value)) {\n prices[key] = value;\n }\n }\n }\n });\n\n // Emit state size trace (throttled to avoid JSON.stringify on every update)\n this.#emitStateSizeTrace();\n\n // Calculate changed prices\n const changedPriceAssets: string[] = normalizedResponse.assetsPrice\n ? Object.keys(normalizedResponse.assetsPrice).filter(\n (assetId) =>\n !isEqual(\n previousPrices[assetId as Caip19AssetId],\n normalizedResponse.assetsPrice?.[assetId as Caip19AssetId],\n ),\n )\n : [];\n\n // Log only actual changes\n if (\n changedBalances.length > 0 ||\n changedMetadata.length > 0 ||\n changedPriceAssets.length > 0\n ) {\n log('State updated', {\n changedBalances:\n changedBalances.length > 0 ? changedBalances : undefined,\n changedMetadata:\n changedMetadata.length > 0 ? changedMetadata : undefined,\n changedPrices:\n changedPriceAssets.length > 0 ? changedPriceAssets : undefined,\n });\n }\n\n // Publish balance changed events\n for (const change of changedBalances) {\n this.messenger.publish('AssetsController:balanceChanged', {\n accountId: change.accountId,\n assetId: change.assetId as Caip19AssetId,\n previousAmount: change.oldAmount ?? '0',\n newAmount: change.newAmount,\n });\n }\n\n // Publish price changed event with full price data\n if (changedPriceAssets.length > 0 && normalizedResponse.assetsPrice) {\n // Build prices object with only changed prices\n const changedPrices: Record<Caip19AssetId, AssetPrice> = {};\n for (const assetId of changedPriceAssets) {\n const price =\n normalizedResponse.assetsPrice[assetId as Caip19AssetId];\n if (price) {\n changedPrices[assetId as Caip19AssetId] = price;\n }\n }\n this.messenger.publish('AssetsController:priceChanged', {\n prices: changedPrices,\n });\n }\n } finally {\n releaseLock();\n }\n }\n\n #getAssetsFromState(\n accounts: Pick<InternalAccount, 'id'>[],\n chainIds: ChainId[],\n assetTypes: AssetType[],\n ): Record<AccountId, Record<Caip19AssetId, Asset>> {\n const result = Object.create(null) as Record<\n AccountId,\n Record<Caip19AssetId, Asset>\n >;\n // Convert to Sets for O(1) lookups\n const chainIdSet = new Set(chainIds);\n const assetTypeSet = new Set(assetTypes);\n\n for (const account of accounts) {\n result[account.id] = Object.create(null) as Record<Caip19AssetId, Asset>;\n\n const accountBalances = this.state.assetsBalance[account.id] ?? {};\n\n for (const assetId of Object.keys(accountBalances)) {\n const typedAssetId = assetId as Caip19AssetId;\n\n const asset = this.#getAssetFromState(account.id, typedAssetId, {\n chainIdSet,\n assetTypeSet,\n });\n\n if (asset) {\n result[account.id][typedAssetId] = asset;\n }\n }\n }\n\n return result;\n }\n\n /**\n * Compose a single combined `Asset` (balance + metadata + price + computed\n * `fiatValue`) for an account/asset pair directly from controller state,\n * applying the same filtering rules as `#getAssetsFromState`.\n *\n * @param accountId - The account ID (`InternalAccount.id`).\n * @param assetId - The normalized CAIP-19 asset ID.\n * @param filters - Optional filters applied before composing the asset.\n * @param filters.chainIdSet - When provided, the asset's chain must be in this set.\n * @param filters.assetTypeSet - When provided, the asset's type must be in this set.\n * @returns The combined `Asset`, or `undefined` when the asset is missing a\n * balance/metadata, is hidden/filtered out, or fails a provided filter.\n */\n #getAssetFromState(\n accountId: AccountId,\n assetId: Caip19AssetId,\n filters?: {\n chainIdSet?: Set<ChainId>;\n assetTypeSet?: Set<AssetType>;\n },\n ): Asset | undefined {\n const balance = this.state.assetsBalance[accountId]?.[assetId];\n\n // Skip assets without a balance entry\n if (!balance) {\n return undefined;\n }\n\n const metadata = this.state.assetsInfo[assetId];\n\n // Skip assets without metadata\n if (!metadata) {\n return undefined;\n }\n\n // Skip hidden assets (assetPreferences)\n const prefs = this.state.assetPreferences[assetId];\n if (prefs?.hidden) {\n return undefined;\n }\n\n const assetChainId = extractChainId(assetId);\n\n // Skip native tokens on Tempo networks\n if (this.#shouldHideNativeToken(assetChainId, metadata)) {\n return undefined;\n }\n\n if (filters?.chainIdSet && !filters.chainIdSet.has(assetChainId)) {\n return undefined;\n }\n\n // Filter by asset type\n if (filters?.assetTypeSet) {\n const tokenAssetType = this.#tokenStandardToAssetType(metadata.type);\n if (!filters.assetTypeSet.has(tokenAssetType)) {\n return undefined;\n }\n }\n\n const priceRaw = this.state.assetsPrice[assetId];\n const price: AssetPrice = priceRaw ?? {\n price: 0,\n lastUpdated: 0,\n };\n\n // Compute fiat value using BigNumber for precision\n // Note: balance.amount is already in human-readable format (e.g., \"1\" for 1 ETH)\n // so we do NOT divide by 10^decimals here\n const balanceAmount = new BigNumberJS(balance.amount || '0');\n const fiatValue = balanceAmount.multipliedBy(price.price || 0).toNumber();\n\n return {\n id: assetId,\n chainId: assetChainId,\n balance,\n metadata,\n price,\n fiatValue,\n };\n }\n\n /**\n * Determines if a native token should be hidden on specific networks.\n *\n * @param chainId - The CAIP-2 chain ID (e.g., \"eip155:42431\").\n * @param metadata - The asset metadata.\n * @returns True if the token should be hidden, false otherwise.\n */\n #shouldHideNativeToken(chainId: ChainId, metadata: AssetMetadata): boolean {\n // Check if it's a chain that should skip native tokens\n if (!shouldSkipNativeForCaipChainId(chainId)) {\n return false;\n }\n\n return metadata.type === 'native';\n }\n\n /**\n * Maps a token standard to its corresponding asset type.\n *\n * @param tokenStandard - The token standard from metadata.\n * @returns The corresponding asset type.\n */\n #tokenStandardToAssetType(tokenStandard: string): AssetType {\n switch (tokenStandard) {\n case 'native':\n case 'erc20':\n case 'spl':\n return 'fungible';\n case 'erc721':\n return 'nft';\n case 'erc1155':\n // ERC1155 can be either fungible or non-fungible, treat as collectible\n return 'collectible';\n default:\n // Unknown standards default to fungible\n return 'fungible';\n }\n }\n\n // ============================================================================\n // START / STOP\n // ============================================================================\n\n /**\n * Start asset tracking: subscribe to updates and fetch current balances.\n * Idempotent — returns early if accounts/chains are not yet available or\n * subscriptions are already active.\n */\n #start(): void {\n const accounts = this.#getSelectedAccounts();\n const chainIds = [...this.#enabledChains];\n\n if (accounts.length === 0 || chainIds.length === 0) {\n return;\n }\n\n if (this.#activeSubscriptions.size > 0 || this.#startInFlight) {\n return;\n }\n\n log('Starting asset tracking', {\n selectedAccountCount: accounts.length,\n enabledChainCount: chainIds.length,\n });\n\n this.#startInFlight = true;\n this.#runStartupRefresh(accounts)\n .catch((error) => {\n log('Failed to start asset tracking', error);\n })\n .finally(() => {\n this.#startInFlight = false;\n });\n }\n\n /**\n * Stop asset tracking: unsubscribe from all updates.\n * Called when app closes or keyring locks.\n */\n #stop(): void {\n log('Stopping asset tracking', {\n activeSubscriptionCount: this.#activeSubscriptions.size,\n hasPriceSubscription: this.#activeSubscriptions.has('ds:PriceDataSource'),\n });\n\n this.#firstInitFetchReported = false;\n this.#stateSizeReported = false;\n\n // Stop price subscription first (uses direct messenger call)\n this.unsubscribeAssetsPrice();\n\n // Stop balance subscriptions by properly notifying data sources via messenger\n // This ensures data sources stop their polling timers.\n // Use #allBalanceDataSources + staked balance source so we unsubscribe from\n // every source that may have been subscribed.\n const allSources = [\n ...this.#allBalanceDataSources,\n this.#stakedBalanceDataSource,\n ];\n const subscriptionKeys = [...this.#activeSubscriptions.keys()];\n for (const subscriptionKey of subscriptionKeys) {\n if (!subscriptionKey.startsWith('ds:')) {\n continue;\n }\n // Subscription keys take the form `ds:<SourceName>`.\n const [, sourceId] = subscriptionKey.split(':');\n const source = allSources.find((ds) => ds.getName() === sourceId);\n if (source) {\n this.#unsubscribeBySubscriptionKey(source, subscriptionKey);\n }\n }\n this.#activeSubscriptions.clear();\n }\n\n /**\n * Handle basic functionality toggle change. Call this from the consumer (extension or mobile)\n * when the user changes the \"Basic functionality\" setting. Refreshes subscriptions so the\n * current {@link AssetsControllerOptions.isBasicFunctionality} getter is used (true = APIs on,\n * false = RPC only).\n *\n * @param _isBasic - The new value (for call-site clarity; the getter is the source of truth).\n */\n handleBasicFunctionalityChange(_isBasic: boolean): void {\n this.#stop();\n this.#subscribeAssets();\n }\n\n /**\n * Subscribe to asset updates for all selected accounts.\n *\n * @param options - Subscription options.\n * @param options.skipInitialFetch - When true, AccountsApi skips its\n * one-shot subscribe poll (use after a force `getAssets` for the same scope).\n */\n #subscribeAssets(options?: { skipInitialFetch?: boolean }): void {\n const accounts = this.#getSelectedAccounts();\n const enabledChains = [...this.#enabledChains];\n if (accounts.length === 0 || enabledChains.length === 0) {\n return;\n }\n\n // Subscribe to balance updates (batched by data source)\n this.#subscribeAssetsBalance(accounts, enabledChains, options);\n\n // Subscribe to staked balance updates (separate from regular balance chain-claiming)\n this.#subscribeStakedBalance(accounts, enabledChains);\n\n // Subscribe to price updates for all assets held by selected accounts\n this.subscribeAssetsPrice(accounts, enabledChains);\n }\n\n /**\n * Subscribe to balance updates for the given accounts and chains.\n *\n * Strategy to minimize data source calls:\n * 1. Collect all chains to subscribe based on enabled networks\n * 2. Map chains to accounts based on their scopes\n * 3. Split by data source (priority order) — each source gets one\n * subscription for the chains it was assigned (accounts + chains only).\n * v6 sources read pins/hides/defaults from state themselves (Accounts API\n * sends `includeAssetIds` / `excludeAssetIds`; RPC polls native, balances,\n * pins, and default tracked assets). v5 uses a separate RPC\n * `customAssetsOnly` supplement for pins on chains another source owns.\n *\n * @param accounts - Accounts to subscribe balance updates for.\n * @param chainIds - Chain IDs to subscribe for.\n * @param options - Subscription options.\n * @param options.skipInitialFetch - Forwarded to AccountsApi subscribe.\n */\n #subscribeAssetsBalance(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n options?: { skipInitialFetch?: boolean },\n ): void {\n const chainToAccounts = this.#buildChainToAccountsMap(\n accounts,\n new Set(chainIds),\n );\n const remainingChains = new Set(chainToAccounts.keys());\n const balanceDataSources = this.#isBasicFunctionality()\n ? this.#allBalanceDataSources\n : [this.#rpcDataSource];\n let rpcAssignedChains: Set<ChainId> = new Set();\n\n for (const source of balanceDataSources) {\n const availableChains = new Set(source.getActiveChainsSync());\n const assignedChains: ChainId[] = [];\n\n for (const chainId of remainingChains) {\n if (availableChains.has(chainId)) {\n assignedChains.push(chainId);\n remainingChains.delete(chainId);\n }\n }\n if (assignedChains.length === 0) {\n this.#unsubscribeDataSource(source);\n continue;\n }\n if (source === this.#rpcDataSource) {\n rpcAssignedChains = new Set(assignedChains);\n }\n const seenIds = new Set<string>();\n const accountsForSource = assignedChains\n .flatMap((chainId) => chainToAccounts.get(chainId) ?? [])\n .filter((account) => {\n if (seenIds.has(account.id)) {\n return false;\n }\n seenIds.add(account.id);\n return true;\n });\n if (accountsForSource.length > 0) {\n this.#subscribeDataSource(source, accountsForSource, assignedChains, {\n ...(options?.skipInitialFetch &&\n source === this.#accountsApiDataSource\n ? { skipInitialFetch: true }\n : {}),\n });\n }\n }\n\n if (!this.#isBalanceV6Enabled()) {\n this.#subscribeRpcCustomAssetsSupplement(\n accounts,\n chainToAccounts,\n rpcAssignedChains,\n );\n }\n }\n\n /**\n * Guarantee that customAssets are **always** polled by RPC, even when\n * AccountsApi or another data source has claimed the chain in the\n * regular handoff. RPC is the sole balance fetcher for user-imported\n * tokens on the Accounts API v5 path (see `pickRpcCustomAssetsSupplement`).\n *\n * @param accounts - Accounts to consider for customAssets.\n * @param chainToAccounts - Map of chain → accounts (built by caller).\n * @param rpcAssignedChains - Chains RPC was assigned in the regular handoff.\n */\n #subscribeRpcCustomAssetsSupplement(\n accounts: InternalAccount[],\n chainToAccounts: Map<ChainId, InternalAccount[]>,\n rpcAssignedChains: Set<ChainId>,\n ): void {\n const rpc = this.#rpcDataSource;\n const supplementalKey = `ds:${rpc.getName()}:custom`;\n\n const decision = pickRpcCustomAssetsSupplement({\n accountIds: accounts.map((account) => account.id),\n customAssetsByAccount: this.state.customAssets,\n rpcAssignedChains,\n rpcAvailableChains: new Set(rpc.getActiveChainsSync()),\n enabledChains: new Set(chainToAccounts.keys()),\n });\n\n if (decision.chains.length === 0) {\n this.#unsubscribeBySubscriptionKey(rpc, supplementalKey);\n return;\n }\n\n const supplementalAccounts = accounts.filter((account) =>\n decision.accountIds.has(account.id),\n );\n if (supplementalAccounts.length === 0) {\n this.#unsubscribeBySubscriptionKey(rpc, supplementalKey);\n return;\n }\n\n this.#subscribeDataSource(rpc, supplementalAccounts, decision.chains, {\n subscriptionKey: supplementalKey,\n customAssetsOnly: true,\n });\n }\n\n /**\n * Unsubscribe a data source by an explicit subscription key.\n *\n * @param source - The data source instance.\n * @param subscriptionKey - The subscription key to unsubscribe.\n */\n #unsubscribeBySubscriptionKey(\n source: AbstractDataSource<string, DataSourceState>,\n subscriptionKey: string,\n ): void {\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n if (existingSubscription) {\n source.unsubscribe(subscriptionKey).catch(() => undefined);\n existingSubscription.unsubscribe();\n }\n }\n\n /**\n * Subscribe to staked balance updates.\n * This is the only staked-balance path: subscribe fetches immediately, then\n * polls, and the data source refreshes again when a confirmed transaction\n * touches the staking contract. The fast fetch lane does not query it.\n *\n * Unlike regular balance data sources, the staked balance data source provides\n * supplementary data and does not participate in chain-claiming.\n *\n * @param accounts - Accounts to subscribe staked balance updates for.\n * @param chainIds - Chain IDs to subscribe for.\n */\n #subscribeStakedBalance(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n ): void {\n const source = this.#stakedBalanceDataSource;\n if (!source) {\n return;\n }\n const availableChains = new Set(source.getActiveChainsSync());\n const assignedChains = chainIds.filter((chainId) =>\n availableChains.has(chainId),\n );\n\n if (assignedChains.length === 0) {\n this.#unsubscribeDataSource(source);\n return;\n }\n\n this.#subscribeDataSource(source, accounts, assignedChains);\n }\n\n /**\n * Build a mapping of chainId -> accounts that support that chain.\n * Only includes chains that are in the chainsToSubscribe set.\n *\n * @param accounts - Array of accounts to build mapping for.\n * @param chainsToSubscribe - Set of chain IDs to include in the mapping.\n * @returns Map of chainId to array of accounts that support that chain.\n */\n #buildChainToAccountsMap(\n accounts: InternalAccount[],\n chainsToSubscribe: Set<ChainId>,\n ): Map<ChainId, InternalAccount[]> {\n const chainToAccounts = new Map<ChainId, InternalAccount[]>();\n for (const account of accounts) {\n for (const chainId of this.#getEnabledChainsForAccount(account)) {\n if (!chainsToSubscribe.has(chainId)) {\n continue;\n }\n let list = chainToAccounts.get(chainId);\n if (!list) {\n list = [];\n chainToAccounts.set(chainId, list);\n }\n list.push(account);\n }\n }\n return chainToAccounts;\n }\n\n /**\n * Subscribe to a specific data source with accounts and chains.\n * Uses the data source name as the subscription key for batching.\n *\n * @param source - The balance data source instance.\n * @param accounts - Array of accounts to subscribe for.\n * @param chains - Array of chain IDs to subscribe for.\n * @param options - Optional subscription overrides.\n * @param options.subscriptionKey - Custom subscription key (default: `ds:<sourceId>`).\n * @param options.customAssetsOnly - When true, only poll customAssets for these\n * chains (Accounts API v5 supplemental RPC subscription).\n * @param options.skipInitialFetch - When true, skip the data source's subscribe-time fetch.\n */\n #subscribeDataSource(\n source: AbstractDataSource<string, DataSourceState>,\n accounts: InternalAccount[],\n chains: ChainId[],\n options: {\n subscriptionKey?: string;\n customAssetsOnly?: boolean;\n skipInitialFetch?: boolean;\n } = {},\n ): void {\n const sourceId = source.getName();\n const subscriptionKey = options.subscriptionKey ?? `ds:${sourceId}`;\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n const isUpdate = existingSubscription !== undefined;\n\n log('Subscribe to data source', {\n sourceId,\n subscriptionKey,\n isUpdate,\n accountCount: accounts.length,\n chainCount: chains.length,\n customAssetsOnly: options.customAssetsOnly === true,\n skipInitialFetch: options.skipInitialFetch === true,\n });\n\n const subscribeReq: SubscriptionRequest = {\n request: this.#buildDataRequest(accounts, chains, {\n assetTypes: ['fungible'],\n dataTypes: ['balance'],\n updateInterval: this.#defaultUpdateInterval,\n ...(options.customAssetsOnly === true\n ? { customAssetsOnly: true }\n : {}),\n }),\n subscriptionId: subscriptionKey,\n isUpdate,\n onAssetsUpdate: (response, request) =>\n this.handleAssetsUpdate(response, sourceId, request),\n ...(options.skipInitialFetch === true ? { skipInitialFetch: true } : {}),\n };\n\n source.subscribe(subscribeReq).catch((error) => {\n console.error(\n `[AssetsController] Failed to subscribe to '${sourceId}':`,\n error,\n );\n emitTrace({\n name: TRACE_SUBSCRIPTION_ERROR,\n trace: this.#trace,\n data: {\n source: sourceId,\n error_message: String(error),\n },\n });\n });\n\n // Track subscription\n const subscription: SubscriptionResponse = {\n chains,\n accountId: subscriptionKey,\n assetTypes: ['fungible'],\n dataTypes: ['balance'],\n unsubscribe: () => {\n this.#activeSubscriptions.delete(subscriptionKey);\n },\n };\n\n this.#activeSubscriptions.set(subscriptionKey, subscription);\n }\n\n /**\n * Unsubscribe from a data source if we have an active subscription.\n *\n * @param source - The balance data source instance to unsubscribe from.\n */\n #unsubscribeDataSource(\n source: AbstractDataSource<string, DataSourceState>,\n ): void {\n const subscriptionKey = `ds:${source.getName()}`;\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n\n if (existingSubscription) {\n source.unsubscribe(subscriptionKey).catch(() => undefined);\n existingSubscription.unsubscribe();\n }\n }\n\n // ============================================================================\n // HELPERS\n // ============================================================================\n\n /**\n * Build a DataRequest with accountsWithSupportedChains (enabled chains ∩ account scope ∩ requested chainIds).\n *\n * @param accounts - Accounts to include.\n * @param chainIds - Requested chain IDs (e.g. enabled chains or subset).\n * @param partial - Rest of the request (dataTypes, assetTypes, etc.).\n * @returns DataRequest with accountsWithSupportedChains and chainIds.\n */\n #buildDataRequest(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n partial: Partial<\n Omit<DataRequest, 'accountsWithSupportedChains' | 'chainIds'>\n > = {},\n ): DataRequest {\n const chainIdSet = new Set(chainIds);\n // Force update will pass in additional chains for wildcard account scope\n // Enables updates for chains that are not selected (e.g. for unapproved transactions)\n const forceUpdateChains = partial.forceUpdate ? chainIds : undefined;\n const accountsWithSupportedChains: AccountWithSupportedChains[] =\n accounts.map((account) => ({\n account,\n supportedChains: this.#getEnabledChainsForAccount(\n account,\n forceUpdateChains,\n ).filter((chain) => chainIdSet.has(chain)),\n }));\n return {\n accountsWithSupportedChains,\n chainIds,\n ...partial,\n } as DataRequest;\n }\n\n /**\n * Get the chains that an account supports based on its scopes.\n * Returns the intersection of the account's scopes and the enabled chains.\n *\n * @param account - The account to get supported chains for.\n * @param additionalChains - Optional extra chains to include for wildcard scopes.\n * @returns Array of ChainIds that the account supports and are enabled.\n */\n #getEnabledChainsForAccount(\n account: InternalAccount,\n additionalChains?: ChainId[],\n ): ChainId[] {\n // Account scopes are CAIP-2 chain IDs like \"eip155:1\", \"solana:mainnet\", \"bip122:...\"\n const scopes = account.scopes ?? [];\n const result: ChainId[] = [];\n\n for (const scope of scopes) {\n const scopeStr = scope as string;\n if (!isCaipChainId(scopeStr)) {\n result.push(scope);\n continue;\n }\n const { namespace, reference } = parseCaipChainId(scopeStr);\n\n // Wildcard scope (e.g., \"eip155:0\" means all enabled chains in that namespace)\n if (reference === '0') {\n // Add enabled chains\n for (const chain of this.#enabledChains) {\n if (isCaipChainId(chain)) {\n const chainParsed = parseCaipChainId(chain);\n if (chainParsed.namespace === namespace) {\n result.push(chain);\n }\n }\n }\n // Add additional chains\n for (const chain of additionalChains ?? []) {\n if (isCaipChainId(chain)) {\n const chainParsed = parseCaipChainId(chain);\n if (chainParsed.namespace === namespace) {\n result.push(chain);\n }\n }\n }\n } else if (namespace === 'eip155' && isStrictHexString(reference)) {\n // Normalize hex to decimal for EIP155\n result.push(`eip155:${parseInt(reference, 16)}`);\n } else {\n result.push(scope);\n }\n }\n\n return result;\n }\n\n // ============================================================================\n // EVENT HANDLERS\n // ============================================================================\n\n async #handleAccountGroupChanged(\n groupId: string,\n previousGroupId: string = '',\n ): Promise<void> {\n if (!groupId) {\n return;\n }\n\n // First start is owned by `AccountTreeController:initialized` / `#start`.\n // ATC also re-publishes `selectedAccountGroupChange` on every `init()`\n // (including when the group did not change) so late subscribers can catch\n // up — ignore those until we are already tracking.\n if (this.#activeSubscriptions.size === 0) {\n return;\n }\n if (groupId === previousGroupId) {\n return;\n }\n\n const accounts = this.#getSelectedAccounts();\n\n log('Account group changed', {\n accountCount: accounts.length,\n accountIds: accounts.map((a) => a.id),\n groupId,\n previousGroupId,\n });\n\n const releaseLock = await this.#accountRefreshMutex.acquire();\n try {\n this.#ensureNativeBalancesDefaultZero();\n this.#ensureDefaultTrackedAssetsSeeded();\n if (accounts.length > 0) {\n await this.getAssets(accounts, {\n chainIds: [...this.#enabledChains],\n forceUpdate: true,\n });\n }\n\n this.#subscribeAssets({ skipInitialFetch: true });\n } finally {\n releaseLock();\n }\n }\n\n async #handleEnabledNetworksChanged(\n enabledNetworkMap: NetworkEnablementControllerState['enabledNetworkMap'],\n ): Promise<void> {\n const previousChains = this.#enabledChains;\n this.#enabledChains = this.#extractEnabledChains(enabledNetworkMap);\n\n // Find newly enabled chains (in new set but not in previous)\n const addedChains: ChainId[] = [];\n for (const chain of this.#enabledChains) {\n if (!previousChains.has(chain)) {\n addedChains.push(chain);\n }\n }\n\n // Find disabled chains to clean up (in previous but not in new)\n const removedChains: ChainId[] = [];\n for (const chain of previousChains) {\n if (!this.#enabledChains.has(chain)) {\n removedChains.push(chain);\n }\n }\n\n log('Enabled networks changed', {\n previousCount: previousChains.size,\n newCount: this.#enabledChains.size,\n addedChains,\n removedChains,\n });\n\n // Note: We intentionally do NOT delete balance data for disabled chains.\n // Users may want to see historical balances even if the network is currently disabled.\n // The data will simply not be updated until the network is re-enabled.\n\n const accounts = this.#getSelectedAccounts();\n this.#ensureNativeBalancesDefaultZero();\n if (addedChains.length > 0) {\n this.#ensureDefaultTrackedAssetsSeeded(addedChains);\n }\n\n // Refresh subscriptions for new chain set\n this.#subscribeAssets();\n\n // One-time fetch for newly enabled chains. v6 `full` replace is scoped to\n // those chains; existing balances on other chains are left untouched.\n if (addedChains.length > 0 && accounts.length > 0) {\n await this.getAssets(accounts, {\n chainIds: addedChains,\n forceUpdate: true,\n });\n }\n }\n\n /**\n * Handle a `NetworkController:networkAdded` event. When the user\n * adds a network (e.g. Monad) to NetworkController, seed the\n * controller-managed default tracked assets for that chain (mUSD on\n * Monad) into state immediately — without waiting for the chain to\n * also be enabled in NetworkEnablementController. No-op for chains\n * that aren't in the defaults registry.\n *\n * @param hexChainId - Hex chain id of the newly-added network\n * configuration (e.g. `0x279f`).\n */\n #handleNetworkAdded(hexChainId: Hex): void {\n let caipChainId: ChainId;\n try {\n caipChainId = `eip155:${parseInt(hexChainId, 16)}`;\n } catch {\n return;\n }\n\n if (!CHAINS_WITH_DEFAULT_TRACKED_ASSETS.has(caipChainId)) {\n return;\n }\n\n log('Network added — seeding default tracked assets', {\n hexChainId,\n caipChainId,\n });\n\n this.#ensureDefaultTrackedAssetsSeeded([caipChainId]);\n }\n\n /**\n * Refresh data-source `activeChains` after an EVM network switch so API/Rpc\n * chain claiming is not stuck on an empty or stale init-time list.\n */\n async #refreshActiveChainsOnNetworkSwitch(): Promise<void> {\n await this.#accountsApiDataSource.refreshActiveChains();\n this.#rpcDataSource.refreshActiveChainsFromNetworkState();\n }\n\n /**\n * Resolve the CAIP-2 chain ID for the currently selected EVM network client.\n *\n * @param networkState - NetworkController state from `networkDidChange`.\n * @returns CAIP-2 chain ID (e.g. `eip155:1`) or undefined when unavailable.\n */\n #getSelectedEvmChainIdFromNetworkState(\n networkState: NetworkState,\n ): ChainId | undefined {\n try {\n const networkClient = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkState.selectedNetworkClientId,\n );\n const hexChainId = networkClient.configuration?.chainId;\n if (!hexChainId) {\n return undefined;\n }\n return `eip155:${parseInt(hexChainId, 16)}`;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Refresh subscriptions and fetch balances when the user switches the\n * selected EVM network in the UI (`NetworkController:networkDidChange`).\n *\n * @param networkState - NetworkController state after the switch.\n */\n async #handleNetworkDidChange(networkState: NetworkState): Promise<void> {\n if (!this.#isUiOpen() || !this.#isKeyringUnlocked() || !this.#isEnabled()) {\n return;\n }\n\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n const selectedChainId =\n this.#getSelectedEvmChainIdFromNetworkState(networkState);\n if (!selectedChainId) {\n return;\n }\n\n log('Selected EVM network switched', {\n selectedNetworkClientId: networkState.selectedNetworkClientId,\n selectedChainId,\n });\n\n const releaseLock = await this.#accountRefreshMutex.acquire();\n try {\n await this.#refreshActiveChainsOnNetworkSwitch();\n\n this.#ensureNativeBalancesDefaultZero();\n this.#subscribeAssets();\n\n await this.getAssets(accounts, {\n chainIds: [selectedChainId],\n forceUpdate: true,\n dataTypes: ['balance', 'metadata', 'price'],\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Refresh balances after a network configuration is removed.\n */\n #refreshAssetsAfterNetworkChange(): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n this.getAssets(accounts, {\n forceUpdate: true,\n dataTypes: ['balance', 'metadata'],\n }).catch((error: unknown) => {\n log('Failed to refresh assets after network change', { error });\n });\n }\n\n /**\n * Refresh balances and fetch missing prices after a network is added.\n *\n * @param hexChainId - Hex chain id of the newly-added network.\n */\n async #refreshAssetsAfterNetworkAdded(hexChainId: Hex): Promise<void> {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n let caipChainId: ChainId;\n try {\n caipChainId = `eip155:${parseInt(hexChainId, 16)}`;\n } catch {\n return;\n }\n\n this.#ensureNativeBalancesDefaultZero();\n await this.getAssets(accounts, {\n chainIds: [caipChainId],\n forceUpdate: true,\n dataTypes: ['balance', 'metadata', 'price'],\n });\n }\n\n /**\n * Handle assets updated from a data source.\n * Called via the onAssetsUpdate callback passed in SubscriptionRequest when the controller subscribes to a data source.\n * Runs detection, then (when basic functionality is enabled) token metadata and price enrichment before updating state.\n * When basic functionality is disabled (RPC-only mode), only detection runs; token and price APIs are not used.\n *\n * @param response - The data response with updated assets\n * @param sourceId - The data source ID reporting the update\n * @param request - Optional original request for context when enriching\n */\n async handleAssetsUpdate(\n response: DataResponse,\n sourceId: string,\n request?: DataRequest,\n ): Promise<void> {\n log('Assets updated from data source', {\n sourceId,\n assetsBalance: response.assetsBalance,\n assetsPrice: response.assetsPrice,\n });\n\n if (this.#isBalanceV6Enabled()) {\n await this.#handleAssetsUpdateV6(response, sourceId, request);\n return;\n }\n await this.#handleAssetsUpdateV5(response, sourceId, request);\n }\n\n async #handleAssetsUpdateV5(\n response: DataResponse,\n sourceId: string,\n request?: DataRequest,\n ): Promise<void> {\n const pipelineTrace = this.#firstInitFetchReported\n ? undefined\n : this.#trace;\n await withTrace({\n name: TRACE_UPDATE_PARENT,\n trace: pipelineTrace,\n data: this.#getUpdateTraceData(response, sourceId),\n fn: async (parentContext) => {\n const updateStart = performance.now();\n const pipelineRequest = this.#getUpdatePipelineRequest(request);\n const isBasicFunctionality = this.#isBasicFunctionality();\n const isAccountsApiUpdate = sourceId === 'AccountsApiDataSource';\n const enrichmentSources: AssetsDataSource[] =\n sourceId === 'AccountActivityDataSource'\n ? buildWsUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n { isBasicFunctionality, includeCustomAssetGraduation: true },\n )\n : buildUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n {\n isBasicFunctionality,\n includeCustomAssetGraduation: isAccountsApiUpdate,\n includeRpcFallback: isAccountsApiUpdate,\n },\n );\n\n const { response: enrichedResponse } = await this.#executeMiddlewares({\n sources: enrichmentSources,\n request: pipelineRequest,\n initialResponse: response,\n parentContext,\n trace: pipelineTrace,\n });\n\n await this.#updateState({\n ...enrichedResponse,\n replaceCoveredChainBalances: response.replaceCoveredChainBalances,\n });\n this.#emitUpdateTrace({\n response,\n sourceId,\n enrichedResponse,\n updateStart,\n pipelineTrace,\n parentContext,\n });\n },\n });\n }\n\n async #handleAssetsUpdateV6(\n response: DataResponse,\n sourceId: string,\n request?: DataRequest,\n ): Promise<void> {\n const pipelineTrace = this.#firstInitFetchReported\n ? undefined\n : this.#trace;\n await withTrace({\n name: TRACE_UPDATE_PARENT,\n trace: pipelineTrace,\n data: this.#getUpdateTraceData(response, sourceId),\n fn: async (parentContext) => {\n const updateStart = performance.now();\n const pipelineRequest = this.#getUpdatePipelineRequest(request);\n const isBasicFunctionality = this.#isBasicFunctionality();\n const enrichmentSources: AssetsDataSource[] =\n sourceId === 'AccountActivityDataSource'\n ? buildWsUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n { isBasicFunctionality, includeCustomAssetGraduation: false },\n )\n : buildUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n {\n isBasicFunctionality,\n includeCustomAssetGraduation: false,\n includeRpcFallback: isBasicFunctionality,\n },\n );\n\n const { response: enrichedResponse } = await this.#executeMiddlewares({\n sources: enrichmentSources,\n request: pipelineRequest,\n initialResponse: response,\n parentContext,\n trace: pipelineTrace,\n });\n\n await this.#updateState(enrichedResponse);\n this.#emitUpdateTrace({\n response,\n sourceId,\n enrichedResponse,\n updateStart,\n pipelineTrace,\n parentContext,\n });\n },\n });\n }\n\n #getUpdatePipelineRequest(request?: DataRequest): DataRequest {\n const resolvedRequest: DataRequest = request ?? {\n accountsWithSupportedChains: [],\n chainIds: [],\n dataTypes: ['balance', 'metadata', 'price'],\n };\n if (this.#isBasicFunctionality()) {\n return resolvedRequest;\n }\n return {\n ...resolvedRequest,\n dataTypes: resolvedRequest.dataTypes.filter(\n (dataType) => dataType !== 'metadata' && dataType !== 'price',\n ),\n };\n }\n\n #getUpdateTraceData(response: DataResponse, sourceId: string): TraceSpanData {\n return {\n source: sourceId,\n has_balance: Boolean(response.assetsBalance),\n has_price: Boolean(response.assetsPrice),\n balance_account_count: response.assetsBalance\n ? Object.keys(response.assetsBalance).length\n : 0,\n };\n }\n\n #emitUpdateTrace({\n response,\n sourceId,\n enrichedResponse,\n updateStart,\n pipelineTrace,\n parentContext,\n }: {\n response: DataResponse;\n sourceId: string;\n enrichedResponse: DataResponse;\n updateStart: number;\n pipelineTrace?: TraceCallback;\n parentContext?: TraceContext;\n }): void {\n emitTrace({\n name: TRACE_UPDATE_PIPELINE,\n trace: pipelineTrace,\n data: {\n source: sourceId,\n duration_ms: performance.now() - updateStart,\n has_balance: Boolean(response.assetsBalance),\n has_price: Boolean(response.assetsPrice),\n has_metadata: Boolean(enrichedResponse.assetsInfo),\n balance_account_count: response.assetsBalance\n ? Object.keys(response.assetsBalance).length\n : 0,\n },\n parentContext,\n });\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n log('Destroying AssetsController', {\n dataSourceCount: this.#allBalanceDataSources.length,\n subscriptionCount: this.#activeSubscriptions.size,\n });\n\n // Destroy instantiated data sources\n this.#accountActivityDataSource?.destroy?.();\n this.#accountsApiDataSource?.destroy?.();\n this.#snapDataSource?.destroy?.();\n this.#rpcDataSource?.destroy?.();\n this.#stakedBalanceDataSource?.destroy?.();\n\n // Stop all active subscriptions\n this.#stop();\n\n if (this.#unsubscribeBasicFunctionality) {\n this.#unsubscribeBasicFunctionality();\n this.#unsubscribeBasicFunctionality = null;\n }\n\n // Unregister action handlers\n this.messenger.unregisterActionHandler('AssetsController:getAssets');\n this.messenger.unregisterActionHandler('AssetsController:getAssetsBalance');\n this.messenger.unregisterActionHandler('AssetsController:getAssetMetadata');\n this.messenger.unregisterActionHandler(\n 'AssetsController:getAccountAssetByID',\n );\n this.messenger.unregisterActionHandler(\n 'AssetsController:getAccountAssetsByIDs',\n );\n this.messenger.unregisterActionHandler(\n 'AssetsController:getAccountAssetsByScope',\n );\n this.messenger.unregisterActionHandler('AssetsController:getAssetsPrice');\n this.messenger.unregisterActionHandler('AssetsController:syncAssetsPrices');\n this.messenger.unregisterActionHandler(\n 'AssetsController:getExchangeRatesForBridge',\n );\n this.messenger.unregisterActionHandler(\n 'AssetsController:getStateForTransactionPay',\n );\n this.messenger.unregisterActionHandler('AssetsController:addCustomAsset');\n this.messenger.unregisterActionHandler(\n 'AssetsController:removeCustomAsset',\n );\n this.messenger.unregisterActionHandler('AssetsController:getCustomAssets');\n this.messenger.unregisterActionHandler('AssetsController:hideAsset');\n this.messenger.unregisterActionHandler('AssetsController:unhideAsset');\n this.messenger.unregisterActionHandler(\n 'AssetsController:setSelectedCurrency',\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AssetsController.js","sourceRoot":"","sources":["../src/AssetsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountTreeControllerGetAccountsFromSelectedAccountGroupAction,\n AccountTreeControllerInitializedEvent,\n AccountTreeControllerIsInitializedAction,\n AccountTreeControllerSelectedAccountGroupChangeEvent,\n AccountTreeControllerUninitializedEvent,\n} from '@metamask/account-tree-controller';\nimport type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type {\n ClientControllerGetStateAction,\n ClientControllerStateChangeEvent,\n} from '@metamask/client-controller';\nimport { clientControllerSelectors } from '@metamask/client-controller';\nimport type { ConfigRegistryControllerGetNetworkConfigByCaip2ChainIdAction } from '@metamask/config-registry-controller';\nimport type { TraceCallback, TraceContext } from '@metamask/controller-utils';\nimport type {\n ApiPlatformClient,\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n SupportedCurrency,\n} from '@metamask/core-backend';\nimport type { Transaction as KeyringTransaction } from '@metamask/keyring-api';\nimport type {\n KeyringControllerIsUnlockedAction,\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 { MultichainTransactionsControllerTransactionConfirmedEvent } from '@metamask/multichain-transactions-controller';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkDidChangeEvent,\n NetworkControllerNetworkRemovedEvent,\n NetworkState,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport type {\n NetworkEnablementControllerGetStateAction,\n NetworkEnablementControllerEvents,\n NetworkEnablementControllerState,\n} from '@metamask/network-enablement-controller';\nimport type {\n GetPermissions,\n PermissionControllerStateChange,\n} from '@metamask/permission-controller';\nimport { PhishingControllerBulkScanTokensAction } from '@metamask/phishing-controller';\nimport type { PreferencesControllerStateChangeEvent } from '@metamask/preferences-controller';\nimport type {\n RemoteFeatureFlagControllerGetStateAction,\n RemoteFeatureFlagControllerStateChangeEvent,\n} from '@metamask/remote-feature-flag-controller';\nimport type {\n SnapControllerGetRunnableSnapsAction,\n SnapControllerHandleRequestAction,\n SnapControllerSnapInstalledEvent,\n} from '@metamask/snaps-controllers';\nimport type {\n TransactionControllerTransactionConfirmedEvent,\n TransactionControllerUnapprovedTransactionAddedEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport {\n isCaipChainId,\n isStrictHexString,\n KnownCaipNamespace,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { BigNumber as BigNumberJS } from 'bignumber.js';\nimport { isEqual } from 'lodash-es';\n\nimport type { AssetsControllerMethodActions } from './AssetsController-method-action-types.js';\nimport type {\n AbstractDataSource,\n DataSourceState,\n SubscriptionRequest,\n} from './data-sources/AbstractDataSource.js';\nimport { AccountActivityDataSource } from './data-sources/AccountActivityDataSource.js';\nimport type { AccountsApiDataSourceConfig } from './data-sources/AccountsApiDataSource.js';\nimport { AccountsApiDataSource } from './data-sources/AccountsApiDataSource.js';\nimport { isStakingContractAssetId } from './data-sources/evm-rpc-services/index.js';\nimport { shouldSkipNativeForCaipChainId } from './data-sources/evm-rpc-services/utils/assets.js';\nimport type { PriceDataSourceConfig } from './data-sources/PriceDataSource.js';\nimport { PriceDataSource } from './data-sources/PriceDataSource.js';\nimport type { RpcDataSourceConfig } from './data-sources/RpcDataSource.js';\nimport { RpcDataSource } from './data-sources/RpcDataSource.js';\nimport type { AccountsControllerAccountBalancesUpdatedEvent } from './data-sources/SnapDataSource.js';\nimport { SnapDataSource } from './data-sources/SnapDataSource.js';\nimport type { StakedBalanceDataSourceConfig } from './data-sources/StakedBalanceDataSource.js';\nimport { StakedBalanceDataSource } from './data-sources/StakedBalanceDataSource.js';\nimport {\n CaipAssetNamespace,\n TokenDataSource,\n} from './data-sources/TokenDataSource.js';\nimport {\n CHAINS_WITH_DEFAULT_TRACKED_ASSETS,\n DEFAULT_TRACKED_ASSETS_BY_CHAIN,\n buildDefaultAssetsInfo,\n getDefaultAssetMetadata,\n} from './defaults.js';\nimport { projectLogger, createModuleLogger } from './logger.js';\nimport { CustomAssetGraduationMiddleware } from './middlewares/CustomAssetGraduationMiddleware.js';\nimport {\n createParallelBalanceMiddleware,\n createParallelMiddleware,\n} from './middlewares/ParallelMiddleware.js';\nimport { RpcFallbackMiddleware } from './middlewares/RpcFallbackMiddleware.js';\nimport { dropBalancesOutsideAccountScopes } from './migrations/dropBalancesOutsideAccountScopes.js';\nimport type { Assets3346MigrationState } from './migrations/healAssetsInfoMetadata.js';\nimport {\n cleanSpamAssets,\n isUnlockCleanupEnabled,\n tempHealAssetsInfoMetadata,\n} from './migrations/healAssetsInfoMetadata.js';\nimport {\n buildFastFetchSources,\n buildUpdateSources,\n buildWsUpdateSources,\n executeAssetsPipeline,\n} from './pipeline/index.js';\nimport { trackAssetsLoading } from './trackAssetsLoading.js';\nimport type {\n AccountId,\n AssetsControllerState,\n AssetsDataSource,\n AssetsUpdateMode,\n ChainId,\n Caip19AssetId,\n AssetMetadata,\n FungibleAssetMetadata,\n AssetPrice,\n AssetBalance,\n FungibleAssetBalance,\n AccountWithSupportedChains,\n AssetType,\n DataType,\n DataRequest,\n DataResponse,\n SubscriptionResponse,\n Asset,\n} from './types.js';\nimport type { AssetVisibility } from './utils/assetVisibility.js';\nimport { getAssetVisibility } from './utils/assetVisibility.js';\nimport {\n UNKNOWN_EVM_NATIVE_ASSET_REFERENCE,\n ZERO_ADDRESS,\n} from './utils/constants.js';\nimport { pickRpcCustomAssetsSupplement } from './utils/customAssetsRpcSupplement.js';\nimport {\n normalizeAmountString,\n normalizeAssetId,\n formatExchangeRatesForBridge,\n formatStateForTransactionPay,\n buildNativeAssetsFromConstant,\n buildNativeAssetsFromApi,\n getDefaultNativeAssetBalance,\n getZeroAssetBalance,\n} from './utils/index.js';\nimport type {\n BridgeExchangeRatesFormat,\n TransactionPayLegacyFormat,\n} from './utils/index.js';\nimport { emitTrace, withTrace } from './utils/trace.js';\nimport type { TraceSpanData } from './utils/trace.js';\n\nconst NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];\n\n/** Stable empty map so memoized formatters are not busted by `?? {}` identity churn. */\nconst EMPTY_NATIVE_ASSET_MAP: Record<ChainId, Caip19AssetId> = {};\n\n// ============================================================================\n// PENDING TOKEN METADATA (UI input format for addCustomAsset)\n// ============================================================================\n\n/**\n * Metadata format passed from the UI when adding a custom token.\n * Mirrors the \"pendingTokens\" shape used by the extension.\n */\nexport type PendingTokenMetadata = {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n iconUrl?: string;\n aggregators?: string[];\n occurrences?: number;\n chainId: string;\n unlisted?: boolean;\n};\n\n// ============================================================================\n// CONTROLLER CONSTANTS\n// ============================================================================\n\nconst CONTROLLER_NAME = 'AssetsController' as const;\n\n/** Method names exposed as messenger actions (AssetsController:getAssets, etc.) */\nconst MESSENGER_EXPOSED_METHODS = [\n 'getAssets',\n 'getAssetsBalance',\n 'getAssetMetadata',\n 'getAccountAssetByID',\n 'getAccountAssetsByIDs',\n 'getAccountAssetsByScope',\n 'getAssetsPrice',\n 'syncAssetsPrices',\n 'getExchangeRatesForBridge',\n 'getStateForTransactionPay',\n 'addCustomAsset',\n 'removeCustomAsset',\n 'getCustomAssets',\n 'hideAsset',\n 'unhideAsset',\n 'setSelectedCurrency',\n] as const;\n\n/** Default polling interval hint for data sources (30 seconds) */\nconst DEFAULT_POLLING_INTERVAL_MS = 30_000;\n\n// ============================================================================\n// TRACE NAMES — used in Sentry spans (search these strings in Discover)\n// ============================================================================\nconst TRACE_FIRST_INIT_FETCH = 'AssetsControllerFirstInitFetch';\nconst TRACE_FULL_FETCH = 'AssetsFullFetch';\n/** Parent span that nests per-source timings; dashboard charts {@link TRACE_FULL_FETCH}. */\nconst TRACE_FETCH_PIPELINE = 'AssetsFetchPipeline';\nconst TRACE_BACKGROUND_FETCH = 'AssetsBackgroundFetch';\nconst TRACE_UPDATE_PIPELINE = 'AssetsUpdatePipeline';\n/** Parent span that nests update enrichment; dashboard charts {@link TRACE_UPDATE_PIPELINE}. */\nconst TRACE_UPDATE_PARENT = 'AssetsUpdateEnrichment';\nconst TRACE_SUBSCRIPTION_ERROR = 'AssetsSubscriptionError';\nconst TRACE_STATE_SIZE = 'AssetsStateSize';\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// ============================================================================\n// STATE TYPES\n// ============================================================================\n\nexport type { AssetsControllerState };\n\n/**\n * Returns the default state for AssetsController.\n *\n * @returns The default AssetsController state. Balance, price, and custom\n * asset maps start empty; `assetsInfo` is pre-seeded for default tracked\n * assets (see {@link buildDefaultAssetsInfo}).\n */\nexport function getDefaultAssetsControllerState(): AssetsControllerState {\n return {\n // Pre-populate metadata for controller-managed default tracked assets\n // (e.g. mUSD on Ethereum mainnet, Linea, Monad) so they are\n // immediately renderable in the UI before any RPC poll completes.\n // Per-account zero-balance entries are filled into `assetsBalance`\n // by `#ensureDefaultTrackedAssetsSeeded` once accounts are known.\n assetsInfo: buildDefaultAssetsInfo(),\n assetsBalance: {},\n assetsPrice: {},\n customAssets: {},\n assetPreferences: {},\n selectedCurrency: 'usd',\n };\n}\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\nexport type AssetsControllerGetStateAction = ControllerGetStateAction<\n typeof CONTROLLER_NAME,\n AssetsControllerState\n>;\n\nexport type AssetsControllerActions =\n | AssetsControllerGetStateAction\n | AssetsControllerMethodActions;\n\nexport type AssetsControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof CONTROLLER_NAME,\n AssetsControllerState\n>;\n\nexport type AssetsControllerBalanceChangedEvent = {\n type: `${typeof CONTROLLER_NAME}:balanceChanged`;\n payload: [\n {\n accountId: AccountId;\n assetId: Caip19AssetId;\n previousAmount: string;\n newAmount: string;\n },\n ];\n};\n\nexport type AssetsControllerPriceChangedEvent = {\n type: `${typeof CONTROLLER_NAME}:priceChanged`;\n payload: [{ prices: Record<Caip19AssetId, AssetPrice> }];\n};\n\nexport type AssetsControllerEvents =\n | AssetsControllerStateChangeEvent\n | AssetsControllerBalanceChangedEvent\n | AssetsControllerPriceChangedEvent;\n\ntype AllowedActions =\n // AssetsController\n | AccountsControllerGetSelectedAccountAction\n | AccountTreeControllerGetAccountsFromSelectedAccountGroupAction\n | AccountTreeControllerIsInitializedAction\n | ClientControllerGetStateAction\n | KeyringControllerIsUnlockedAction\n // RpcDataSource\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | ConfigRegistryControllerGetNetworkConfigByCaip2ChainIdAction\n // StakedBalanceDataSource\n | NetworkEnablementControllerGetStateAction\n // SnapDataSource\n | SnapControllerGetRunnableSnapsAction\n | SnapControllerHandleRequestAction\n | GetPermissions\n // PhishingController\n | PhishingControllerBulkScanTokensAction\n // AccountsApiDataSource (Accounts API v6 balances feature flag)\n | RemoteFeatureFlagControllerGetStateAction;\n\ntype AllowedEvents =\n // AssetsController — account tree lifecycle and group switches\n | AccountTreeControllerSelectedAccountGroupChangeEvent\n | AccountTreeControllerInitializedEvent\n | AccountTreeControllerUninitializedEvent\n | ClientControllerStateChangeEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent\n | TransactionControllerUnapprovedTransactionAddedEvent\n | TransactionControllerTransactionConfirmedEvent\n // AssetsController — non-EVM (Snap keyring) transaction confirmations\n | MultichainTransactionsControllerTransactionConfirmedEvent\n // RpcDataSource, StakedBalanceDataSource\n | NetworkControllerStateChangeEvent\n // AssetsController (default-asset seeding + cross-source asset refresh\n // whenever a network configuration is added to or removed from\n // NetworkController)\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkDidChangeEvent\n | NetworkControllerNetworkRemovedEvent\n // StakedBalanceDataSource\n | NetworkEnablementControllerEvents\n // SnapDataSource\n | AccountsControllerAccountBalancesUpdatedEvent\n | PermissionControllerStateChange\n | SnapControllerSnapInstalledEvent\n // AccountActivityService (real-time balance updates + chain status for unified assets)\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent\n // AccountsApiDataSource subscribes to react to Snaps → AssetsController\n // migration flag changes (which gate the chains it surfaces as active)\n | RemoteFeatureFlagControllerStateChangeEvent;\n\nexport type AssetsControllerMessenger = Messenger<\n typeof CONTROLLER_NAME,\n AssetsControllerActions | AllowedActions,\n AssetsControllerEvents | AllowedEvents\n>;\n\n// ============================================================================\n// CONTROLLER OPTIONS\n// ============================================================================\n\nexport type AssetsControllerOptions = {\n messenger: AssetsControllerMessenger;\n state?: Partial<AssetsControllerState>;\n /** Default polling interval hint passed to data sources (ms) */\n defaultUpdateInterval?: number;\n /** Function to determine if the controller is enabled. Defaults to true. */\n isEnabled?: () => boolean;\n /**\n * Getter for basic functionality (matches the \"Basic functionality\" setting in the UI).\n * When it returns true, internet services are on: token/price APIs are used for metadata, price,\n * and price subscription. When false, only RPC is used (no token/price APIs).\n * No value is stored; the getter is invoked when needed.\n * Defaults to () => true when not provided (APIs enabled).\n */\n isBasicFunctionality?: () => boolean;\n /**\n * Called by the controller with an onChange callback. The consumer subscribes to its own\n * basic-functionality source (e.g. PreferencesController:stateChange in extension, or a\n * different mechanism in mobile) and invokes onChange(isBasic) when the value changes.\n * The controller will then refresh its subscriptions. May return an unsubscribe function\n * called on controller destroy. Optional; when omitted, basic-functionality changes are not\n * subscribed to (e.g. host can notify via root messenger or another path).\n */\n subscribeToBasicFunctionalityChange?: (\n onChange: (isBasic: boolean) => void,\n ) => void | (() => void);\n /**\n * API client for balance/price/metadata. The controller instantiates data sources\n * and uses them directly when this is provided.\n */\n queryApiClient: ApiPlatformClient;\n /** Optional configuration for RpcDataSource. */\n rpcDataSourceConfig?: RpcDataSourceConfig;\n /**\n * Optional trace callback. When provided, the controller invokes it with a\n * trace request when the first init/fetch completes (e.g. after unlock).\n * Use this to report first init fetch duration to Sentry (e.g. via addBreadcrumb or setMeasurement).\n */\n trace?: TraceCallback;\n /**\n * Optional Sentry (or compatible) reporter for **issue** events. When data source middlewares\n * fail, the controller constructs an `AssetsDataSourceError` and passes it here so you can call\n * `Sentry.captureException`. Span-only trace callbacks do not create Issues;\n * wire this if you need Sentry alerts on middleware failures.\n */\n captureException?: (error: Error) => void;\n /** Optional configuration for AccountsApiDataSource. */\n accountsApiDataSourceConfig?: AccountsApiDataSourceConfig;\n /** Optional configuration for PriceDataSource. */\n priceDataSourceConfig?: PriceDataSourceConfig;\n /** Optional configuration for StakedBalanceDataSource. */\n stakedBalanceDataSourceConfig?: StakedBalanceDataSourceConfig;\n /**\n * Function returning whether onboarding is complete. When false,\n * RPC and staked balance data sources skip fetch and subscribe\n * (no on-chain calls until the user has finished onboarding).\n * Defaults to () => true.\n */\n isOnboarded?: () => boolean;\n\n /**\n * TEMPORARY — will be removed in a future release.\n * Issue: https://consensyssoftware.atlassian.net/browse/ASSETS-3346\n */\n tempMigrateAssetsInfoMetadataAssets3346?: () => Assets3346MigrationState;\n};\n\n// ============================================================================\n// STATE METADATA\n// ============================================================================\n\nconst stateMetadata: StateMetadata<AssetsControllerState> = {\n assetsInfo: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetsBalance: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetsPrice: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n customAssets: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetPreferences: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n selectedCurrency: {\n persist: true,\n includeInStateLogs: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n assetsLoadingStatus: {\n persist: false,\n includeInStateLogs: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n};\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nfunction extractChainId(assetId: Caip19AssetId): ChainId {\n const parsed = parseCaipAssetType(assetId);\n return parsed.chainId;\n}\n\n/**\n * Normalizes all asset IDs in a DataResponse.\n * This is applied at the controller level to ensure consistent state\n * regardless of how data sources format their asset IDs.\n *\n * @param response - The DataResponse to normalize.\n * @returns The normalized DataResponse with checksummed EVM addresses.\n */\nfunction normalizeResponse(response: DataResponse): DataResponse {\n const normalized: DataResponse = {};\n\n if (response.assetsInfo) {\n normalized.assetsInfo = {};\n for (const [assetId, metadata] of Object.entries(response.assetsInfo)) {\n const normalizedId = normalizeAssetId(assetId as Caip19AssetId);\n normalized.assetsInfo[normalizedId] = metadata;\n }\n }\n\n if (response.assetsPrice) {\n normalized.assetsPrice = {};\n for (const [assetId, price] of Object.entries(response.assetsPrice)) {\n const normalizedId = normalizeAssetId(assetId as Caip19AssetId);\n normalized.assetsPrice[normalizedId] = price;\n }\n }\n\n if (response.assetsBalance) {\n normalized.assetsBalance = {};\n for (const [accountId, balances] of Object.entries(\n response.assetsBalance,\n )) {\n normalized.assetsBalance[accountId] = {};\n for (const [assetId, balance] of Object.entries(balances)) {\n const normalizedId = normalizeAssetId(assetId as Caip19AssetId);\n normalized.assetsBalance[accountId][normalizedId] = balance;\n }\n }\n }\n\n // Preserve errors (chain IDs don't need normalization)\n if (response.errors) {\n normalized.errors = { ...response.errors };\n }\n\n if (response.updateMode) {\n normalized.updateMode = response.updateMode;\n }\n\n if (response.replaceCoveredChainBalances) {\n normalized.replaceCoveredChainBalances = true;\n }\n\n return normalized;\n}\n\n/**\n * Compute the effective account balances from a data-source response and prior state.\n *\n * @param previousBalances - Balances already in state for this account.\n * @param accountBalances - Balances from the incoming response.\n * @param customAssetIds - Custom assets to preserve when replacing covered chains\n * on the Accounts API v5 path (`replaceCoveredChainBalances`).\n * @param replaceCoveredChains - When true (v5 force refresh), drop prior balances\n * on chains present in the response before applying it, then restore custom assets.\n * @returns The effective balance map for the account.\n */\nfunction effectiveAccountBalancesV5(\n previousBalances: Record<string, AssetBalance>,\n accountBalances: Record<string, AssetBalance>,\n customAssetIds: Caip19AssetId[],\n replaceCoveredChains: boolean,\n): Record<string, AssetBalance> {\n if (!replaceCoveredChains) {\n return { ...previousBalances, ...accountBalances };\n }\n\n const coveredChains = new Set(\n Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]),\n );\n\n const next: Record<string, AssetBalance> = {};\n for (const [assetId, balance] of Object.entries(previousBalances)) {\n if (!coveredChains.has(assetId.split('/')[0])) {\n next[assetId] = balance;\n }\n }\n\n Object.assign(next, accountBalances);\n\n for (const customId of customAssetIds) {\n if (!Object.prototype.hasOwnProperty.call(next, customId)) {\n const prev = previousBalances[customId];\n next[customId] = prev ?? getZeroAssetBalance(customId);\n }\n }\n\n // Staked vault balances are owned by StakedBalanceDataSource. When an\n // Accounts API (or other) chain-slice replace omits them, keep the prior\n // on-chain staked amount instead of clearing it to missing/0.\n for (const [assetId, balance] of Object.entries(previousBalances)) {\n if (\n isStakingContractAssetId(assetId) &&\n !Object.prototype.hasOwnProperty.call(next, assetId)\n ) {\n next[assetId] = balance;\n }\n }\n\n return next;\n}\n\n/**\n * Compute the effective account balances for an Accounts API v6 update.\n *\n * `merge` overlays the incoming balances on prior state (Account Activity,\n * Snap events, staking). `full` replaces each covered chain slice. v6 asks\n * for natives, pins, and default tracked assets through `includeAssetIds`\n * and either returns them (at zero when the account holds none) or names\n * them in `unprocessedIncludeAssetIds`. Assets the client tracks on purpose\n * survive a `full` replace even when the response omits them, so an upstream\n * gap cannot wipe them — see `shouldKeepAsset`.\n *\n * @param previousBalances - Balances already in state for this account.\n * @param updatedBalances - Balances from the incoming response.\n * @param undeletableAssetIds - Visible assets the client asked for (native,\n * pin, or default tracked). They survive a `full` replace if the response\n * omits them. Hidden assets are excluded from snapshots and dropped here;\n * unhide is expected to fetch a new snapshot.\n * @param updateMode - `'merge'` overlays incoming balances; `'full'` replaces\n * each updated chain slice except undeletable and staking assets.\n * @returns The effective balance map for the account.\n */\nfunction effectiveAccountBalancesV6(\n previousBalances: Record<string, AssetBalance>,\n updatedBalances: Record<string, AssetBalance>,\n undeletableAssetIds: Set<string>,\n updateMode: AssetsUpdateMode,\n): Record<string, AssetBalance> {\n if (updateMode === 'merge') {\n return { ...previousBalances, ...updatedBalances };\n }\n\n const updatedChains = new Set(\n Object.keys(updatedBalances).map((assetId) =>\n extractChainId(assetId as Caip19AssetId),\n ),\n );\n const shouldKeepAsset = (assetId: Caip19AssetId): boolean =>\n !updatedChains.has(extractChainId(assetId)) ||\n undeletableAssetIds.has(assetId.toLowerCase()) ||\n isStakingContractAssetId(assetId);\n\n const keptBalances: Record<string, AssetBalance> = {};\n for (const [assetId, balance] of Object.entries(previousBalances)) {\n if (shouldKeepAsset(assetId as Caip19AssetId)) {\n keptBalances[assetId] = balance;\n }\n }\n return { ...keptBalances, ...updatedBalances };\n}\n\n// ============================================================================\n// CONTROLLER IMPLEMENTATION\n// ============================================================================\n\n/**\n * AssetsController provides a unified interface for managing asset balances\n * across all blockchain networks (EVM and non-EVM) and all asset types.\n *\n * ## Core Responsibilities\n *\n * 1. **One-Time Fetch (Sync)**: For initial load, force refresh, or on-demand queries.\n * Uses `getAssets()`, `getAssetsBalance()`, etc. with `forceUpdate: true`.\n *\n * 2. **Async Subscriptions**: Subscribes to data sources for ongoing updates.\n * Data sources push updates via callbacks; the controller updates state.\n *\n * 3. **Dynamic Source Selection**: Routes requests to appropriate data sources\n * based on which chains they support. When active chains change, the controller\n * dynamically adjusts subscriptions.\n *\n * 4. **Client + Keyring Lifecycle**: Starts subscriptions only when both the UI is\n * open (ClientController) and the wallet is unlocked (KeyringController).\n * Stops when either the UI closes or the keyring locks. See client-controller\n * README for the combined pattern.\n *\n * ## Architecture\n *\n * - Data sources declare their supported chains (async, can change over time)\n * - Data sources are responsible for their own update mechanisms (WebSocket, polling, events)\n * - The controller does NOT manage polling - it simply receives pushed updates\n */\nexport class AssetsController extends BaseController<\n typeof CONTROLLER_NAME,\n AssetsControllerState,\n AssetsControllerMessenger\n> {\n /** Whether the controller is enabled */\n readonly #isEnabled: () => boolean;\n\n /** Getter for basic functionality (only balance fetch/subscribe use RPC; token/price API not used). No attribute stored. */\n readonly #isBasicFunctionality: () => boolean;\n\n /** Default update interval hint passed to data sources */\n readonly #defaultUpdateInterval: number;\n\n /** Optional trace callback for first init/fetch measurement (duration). */\n readonly #trace?: TraceCallback;\n\n /** Optional reporter for Issue-style errors (e.g. Sentry.captureException). */\n readonly #captureException?: (error: Error) => void;\n\n /** Whether we have already reported first init fetch for this session (reset on #stop). */\n #firstInitFetchReported = false;\n\n /** Whether we have already reported state size for this session (reset on #stop). */\n #stateSizeReported = false;\n\n /**\n * Emit a state-size trace once on app start (first state update after unlock).\n */\n #emitStateSizeTrace(): void {\n if (!this.#trace || this.#stateSizeReported) {\n return;\n }\n this.#stateSizeReported = true;\n\n const {\n assetsBalance: balances,\n customAssets,\n assetsInfo,\n assetsPrice,\n } = this.state;\n\n // Count balance entries and collect unique asset IDs / chain IDs in one pass.\n let balanceEntries = 0;\n const uniqueAssets = new Set<string>();\n const uniqueNetworks = new Set<string>();\n\n for (const acct of Object.values(balances)) {\n const assetIds = Object.keys(acct);\n balanceEntries += assetIds.length;\n for (const assetId of assetIds) {\n uniqueAssets.add(assetId);\n // CAIP-19 format: \"eip155:1/slip44:60\" — chainId is everything before \"/\"\n const slash = assetId.indexOf('/');\n if (slash > 0) {\n uniqueNetworks.add(assetId.slice(0, slash));\n }\n }\n }\n\n let customAssetEntries = 0;\n for (const ids of Object.values(customAssets)) {\n if (Array.isArray(ids)) {\n customAssetEntries += ids.length;\n }\n }\n\n emitTrace({\n name: TRACE_STATE_SIZE,\n trace: this.#trace,\n data: {\n balance_entries: balanceEntries,\n balance_accounts: Object.keys(balances).length,\n // `asset_count` matches the Assets Health dashboard widget field name.\n asset_count: uniqueAssets.size,\n unique_asset_count: uniqueAssets.size,\n network_count: uniqueNetworks.size,\n metadata_entries: Object.keys(assetsInfo).length,\n price_entries: Object.keys(assetsPrice).length,\n custom_asset_entries: customAssetEntries,\n },\n });\n }\n\n readonly #controllerMutex = new Mutex();\n\n /** Serializes account-switch fetch + subscribe to prevent overlapping races. */\n readonly #accountRefreshMutex = new Mutex();\n\n /**\n * Active balance subscriptions keyed by account ID.\n * Each account has one logical subscription that may span multiple data sources.\n * For example, if WebSocket covers chains A,B and RPC covers chain C,\n * the account subscribes to both data sources for its chains.\n */\n readonly #activeSubscriptions: Map<string, SubscriptionResponse> = new Map();\n\n /**\n * Guards against `#start()` re-entrancy. `#activeSubscriptions` only\n * becomes non-empty once `#runStartupRefresh()`'s forced `getAssets()`\n * call resolves, which can take many seconds for accounts with many\n * chains/snaps. `#start()` is invoked by `#updateActive()`, which is\n * wired to several independent events (e.g. keyring unlock, account tree\n * init, client state change). If a second such event fires before the\n * first `getAssets()` call resolves, the `#activeSubscriptions.size > 0`\n * guard alone doesn't catch it, and the whole startup refresh (including\n * its forced `getAssets()` call) runs a second time for the same accounts.\n */\n #startInFlight = false;\n\n /** Currently enabled chains from NetworkEnablementController */\n #enabledChains: Set<ChainId> = new Set();\n\n /**\n * Get the currently selected accounts from AccountTreeController.\n * This includes all accounts in the same group as the selected account\n * (EVM, Bitcoin, Solana, Tron, etc. that belong to the same logical account group).\n *\n * @returns Array of InternalAccount objects from the selected account group.\n */\n #getSelectedAccounts(): InternalAccount[] {\n const accounts = this.messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n );\n if (accounts.length > 0) {\n return accounts;\n }\n const selectedAccount = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n if (selectedAccount) {\n return [selectedAccount];\n }\n return [];\n }\n\n /**\n * Whether `AccountTreeController.init()` has completed and the tree is ready.\n *\n * @returns True when the account tree has been initialized.\n */\n #isAccountTreeInitialized(): boolean {\n return this.messenger.call('AccountTreeController:isInitialized');\n }\n\n /**\n * Whether the client (UI) is open, read from ClientController state.\n *\n * @returns True when the UI is open.\n */\n #isUiOpen(): boolean {\n return clientControllerSelectors.selectIsUiOpen(\n this.messenger.call('ClientController:getState'),\n );\n }\n\n /**\n * Whether the keyring is unlocked, read from KeyringController.\n *\n * @returns True when the wallet vault is unlocked.\n */\n #isKeyringUnlocked(): boolean {\n return this.messenger.call('KeyringController:isUnlocked');\n }\n\n readonly #accountActivityDataSource: AccountActivityDataSource;\n\n readonly #accountsApiDataSource: AccountsApiDataSource;\n\n readonly #snapDataSource: SnapDataSource;\n\n readonly #rpcDataSource: RpcDataSource;\n\n readonly #stakedBalanceDataSource: StakedBalanceDataSource;\n\n /**\n * All balance data sources in priority order for chain-claiming and cleanup.\n * Note: StakedBalanceDataSource is excluded because it provides supplementary\n * data and should not participate in chain-claiming.\n *\n * @returns The four balance data source instances in priority order.\n */\n get #allBalanceDataSources(): [\n AccountActivityDataSource,\n AccountsApiDataSource,\n SnapDataSource,\n RpcDataSource,\n ] {\n return [\n this.#accountActivityDataSource,\n this.#accountsApiDataSource,\n this.#snapDataSource,\n this.#rpcDataSource,\n ];\n }\n\n readonly #priceDataSource: PriceDataSource;\n\n readonly #customAssetGraduationMiddleware: CustomAssetGraduationMiddleware;\n\n readonly #rpcFallbackMiddleware: RpcFallbackMiddleware;\n\n readonly #tokenDataSource: TokenDataSource;\n\n #unsubscribeBasicFunctionality: (() => void) | null = null;\n\n readonly #queryApiClient: ApiPlatformClient;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n constructor({\n messenger,\n state = {},\n defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS,\n isEnabled = (): boolean => true,\n isBasicFunctionality,\n subscribeToBasicFunctionalityChange,\n queryApiClient,\n rpcDataSourceConfig,\n trace,\n captureException,\n accountsApiDataSourceConfig,\n priceDataSourceConfig,\n stakedBalanceDataSourceConfig,\n isOnboarded,\n tempMigrateAssetsInfoMetadataAssets3346,\n }: AssetsControllerOptions) {\n super({\n name: CONTROLLER_NAME,\n messenger,\n metadata: stateMetadata,\n state: {\n ...getDefaultAssetsControllerState(),\n ...state,\n },\n });\n\n this.#isEnabled = isEnabled;\n this.#isBasicFunctionality = isBasicFunctionality ?? ((): boolean => true);\n this.#defaultUpdateInterval = defaultUpdateInterval;\n this.#trace = trace;\n this.#captureException = captureException;\n this.#queryApiClient = queryApiClient;\n const rpcConfig = rpcDataSourceConfig ?? {};\n\n // TEMPORARY: heal assetsInfo metadata wiped by a prior defect\n // (see extension migration #215 / ASSETS-3346). Remove in a future release.\n if (tempMigrateAssetsInfoMetadataAssets3346) {\n this.update(() =>\n tempHealAssetsInfoMetadata({\n state: this.state,\n getMigrationState: tempMigrateAssetsInfoMetadataAssets3346,\n captureException,\n }),\n );\n }\n\n this.#initializeNativeAssetsMap(queryApiClient);\n\n this.#onActiveChainsUpdated = (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ): void => {\n try {\n this.#handleActiveChainsUpdate(dataSourceName, chains, previousChains);\n } catch (error) {\n log('Failed to handle active chains update', {\n dataSourceName,\n error,\n });\n }\n };\n\n this.#accountActivityDataSource = new AccountActivityDataSource({\n messenger: this.messenger,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n onAssetsUpdate: (response, request): Promise<void> =>\n this.handleAssetsUpdate(\n response,\n this.#accountActivityDataSource.getName(),\n request,\n ),\n });\n this.#accountsApiDataSource = new AccountsApiDataSource({\n messenger: this.messenger,\n queryApiClient,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n ...accountsApiDataSourceConfig,\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetsState: (): AssetsControllerState => this.state,\n getAssetVisibility: this.#getAssetVisibility.bind(this),\n });\n this.#snapDataSource = new SnapDataSource({\n messenger: this.messenger,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n onAssetsUpdate: (response): Promise<void> =>\n this.handleAssetsUpdate(response, 'SnapDataSource'),\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetVisibility: this.#getAssetVisibility.bind(this),\n getAssetsState: (): AssetsControllerState => this.state,\n });\n this.#rpcDataSource = new RpcDataSource({\n messenger: this.messenger,\n getAssetsState: (): AssetsControllerState => this.state,\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetVisibility: this.#getAssetVisibility.bind(this),\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n getNativeAssetForChain: (chainId: ChainId): Caip19AssetId | undefined =>\n this.#getNativeAssetForChain(chainId),\n queryApiClient,\n ...rpcConfig,\n isOnboarded: rpcConfig.isOnboarded ?? isOnboarded,\n getAssetType: (assetId: Caip19AssetId): 'native' | 'erc20' | 'spl' =>\n this.#getAssetType(assetId),\n });\n this.#stakedBalanceDataSource = new StakedBalanceDataSource({\n messenger: this.messenger,\n onActiveChainsUpdated: this.#onActiveChainsUpdated,\n ...stakedBalanceDataSourceConfig,\n });\n this.#tokenDataSource = new TokenDataSource(this.messenger, {\n queryApiClient,\n getNativeAssetIds: (): Caip19AssetId[] => {\n return this.#getNativeAssetIdsForEnabledChains();\n },\n getAssetType: (assetId: Caip19AssetId): 'native' | 'erc20' | 'spl' =>\n this.#getAssetType(assetId),\n getAssetsState: (): AssetsControllerState => this.state,\n });\n this.#priceDataSource = new PriceDataSource({\n queryApiClient,\n getSelectedCurrency: (): SupportedCurrency => this.state.selectedCurrency,\n getAssetsState: (): AssetsControllerState => this.state,\n ...priceDataSourceConfig,\n });\n this.#customAssetGraduationMiddleware = new CustomAssetGraduationMiddleware(\n {\n getSelectedAccountId: (): AccountId | undefined => {\n try {\n return this.#getSelectedAccounts()[0]?.id;\n } catch {\n return undefined;\n }\n },\n removeCustomAsset: (accountId, assetId): void =>\n this.removeCustomAsset(accountId, assetId),\n getAssetsState: (): AssetsControllerState => this.state,\n },\n );\n this.#rpcFallbackMiddleware = new RpcFallbackMiddleware({\n rpcDataSource: this.#rpcDataSource,\n isBalanceV6Enabled: (): boolean => this.#isBalanceV6Enabled(),\n getAssetsState: (): AssetsControllerState => this.state,\n });\n\n log('Initializing AssetsController', {\n defaultUpdateInterval: this.#defaultUpdateInterval,\n });\n\n // Subscribe before the first read so a stateChange published while\n // NetworkEnablementController is still starting is not missed.\n this.#subscribeToEvents();\n this.#initializeState();\n this.#registerActionHandlers();\n // Subscriptions start only when both UI is open and keyring unlocked -> #updateActive().\n\n // Subscribe to basic-functionality changes after construction so a synchronous\n // onChange during subscribe cannot run before data sources are initialized.\n if (subscribeToBasicFunctionalityChange) {\n const unsubscribe = subscribeToBasicFunctionalityChange((isBasic) =>\n this.handleBasicFunctionalityChange(isBasic),\n );\n if (typeof unsubscribe === 'function') {\n this.#unsubscribeBasicFunctionality = unsubscribe;\n }\n }\n }\n\n // ============================================================================\n // INITIALIZATION\n // ============================================================================\n\n #initializeNativeAssetsMap(queryApiClient: ApiPlatformClient): void {\n queryApiClient.queryClient\n .fetchQuery({\n queryKey: NATIVE_ASSETS_QUERY_KEY,\n queryFn: buildNativeAssetsFromApi,\n staleTime: Infinity,\n gcTime: Infinity,\n })\n .catch((error) => {\n // Failure to populate native asset cache is non-fatal;\n // #isNativeAsset falls back to the seed data from buildNativeAssetsFromConstant.\n log(\n 'Failed to populate native asset cache, falling back to seed data',\n error,\n );\n });\n\n // Seed the cache synchronously so that synchronous consumers (e.g.\n // #isNativeAsset, #resolveNativeAssetIds) have data available immediately.\n // When fetchQuery resolves (currently instant, future: API), it overwrites\n // this with potentially fresher data.\n const initialNativeAssetMap = buildNativeAssetsFromConstant();\n queryApiClient.setCachedData(\n NATIVE_ASSETS_QUERY_KEY,\n initialNativeAssetMap,\n );\n }\n\n /**\n * Read the current enabled chains from NetworkEnablementController.\n *\n * `Wallet` constructs additional controllers before default ones, so this\n * controller can be constructed before `NetworkEnablementController:getState`\n * is registered. `Wallet.init()` calls `init()` after that controller\n * exists. Later enablement changes arrive on\n * `NetworkEnablementController:stateChange`.\n */\n async init(): Promise<void> {\n this.#initializeState();\n }\n\n #initializeState(): void {\n let enabledNetworkMap: NetworkEnablementControllerState['enabledNetworkMap'];\n try {\n ({ enabledNetworkMap } = this.messenger.call(\n 'NetworkEnablementController:getState',\n ));\n } catch (error) {\n if (!isUnregisteredActionError(error)) {\n throw error;\n }\n log(\n 'NetworkEnablementController:getState is not registered yet. Enabled chains are applied from NetworkEnablementController:stateChange.',\n { error },\n );\n return;\n }\n\n this.#enabledChains = this.#extractEnabledChains(enabledNetworkMap);\n\n log('Initialized state', {\n enabledNetworkMap,\n enabledChains: this.#enabledChains,\n });\n }\n\n /**\n * Extract enabled chains from enabledNetworkMap.\n * Returns CAIP-2 chain IDs for all enabled networks across all namespaces.\n *\n * Note: For EIP155 (EVM) chains, the reference is normalized to decimal format\n * to ensure consistency with CAIP-2 standard and API responses.\n *\n * @param enabledNetworkMap - The enabled network map from NetworkEnablementController.\n * @returns Set of CAIP-2 chain IDs for all enabled networks.\n */\n #extractEnabledChains(\n enabledNetworkMap: NetworkEnablementControllerState['enabledNetworkMap'],\n ): Set<ChainId> {\n const chains = new Set<ChainId>();\n\n for (const [namespace, networks] of Object.entries(enabledNetworkMap)) {\n for (const [reference, isEnabled] of Object.entries(networks)) {\n if (isEnabled) {\n // Check if reference is already a full CAIP-2 chain ID (contains colon)\n if (reference.includes(':')) {\n // Already a full chain ID, use as-is\n chains.add(reference as ChainId);\n } else {\n // Normalize EIP155 chain references from hex to decimal (CAIP-2 standard)\n const normalizedReference = this.#normalizeChainReference(\n namespace,\n reference,\n );\n chains.add(`${namespace}:${normalizedReference}`);\n }\n }\n }\n }\n return chains;\n }\n\n /**\n * Normalize chain reference to CAIP-2 standard format.\n * For EIP155, converts hex chain IDs to decimal.\n *\n * @param namespace - The chain namespace (e.g., \"eip155\").\n * @param reference - The chain reference (e.g., \"0x1\" or \"1\").\n * @returns The normalized chain reference in decimal format.\n */\n #normalizeChainReference(namespace: string, reference: string): string {\n if (namespace === 'eip155' && isStrictHexString(reference)) {\n // Convert hex to decimal for EIP155 chains\n return parseInt(reference, 16).toString();\n }\n return reference;\n }\n\n #subscribeToEvents(): void {\n this.messenger.subscribe(\n 'AccountTreeController:selectedAccountGroupChange',\n (groupId, previousGroupId) => {\n this.#handleAccountGroupChanged(groupId, previousGroupId).catch(\n console.error,\n );\n },\n );\n\n this.messenger.subscribe('AccountTreeController:initialized', () => {\n this.#updateActive();\n });\n this.messenger.subscribe('AccountTreeController:uninitialized', () => {\n this.#updateActive();\n });\n\n // Subscribe to network enablement changes (only enabledNetworkMap)\n this.messenger.subscribe(\n 'NetworkEnablementController:stateChange',\n ({ enabledNetworkMap }) => {\n this.#handleEnabledNetworksChanged(enabledNetworkMap).catch(\n console.error,\n );\n },\n );\n\n // When a network is added or removed from NetworkController, refresh\n // assets across every data source so balances, prices, and metadata\n // stay consistent. On add we also seed default tracked assets (e.g.\n // mUSD on Monad) when the chain is in our defaults registry, so the\n // entries appear immediately without waiting for it to also be\n // enabled in NetworkEnablementController.\n this.messenger.subscribe(\n 'NetworkController:networkAdded',\n (networkConfiguration) => {\n this.#handleNetworkAdded(networkConfiguration.chainId);\n this.#refreshAssetsAfterNetworkAdded(\n networkConfiguration.chainId,\n ).catch((error: unknown) => {\n log('Failed to refresh assets after network added', { error });\n });\n },\n );\n\n this.messenger.subscribe('NetworkController:networkRemoved', () => {\n this.#refreshAssetsAfterNetworkChange();\n });\n\n // Selected EVM network switch (network picker). Enablement changes are\n // handled separately via NetworkEnablementController:stateChange.\n this.messenger.subscribe(\n 'NetworkController:networkDidChange',\n (networkState) => {\n this.#handleNetworkDidChange(networkState).catch(console.error);\n },\n );\n\n // Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked\n this.messenger.subscribe(\n 'ClientController:stateChange',\n () => {\n this.#updateActive();\n },\n clientControllerSelectors.selectIsUiOpen,\n );\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.messenger.subscribe('KeyringController:unlock', async () => {\n try {\n this.#runOutOfScopeBalanceCleanup();\n } catch {\n /* Do nothing */\n }\n await this.#runSpamCleanup().catch(() => {\n /* Do nothing */\n });\n this.#updateActive();\n });\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#updateActive();\n });\n\n // Subscribe to unapproved transactions - TXs that need confirmation.\n // Ensures balances for the account making the transaction are updated\n // (e.g. for gas estimations), except on AccountActivity-active chains.\n this.messenger.subscribe(\n 'TransactionController:unapprovedTransactionAdded',\n (transactionMeta: TransactionMeta) => {\n this.#refreshAssetsForEVMTransaction(transactionMeta);\n },\n );\n\n // Post-tx refresh via the full fetch pipeline (Accounts API + RPC fallback).\n // Skipped for chains covered by AccountActivity (real-time WS updates).\n // RpcDataSource also listens for transactionConfirmed, but only refreshes\n // chains it owns via an active subscription.\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta: TransactionMeta) => {\n this.#refreshAssetsForEVMTransaction(transactionMeta);\n },\n );\n\n // Non-EVM equivalent of the above: Snap keyrings report transaction\n // lifecycle through MultichainTransactionsController. When the chain is\n // not covered by AccountActivity (WebSocket down / unsupported), refresh\n // via the Accounts API with the server cache bypassed.\n this.messenger.subscribe(\n 'MultichainTransactionsController:transactionConfirmed',\n (transaction: KeyringTransaction) => {\n this.#refreshAssetsForNonEvmTransaction(transaction);\n },\n );\n }\n\n /**\n * Force-refresh assets for the account/chain of an EVM transaction, unless\n * the chain is already covered by AccountActivity (real-time WebSocket\n * balances). Always bypasses the Accounts API's server-side cache so a\n * refresh cannot be answered with a stale pre-transaction snapshot.\n *\n * @param transactionMeta - The transaction that triggered the refresh.\n */\n #refreshAssetsForEVMTransaction(transactionMeta: TransactionMeta): void {\n const hexChainId = transactionMeta.chainId;\n if (!hexChainId) {\n return;\n }\n\n const caipChainId = `eip155:${parseInt(hexChainId, 16)}` as ChainId;\n\n const fromAddress = transactionMeta.txParams.from?.toLowerCase();\n if (!fromAddress) {\n return;\n }\n\n this.#refreshAssetsAfterConfirmed(\n caipChainId,\n (account) => account.address.toLowerCase() === fromAddress,\n );\n }\n\n /**\n * Non-EVM counterpart of `#refreshAssetsForEVMTransaction` for transactions\n * reported by Snap keyrings via\n * `MultichainTransactionsController`. The keyring `Transaction` already\n * carries a CAIP-2 `chain` and the internal `account` id, so no address\n * normalisation is needed.\n *\n * @param transaction - The confirmed keyring transaction.\n */\n #refreshAssetsForNonEvmTransaction(transaction: KeyringTransaction): void {\n const { chain, account: accountId } = transaction;\n if (!chain || !accountId || !isCaipChainId(chain)) {\n return;\n }\n\n this.#refreshAssetsAfterConfirmed(\n chain,\n (account) => account.id === accountId,\n );\n }\n\n /**\n * Shared post-transaction refresh: skip when AccountActivity already pushes\n * live balances for `caipChainId` (a force fetch would be redundant and can\n * race the WebSocket path); otherwise run a force `getAssets` for the first\n * selected account matching `matchAccount`, bypassing the Accounts API's\n * server-side cache.\n *\n * @param caipChainId - CAIP-2 chain the transaction was on.\n * @param matchAccount - Predicate selecting the originating account among\n * the currently selected accounts.\n */\n #refreshAssetsAfterConfirmed(\n caipChainId: ChainId,\n matchAccount: (account: InternalAccount) => boolean,\n ): void {\n if (\n this.#accountActivityDataSource\n .getActiveChainsSync()\n .includes(caipChainId)\n ) {\n return;\n }\n\n const matchedAccount = this.#getSelectedAccounts().find(matchAccount);\n if (!matchedAccount) {\n return;\n }\n\n this.getAssets([matchedAccount], {\n chainIds: [caipChainId],\n forceUpdate: true,\n bypassServerCache: true,\n }).catch((error: unknown) => {\n log('Failed to refresh assets after transaction event', { error });\n });\n }\n\n /**\n * One-time cleanup of balances a v5 update stamped onto accounts after a\n * group switch. Runs on unlock, the same point as spam cleanup, and only\n * touches the selected accounts (their scopes are what define ownership).\n */\n #runOutOfScopeBalanceCleanup(): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n this.update((state) => {\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n dropBalancesOutsideAccountScopes(balances, accounts);\n });\n }\n\n async #runSpamCleanup(): Promise<void> {\n try {\n const shouldRun =\n this.#isKeyringUnlocked() &&\n this.#isBasicFunctionality() &&\n isUnlockCleanupEnabled(\n this.messenger.call('RemoteFeatureFlagController:getState')\n ?.remoteFeatureFlags,\n );\n if (!shouldRun) {\n return;\n }\n } catch (error) {\n log('Failed to start spam cleanup', { error });\n return;\n }\n\n try {\n const originalState = this.state;\n const result = await cleanSpamAssets({\n state: originalState,\n apiClient: this.#queryApiClient,\n captureException: this.#captureException,\n });\n\n if (!result) {\n return;\n }\n\n this.update((state) => {\n result.applyPatch(\n /* oxlint-disable typescript/no-unnecessary-type-assertion */\n state as Pick<\n AssetsControllerState,\n 'assetsInfo' | 'assetsBalance' | 'assetsPrice'\n >,\n /* oxlint-enable typescript/no-unnecessary-type-assertion */\n {\n spamAssetIds: result.spamAssetIds,\n },\n );\n });\n } catch (error) {\n log('Failed to run spam cleanup', { error });\n }\n }\n\n /**\n * Start or stop asset tracking based on client (UI) open state, keyring\n * unlock state, and account-tree readiness. Only runs when the UI is open,\n * the keyring is unlocked, and the account tree has finished `init()`.\n */\n #updateActive(): void {\n const shouldRun =\n this.#isUiOpen() &&\n this.#isKeyringUnlocked() &&\n this.#isAccountTreeInitialized();\n if (shouldRun) {\n this.#start();\n } else {\n this.#stop();\n }\n }\n\n /**\n * Force-fetch balances then subscribe. Used on unlock / first startup.\n *\n * @param accounts - Selected accounts to refresh.\n */\n async #runStartupRefresh(accounts: InternalAccount[]): Promise<void> {\n const releaseLock = await this.#accountRefreshMutex.acquire();\n try {\n await this.getAssets(accounts, {\n chainIds: [...this.#enabledChains],\n forceUpdate: true,\n });\n // Seed before subscribe so the price poll / update fetch sees natives\n // and default tracked assets that were never returned by balance APIs.\n this.#ensureNativeBalancesDefaultZero();\n this.#ensureDefaultTrackedAssetsSeeded();\n // Balances were just force-fetched — skip AccountsApi's subscribe-time poll.\n this.#subscribeAssets({ skipInitialFetch: true });\n } catch (error) {\n log('Failed to fetch assets on startup', error);\n this.#ensureNativeBalancesDefaultZero();\n this.#ensureDefaultTrackedAssetsSeeded();\n this.#subscribeAssets({ skipInitialFetch: true });\n } finally {\n releaseLock();\n }\n }\n\n #registerActionHandlers(): void {\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n // ============================================================================\n // DATA SOURCE CHAIN MANAGEMENT\n // ============================================================================\n\n /**\n * Handle when a data source's supported chains change.\n * Used to refresh balance subscriptions and run a one-time fetch when a new chain is supported.\n *\n * - On any add/remove: re-subscribes to data sources so chain assignment stays correct.\n * - When chains are added: fetches balances for the new chains (for selected accounts on enabled networks).\n *\n * Controller does not store chains; sources report via this callback. previousChains is required for diff.\n *\n * @param dataSourceId - The identifier of the data source reporting the change.\n * @param activeChains - Currently active (supported and available) chain IDs for this source.\n * @param previousChains - Previous chains; used to compute added/removed.\n */\n #handleActiveChainsUpdate(\n dataSourceId: string,\n activeChains: ChainId[],\n previousChains: ChainId[],\n ): void {\n if (!this.#isUiOpen() || !this.#isKeyringUnlocked() || !this.#isEnabled()) {\n return;\n }\n log('Data source active chains changed', {\n dataSourceId,\n chainCount: activeChains.length,\n chains: activeChains,\n });\n\n const previous: ChainId[] = previousChains;\n\n const previousSet = new Set(previous);\n const addedChains = activeChains.filter((ch) => !previousSet.has(ch));\n const removedChains = previous.filter((ch) => !activeChains.includes(ch));\n\n // Refresh subscriptions to use updated data source availability.\n if (addedChains.length > 0 || removedChains.length > 0) {\n this.#subscribeAssets();\n }\n }\n\n /**\n * Returns the callback passed to data sources for reporting active chain updates.\n * Used by tests to simulate a data source reporting chain changes.\n *\n * @returns The onActiveChainsUpdated callback.\n */\n getOnActiveChainsUpdated(): (\n dataSourceId: string,\n activeChains: ChainId[],\n previousChains: ChainId[],\n ) => void {\n return this.#onActiveChainsUpdated;\n }\n\n // ============================================================================\n // MIDDLEWARE EXECUTION\n // ============================================================================\n\n /**\n * Execute middlewares with request/response context.\n * Returns response and exclusive duration per source (sum ≈ wall time).\n *\n * Thin wrapper over {@link executeAssetsPipeline} that supplies the\n * controller-owned exception reporter.\n *\n * @param params - Middleware execution options.\n * @param params.sources - Data sources or middlewares with getName() and assetsMiddleware.\n * @param params.request - The data request.\n * @param params.initialResponse - Optional initial response (for enriching existing data).\n * @param params.parentContext - Optional parent Sentry span; per-source timings nest under it.\n * @param params.trace - Optional trace callback; omit after unlock/first-init to skip spans.\n * @returns Response and durationByDataSource (exclusive ms per source name).\n */\n async #executeMiddlewares(params: {\n sources: AssetsDataSource[];\n request: DataRequest;\n initialResponse?: DataResponse;\n parentContext?: TraceContext;\n /** Omit after unlock/first-init so timing spans are not emitted. */\n trace?: TraceCallback;\n }): Promise<{\n response: DataResponse;\n durationByDataSource: Record<string, number>;\n }> {\n return executeAssetsPipeline({\n ...params,\n captureException: this.#captureException,\n });\n }\n\n // ============================================================================\n // PUBLIC API: QUERY METHODS\n // ============================================================================\n\n @trackAssetsLoading\n async getAssets(\n accounts: InternalAccount[],\n options?: {\n chainIds?: ChainId[];\n assetTypes?: AssetType[];\n forceUpdate?: boolean;\n /**\n * Also bypass server-side HTTP caches (e.g. the Accounts API's 60s\n * cache, via a random `bypassServerCache` query param). Only meaningful\n * together with `forceUpdate`. Use sparingly — e.g. right after a\n * transaction confirms, when the API's cached snapshot is known stale.\n */\n bypassServerCache?: boolean;\n dataTypes?: DataType[];\n },\n ): Promise<Record<AccountId, Record<Caip19AssetId, Asset>>> {\n const chainIds = options?.chainIds ?? [...this.#enabledChains];\n const assetTypes = options?.assetTypes ?? ['fungible'];\n const dataTypes = options?.dataTypes ?? ['balance', 'metadata', 'price'];\n\n if (accounts.length === 0 || chainIds.length === 0) {\n return this.#getAssetsFromState(accounts, chainIds, assetTypes);\n }\n\n if (options?.forceUpdate) {\n await this.#forceUpdateAssets({\n accounts,\n chainIds,\n requestOptions: {\n assetTypes,\n dataTypes,\n forceUpdate: true,\n bypassServerCache: options.bypassServerCache,\n },\n });\n }\n\n const result = this.#getAssetsFromState(accounts, chainIds, assetTypes);\n return result;\n }\n\n /**\n * Force-fetch spot prices for an explicit asset list.\n *\n * Calls `PriceDataSource` directly and merges the result into `assetsPrice`.\n * Prices are shared across accounts, so this does not take an account or\n * chain scope and does not run the balance pipeline.\n *\n * Returns without calling the Price API when basic functionality is off.\n * That matches the asset pipeline, which drops the price source in RPC-only\n * mode, and `setSelectedCurrency`, which skips its price refresh.\n *\n * @param assetIds - CAIP-19 asset IDs to sync.\n */\n async syncAssetsPrices(assetIds: Caip19AssetId[]): Promise<void> {\n if (!this.#isBasicFunctionality() || assetIds.length === 0) {\n return;\n }\n\n const assetsPrice = await this.#priceDataSource.fetchAssetPrices(assetIds);\n if (Object.keys(assetsPrice).length === 0) {\n return;\n }\n\n await this.#updateState({\n assetsPrice,\n updateMode: 'merge',\n });\n }\n\n /**\n * Run a forced fetch on the v5 or v6 pipeline.\n *\n * @param params - Accounts, chains, and request fields for this fetch.\n * @param params.accounts - Accounts in this fetch.\n * @param params.chainIds - Chains in this fetch.\n * @param params.requestOptions - Shared force-update request fields.\n */\n async #forceUpdateAssets({\n accounts,\n chainIds,\n requestOptions,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n requestOptions: {\n assetTypes: AssetType[];\n dataTypes: DataType[];\n forceUpdate: true;\n bypassServerCache?: boolean;\n };\n }): Promise<void> {\n const pipelineTrace = this.#firstInitFetchReported\n ? undefined\n : this.#trace;\n\n if (this.#isBalanceV6Enabled()) {\n await this.#forceUpdateAssetsV6({\n accounts,\n chainIds,\n request: this.#buildDataRequest(accounts, chainIds, requestOptions),\n pipelineTrace,\n });\n return;\n }\n\n await this.#forceUpdateAssetsV5({\n accounts,\n chainIds,\n request: this.#buildForceUpdateRequestV5(\n accounts,\n chainIds,\n requestOptions,\n ),\n pipelineTrace,\n });\n }\n\n /**\n * v5 force-update request: every pin of the requested accounts, unscoped.\n * Delete with the rest of the v5 path when `assetsAccountsApiV6` is the default.\n *\n * @param accounts - Accounts in this fetch.\n * @param chainIds - Chains in this fetch.\n * @param requestOptions - Shared force-update request fields.\n * @param requestOptions.assetTypes - Asset types to fetch.\n * @param requestOptions.dataTypes - Data types to fetch.\n * @param requestOptions.forceUpdate - Always `true` to bypass caches.\n * @param requestOptions.bypassServerCache - Also bypass server-side HTTP caches.\n * @returns The v5 data request.\n */\n #buildForceUpdateRequestV5(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n requestOptions: {\n assetTypes: AssetType[];\n dataTypes: DataType[];\n forceUpdate: true;\n bypassServerCache?: boolean;\n },\n ): DataRequest {\n const customAssets: Caip19AssetId[] = [];\n for (const account of accounts) {\n customAssets.push(...this.getCustomAssets(account.id));\n }\n\n return this.#buildDataRequest(accounts, chainIds, {\n ...requestOptions,\n customAssets: customAssets.length > 0 ? customAssets : undefined,\n });\n }\n\n async #forceUpdateAssetsV5({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n }): Promise<void> {\n const isBasicFunctionality = this.#isBasicFunctionality();\n const fastSources = buildFastFetchSources(\n {\n accountsApiDataSource: this.#accountsApiDataSource,\n customAssetGraduationMiddleware: this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n { isBasicFunctionality, includeCustomAssetGraduation: true },\n );\n\n const fastResponse = await this.#runFastFetchV5({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n });\n this.#firstInitFetchReported = true;\n\n this.#runBackgroundFetch({\n accounts,\n request,\n pipelineTrace,\n chainIds: this.#getSlowPipelineChainIds(chainIds, fastResponse),\n isBasicFunctionality,\n });\n }\n\n async #forceUpdateAssetsV6({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n }): Promise<void> {\n const isBasicFunctionality = this.#isBasicFunctionality();\n const fastSources = buildFastFetchSources(\n {\n accountsApiDataSource: this.#accountsApiDataSource,\n customAssetGraduationMiddleware: this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n {\n isBasicFunctionality,\n includeCustomAssetGraduation: false,\n },\n );\n\n const fastResponse = await this.#runFastFetchV6({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n });\n this.#firstInitFetchReported = true;\n\n this.#runBackgroundFetch({\n accounts,\n request,\n pipelineTrace,\n chainIds: this.#getSlowPipelineChainIds(chainIds, fastResponse),\n isBasicFunctionality,\n });\n }\n\n async #runFastFetchV5({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n fastSources: AssetsDataSource[];\n isBasicFunctionality: boolean;\n }): Promise<DataResponse> {\n const { response } = await withTrace({\n name: TRACE_FETCH_PIPELINE,\n trace: pipelineTrace,\n data: {\n chain_count: chainIds.length,\n account_count: accounts.length,\n basic_functionality: isBasicFunctionality,\n },\n fn: async (parentContext) => {\n const startTime = performance.now();\n const result = await this.#executeMiddlewares({\n sources: fastSources,\n request,\n parentContext,\n trace: pipelineTrace,\n });\n await this.#updateState({\n ...result.response,\n updateMode: 'merge',\n replaceCoveredChainBalances: true,\n });\n this.#emitFastFetchTraces({\n accounts,\n chainIds,\n result,\n durationMs: performance.now() - startTime,\n isBasicFunctionality,\n parentContext,\n pipelineTrace,\n });\n return result;\n },\n });\n return response;\n }\n\n async #runFastFetchV6({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n fastSources,\n isBasicFunctionality,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n fastSources: AssetsDataSource[];\n isBasicFunctionality: boolean;\n }): Promise<DataResponse> {\n const { response } = await withTrace({\n name: TRACE_FETCH_PIPELINE,\n trace: pipelineTrace,\n data: {\n chain_count: chainIds.length,\n account_count: accounts.length,\n basic_functionality: isBasicFunctionality,\n },\n fn: async (parentContext) => {\n const startTime = performance.now();\n const result = await this.#executeMiddlewares({\n sources: fastSources,\n request,\n parentContext,\n trace: pipelineTrace,\n });\n await this.#updateState(result.response);\n this.#emitFastFetchTraces({\n accounts,\n chainIds,\n result,\n durationMs: performance.now() - startTime,\n isBasicFunctionality,\n parentContext,\n pipelineTrace,\n });\n return result;\n },\n });\n return response;\n }\n\n #runBackgroundFetch({\n accounts,\n chainIds,\n request,\n pipelineTrace,\n isBasicFunctionality,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n request: DataRequest;\n pipelineTrace?: TraceCallback;\n isBasicFunctionality: boolean;\n }): void {\n if (chainIds.length === 0) {\n return;\n }\n const slowSources = isBasicFunctionality\n ? [this.#snapDataSource, this.#rpcDataSource]\n : [this.#rpcDataSource];\n const slowRequest = { ...request, chainIds };\n\n withTrace({\n name: TRACE_BACKGROUND_FETCH,\n trace: pipelineTrace,\n data: {\n chain_count: chainIds.length,\n account_count: accounts.length,\n },\n fn: async (parentContext) => {\n const { response } = await this.#executeMiddlewares({\n sources: [\n createParallelBalanceMiddleware(slowSources),\n ...(isBasicFunctionality\n ? [\n createParallelMiddleware([\n this.#tokenDataSource,\n this.#priceDataSource,\n ]),\n ]\n : []),\n ],\n request: slowRequest,\n parentContext,\n trace: pipelineTrace,\n });\n await this.#updateState(response);\n },\n }).catch((error: unknown) => log('Background pipeline failed', { error }));\n }\n\n #emitFastFetchTraces({\n accounts,\n chainIds,\n result,\n durationMs,\n isBasicFunctionality,\n parentContext,\n pipelineTrace,\n }: {\n accounts: InternalAccount[];\n chainIds: ChainId[];\n result: {\n response: DataResponse;\n durationByDataSource: Record<string, number>;\n };\n durationMs: number;\n isBasicFunctionality: boolean;\n parentContext?: TraceContext;\n pipelineTrace?: TraceCallback;\n }): void {\n emitTrace({\n name: TRACE_FULL_FETCH,\n trace: pipelineTrace,\n data: {\n duration_ms: durationMs,\n chain_count: chainIds.length,\n account_count: accounts.length,\n basic_functionality: isBasicFunctionality,\n asset_count: result.response.assetsBalance\n ? Object.values(result.response.assetsBalance).reduce(\n (sum, account) => sum + Object.keys(account).length,\n 0,\n )\n : 0,\n price_count: result.response.assetsPrice\n ? Object.keys(result.response.assetsPrice).length\n : 0,\n ...result.durationByDataSource,\n },\n parentContext,\n });\n emitTrace({\n name: TRACE_FIRST_INIT_FETCH,\n trace: pipelineTrace,\n data: {\n duration_ms: durationMs,\n chain_ids: JSON.stringify(chainIds),\n ...result.durationByDataSource,\n },\n parentContext,\n });\n }\n\n async getAssetsBalance(\n accounts: InternalAccount[],\n options?: {\n chainIds?: ChainId[];\n assetTypes?: AssetType[];\n forceUpdate?: boolean;\n },\n ): Promise<Record<AccountId, Record<Caip19AssetId, AssetBalance>>> {\n // Reuse getAssets with dataTypes: ['balance'] only\n const assets = await this.getAssets(accounts, {\n chainIds: options?.chainIds,\n assetTypes: options?.assetTypes,\n forceUpdate: options?.forceUpdate,\n dataTypes: ['balance', 'metadata'],\n });\n\n // Extract just the balance from each asset\n const result: Record<AccountId, Record<Caip19AssetId, AssetBalance>> = {};\n for (const [accountId, accountAssets] of Object.entries(assets)) {\n result[accountId] = {};\n for (const [assetId, asset] of Object.entries(accountAssets)) {\n if (asset.balance) {\n result[accountId][assetId as Caip19AssetId] = asset.balance;\n }\n }\n }\n\n return result;\n }\n\n getAssetMetadata(assetId: Caip19AssetId): AssetMetadata | undefined {\n return this.state.assetsInfo[assetId];\n }\n\n /**\n * Get a single combined asset (balance + metadata + price + computed\n * `fiatValue`) for an account directly from controller state.\n *\n * Reuses the same state-composition and filtering logic as `getAssets`\n * (balance and metadata are required, a missing price falls back to\n * `{ price: 0, lastUpdated: 0 }` with `fiatValue: 0`, and hidden or\n * otherwise filtered assets are excluded) so the returned shape never\n * drifts from `getAssets`. Reads from current state only and does not\n * trigger a data-source refresh.\n *\n * @param accountId - The account ID (`InternalAccount.id`, not an address).\n * @param assetId - The CAIP-19 asset ID including chain scope\n * (e.g. `eip155:1/erc20:0x...`).\n * @returns The combined `Asset`, or `undefined` when no complete\n * renderable asset (balance + metadata) exists for the account/asset pair.\n * @throws If `accountId` is empty or `assetId` is not a valid CAIP-19 asset ID.\n */\n getAccountAssetByID(\n accountId: AccountId,\n assetId: Caip19AssetId,\n ): Asset | undefined {\n this.#assertNonEmptyAccountId(accountId, 'getAccountAssetByID');\n\n const normalizedAssetId = this.#normalizeAssetIdOrThrow(\n assetId,\n 'getAccountAssetByID',\n );\n\n return this.#getAssetFromState(accountId, normalizedAssetId, {\n assetTypeSet: new Set(['fungible']),\n });\n }\n\n /**\n * Get multiple combined assets (balance + metadata + price + computed\n * `fiatValue`) for an account directly from controller state.\n *\n * Applies the same state-composition and filtering rules as\n * `getAccountAssetByID` to each requested asset ID. Asset IDs that do not\n * resolve to a complete renderable asset (missing balance/metadata, hidden,\n * or otherwise filtered out) are omitted from the result. Reads from\n * current state only and does not trigger a data-source refresh.\n *\n * @param accountId - The account ID (`InternalAccount.id`, not an address).\n * @param assetIds - The CAIP-19 asset IDs including chain scope\n * (e.g. `eip155:1/erc20:0x...`).\n * @returns A record of combined `Asset`s keyed by normalized CAIP-19 asset\n * ID, containing only the requested assets that resolved.\n * @throws If `accountId` is empty or any `assetIds` entry is not a valid\n * CAIP-19 asset ID.\n */\n getAccountAssetsByIDs(\n accountId: AccountId,\n assetIds: Caip19AssetId[],\n ): Record<Caip19AssetId, Asset> {\n this.#assertNonEmptyAccountId(accountId, 'getAccountAssetsByIDs');\n\n const result = Object.create(null) as Record<Caip19AssetId, Asset>;\n\n for (const assetId of assetIds) {\n const normalizedAssetId = this.#normalizeAssetIdOrThrow(\n assetId,\n 'getAccountAssetsByIDs',\n );\n\n const asset = this.#getAssetFromState(accountId, normalizedAssetId, {\n assetTypeSet: new Set(['fungible']),\n });\n\n if (asset) {\n result[normalizedAssetId] = asset;\n }\n }\n\n return result;\n }\n\n /**\n * Get all combined assets (balance + metadata + price + computed\n * `fiatValue`) an account holds on a given chain scope, directly from\n * controller state.\n *\n * Applies the same state-composition and filtering rules as\n * `getAccountAssetByID` (hidden or otherwise filtered assets are excluded).\n * Reads from current state only and does not trigger a data-source refresh.\n *\n * @param accountId - The account ID (`InternalAccount.id`, not an address).\n * @param scope - The CAIP-2 chain ID to filter by (e.g. `eip155:1`).\n * @returns A record of combined `Asset`s keyed by CAIP-19 asset ID,\n * containing only the account's assets on the given scope.\n * @throws If `accountId` is empty or `scope` is not a valid CAIP-2 chain ID.\n */\n getAccountAssetsByScope(\n accountId: AccountId,\n scope: ChainId,\n ): Record<Caip19AssetId, Asset> {\n this.#assertNonEmptyAccountId(accountId, 'getAccountAssetsByScope');\n\n if (!isCaipChainId(scope)) {\n throw new Error(\n `AssetsController.getAccountAssetsByScope: invalid CAIP-2 scope \"${String(\n scope,\n )}\"`,\n );\n }\n\n const result = Object.create(null) as Record<Caip19AssetId, Asset>;\n const chainIdSet = new Set<ChainId>([scope]);\n const assetTypeSet = new Set<AssetType>(['fungible']);\n const accountBalances = this.state.assetsBalance[accountId] ?? {};\n\n for (const assetId of Object.keys(accountBalances)) {\n const typedAssetId = assetId as Caip19AssetId;\n\n const asset = this.#getAssetFromState(accountId, typedAssetId, {\n chainIdSet,\n assetTypeSet,\n });\n\n if (asset) {\n result[typedAssetId] = asset;\n }\n }\n\n return result;\n }\n\n /**\n * Throws when the provided account ID is not a non-empty string.\n *\n * @param accountId - The account ID to validate.\n * @param methodName - The public method name used in the error message.\n */\n #assertNonEmptyAccountId(accountId: AccountId, methodName: string): void {\n if (typeof accountId !== 'string' || accountId.length === 0) {\n throw new Error(\n `AssetsController.${methodName}: accountId must be a non-empty string`,\n );\n }\n }\n\n /**\n * Normalizes a CAIP-19 asset ID, converting normalization failures into a\n * descriptive error.\n *\n * @param assetId - The CAIP-19 asset ID to normalize.\n * @param methodName - The public method name used in the error message.\n * @returns The normalized CAIP-19 asset ID.\n */\n #normalizeAssetIdOrThrow(\n assetId: Caip19AssetId,\n methodName: string,\n ): Caip19AssetId {\n try {\n return normalizeAssetId(assetId);\n } catch {\n throw new Error(\n `AssetsController.${methodName}: invalid CAIP-19 assetId \"${assetId}\"`,\n );\n }\n }\n\n async getAssetsPrice(\n accounts: InternalAccount[],\n options?: {\n chainIds?: ChainId[];\n assetTypes?: AssetType[];\n forceUpdate?: boolean;\n },\n ): Promise<Record<Caip19AssetId, AssetPrice>> {\n const assets = await this.getAssets(accounts, {\n chainIds: options?.chainIds,\n assetTypes: options?.assetTypes,\n forceUpdate: options?.forceUpdate,\n dataTypes: ['price'],\n });\n\n // Extract just the price from each asset (flattened across accounts)\n const result: Record<Caip19AssetId, AssetPrice> = {};\n for (const accountAssets of Object.values(assets)) {\n for (const [assetId, asset] of Object.entries(accountAssets)) {\n if (asset.price) {\n result[assetId as Caip19AssetId] = asset.price;\n }\n }\n }\n\n return result;\n }\n\n /**\n * Returns exchange rates in the format expected by the bridge controller\n * (conversionRates, currencyRates, marketData, currentCurrency) so that\n * when useAssetsControllerForRates is true the bridge can use a single\n * action instead of MultichainAssetsRatesController, TokenRatesController,\n * and CurrencyRateController.\n *\n * @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency.\n */\n getExchangeRatesForBridge(): BridgeExchangeRatesFormat {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n return formatExchangeRatesForBridge({\n assetsInfo: this.state.assetsInfo,\n assetsPrice: this.state.assetsPrice,\n selectedCurrency: this.state.selectedCurrency,\n nativeAssetIdentifiers: this.#getNativeAssetMap(),\n networkConfigurationsByChainId,\n });\n }\n\n /**\n * Returns state in the legacy format expected by transaction-pay-controller\n * (TokenBalancesController, AccountTrackerController, TokensController,\n * TokenRatesController, CurrencyRateController shapes) so that when\n * useAssetsController is true the transaction-pay-controller can use a\n * single action instead of five separate getState calls.\n *\n * @returns Legacy-compatible state for transaction-pay-controller.\n */\n getStateForTransactionPay(): TransactionPayLegacyFormat {\n const accounts = this.#getSelectedAccounts();\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n return formatStateForTransactionPay({\n assetsBalance: this.state.assetsBalance,\n assetsInfo: this.state.assetsInfo,\n assetsPrice: this.state.assetsPrice,\n selectedCurrency: this.state.selectedCurrency,\n accounts: accounts.map((a) => ({ id: a.id, address: a.address })),\n nativeAssetIdentifiers: this.#getNativeAssetMap(),\n networkConfigurationsByChainId,\n });\n }\n\n // ============================================================================\n // CUSTOM ASSETS MANAGEMENT\n // ============================================================================\n\n /**\n * Add a custom asset for an account.\n * Custom assets are included in subscription and fetch operations.\n * Adding a custom asset also unhides it if it was previously hidden,\n * and force-fetches that asset's chain (including every visible pin).\n *\n * When `pendingMetadata` is provided (e.g. from the extension's pending-tokens\n * flow), the token metadata is persisted immediately into `assetsInfo` so the\n * UI can render it without waiting for the next pipeline fetch.\n *\n * @param accountId - The account ID to add the custom asset for.\n * @param assetId - The CAIP-19 asset ID to add.\n * @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).\n */\n async addCustomAsset(\n accountId: AccountId,\n assetId: Caip19AssetId,\n pendingMetadata?: PendingTokenMetadata,\n ): Promise<void> {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Adding custom asset', { accountId, assetId: normalizedAssetId });\n\n this.update((state) => {\n const customAssets = state.customAssets as Record<string, string[]>;\n if (!customAssets[accountId]) {\n customAssets[accountId] = [];\n }\n\n // Only add if not already present\n if (!customAssets[accountId].includes(normalizedAssetId)) {\n customAssets[accountId].push(normalizedAssetId);\n }\n\n // Unhide the asset if it was hidden (via assetPreferences)\n const prefs = state.assetPreferences[normalizedAssetId];\n if (prefs?.hidden) {\n delete prefs.hidden;\n if (Object.keys(prefs).length === 0) {\n delete state.assetPreferences[normalizedAssetId];\n }\n }\n\n // Persist metadata from the UI so the token is immediately renderable\n if (pendingMetadata) {\n const parsed = parseCaipAssetType(normalizedAssetId);\n let tokenType: FungibleAssetMetadata['type'] = 'erc20';\n if (this.#isNativeAsset(normalizedAssetId)) {\n tokenType = 'native';\n } else if (\n parsed.chain.namespace === KnownCaipNamespace.Solana &&\n parsed.assetNamespace === CaipAssetNamespace.Token\n ) {\n tokenType = 'spl';\n }\n\n const assetMetadata: FungibleAssetMetadata = {\n type: tokenType,\n symbol: pendingMetadata.symbol,\n name: pendingMetadata.name,\n decimals: pendingMetadata.decimals,\n image: pendingMetadata.iconUrl,\n aggregators: pendingMetadata.aggregators,\n occurrences: pendingMetadata.occurrences,\n };\n\n (state.assetsInfo as Record<string, AssetMetadata>)[normalizedAssetId] =\n assetMetadata;\n }\n\n // Seed a zero balance so the UI can render the asset immediately,\n // before the next pipeline fetch returns the real amount.\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n balances[accountId] ??= {};\n balances[accountId][normalizedAssetId] ??=\n getZeroAssetBalance(normalizedAssetId);\n });\n\n const account = this.#getSelectedAccounts().find((a) => a.id === accountId);\n if (account) {\n await this.getAssets([account], {\n chainIds: [extractChainId(normalizedAssetId)],\n dataTypes: ['balance', 'metadata', 'price'],\n assetTypes: ['fungible'],\n forceUpdate: true,\n });\n }\n\n // Re-evaluate subscriptions so polls pick up the new pin.\n this.#subscribeAssets();\n }\n\n /**\n * Remove a custom asset from an account.\n *\n * @param accountId - The account ID to remove the custom asset from.\n * @param assetId - The CAIP-19 asset ID to remove.\n */\n removeCustomAsset(accountId: AccountId, assetId: Caip19AssetId): void {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Removing custom asset', { accountId, assetId: normalizedAssetId });\n\n this.update((state) => {\n if (state.customAssets[accountId]) {\n state.customAssets[accountId] = state.customAssets[accountId].filter(\n (id) => id !== normalizedAssetId,\n );\n\n // Clean up empty arrays\n if (state.customAssets[accountId].length === 0) {\n delete state.customAssets[accountId];\n }\n }\n });\n\n // Re-evaluate subscriptions so polls drop the removed pin.\n this.#subscribeAssets();\n }\n\n /**\n * Get all custom assets for an account.\n *\n * @param accountId - The account ID to get custom assets for.\n * @returns Array of CAIP-19 asset IDs for the account's custom assets.\n */\n getCustomAssets(accountId: AccountId): Caip19AssetId[] {\n return this.state.customAssets[accountId] ?? [];\n }\n\n // ============================================================================\n // HIDDEN ASSETS MANAGEMENT\n // ============================================================================\n\n /**\n * Hide an asset globally.\n * Hidden assets are excluded from the asset list returned by getAssets.\n * The hidden state is stored in assetPreferences.\n *\n * @param assetId - The CAIP-19 asset ID to hide.\n */\n hideAsset(assetId: Caip19AssetId): void {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Hiding asset', { assetId: normalizedAssetId });\n\n this.update((state) => {\n if (!state.assetPreferences[normalizedAssetId]) {\n state.assetPreferences[normalizedAssetId] = {};\n }\n state.assetPreferences[normalizedAssetId].hidden = true;\n });\n\n // Re-evaluate subscriptions so polls exclude the newly hidden asset.\n this.#subscribeAssets();\n }\n\n /**\n * Unhide an asset globally.\n * Force-fetches that asset's chain (including every visible pin) so a\n * `full` snapshot can restore the balance immediately, then re-evaluates\n * subscriptions so later polls stop excluding it.\n *\n * @param assetId - The CAIP-19 asset ID to unhide.\n */\n async unhideAsset(assetId: Caip19AssetId): Promise<void> {\n const normalizedAssetId = normalizeAssetId(assetId);\n\n log('Unhiding asset', { assetId: normalizedAssetId });\n\n this.update((state) => {\n const prefs = state.assetPreferences[normalizedAssetId];\n if (prefs) {\n delete prefs.hidden;\n if (Object.keys(prefs).length === 0) {\n delete state.assetPreferences[normalizedAssetId];\n }\n }\n });\n\n const chainId = extractChainId(normalizedAssetId);\n const account = this.#getSelectedAccounts().find((selectedAccount) =>\n this.#getEnabledChainsForAccount(selectedAccount).includes(chainId),\n );\n if (account) {\n await this.getAssets([account], {\n chainIds: [chainId],\n dataTypes: ['balance', 'metadata', 'price'],\n assetTypes: ['fungible'],\n forceUpdate: true,\n });\n }\n\n this.#subscribeAssets();\n }\n\n /**\n * Whether Accounts API v6 (and the v6 custom-asset path) is enabled.\n * Injected into AccountsApiDataSource and RpcFallbackMiddleware.\n *\n * `RemoteFeatureFlagController` resolves a threshold-scoped flag to the\n * selected group's `value`, so processed state is a boolean.\n *\n * @returns `true` when the v6 remote flag is on.\n */\n #isBalanceV6Enabled(): boolean {\n try {\n const { remoteFeatureFlags } = this.messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n return remoteFeatureFlags?.assetsAccountsApiV6 === true;\n } catch {\n return false;\n }\n }\n\n // ============================================================================\n // CURRENT CURRENCY MANAGEMENT\n // ============================================================================\n\n /**\n * Set the current currency.\n *\n * @param selectedCurrency - The ISO 4217 currency code to set.\n */\n setSelectedCurrency(selectedCurrency: SupportedCurrency): void {\n const previousCurrency = this.state.selectedCurrency;\n\n if (previousCurrency === selectedCurrency) {\n return;\n }\n\n this.update((state) => {\n state.selectedCurrency = selectedCurrency;\n });\n\n log('Current currency changed', {\n previousCurrency,\n selectedCurrency,\n });\n\n if (!this.#isBasicFunctionality()) {\n return;\n }\n\n // Currency changed — old cached prices are in the wrong currency.\n this.#priceDataSource.invalidatePriceCache();\n\n this.syncAssetsPrices(\n Object.values(this.state.assetsBalance).flatMap(\n (balances) => Object.keys(balances) as Caip19AssetId[],\n ),\n ).catch((error) => {\n log('Failed to fetch asset prices after current currency change', error);\n });\n }\n\n // ============================================================================\n // SUBSCRIPTIONS\n // ============================================================================\n\n /**\n * Subscribe to price updates for all assets held by the given accounts.\n * Polls PriceDataSource which fetches prices from balance state.\n *\n * @param accounts - Accounts to subscribe price updates for.\n * @param chainIds - Chain IDs to filter prices for.\n */\n subscribeAssetsPrice(accounts: InternalAccount[], chainIds: ChainId[]): void {\n if (!this.#isBasicFunctionality()) {\n return;\n }\n const subscriptionKey = 'ds:PriceDataSource';\n\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n const isUpdate = existingSubscription !== undefined;\n\n const request = this.#buildDataRequest(accounts, chainIds, {\n dataTypes: ['price'],\n });\n const subscribeReq: SubscriptionRequest = {\n request,\n subscriptionId: subscriptionKey,\n isUpdate,\n onAssetsUpdate: (response) =>\n this.handleAssetsUpdate(response, 'PriceDataSource'),\n };\n\n this.#priceDataSource.subscribe(subscribeReq).catch(console.error);\n\n // Track subscription\n const subscription: SubscriptionResponse = {\n chains: chainIds,\n accountId: subscriptionKey,\n assetTypes: ['fungible'],\n dataTypes: ['price'],\n unsubscribe: () => {\n this.#activeSubscriptions.delete(subscriptionKey);\n },\n };\n\n this.#activeSubscriptions.set(subscriptionKey, subscription);\n }\n\n /**\n * Unsubscribe from price updates.\n */\n unsubscribeAssetsPrice(): void {\n const subscriptionKey = 'ds:PriceDataSource';\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n\n if (!existingSubscription) {\n return;\n }\n this.#priceDataSource.unsubscribe(subscriptionKey).catch(console.error);\n existingSubscription.unsubscribe();\n }\n\n // ============================================================================\n // STATE MANAGEMENT\n // ============================================================================\n\n /**\n * Reads the native asset map (CAIP-2 chain ID -> CAIP-19 native asset ID)\n * from the QueryClient cache. Populated at construction via fetchQuery.\n *\n * @returns Cached map, or a stable empty object if not yet populated\n * (stable identity so downstream memoized formatters can cache-hit).\n */\n #getNativeAssetMap(): Record<ChainId, Caip19AssetId> {\n return (\n this.#queryApiClient.getCachedData<Record<ChainId, Caip19AssetId>>(\n NATIVE_ASSETS_QUERY_KEY,\n ) ?? EMPTY_NATIVE_ASSET_MAP\n );\n }\n\n /**\n * Canonical native CAIP-19 ID for a chain. Uses the native asset map when\n * the chain is registered. An unregistered EVM chain falls back to the\n * zero-address ERC-20 encoding used for EVM natives without a SLIP-44 id;\n * an unregistered non-EVM chain resolves no native at all — fabricating an\n * `erc20:` asset on a non-EVM namespace would produce an ID no data source\n * ever writes.\n *\n * @param chainId - CAIP-2 chain ID.\n * @returns The native asset ID for the chain, or `undefined` when the\n * chain is unregistered and non-EVM.\n */\n #getNativeAssetForChain(chainId: ChainId): Caip19AssetId | undefined {\n const registered = this.#getNativeAssetMap()[chainId];\n if (registered) {\n return registered;\n }\n if (parseCaipChainId(chainId).namespace === KnownCaipNamespace.Eip155) {\n return `${chainId}/${UNKNOWN_EVM_NATIVE_ASSET_REFERENCE}` as Caip19AssetId;\n }\n return undefined;\n }\n\n #getAssetVisibility(\n accountIds: AccountId[],\n chainIds: ChainId[],\n ): AssetVisibility {\n return getAssetVisibility({\n state: this.state,\n accountIds,\n chainIds,\n getNativeAssetForChain: (chainId) =>\n this.#getNativeAssetForChain(chainId),\n });\n }\n\n /**\n * Lowercased asset IDs a v6 `full` snapshot must keep for an account, even\n * when the response omits them: natives, pins, and default tracked assets\n * the client asked for. Hidden assets are sent as `excludeAssetIds` and are\n * dropped here; unhide is expected to fetch a new snapshot. Everything else\n * on a covered chain was discovered by the source, so its absence means the\n * balance is gone.\n *\n * @param state - State being updated (the in-flight draft, not `this.state`).\n * @param accountId - Account whose pins apply.\n * @param accountBalances - Incoming balances, which define the covered chains.\n * @returns Lowercased CAIP-19 IDs that must survive the replace.\n */\n #getUndeletableAssetIds(\n state: AssetsControllerState,\n accountId: AccountId,\n accountBalances: Record<string, AssetBalance>,\n ): Set<string> {\n const coveredChainIds = [\n ...new Set(\n Object.keys(accountBalances).map(\n (assetId) => assetId.split('/')[0] as ChainId,\n ),\n ),\n ];\n const { visibleAssetIds } = getAssetVisibility({\n state,\n accountIds: [accountId],\n chainIds: coveredChainIds,\n // Registered natives only: the unknown-native fallback is a fabricated\n // ID, so it must never shield a row from a `full` replace.\n getNativeAssetForChain: (chainId) => this.#getNativeAssetMap()[chainId],\n });\n\n return new Set(visibleAssetIds.map((assetId) => assetId.toLowerCase()));\n }\n\n /**\n * Checks whether the given CAIP-19 asset ID represents a native asset\n * according to the cached native asset map, the asset namespace, and the asset reference.\n *\n * @param assetId - The CAIP-19 asset ID to check (case-insensitive).\n * @returns True if the asset ID is a native asset.\n */\n #isNativeAsset(assetId: Caip19AssetId): boolean {\n const parsed = parseCaipAssetType(assetId);\n\n if (parsed.assetNamespace === 'slip44') {\n return true;\n }\n\n const lower = assetId.toLowerCase();\n const isInNativeAssetMap = Object.values(this.#getNativeAssetMap()).some(\n (id) => id.toLowerCase() === lower,\n );\n if (isInNativeAssetMap) {\n return true;\n }\n\n if (\n parsed.assetNamespace === 'erc20' &&\n parsed.assetReference === ZERO_ADDRESS\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Determines the asset type for a given CAIP-19 asset ID.\n *\n * @param assetId - The CAIP-19 asset ID.\n * @returns The asset type: 'native', 'erc20', or 'spl'.\n */\n #getAssetType(assetId: Caip19AssetId): 'native' | 'erc20' | 'spl' {\n const parsed = parseCaipAssetType(assetId);\n\n if (this.#isNativeAsset(assetId)) {\n return 'native';\n }\n\n if (\n parsed.chain.namespace === KnownCaipNamespace.Solana &&\n parsed.assetNamespace === CaipAssetNamespace.Token\n ) {\n return 'spl';\n }\n\n return 'erc20';\n }\n\n /**\n * Resolves native asset IDs (CAIP-19) for the given chains by looking them up\n * in the cached native asset map.\n * Chains without a registered native identifier are skipped.\n *\n * @param chains - The chain IDs to resolve native assets for.\n * @returns Array of native asset IDs for the chains that have a registered identifier.\n */\n #resolveNativeAssetIds(chains: Iterable<ChainId>): Caip19AssetId[] {\n const nativeAssetMap = this.#getNativeAssetMap();\n const ids: Caip19AssetId[] = [];\n for (const chainId of chains) {\n const nativeId = nativeAssetMap[chainId];\n if (nativeId) {\n ids.push(nativeId);\n }\n }\n return ids;\n }\n\n /**\n * Returns native asset IDs for all enabled chains.\n *\n * @returns Array of native asset IDs, one per enabled chain that has a registered identifier.\n */\n #getNativeAssetIdsForEnabledChains(): Caip19AssetId[] {\n return this.#resolveNativeAssetIds(this.#enabledChains);\n }\n\n /**\n * Returns native asset IDs for the chains that this account supports\n * (account scopes ∩ enabled chains).\n *\n * @param account - The account (scopes determine which chains apply).\n * @returns Array of native asset IDs, one per supported chain that has a registered identifier.\n */\n #getNativeAssetIdsForAccount(account: InternalAccount): Caip19AssetId[] {\n return this.#resolveNativeAssetIds(\n this.#getEnabledChainsForAccount(account),\n );\n }\n\n /**\n * Chains for the post-commit slow pipeline (Snap + RPC). Excludes chains the\n * fast Accounts API path already handled without error so stale RPC data cannot\n * overwrite fresh API zeros (e.g. after max send).\n *\n * @param chainIds - Chains requested by the caller.\n * @param fastResponse - Response committed by the fast pipeline.\n * @returns Chain IDs that still need the slow pipeline.\n */\n #getSlowPipelineChainIds(\n chainIds: ChainId[],\n fastResponse: DataResponse,\n ): ChainId[] {\n const accountsApiChains = new Set(\n this.#accountsApiDataSource.getActiveChainsSync(),\n );\n\n return chainIds.filter((chainId) => {\n if (fastResponse.errors?.[chainId]) {\n return true;\n }\n if (!accountsApiChains.has(chainId)) {\n return true;\n }\n return false;\n });\n }\n\n /**\n * Ensures assetsBalance has a 0 balance for each native token (from\n * NetworkEnablementController.nativeAssetIdentifiers) for each selected account.\n * Only adds natives for chains that the account supports (correct accountId ↔ chain mapping).\n */\n #ensureNativeBalancesDefaultZero(): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n this.update((state) => {\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n for (const account of accounts) {\n const accountId = account.id;\n const nativeAssetIds = this.#getNativeAssetIdsForAccount(account);\n if (nativeAssetIds.length === 0) {\n continue;\n }\n if (!balances[accountId]) {\n balances[accountId] = {};\n }\n for (const nativeAssetId of nativeAssetIds) {\n if (\n !Object.prototype.hasOwnProperty.call(\n balances[accountId],\n nativeAssetId,\n )\n ) {\n balances[accountId][nativeAssetId] =\n getDefaultNativeAssetBalance(nativeAssetId);\n }\n }\n }\n });\n }\n\n /**\n * Seed selected accounts with zero-balance entries for every\n * controller-managed default tracked asset (e.g. mUSD on mainnet,\n * Linea, Monad). Also re-asserts the metadata in `assetsInfo` so the\n * defaults survive a future state migration that strips them.\n *\n * `chainsToSeed` lets callers narrow the work to a specific subset\n * of chains — useful when reacting to a `NetworkEnablementController`\n * change to seed only the chain that was just added (e.g. when the\n * user finally turns on Monad). When `undefined`, every chain in the\n * default tracked assets registry is seeded.\n *\n * Existing entries are never clobbered.\n *\n * @param chainsToSeed - Optional subset of CAIP-2 chain ids to seed.\n * If omitted, all default tracked chains are seeded.\n */\n #ensureDefaultTrackedAssetsSeeded(chainsToSeed?: ChainId[]): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n // Default tracked assets are ERC-20s on EVM chains today. Restrict\n // seeding to accounts that have at least one EVM scope so we don't\n // pollute non-EVM accounts. The wildcard `eip155:0` scope counts.\n const evmAccounts = accounts.filter((account) =>\n (account.scopes ?? []).some((scope) => scope.startsWith('eip155:')),\n );\n if (evmAccounts.length === 0) {\n return;\n }\n\n // Gate seeding on whether the chain is currently enabled. This is\n // why mUSD appears on mainnet/Linea immediately (those are normally\n // enabled at startup) but only appears on Monad once the user\n // turns the Monad network on.\n const candidateChains = chainsToSeed ?? [...this.#enabledChains];\n const targetChains = candidateChains.filter((chainId) =>\n CHAINS_WITH_DEFAULT_TRACKED_ASSETS.has(chainId),\n );\n if (targetChains.length === 0) {\n return;\n }\n this.update((state) => {\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n const metadata = state.assetsInfo as Record<string, AssetMetadata>;\n\n for (const chainId of targetChains) {\n const defaultAssetIds =\n DEFAULT_TRACKED_ASSETS_BY_CHAIN.get(chainId) ?? [];\n for (const assetId of defaultAssetIds) {\n // Re-seed metadata if state was hydrated from a prior version\n // that didn't include defaults.\n if (!metadata[assetId]) {\n const seed = getDefaultAssetMetadata(assetId);\n if (seed) {\n metadata[assetId] = seed;\n }\n }\n\n for (const account of evmAccounts) {\n balances[account.id] ??= {};\n const accountBalances = balances[account.id];\n accountBalances[assetId] ??= { amount: '0' };\n }\n }\n }\n });\n }\n\n async #updateState(response: DataResponse): Promise<void> {\n const normalizedResponse = normalizeResponse(response);\n const mode: AssetsUpdateMode = normalizedResponse.updateMode ?? 'merge';\n const isBalanceV6Enabled = this.#isBalanceV6Enabled();\n\n const releaseLock = await this.#controllerMutex.acquire();\n\n try {\n const previousState = this.state;\n const previousPrices = { ...this.state.assetsPrice };\n\n // Track actual changes for logging\n const changedBalances: {\n accountId: string;\n assetId: string;\n oldAmount: string | undefined;\n newAmount: string;\n }[] = [];\n const changedMetadata: string[] = [];\n\n this.update((state) => {\n // Use type assertions to avoid deep type instantiation issues with Immer Draft types\n const metadata = state.assetsInfo as Record<string, AssetMetadata>;\n const balances = state.assetsBalance as Record<\n string,\n Record<string, AssetBalance>\n >;\n const prices = state.assetsPrice as Record<string, AssetPrice>;\n\n if (normalizedResponse.assetsInfo) {\n for (const [key, value] of Object.entries(\n normalizedResponse.assetsInfo,\n )) {\n const existing = metadata[key] as FungibleAssetMetadata | undefined;\n const incoming = value as FungibleAssetMetadata;\n\n // When the API returns no symbol or name for this token, it has no\n // real knowledge of it (e.g. a user-deployed token not indexed by\n // the API). Preserve richer metadata already in state (e.g. from\n // pendingMetadata set by addCustomAsset) so that the correct\n // decimals/symbol/name/image are not overwritten with empty values.\n const nextValue =\n existing && !incoming.symbol && !incoming.name\n ? {\n ...existing,\n ...incoming,\n symbol: existing.symbol,\n name: existing.name,\n decimals: existing.decimals ?? incoming.decimals,\n image: existing.image ?? incoming.image,\n }\n : value;\n\n if (\n !isEqual(\n previousState.assetsInfo[key as Caip19AssetId],\n nextValue,\n )\n ) {\n metadata[key] = nextValue;\n changedMetadata.push(key);\n }\n }\n }\n\n // Reconcile & self-heal stale asset \"types\" (e.g. erc20 -> native)\n // using IDs from new response assetInfo and assetBalance\n const assetsInfoAssetIdsSet = new Set<Caip19AssetId>([\n ...Object.keys(normalizedResponse.assetsInfo ?? {}),\n ...Object.values(normalizedResponse.assetsBalance ?? {}).flatMap(\n (accountBalances) => Object.keys(accountBalances),\n ),\n ] as Caip19AssetId[]);\n for (const assetId of assetsInfoAssetIdsSet) {\n const entry = metadata[assetId] as FungibleAssetMetadata | undefined;\n if (!entry) {\n continue;\n }\n const correctType = this.#getAssetType(assetId);\n if (entry.type !== correctType) {\n metadata[assetId] = { ...entry, type: correctType };\n if (!changedMetadata.includes(assetId)) {\n changedMetadata.push(assetId);\n }\n }\n }\n\n if (normalizedResponse.assetsBalance) {\n const applyV5AccountBalanceUpdate = (\n accountId: string,\n accountBalances: Record<string, AssetBalance>,\n previousBalances: Record<string, AssetBalance>,\n ): void => {\n const customAssetIds =\n (state.customAssets as Record<string, Caip19AssetId[]>)[\n accountId\n ] ?? [];\n\n const replaceCoveredChains =\n mode === 'full' ||\n normalizedResponse.replaceCoveredChainBalances === true;\n\n const effectiveAccountBalances = effectiveAccountBalancesV5(\n previousBalances,\n accountBalances,\n customAssetIds,\n replaceCoveredChains,\n );\n\n // Ensure native tokens have an entry (0 if missing) for chains this account supports\n const account = this.#getSelectedAccounts().find(\n (a) => a.id === accountId,\n );\n const nativeAssetIdsForAccount = account\n ? this.#getNativeAssetIdsForAccount(account)\n : [];\n for (const nativeAssetId of nativeAssetIdsForAccount) {\n if (\n !Object.prototype.hasOwnProperty.call(\n effectiveAccountBalances,\n nativeAssetId,\n )\n ) {\n effectiveAccountBalances[nativeAssetId] =\n getDefaultNativeAssetBalance(nativeAssetId);\n }\n }\n\n for (const [assetId, balance] of Object.entries(\n effectiveAccountBalances,\n )) {\n const previousBalance = previousBalances[\n assetId as Caip19AssetId\n ] as AssetBalance | undefined;\n // Coerce amounts (e.g. \"1e-18\" from a data source stringifying\n // a JS Number) into a plain decimal so downstream BigInt()\n // consumers don't crash. Decimals are read from the freshest\n // merged metadata when available; when metadata is not yet\n // known, the amount is left at its natural precision (only\n // exponent form is rewritten) so balances arriving before\n // their metadata aren't lossily truncated.\n const assetDecimals = (\n metadata[assetId] as { decimals?: number } | undefined\n )?.decimals;\n const newAmount = normalizeAmountString(\n (balance as { amount: unknown }).amount,\n assetDecimals,\n );\n const newMetadata =\n (balance as FungibleAssetBalance).metadata ??\n (previousBalance as FungibleAssetBalance | undefined)?.metadata;\n effectiveAccountBalances[assetId] = {\n amount: newAmount,\n ...(newMetadata === undefined ? {} : { metadata: newMetadata }),\n };\n const oldAmount = previousBalance?.amount;\n const isNewSeededZero =\n oldAmount === undefined &&\n newAmount === '0' &&\n (nativeAssetIdsForAccount.includes(assetId as Caip19AssetId) ||\n getDefaultAssetMetadata(assetId as Caip19AssetId) !==\n undefined);\n if (oldAmount !== newAmount && !isNewSeededZero) {\n changedBalances.push({\n accountId,\n assetId,\n oldAmount,\n newAmount,\n });\n }\n }\n\n if (!isEqual(previousBalances, effectiveAccountBalances)) {\n balances[accountId] = effectiveAccountBalances;\n }\n };\n\n // Delete with the rest of the v6 path if `assetsAccountsApiV6` is\n // rolled back; v5 keeps using `applyV5AccountBalanceUpdate`.\n const applyV6AccountBalanceUpdate = (\n accountId: string,\n accountBalances: Record<string, AssetBalance>,\n previousBalances: Record<string, AssetBalance>,\n ): void => {\n const effectiveAccountBalances = effectiveAccountBalancesV6(\n previousBalances,\n accountBalances,\n this.#getUndeletableAssetIds(\n state as unknown as AssetsControllerState,\n accountId,\n accountBalances,\n ),\n mode,\n );\n\n for (const [assetId, balance] of Object.entries(\n effectiveAccountBalances,\n )) {\n const previousBalance = previousBalances[\n assetId as Caip19AssetId\n ] as AssetBalance | undefined;\n const assetDecimals = (\n metadata[assetId] as { decimals?: number } | undefined\n )?.decimals;\n const newAmount = normalizeAmountString(\n (balance as { amount: unknown }).amount,\n assetDecimals,\n );\n const newMetadata =\n (balance as FungibleAssetBalance).metadata ??\n (previousBalance as FungibleAssetBalance | undefined)?.metadata;\n effectiveAccountBalances[assetId] = {\n amount: newAmount,\n ...(newMetadata === undefined ? {} : { metadata: newMetadata }),\n };\n const oldAmount = previousBalance?.amount;\n // A v6 snapshot reports assets the account holds none of (its\n // `includeAssetIds`) at zero. Publishing those as a change would\n // emit `0 -> 0`, since a missing previous amount reads as '0'.\n const isNewZero = oldAmount === undefined && newAmount === '0';\n if (oldAmount !== newAmount && !isNewZero) {\n changedBalances.push({\n accountId,\n assetId,\n oldAmount,\n newAmount,\n });\n }\n }\n\n if (!isEqual(previousBalances, effectiveAccountBalances)) {\n balances[accountId] = effectiveAccountBalances;\n }\n };\n\n for (const [accountId, accountBalances] of Object.entries(\n normalizedResponse.assetsBalance,\n )) {\n const previousBalances =\n previousState.assetsBalance[accountId] ?? {};\n\n if (isBalanceV6Enabled) {\n applyV6AccountBalanceUpdate(\n accountId,\n accountBalances,\n previousBalances,\n );\n } else {\n applyV5AccountBalanceUpdate(\n accountId,\n accountBalances,\n previousBalances,\n );\n }\n }\n }\n\n if (normalizedResponse.assetsPrice) {\n for (const [key, value] of Object.entries(\n normalizedResponse.assetsPrice,\n )) {\n if (!isEqual(previousPrices[key as Caip19AssetId], value)) {\n prices[key] = value;\n }\n }\n }\n });\n\n // Emit state size trace (throttled to avoid JSON.stringify on every update)\n this.#emitStateSizeTrace();\n\n // Calculate changed prices\n const changedPriceAssets: string[] = normalizedResponse.assetsPrice\n ? Object.keys(normalizedResponse.assetsPrice).filter(\n (assetId) =>\n !isEqual(\n previousPrices[assetId as Caip19AssetId],\n normalizedResponse.assetsPrice?.[assetId as Caip19AssetId],\n ),\n )\n : [];\n\n // Log only actual changes\n if (\n changedBalances.length > 0 ||\n changedMetadata.length > 0 ||\n changedPriceAssets.length > 0\n ) {\n log('State updated', {\n changedBalances:\n changedBalances.length > 0 ? changedBalances : undefined,\n changedMetadata:\n changedMetadata.length > 0 ? changedMetadata : undefined,\n changedPrices:\n changedPriceAssets.length > 0 ? changedPriceAssets : undefined,\n });\n }\n\n // Publish balance changed events\n for (const change of changedBalances) {\n this.messenger.publish('AssetsController:balanceChanged', {\n accountId: change.accountId,\n assetId: change.assetId as Caip19AssetId,\n previousAmount: change.oldAmount ?? '0',\n newAmount: change.newAmount,\n });\n }\n\n // Publish price changed event with full price data\n if (changedPriceAssets.length > 0 && normalizedResponse.assetsPrice) {\n // Build prices object with only changed prices\n const changedPrices: Record<Caip19AssetId, AssetPrice> = {};\n for (const assetId of changedPriceAssets) {\n const price =\n normalizedResponse.assetsPrice[assetId as Caip19AssetId];\n if (price) {\n changedPrices[assetId as Caip19AssetId] = price;\n }\n }\n this.messenger.publish('AssetsController:priceChanged', {\n prices: changedPrices,\n });\n }\n } finally {\n releaseLock();\n }\n }\n\n #getAssetsFromState(\n accounts: Pick<InternalAccount, 'id'>[],\n chainIds: ChainId[],\n assetTypes: AssetType[],\n ): Record<AccountId, Record<Caip19AssetId, Asset>> {\n const result = Object.create(null) as Record<\n AccountId,\n Record<Caip19AssetId, Asset>\n >;\n // Convert to Sets for O(1) lookups\n const chainIdSet = new Set(chainIds);\n const assetTypeSet = new Set(assetTypes);\n\n for (const account of accounts) {\n result[account.id] = Object.create(null) as Record<Caip19AssetId, Asset>;\n\n const accountBalances = this.state.assetsBalance[account.id] ?? {};\n\n for (const assetId of Object.keys(accountBalances)) {\n const typedAssetId = assetId as Caip19AssetId;\n\n const asset = this.#getAssetFromState(account.id, typedAssetId, {\n chainIdSet,\n assetTypeSet,\n });\n\n if (asset) {\n result[account.id][typedAssetId] = asset;\n }\n }\n }\n\n return result;\n }\n\n /**\n * Compose a single combined `Asset` (balance + metadata + price + computed\n * `fiatValue`) for an account/asset pair directly from controller state,\n * applying the same filtering rules as `#getAssetsFromState`.\n *\n * @param accountId - The account ID (`InternalAccount.id`).\n * @param assetId - The normalized CAIP-19 asset ID.\n * @param filters - Optional filters applied before composing the asset.\n * @param filters.chainIdSet - When provided, the asset's chain must be in this set.\n * @param filters.assetTypeSet - When provided, the asset's type must be in this set.\n * @returns The combined `Asset`, or `undefined` when the asset is missing a\n * balance/metadata, is hidden/filtered out, or fails a provided filter.\n */\n #getAssetFromState(\n accountId: AccountId,\n assetId: Caip19AssetId,\n filters?: {\n chainIdSet?: Set<ChainId>;\n assetTypeSet?: Set<AssetType>;\n },\n ): Asset | undefined {\n const balance = this.state.assetsBalance[accountId]?.[assetId];\n\n // Skip assets without a balance entry\n if (!balance) {\n return undefined;\n }\n\n const metadata = this.state.assetsInfo[assetId];\n\n // Skip assets without metadata\n if (!metadata) {\n return undefined;\n }\n\n // Skip hidden assets (assetPreferences)\n const prefs = this.state.assetPreferences[assetId];\n if (prefs?.hidden) {\n return undefined;\n }\n\n const assetChainId = extractChainId(assetId);\n\n // Skip native tokens on Tempo networks\n if (this.#shouldHideNativeToken(assetChainId, metadata)) {\n return undefined;\n }\n\n if (filters?.chainIdSet && !filters.chainIdSet.has(assetChainId)) {\n return undefined;\n }\n\n // Filter by asset type\n if (filters?.assetTypeSet) {\n const tokenAssetType = this.#tokenStandardToAssetType(metadata.type);\n if (!filters.assetTypeSet.has(tokenAssetType)) {\n return undefined;\n }\n }\n\n const priceRaw = this.state.assetsPrice[assetId];\n const price: AssetPrice = priceRaw ?? {\n price: 0,\n lastUpdated: 0,\n };\n\n // Compute fiat value using BigNumber for precision\n // Note: balance.amount is already in human-readable format (e.g., \"1\" for 1 ETH)\n // so we do NOT divide by 10^decimals here\n const balanceAmount = new BigNumberJS(balance.amount || '0');\n const fiatValue = balanceAmount.multipliedBy(price.price || 0).toNumber();\n\n return {\n id: assetId,\n chainId: assetChainId,\n balance,\n metadata,\n price,\n fiatValue,\n };\n }\n\n /**\n * Determines if a native token should be hidden on specific networks.\n *\n * @param chainId - The CAIP-2 chain ID (e.g., \"eip155:42431\").\n * @param metadata - The asset metadata.\n * @returns True if the token should be hidden, false otherwise.\n */\n #shouldHideNativeToken(chainId: ChainId, metadata: AssetMetadata): boolean {\n // Check if it's a chain that should skip native tokens\n if (!shouldSkipNativeForCaipChainId(chainId)) {\n return false;\n }\n\n return metadata.type === 'native';\n }\n\n /**\n * Maps a token standard to its corresponding asset type.\n *\n * @param tokenStandard - The token standard from metadata.\n * @returns The corresponding asset type.\n */\n #tokenStandardToAssetType(tokenStandard: string): AssetType {\n switch (tokenStandard) {\n case 'native':\n case 'erc20':\n case 'spl':\n return 'fungible';\n case 'erc721':\n return 'nft';\n case 'erc1155':\n // ERC1155 can be either fungible or non-fungible, treat as collectible\n return 'collectible';\n default:\n // Unknown standards default to fungible\n return 'fungible';\n }\n }\n\n // ============================================================================\n // START / STOP\n // ============================================================================\n\n /**\n * Start asset tracking: subscribe to updates and fetch current balances.\n * Idempotent — returns early if accounts/chains are not yet available or\n * subscriptions are already active.\n */\n #start(): void {\n const accounts = this.#getSelectedAccounts();\n const chainIds = [...this.#enabledChains];\n\n if (accounts.length === 0 || chainIds.length === 0) {\n return;\n }\n\n if (this.#activeSubscriptions.size > 0 || this.#startInFlight) {\n return;\n }\n\n log('Starting asset tracking', {\n selectedAccountCount: accounts.length,\n enabledChainCount: chainIds.length,\n });\n\n this.#startInFlight = true;\n this.#runStartupRefresh(accounts)\n .catch((error) => {\n log('Failed to start asset tracking', error);\n })\n .finally(() => {\n this.#startInFlight = false;\n });\n }\n\n /**\n * Stop asset tracking: unsubscribe from all updates.\n * Called when app closes or keyring locks.\n */\n #stop(): void {\n log('Stopping asset tracking', {\n activeSubscriptionCount: this.#activeSubscriptions.size,\n hasPriceSubscription: this.#activeSubscriptions.has('ds:PriceDataSource'),\n });\n\n this.#firstInitFetchReported = false;\n this.#stateSizeReported = false;\n\n // Stop price subscription first (uses direct messenger call)\n this.unsubscribeAssetsPrice();\n\n // Stop balance subscriptions by properly notifying data sources via messenger\n // This ensures data sources stop their polling timers.\n // Use #allBalanceDataSources + staked balance source so we unsubscribe from\n // every source that may have been subscribed.\n const allSources = [\n ...this.#allBalanceDataSources,\n this.#stakedBalanceDataSource,\n ];\n const subscriptionKeys = [...this.#activeSubscriptions.keys()];\n for (const subscriptionKey of subscriptionKeys) {\n if (!subscriptionKey.startsWith('ds:')) {\n continue;\n }\n // Subscription keys take the form `ds:<SourceName>`.\n const [, sourceId] = subscriptionKey.split(':');\n const source = allSources.find((ds) => ds.getName() === sourceId);\n if (source) {\n this.#unsubscribeBySubscriptionKey(source, subscriptionKey);\n }\n }\n this.#activeSubscriptions.clear();\n }\n\n /**\n * Handle basic functionality toggle change. Call this from the consumer (extension or mobile)\n * when the user changes the \"Basic functionality\" setting. Refreshes subscriptions so the\n * current {@link AssetsControllerOptions.isBasicFunctionality} getter is used (true = APIs on,\n * false = RPC only).\n *\n * @param _isBasic - The new value (for call-site clarity; the getter is the source of truth).\n */\n handleBasicFunctionalityChange(_isBasic: boolean): void {\n this.#stop();\n this.#subscribeAssets();\n }\n\n /**\n * Subscribe to asset updates for all selected accounts.\n *\n * @param options - Subscription options.\n * @param options.skipInitialFetch - When true, AccountsApi skips its\n * one-shot subscribe poll (use after a force `getAssets` for the same scope).\n */\n #subscribeAssets(options?: { skipInitialFetch?: boolean }): void {\n const accounts = this.#getSelectedAccounts();\n const enabledChains = [...this.#enabledChains];\n if (accounts.length === 0 || enabledChains.length === 0) {\n return;\n }\n\n // Subscribe to balance updates (batched by data source)\n this.#subscribeAssetsBalance(accounts, enabledChains, options);\n\n // Subscribe to staked balance updates (separate from regular balance chain-claiming)\n this.#subscribeStakedBalance(accounts, enabledChains);\n\n // Subscribe to price updates for all assets held by selected accounts\n this.subscribeAssetsPrice(accounts, enabledChains);\n }\n\n /**\n * Subscribe to balance updates for the given accounts and chains.\n *\n * Strategy to minimize data source calls:\n * 1. Collect all chains to subscribe based on enabled networks\n * 2. Map chains to accounts based on their scopes\n * 3. Split by data source (priority order) — each source gets one\n * subscription for the chains it was assigned (accounts + chains only).\n * v6 sources read pins/hides/defaults from state themselves (Accounts API\n * sends `includeAssetIds` / `excludeAssetIds`; RPC polls native, balances,\n * pins, and default tracked assets). v5 uses a separate RPC\n * `customAssetsOnly` supplement for pins on chains another source owns.\n *\n * @param accounts - Accounts to subscribe balance updates for.\n * @param chainIds - Chain IDs to subscribe for.\n * @param options - Subscription options.\n * @param options.skipInitialFetch - Forwarded to AccountsApi subscribe.\n */\n #subscribeAssetsBalance(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n options?: { skipInitialFetch?: boolean },\n ): void {\n const chainToAccounts = this.#buildChainToAccountsMap(\n accounts,\n new Set(chainIds),\n );\n const remainingChains = new Set(chainToAccounts.keys());\n const balanceDataSources = this.#isBasicFunctionality()\n ? this.#allBalanceDataSources\n : [this.#rpcDataSource];\n let rpcAssignedChains: Set<ChainId> = new Set();\n\n for (const source of balanceDataSources) {\n const availableChains = new Set(source.getActiveChainsSync());\n const assignedChains: ChainId[] = [];\n\n for (const chainId of remainingChains) {\n if (availableChains.has(chainId)) {\n assignedChains.push(chainId);\n remainingChains.delete(chainId);\n }\n }\n if (assignedChains.length === 0) {\n this.#unsubscribeDataSource(source);\n continue;\n }\n if (source === this.#rpcDataSource) {\n rpcAssignedChains = new Set(assignedChains);\n }\n const seenIds = new Set<string>();\n const accountsForSource = assignedChains\n .flatMap((chainId) => chainToAccounts.get(chainId) ?? [])\n .filter((account) => {\n if (seenIds.has(account.id)) {\n return false;\n }\n seenIds.add(account.id);\n return true;\n });\n if (accountsForSource.length > 0) {\n this.#subscribeDataSource(source, accountsForSource, assignedChains, {\n ...(options?.skipInitialFetch &&\n source === this.#accountsApiDataSource\n ? { skipInitialFetch: true }\n : {}),\n });\n }\n }\n\n if (!this.#isBalanceV6Enabled()) {\n this.#subscribeRpcCustomAssetsSupplement(\n accounts,\n chainToAccounts,\n rpcAssignedChains,\n );\n }\n }\n\n /**\n * Guarantee that customAssets are **always** polled by RPC, even when\n * AccountsApi or another data source has claimed the chain in the\n * regular handoff. RPC is the sole balance fetcher for user-imported\n * tokens on the Accounts API v5 path (see `pickRpcCustomAssetsSupplement`).\n *\n * @param accounts - Accounts to consider for customAssets.\n * @param chainToAccounts - Map of chain → accounts (built by caller).\n * @param rpcAssignedChains - Chains RPC was assigned in the regular handoff.\n */\n #subscribeRpcCustomAssetsSupplement(\n accounts: InternalAccount[],\n chainToAccounts: Map<ChainId, InternalAccount[]>,\n rpcAssignedChains: Set<ChainId>,\n ): void {\n const rpc = this.#rpcDataSource;\n const supplementalKey = `ds:${rpc.getName()}:custom`;\n\n const decision = pickRpcCustomAssetsSupplement({\n accountIds: accounts.map((account) => account.id),\n customAssetsByAccount: this.state.customAssets,\n rpcAssignedChains,\n rpcAvailableChains: new Set(rpc.getActiveChainsSync()),\n enabledChains: new Set(chainToAccounts.keys()),\n });\n\n if (decision.chains.length === 0) {\n this.#unsubscribeBySubscriptionKey(rpc, supplementalKey);\n return;\n }\n\n const supplementalAccounts = accounts.filter((account) =>\n decision.accountIds.has(account.id),\n );\n if (supplementalAccounts.length === 0) {\n this.#unsubscribeBySubscriptionKey(rpc, supplementalKey);\n return;\n }\n\n this.#subscribeDataSource(rpc, supplementalAccounts, decision.chains, {\n subscriptionKey: supplementalKey,\n customAssetsOnly: true,\n });\n }\n\n /**\n * Unsubscribe a data source by an explicit subscription key.\n *\n * @param source - The data source instance.\n * @param subscriptionKey - The subscription key to unsubscribe.\n */\n #unsubscribeBySubscriptionKey(\n source: AbstractDataSource<string, DataSourceState>,\n subscriptionKey: string,\n ): void {\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n if (existingSubscription) {\n source.unsubscribe(subscriptionKey).catch(() => undefined);\n existingSubscription.unsubscribe();\n }\n }\n\n /**\n * Subscribe to staked balance updates.\n * This is the only staked-balance path: subscribe fetches immediately, then\n * polls, and the data source refreshes again when a confirmed transaction\n * touches the staking contract. The fast fetch lane does not query it.\n *\n * Unlike regular balance data sources, the staked balance data source provides\n * supplementary data and does not participate in chain-claiming.\n *\n * @param accounts - Accounts to subscribe staked balance updates for.\n * @param chainIds - Chain IDs to subscribe for.\n */\n #subscribeStakedBalance(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n ): void {\n const source = this.#stakedBalanceDataSource;\n if (!source) {\n return;\n }\n const availableChains = new Set(source.getActiveChainsSync());\n const assignedChains = chainIds.filter((chainId) =>\n availableChains.has(chainId),\n );\n\n if (assignedChains.length === 0) {\n this.#unsubscribeDataSource(source);\n return;\n }\n\n this.#subscribeDataSource(source, accounts, assignedChains);\n }\n\n /**\n * Build a mapping of chainId -> accounts that support that chain.\n * Only includes chains that are in the chainsToSubscribe set.\n *\n * @param accounts - Array of accounts to build mapping for.\n * @param chainsToSubscribe - Set of chain IDs to include in the mapping.\n * @returns Map of chainId to array of accounts that support that chain.\n */\n #buildChainToAccountsMap(\n accounts: InternalAccount[],\n chainsToSubscribe: Set<ChainId>,\n ): Map<ChainId, InternalAccount[]> {\n const chainToAccounts = new Map<ChainId, InternalAccount[]>();\n for (const account of accounts) {\n for (const chainId of this.#getEnabledChainsForAccount(account)) {\n if (!chainsToSubscribe.has(chainId)) {\n continue;\n }\n let list = chainToAccounts.get(chainId);\n if (!list) {\n list = [];\n chainToAccounts.set(chainId, list);\n }\n list.push(account);\n }\n }\n return chainToAccounts;\n }\n\n /**\n * Subscribe to a specific data source with accounts and chains.\n * Uses the data source name as the subscription key for batching.\n *\n * @param source - The balance data source instance.\n * @param accounts - Array of accounts to subscribe for.\n * @param chains - Array of chain IDs to subscribe for.\n * @param options - Optional subscription overrides.\n * @param options.subscriptionKey - Custom subscription key (default: `ds:<sourceId>`).\n * @param options.customAssetsOnly - When true, only poll customAssets for these\n * chains (Accounts API v5 supplemental RPC subscription).\n * @param options.skipInitialFetch - When true, skip the data source's subscribe-time fetch.\n */\n #subscribeDataSource(\n source: AbstractDataSource<string, DataSourceState>,\n accounts: InternalAccount[],\n chains: ChainId[],\n options: {\n subscriptionKey?: string;\n customAssetsOnly?: boolean;\n skipInitialFetch?: boolean;\n } = {},\n ): void {\n const sourceId = source.getName();\n const subscriptionKey = options.subscriptionKey ?? `ds:${sourceId}`;\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n const isUpdate = existingSubscription !== undefined;\n\n log('Subscribe to data source', {\n sourceId,\n subscriptionKey,\n isUpdate,\n accountCount: accounts.length,\n chainCount: chains.length,\n customAssetsOnly: options.customAssetsOnly === true,\n skipInitialFetch: options.skipInitialFetch === true,\n });\n\n const subscribeReq: SubscriptionRequest = {\n request: this.#buildDataRequest(accounts, chains, {\n assetTypes: ['fungible'],\n dataTypes: ['balance'],\n updateInterval: this.#defaultUpdateInterval,\n ...(options.customAssetsOnly === true\n ? { customAssetsOnly: true }\n : {}),\n }),\n subscriptionId: subscriptionKey,\n isUpdate,\n onAssetsUpdate: (response, request) =>\n this.handleAssetsUpdate(response, sourceId, request),\n ...(options.skipInitialFetch === true ? { skipInitialFetch: true } : {}),\n };\n\n source.subscribe(subscribeReq).catch((error) => {\n console.error(\n `[AssetsController] Failed to subscribe to '${sourceId}':`,\n error,\n );\n emitTrace({\n name: TRACE_SUBSCRIPTION_ERROR,\n trace: this.#trace,\n data: {\n source: sourceId,\n error_message: String(error),\n },\n });\n });\n\n // Track subscription\n const subscription: SubscriptionResponse = {\n chains,\n accountId: subscriptionKey,\n assetTypes: ['fungible'],\n dataTypes: ['balance'],\n unsubscribe: () => {\n this.#activeSubscriptions.delete(subscriptionKey);\n },\n };\n\n this.#activeSubscriptions.set(subscriptionKey, subscription);\n }\n\n /**\n * Unsubscribe from a data source if we have an active subscription.\n *\n * @param source - The balance data source instance to unsubscribe from.\n */\n #unsubscribeDataSource(\n source: AbstractDataSource<string, DataSourceState>,\n ): void {\n const subscriptionKey = `ds:${source.getName()}`;\n const existingSubscription = this.#activeSubscriptions.get(subscriptionKey);\n\n if (existingSubscription) {\n source.unsubscribe(subscriptionKey).catch(() => undefined);\n existingSubscription.unsubscribe();\n }\n }\n\n // ============================================================================\n // HELPERS\n // ============================================================================\n\n /**\n * Build a DataRequest with accountsWithSupportedChains (enabled chains ∩ account scope ∩ requested chainIds).\n *\n * @param accounts - Accounts to include.\n * @param chainIds - Requested chain IDs (e.g. enabled chains or subset).\n * @param partial - Rest of the request (dataTypes, assetTypes, etc.).\n * @returns DataRequest with accountsWithSupportedChains and chainIds.\n */\n #buildDataRequest(\n accounts: InternalAccount[],\n chainIds: ChainId[],\n partial: Partial<\n Omit<DataRequest, 'accountsWithSupportedChains' | 'chainIds'>\n > = {},\n ): DataRequest {\n const chainIdSet = new Set(chainIds);\n // Force update will pass in additional chains for wildcard account scope\n // Enables updates for chains that are not selected (e.g. for unapproved transactions)\n const forceUpdateChains = partial.forceUpdate ? chainIds : undefined;\n const accountsWithSupportedChains: AccountWithSupportedChains[] =\n accounts.map((account) => ({\n account,\n supportedChains: this.#getEnabledChainsForAccount(\n account,\n forceUpdateChains,\n ).filter((chain) => chainIdSet.has(chain)),\n }));\n return {\n accountsWithSupportedChains,\n chainIds,\n ...partial,\n } as DataRequest;\n }\n\n /**\n * Get the chains that an account supports based on its scopes.\n * Returns the intersection of the account's scopes and the enabled chains.\n *\n * @param account - The account to get supported chains for.\n * @param additionalChains - Optional extra chains to include for wildcard scopes.\n * @returns Array of ChainIds that the account supports and are enabled.\n */\n #getEnabledChainsForAccount(\n account: InternalAccount,\n additionalChains?: ChainId[],\n ): ChainId[] {\n // Account scopes are CAIP-2 chain IDs like \"eip155:1\", \"solana:mainnet\", \"bip122:...\"\n const scopes = account.scopes ?? [];\n const result: ChainId[] = [];\n\n for (const scope of scopes) {\n const scopeStr = scope as string;\n if (!isCaipChainId(scopeStr)) {\n result.push(scope);\n continue;\n }\n const { namespace, reference } = parseCaipChainId(scopeStr);\n\n // Wildcard scope (e.g., \"eip155:0\" means all enabled chains in that namespace)\n if (reference === '0') {\n // Add enabled chains\n for (const chain of this.#enabledChains) {\n if (isCaipChainId(chain)) {\n const chainParsed = parseCaipChainId(chain);\n if (chainParsed.namespace === namespace) {\n result.push(chain);\n }\n }\n }\n // Add additional chains\n for (const chain of additionalChains ?? []) {\n if (isCaipChainId(chain)) {\n const chainParsed = parseCaipChainId(chain);\n if (chainParsed.namespace === namespace) {\n result.push(chain);\n }\n }\n }\n } else if (namespace === 'eip155' && isStrictHexString(reference)) {\n // Normalize hex to decimal for EIP155\n result.push(`eip155:${parseInt(reference, 16)}`);\n } else {\n result.push(scope);\n }\n }\n\n return result;\n }\n\n // ============================================================================\n // EVENT HANDLERS\n // ============================================================================\n\n async #handleAccountGroupChanged(\n groupId: string,\n previousGroupId: string = '',\n ): Promise<void> {\n if (!groupId) {\n return;\n }\n\n // First start is owned by `AccountTreeController:initialized` / `#start`.\n // ATC also re-publishes `selectedAccountGroupChange` on every `init()`\n // (including when the group did not change) so late subscribers can catch\n // up — ignore those until we are already tracking.\n if (this.#activeSubscriptions.size === 0) {\n return;\n }\n if (groupId === previousGroupId) {\n return;\n }\n\n const accounts = this.#getSelectedAccounts();\n\n log('Account group changed', {\n accountCount: accounts.length,\n accountIds: accounts.map((a) => a.id),\n groupId,\n previousGroupId,\n });\n\n const releaseLock = await this.#accountRefreshMutex.acquire();\n try {\n this.#ensureNativeBalancesDefaultZero();\n this.#ensureDefaultTrackedAssetsSeeded();\n if (accounts.length > 0) {\n await this.getAssets(accounts, {\n chainIds: [...this.#enabledChains],\n forceUpdate: true,\n });\n }\n\n this.#subscribeAssets({ skipInitialFetch: true });\n } finally {\n releaseLock();\n }\n }\n\n async #handleEnabledNetworksChanged(\n enabledNetworkMap: NetworkEnablementControllerState['enabledNetworkMap'],\n ): Promise<void> {\n const previousChains = this.#enabledChains;\n this.#enabledChains = this.#extractEnabledChains(enabledNetworkMap);\n\n // Find newly enabled chains (in new set but not in previous)\n const addedChains: ChainId[] = [];\n for (const chain of this.#enabledChains) {\n if (!previousChains.has(chain)) {\n addedChains.push(chain);\n }\n }\n\n // Find disabled chains to clean up (in previous but not in new)\n const removedChains: ChainId[] = [];\n for (const chain of previousChains) {\n if (!this.#enabledChains.has(chain)) {\n removedChains.push(chain);\n }\n }\n\n log('Enabled networks changed', {\n previousCount: previousChains.size,\n newCount: this.#enabledChains.size,\n addedChains,\n removedChains,\n });\n\n // Note: We intentionally do NOT delete balance data for disabled chains.\n // Users may want to see historical balances even if the network is currently disabled.\n // The data will simply not be updated until the network is re-enabled.\n\n const accounts = this.#getSelectedAccounts();\n this.#ensureNativeBalancesDefaultZero();\n if (addedChains.length > 0) {\n this.#ensureDefaultTrackedAssetsSeeded(addedChains);\n }\n\n // Refresh subscriptions for new chain set\n this.#subscribeAssets();\n\n // One-time fetch for newly enabled chains. v6 `full` replace is scoped to\n // those chains; existing balances on other chains are left untouched.\n if (addedChains.length > 0 && accounts.length > 0) {\n await this.getAssets(accounts, {\n chainIds: addedChains,\n forceUpdate: true,\n });\n }\n }\n\n /**\n * Handle a `NetworkController:networkAdded` event. When the user\n * adds a network (e.g. Monad) to NetworkController, seed the\n * controller-managed default tracked assets for that chain (mUSD on\n * Monad) into state immediately — without waiting for the chain to\n * also be enabled in NetworkEnablementController. No-op for chains\n * that aren't in the defaults registry.\n *\n * @param hexChainId - Hex chain id of the newly-added network\n * configuration (e.g. `0x279f`).\n */\n #handleNetworkAdded(hexChainId: Hex): void {\n let caipChainId: ChainId;\n try {\n caipChainId = `eip155:${parseInt(hexChainId, 16)}`;\n } catch {\n return;\n }\n\n if (!CHAINS_WITH_DEFAULT_TRACKED_ASSETS.has(caipChainId)) {\n return;\n }\n\n log('Network added — seeding default tracked assets', {\n hexChainId,\n caipChainId,\n });\n\n this.#ensureDefaultTrackedAssetsSeeded([caipChainId]);\n }\n\n /**\n * Refresh data-source `activeChains` after an EVM network switch so API/Rpc\n * chain claiming is not stuck on an empty or stale init-time list.\n */\n async #refreshActiveChainsOnNetworkSwitch(): Promise<void> {\n await this.#accountsApiDataSource.refreshActiveChains();\n this.#rpcDataSource.refreshActiveChainsFromNetworkState();\n }\n\n /**\n * Resolve the CAIP-2 chain ID for the currently selected EVM network client.\n *\n * @param networkState - NetworkController state from `networkDidChange`.\n * @returns CAIP-2 chain ID (e.g. `eip155:1`) or undefined when unavailable.\n */\n #getSelectedEvmChainIdFromNetworkState(\n networkState: NetworkState,\n ): ChainId | undefined {\n try {\n const networkClient = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkState.selectedNetworkClientId,\n );\n const hexChainId = networkClient.configuration?.chainId;\n if (!hexChainId) {\n return undefined;\n }\n return `eip155:${parseInt(hexChainId, 16)}`;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Refresh subscriptions and fetch balances when the user switches the\n * selected EVM network in the UI (`NetworkController:networkDidChange`).\n *\n * @param networkState - NetworkController state after the switch.\n */\n async #handleNetworkDidChange(networkState: NetworkState): Promise<void> {\n if (!this.#isUiOpen() || !this.#isKeyringUnlocked() || !this.#isEnabled()) {\n return;\n }\n\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n const selectedChainId =\n this.#getSelectedEvmChainIdFromNetworkState(networkState);\n if (!selectedChainId) {\n return;\n }\n\n log('Selected EVM network switched', {\n selectedNetworkClientId: networkState.selectedNetworkClientId,\n selectedChainId,\n });\n\n const releaseLock = await this.#accountRefreshMutex.acquire();\n try {\n await this.#refreshActiveChainsOnNetworkSwitch();\n\n this.#ensureNativeBalancesDefaultZero();\n this.#subscribeAssets();\n\n await this.getAssets(accounts, {\n chainIds: [selectedChainId],\n forceUpdate: true,\n dataTypes: ['balance', 'metadata', 'price'],\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Refresh balances after a network configuration is removed.\n */\n #refreshAssetsAfterNetworkChange(): void {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n this.getAssets(accounts, {\n forceUpdate: true,\n dataTypes: ['balance', 'metadata'],\n }).catch((error: unknown) => {\n log('Failed to refresh assets after network change', { error });\n });\n }\n\n /**\n * Refresh balances and fetch missing prices after a network is added.\n *\n * @param hexChainId - Hex chain id of the newly-added network.\n */\n async #refreshAssetsAfterNetworkAdded(hexChainId: Hex): Promise<void> {\n const accounts = this.#getSelectedAccounts();\n if (accounts.length === 0) {\n return;\n }\n\n let caipChainId: ChainId;\n try {\n caipChainId = `eip155:${parseInt(hexChainId, 16)}`;\n } catch {\n return;\n }\n\n this.#ensureNativeBalancesDefaultZero();\n await this.getAssets(accounts, {\n chainIds: [caipChainId],\n forceUpdate: true,\n dataTypes: ['balance', 'metadata', 'price'],\n });\n }\n\n /**\n * Handle assets updated from a data source.\n * Called via the onAssetsUpdate callback passed in SubscriptionRequest when the controller subscribes to a data source.\n * Runs detection, then (when basic functionality is enabled) token metadata and price enrichment before updating state.\n * When basic functionality is disabled (RPC-only mode), only detection runs; token and price APIs are not used.\n *\n * @param response - The data response with updated assets\n * @param sourceId - The data source ID reporting the update\n * @param request - Optional original request for context when enriching\n */\n async handleAssetsUpdate(\n response: DataResponse,\n sourceId: string,\n request?: DataRequest,\n ): Promise<void> {\n log('Assets updated from data source', {\n sourceId,\n assetsBalance: response.assetsBalance,\n assetsPrice: response.assetsPrice,\n });\n\n if (this.#isBalanceV6Enabled()) {\n await this.#handleAssetsUpdateV6(response, sourceId, request);\n return;\n }\n await this.#handleAssetsUpdateV5(response, sourceId, request);\n }\n\n async #handleAssetsUpdateV5(\n response: DataResponse,\n sourceId: string,\n request?: DataRequest,\n ): Promise<void> {\n const pipelineTrace = this.#firstInitFetchReported\n ? undefined\n : this.#trace;\n await withTrace({\n name: TRACE_UPDATE_PARENT,\n trace: pipelineTrace,\n data: this.#getUpdateTraceData(response, sourceId),\n fn: async (parentContext) => {\n const updateStart = performance.now();\n const pipelineRequest = this.#getUpdatePipelineRequest(request);\n const isBasicFunctionality = this.#isBasicFunctionality();\n const isAccountsApiUpdate = sourceId === 'AccountsApiDataSource';\n const enrichmentSources: AssetsDataSource[] =\n sourceId === 'AccountActivityDataSource'\n ? buildWsUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n { isBasicFunctionality, includeCustomAssetGraduation: true },\n )\n : buildUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n {\n isBasicFunctionality,\n includeCustomAssetGraduation: isAccountsApiUpdate,\n includeRpcFallback: isAccountsApiUpdate,\n },\n );\n\n const { response: enrichedResponse } = await this.#executeMiddlewares({\n sources: enrichmentSources,\n request: pipelineRequest,\n initialResponse: response,\n parentContext,\n trace: pipelineTrace,\n });\n\n await this.#updateState({\n ...enrichedResponse,\n replaceCoveredChainBalances: response.replaceCoveredChainBalances,\n });\n this.#emitUpdateTrace({\n response,\n sourceId,\n enrichedResponse,\n updateStart,\n pipelineTrace,\n parentContext,\n });\n },\n });\n }\n\n async #handleAssetsUpdateV6(\n response: DataResponse,\n sourceId: string,\n request?: DataRequest,\n ): Promise<void> {\n const pipelineTrace = this.#firstInitFetchReported\n ? undefined\n : this.#trace;\n await withTrace({\n name: TRACE_UPDATE_PARENT,\n trace: pipelineTrace,\n data: this.#getUpdateTraceData(response, sourceId),\n fn: async (parentContext) => {\n const updateStart = performance.now();\n const pipelineRequest = this.#getUpdatePipelineRequest(request);\n const isBasicFunctionality = this.#isBasicFunctionality();\n const enrichmentSources: AssetsDataSource[] =\n sourceId === 'AccountActivityDataSource'\n ? buildWsUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n { isBasicFunctionality, includeCustomAssetGraduation: false },\n )\n : buildUpdateSources(\n {\n customAssetGraduationMiddleware:\n this.#customAssetGraduationMiddleware,\n rpcFallbackMiddleware: this.#rpcFallbackMiddleware,\n tokenDataSource: this.#tokenDataSource,\n priceDataSource: this.#priceDataSource,\n },\n {\n isBasicFunctionality,\n includeCustomAssetGraduation: false,\n includeRpcFallback: isBasicFunctionality,\n },\n );\n\n const { response: enrichedResponse } = await this.#executeMiddlewares({\n sources: enrichmentSources,\n request: pipelineRequest,\n initialResponse: response,\n parentContext,\n trace: pipelineTrace,\n });\n\n await this.#updateState(enrichedResponse);\n this.#emitUpdateTrace({\n response,\n sourceId,\n enrichedResponse,\n updateStart,\n pipelineTrace,\n parentContext,\n });\n },\n });\n }\n\n #getUpdatePipelineRequest(request?: DataRequest): DataRequest {\n const resolvedRequest: DataRequest = request ?? {\n accountsWithSupportedChains: [],\n chainIds: [],\n dataTypes: ['balance', 'metadata', 'price'],\n };\n if (this.#isBasicFunctionality()) {\n return resolvedRequest;\n }\n return {\n ...resolvedRequest,\n dataTypes: resolvedRequest.dataTypes.filter(\n (dataType) => dataType !== 'metadata' && dataType !== 'price',\n ),\n };\n }\n\n #getUpdateTraceData(response: DataResponse, sourceId: string): TraceSpanData {\n return {\n source: sourceId,\n has_balance: Boolean(response.assetsBalance),\n has_price: Boolean(response.assetsPrice),\n balance_account_count: response.assetsBalance\n ? Object.keys(response.assetsBalance).length\n : 0,\n };\n }\n\n #emitUpdateTrace({\n response,\n sourceId,\n enrichedResponse,\n updateStart,\n pipelineTrace,\n parentContext,\n }: {\n response: DataResponse;\n sourceId: string;\n enrichedResponse: DataResponse;\n updateStart: number;\n pipelineTrace?: TraceCallback;\n parentContext?: TraceContext;\n }): void {\n emitTrace({\n name: TRACE_UPDATE_PIPELINE,\n trace: pipelineTrace,\n data: {\n source: sourceId,\n duration_ms: performance.now() - updateStart,\n has_balance: Boolean(response.assetsBalance),\n has_price: Boolean(response.assetsPrice),\n has_metadata: Boolean(enrichedResponse.assetsInfo),\n balance_account_count: response.assetsBalance\n ? Object.keys(response.assetsBalance).length\n : 0,\n },\n parentContext,\n });\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n log('Destroying AssetsController', {\n dataSourceCount: this.#allBalanceDataSources.length,\n subscriptionCount: this.#activeSubscriptions.size,\n });\n\n // Destroy instantiated data sources\n this.#accountActivityDataSource?.destroy?.();\n this.#accountsApiDataSource?.destroy?.();\n this.#snapDataSource?.destroy?.();\n this.#rpcDataSource?.destroy?.();\n this.#stakedBalanceDataSource?.destroy?.();\n\n // Stop all active subscriptions\n this.#stop();\n\n if (this.#unsubscribeBasicFunctionality) {\n this.#unsubscribeBasicFunctionality();\n this.#unsubscribeBasicFunctionality = null;\n }\n\n // Unregister action handlers\n this.messenger.unregisterActionHandler('AssetsController:getAssets');\n this.messenger.unregisterActionHandler('AssetsController:getAssetsBalance');\n this.messenger.unregisterActionHandler('AssetsController:getAssetMetadata');\n this.messenger.unregisterActionHandler(\n 'AssetsController:getAccountAssetByID',\n );\n this.messenger.unregisterActionHandler(\n 'AssetsController:getAccountAssetsByIDs',\n );\n this.messenger.unregisterActionHandler(\n 'AssetsController:getAccountAssetsByScope',\n );\n this.messenger.unregisterActionHandler('AssetsController:getAssetsPrice');\n this.messenger.unregisterActionHandler('AssetsController:syncAssetsPrices');\n this.messenger.unregisterActionHandler(\n 'AssetsController:getExchangeRatesForBridge',\n );\n this.messenger.unregisterActionHandler(\n 'AssetsController:getStateForTransactionPay',\n );\n this.messenger.unregisterActionHandler('AssetsController:addCustomAsset');\n this.messenger.unregisterActionHandler(\n 'AssetsController:removeCustomAsset',\n );\n this.messenger.unregisterActionHandler('AssetsController:getCustomAssets');\n this.messenger.unregisterActionHandler('AssetsController:hideAsset');\n this.messenger.unregisterActionHandler('AssetsController:unhideAsset');\n this.messenger.unregisterActionHandler(\n 'AssetsController:setSelectedCurrency',\n );\n }\n}\n\n/**\n * Whether a messenger call failed because no controller has registered the action yet.\n *\n * @param error - The error thrown by `messenger.call`.\n * @returns True when the action handler is not registered.\n */\nfunction isUnregisteredActionError(error: unknown): boolean {\n return (\n error instanceof Error && error.message.includes('has not been registered')\n );\n}\n"]}
|