@metamask-previews/assets-controller 2.0.2-preview-d1f62d044 → 2.0.2-preview-06d68e653

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +0 -6
  2. package/dist/AssetsController.cjs +27 -81
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +3 -6
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +3 -6
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +27 -81
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AccountsApiDataSource.cjs +0 -1
  11. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  12. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  13. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  14. package/dist/data-sources/AccountsApiDataSource.mjs +0 -1
  15. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  16. package/dist/data-sources/BackendWebsocketDataSource.cjs +1 -1
  17. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
  18. package/dist/data-sources/BackendWebsocketDataSource.mjs +1 -1
  19. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
  20. package/dist/data-sources/PriceDataSource.cjs +1 -4
  21. package/dist/data-sources/PriceDataSource.cjs.map +1 -1
  22. package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
  23. package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
  24. package/dist/data-sources/PriceDataSource.mjs +1 -4
  25. package/dist/data-sources/PriceDataSource.mjs.map +1 -1
  26. package/dist/data-sources/RpcDataSource.cjs +0 -2
  27. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  28. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  29. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  30. package/dist/data-sources/RpcDataSource.mjs +0 -2
  31. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  32. package/dist/data-sources/SnapDataSource.cjs +2 -3
  33. package/dist/data-sources/SnapDataSource.cjs.map +1 -1
  34. package/dist/data-sources/SnapDataSource.d.cts.map +1 -1
  35. package/dist/data-sources/SnapDataSource.d.mts.map +1 -1
  36. package/dist/data-sources/SnapDataSource.mjs +2 -3
  37. package/dist/data-sources/SnapDataSource.mjs.map +1 -1
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +1 -1
  40. package/dist/index.d.cts.map +1 -1
  41. package/dist/index.d.mts +1 -1
  42. package/dist/index.d.mts.map +1 -1
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/middlewares/index.cjs +1 -5
  45. package/dist/middlewares/index.cjs.map +1 -1
  46. package/dist/middlewares/index.d.cts +0 -2
  47. package/dist/middlewares/index.d.cts.map +1 -1
  48. package/dist/middlewares/index.d.mts +0 -2
  49. package/dist/middlewares/index.d.mts.map +1 -1
  50. package/dist/middlewares/index.mjs +0 -1
  51. package/dist/middlewares/index.mjs.map +1 -1
  52. package/dist/types.cjs.map +1 -1
  53. package/dist/types.d.cts +0 -14
  54. package/dist/types.d.cts.map +1 -1
  55. package/dist/types.d.mts +0 -14
  56. package/dist/types.d.mts.map +1 -1
  57. package/dist/types.mjs.map +1 -1
  58. package/package.json +2 -4
  59. package/dist/middlewares/ParallelMiddleware.cjs +0 -216
  60. package/dist/middlewares/ParallelMiddleware.cjs.map +0 -1
  61. package/dist/middlewares/ParallelMiddleware.d.cts +0 -45
  62. package/dist/middlewares/ParallelMiddleware.d.cts.map +0 -1
  63. package/dist/middlewares/ParallelMiddleware.d.mts +0 -45
  64. package/dist/middlewares/ParallelMiddleware.d.mts.map +0 -1
  65. package/dist/middlewares/ParallelMiddleware.mjs +0 -214
  66. package/dist/middlewares/ParallelMiddleware.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RpcDataSource.mjs","sourceRoot":"","sources":["../../src/data-sources/RpcDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type { GetTokenListState } from '@metamask/assets-controllers';\nimport { toHex } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkStatus,\n} from '@metamask/network-controller';\nimport type { NetworkEnablementControllerGetStateAction } from '@metamask/network-enablement-controller';\nimport type {\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerTransactionConfirmedEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport {\n isStrictHexString,\n isCaipChainId,\n numberToHex,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport BigNumberJS from 'bignumber.js';\n\nimport { AbstractDataSource } from './AbstractDataSource';\nimport type {\n DataSourceState,\n SubscriptionRequest,\n} from './AbstractDataSource';\nimport {\n BalanceFetcher,\n MulticallClient,\n TokenDetector,\n} from './evm-rpc-services';\nimport type {\n BalancePollingInput,\n DetectionPollingInput,\n} from './evm-rpc-services';\nimport type {\n Address,\n Provider as RpcProvider,\n TokenListState,\n BalanceFetchResult,\n TokenDetectionResult,\n} from './evm-rpc-services';\nimport type {\n AssetsControllerGetStateAction,\n AssetsControllerMessenger,\n} from '../AssetsController';\nimport { projectLogger, createModuleLogger } from '../logger';\nimport type {\n ChainId,\n Caip19AssetId,\n AssetBalance,\n AssetMetadata,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\n\nconst CONTROLLER_NAME = 'RpcDataSource';\nconst DEFAULT_BALANCE_INTERVAL = 30_000; // 30 seconds\nconst DEFAULT_DETECTION_INTERVAL = 180_000; // 3 minutes\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// Allowed actions that RpcDataSource can call\nexport type RpcDataSourceAllowedActions =\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | AssetsControllerGetStateAction\n | GetTokenListState\n | NetworkEnablementControllerGetStateAction;\n\n// Allowed events that RpcDataSource can subscribe to\nexport type RpcDataSourceAllowedEvents =\n | NetworkControllerStateChangeEvent\n | TransactionControllerTransactionConfirmedEvent\n | TransactionControllerIncomingTransactionsReceivedEvent;\n\n/** Network status for each chain */\nexport type ChainStatus = {\n chainId: ChainId;\n status: NetworkStatus;\n name: string;\n nativeCurrency: string;\n /** Network client ID for getting the provider */\n networkClientId: string;\n};\n\n/** RpcDataSource is stateless */\nexport type RpcDataSourceState = Record<never, never>;\n\n/** Optional configuration for RpcDataSource when the controller instantiates it. */\nexport type RpcDataSourceConfig = {\n balanceInterval?: number;\n detectionInterval?: number;\n /** Function returning whether token detection is enabled (avoids stale value) */\n tokenDetectionEnabled?: () => boolean;\n /** Function returning whether external services are allowed (avoids stale value; default: () => true) */\n useExternalService?: () => boolean;\n timeout?: number;\n};\n\nexport type RpcDataSourceOptions = {\n /** The AssetsController messenger (shared by all data sources). */\n messenger: AssetsControllerMessenger;\n /** Called when active chains are updated. Pass dataSourceName so the controller knows the source. */\n onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n /** Request timeout in ms */\n timeout?: number;\n /** Balance polling interval in ms (default: 30s) */\n balanceInterval?: number;\n /** Token detection polling interval in ms (default: 180s / 3 min) */\n detectionInterval?: number;\n /** Function returning whether token detection is enabled (avoids stale value) */\n tokenDetectionEnabled?: () => boolean;\n /** Function returning whether external services are allowed (avoids stale value; default: () => true) */\n useExternalService?: () => boolean;\n};\n\n/**\n * Subscription data stored for each active subscription.\n */\ntype SubscriptionData = {\n /** Polling tokens from BalanceFetcher */\n balancePollingTokens: string[];\n /** Polling tokens from TokenDetector */\n detectionPollingTokens: string[];\n /** Chain IDs being polled */\n chains: ChainId[];\n /** Accounts being polled */\n accounts: InternalAccount[];\n /** Callback to report asset updates to the controller */\n onAssetsUpdate: (response: DataResponse) => void | Promise<void>;\n};\n\n/**\n * Convert CAIP chain ID or hex chain ID to hex chain ID.\n *\n * @param chainId - CAIP chain ID or hex chain ID.\n * @returns Hex chain ID.\n */\nexport const caipChainIdToHex = (chainId: string): Hex => {\n if (isStrictHexString(chainId)) {\n return chainId;\n }\n\n if (isCaipChainId(chainId)) {\n return toHex(parseCaipChainId(chainId).reference);\n }\n\n throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');\n};\n\n/**\n * Data source for fetching balances via RPC calls.\n *\n * Orchestrates polling through BalanceFetcher and TokenDetector,\n * each of which handle their own polling intervals.\n *\n * Communicates with AssetsController via Messenger:\n *\n * Actions:\n * - RpcDataSource:getActiveChains\n * - RpcDataSource:fetch\n * - RpcDataSource:subscribe\n * - RpcDataSource:unsubscribe\n *\n * Events:\n * - RpcDataSource:activeChainsUpdated\n * - RpcDataSource:assetsUpdated\n */\nexport class RpcDataSource extends AbstractDataSource<\n typeof CONTROLLER_NAME,\n DataSourceState\n> {\n readonly #messenger: AssetsControllerMessenger;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n readonly #timeout: number;\n\n readonly #tokenDetectionEnabled: () => boolean;\n\n readonly #useExternalService: () => boolean;\n\n /** Currently active chains */\n #activeChains: ChainId[] = [];\n\n /** Network status for each active chain */\n #chainStatuses: Record<ChainId, ChainStatus> = {};\n\n /** Cache of Web3Provider instances by chainId */\n readonly #providerCache: Map<ChainId, Web3Provider> = new Map();\n\n /** Active subscriptions by ID */\n readonly #activeSubscriptions: Map<string, SubscriptionData> = new Map();\n\n #unsubscribeTransactionConfirmed: (() => void) | undefined = undefined;\n\n #unsubscribeIncomingTransactions: (() => void) | undefined = undefined;\n\n // Rpc-datasource components\n readonly #multicallClient: MulticallClient;\n\n readonly #balanceFetcher: BalanceFetcher;\n\n readonly #tokenDetector: TokenDetector;\n\n constructor(options: RpcDataSourceOptions) {\n super(CONTROLLER_NAME, { activeChains: [] });\n this.#messenger = options.messenger;\n this.#onActiveChainsUpdated = options.onActiveChainsUpdated;\n this.#timeout = options.timeout ?? 10_000;\n this.#tokenDetectionEnabled =\n options.tokenDetectionEnabled ?? ((): boolean => true);\n this.#useExternalService =\n options.useExternalService ?? ((): boolean => true);\n\n const balanceInterval = options.balanceInterval ?? DEFAULT_BALANCE_INTERVAL;\n const detectionInterval =\n options.detectionInterval ?? DEFAULT_DETECTION_INTERVAL;\n\n log('Initializing RpcDataSource', {\n timeout: this.#timeout,\n balanceInterval,\n detectionInterval,\n tokenDetectionEnabled: this.#tokenDetectionEnabled(),\n useExternalService: this.#useExternalService(),\n });\n\n // Initialize MulticallClient with a provider getter\n this.#multicallClient = new MulticallClient((hexChainId: string) => {\n return this.#getMulticallProvider(hexChainId);\n });\n\n // Create messenger adapters for BalanceFetcher and TokenDetector\n const balanceFetcherMessenger = {\n call: (\n _action: 'AssetsController:getState',\n ): {\n assetsBalance: Record<string, Record<string, { amount: string }>>;\n } => {\n const state = this.#messenger.call('AssetsController:getState');\n return {\n assetsBalance: (state.assetsBalance ?? {}) as Record<\n string,\n Record<string, { amount: string }>\n >,\n };\n },\n };\n\n const tokenDetectorMessenger = {\n call: (_action: 'TokenListController:getState'): TokenListState => {\n return this.#messenger.call('TokenListController:getState');\n },\n };\n\n // Initialize BalanceFetcher with polling interval\n this.#balanceFetcher = new BalanceFetcher(\n this.#multicallClient,\n balanceFetcherMessenger,\n { pollingInterval: balanceInterval },\n );\n this.#balanceFetcher.setOnBalanceUpdate(\n this.#handleBalanceUpdate.bind(this),\n );\n\n // Initialize TokenDetector with polling interval\n this.#tokenDetector = new TokenDetector(\n this.#multicallClient,\n tokenDetectorMessenger,\n {\n pollingInterval: detectionInterval,\n tokenDetectionEnabled: this.#tokenDetectionEnabled,\n useExternalService: this.#useExternalService,\n },\n );\n this.#tokenDetector.setOnDetectionUpdate(\n this.#handleDetectionUpdate.bind(this),\n );\n\n this.#subscribeToNetworkController();\n this.#subscribeToTransactionEvents();\n this.#initializeFromNetworkController();\n }\n\n /**\n * Convert a raw balance to human-readable format using decimals.\n *\n * @param rawBalance - The raw balance string.\n * @param decimals - The number of decimals for the token.\n * @returns The human-readable balance string.\n */\n #convertToHumanReadable(rawBalance: string, decimals: number): string {\n const rawAmount = new BigNumberJS(rawBalance);\n const divisor = new BigNumberJS(10).pow(decimals);\n return rawAmount.dividedBy(divisor).toString();\n }\n\n /**\n * Collect metadata for a list of balance entries.\n * For native tokens, generates metadata from chain status.\n * For ERC20 tokens, looks up from existing state or token list.\n *\n * @param balances - Array of balance entries with assetId.\n * @param chainId - The CAIP-2 chain ID.\n * @returns Record of asset metadata keyed by asset ID.\n */\n #collectMetadataForBalances(\n balances: { assetId: Caip19AssetId }[],\n chainId: ChainId,\n ): Record<Caip19AssetId, AssetMetadata> {\n const assetsInfo: Record<Caip19AssetId, AssetMetadata> = {};\n const existingMetadata = this.#getExistingAssetsMetadata();\n\n for (const balance of balances) {\n const isNative = balance.assetId.includes('/slip44:');\n if (isNative) {\n const chainStatus = this.#chainStatuses[chainId];\n\n if (chainStatus) {\n assetsInfo[balance.assetId] = {\n type: 'native',\n symbol: chainStatus.nativeCurrency,\n name: chainStatus.nativeCurrency,\n decimals: 18,\n };\n }\n } else {\n // For ERC20 tokens, try existing metadata from state first\n const existingMeta = existingMetadata[balance.assetId];\n\n if (existingMeta) {\n assetsInfo[balance.assetId] = existingMeta;\n } else {\n // Fallback to token list if not in state\n const tokenListMeta = this.#getTokenMetadataFromTokenList(\n balance.assetId,\n );\n if (tokenListMeta) {\n assetsInfo[balance.assetId] = tokenListMeta;\n } else {\n // Default metadata for unknown ERC20 tokens.\n // Use 18 decimals (the standard for most ERC20 tokens)\n // to ensure consistent human-readable balance format.\n assetsInfo[balance.assetId] = {\n type: 'erc20',\n symbol: '',\n name: '',\n decimals: 18,\n };\n }\n }\n }\n }\n\n return assetsInfo;\n }\n\n /**\n * Handle balance update from BalanceFetcher.\n *\n * @param result - The balance fetch result.\n */\n #handleBalanceUpdate(result: BalanceFetchResult): void {\n const newBalances: Record<string, { amount: string }> = {};\n\n // Convert hex chain ID to CAIP-2 format\n const chainIdDecimal = parseInt(result.chainId, 16);\n const caipChainId = `eip155:${chainIdDecimal}` as ChainId;\n\n // Collect metadata for all balances\n const assetsInfo = this.#collectMetadataForBalances(\n result.balances,\n caipChainId,\n );\n\n // Convert balances to human-readable format using metadata\n for (const balance of result.balances) {\n const metadata = assetsInfo[balance.assetId];\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = metadata?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n newBalances[balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n\n // Only send new data to AssetsController - it handles merging atomically\n // to avoid race conditions when concurrent updates occur for the same account\n const response: DataResponse = {\n assetsBalance: {\n [result.accountId]: newBalances,\n },\n assetsInfo,\n updateMode: 'full',\n };\n\n log('Balance update response', {\n accountId: result.accountId,\n newBalanceCount: Object.keys(newBalances).length,\n });\n\n for (const subscription of this.#activeSubscriptions.values()) {\n subscription.onAssetsUpdate(response)?.catch((error) => {\n log('Failed to update assets', { error });\n });\n }\n }\n\n /**\n * Handle detection update from TokenDetector.\n *\n * @param result - The token detection result.\n */\n #handleDetectionUpdate(result: TokenDetectionResult): void {\n log('Detected new tokens', {\n count: result.detectedAssets.length,\n });\n\n // Build new metadata from detected assets\n const newMetadata: Record<Caip19AssetId, AssetMetadata> = {};\n if (result.detectedAssets.length > 0) {\n for (const asset of result.detectedAssets) {\n // Only include if we have metadata (symbol and decimals at minimum)\n if (asset.symbol && asset.decimals !== undefined) {\n newMetadata[asset.assetId] = {\n type: 'erc20',\n symbol: asset.symbol,\n name: asset.name ?? asset.symbol,\n decimals: asset.decimals,\n image: asset.image,\n };\n }\n }\n }\n\n // Build new balances from detected tokens\n const newBalances: Record<string, { amount: string }> = {};\n if (result.detectedBalances.length > 0) {\n for (const balance of result.detectedBalances) {\n // Get decimals from the detected asset metadata\n const detectedAsset = result.detectedAssets.find(\n (asset) => asset.assetId === balance.assetId,\n );\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = detectedAsset?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n newBalances[balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n }\n\n // Only send new data to AssetsController - it handles merging atomically\n // to avoid race conditions when concurrent updates occur for the same account\n const response: DataResponse = {\n detectedAssets: {\n [result.accountId]: result.detectedAssets.map((asset) => asset.assetId),\n },\n assetsInfo: newMetadata,\n assetsBalance: {\n [result.accountId]: newBalances,\n },\n updateMode: 'full',\n };\n\n for (const subscription of this.#activeSubscriptions.values()) {\n subscription.onAssetsUpdate(response)?.catch((error) => {\n log('Failed to update detected assets', { error });\n });\n }\n }\n\n #subscribeToNetworkController(): void {\n this.#messenger.subscribe(\n 'NetworkController:stateChange',\n (networkState: NetworkState) => {\n log('NetworkController state changed');\n this.#clearProviderCache();\n this.#updateFromNetworkState(networkState);\n },\n );\n }\n\n #subscribeToTransactionEvents(): void {\n const unsubConfirmed = this.#messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n this.#onTransactionConfirmed.bind(this),\n );\n this.#unsubscribeTransactionConfirmed =\n typeof unsubConfirmed === 'function' ? unsubConfirmed : undefined;\n\n const unsubIncoming = this.#messenger.subscribe(\n 'TransactionController:incomingTransactionsReceived',\n this.#onIncomingTransactions.bind(this),\n );\n this.#unsubscribeIncomingTransactions =\n typeof unsubIncoming === 'function' ? unsubIncoming : undefined;\n }\n\n #onTransactionConfirmed(payload: TransactionMeta): void {\n const hexChainId = payload?.chainId;\n if (!hexChainId) {\n return;\n }\n const caipChainId = `eip155:${parseInt(hexChainId, 16)}` as ChainId;\n this.#refreshBalanceForChains([caipChainId]).catch((error) => {\n log('Failed to refresh balance after transaction confirmed', { error });\n });\n }\n\n #onIncomingTransactions(payload: TransactionMeta[]): void {\n const chainIds = Array.from(\n new Set(\n (payload ?? [])\n .map((item) => item?.chainId)\n .filter((id): id is Hex => Boolean(id)),\n ),\n );\n const caipChainIds = chainIds.map(\n (hexChainId) => `eip155:${parseInt(hexChainId, 16)}` as ChainId,\n );\n const toRefresh =\n caipChainIds.length > 0 ? caipChainIds : [...this.#activeChains];\n this.#refreshBalanceForChains(toRefresh).catch((error) => {\n log('Failed to refresh balance after incoming transactions', { error });\n });\n }\n\n /**\n * Fetch balances for the given chains across all active subscriptions and\n * push updates to the controller.\n *\n * @param chainIds - CAIP-2 chain IDs to refresh.\n */\n async #refreshBalanceForChains(chainIds: ChainId[]): Promise<void> {\n const chainIdsSet = new Set(chainIds);\n const chainsToFetch = chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n if (chainsToFetch.length === 0) {\n return;\n }\n\n for (const subscription of this.#activeSubscriptions.values()) {\n const subscriptionChains = subscription.chains.filter((chainId) =>\n chainIdsSet.has(chainId),\n );\n if (subscriptionChains.length === 0) {\n continue;\n }\n\n const request: DataRequest = {\n accountsWithSupportedChains: subscription.accounts.map((account) => ({\n account,\n supportedChains: subscriptionChains,\n })),\n chainIds: subscriptionChains,\n dataTypes: ['balance'],\n };\n\n try {\n const response = await this.fetch(request);\n if (\n response.assetsBalance &&\n Object.keys(response.assetsBalance).length > 0\n ) {\n subscription.onAssetsUpdate(response)?.catch((error) => {\n log('Failed to report balance update after transaction', {\n error,\n });\n });\n }\n } catch (error) {\n log('Failed to fetch balance after transaction', {\n chains: subscriptionChains,\n error,\n });\n }\n }\n }\n\n #initializeFromNetworkController(): void {\n log('Initializing from NetworkController');\n try {\n const networkState = this.#messenger.call('NetworkController:getState');\n this.#updateFromNetworkState(networkState);\n } catch (error) {\n log('Failed to initialize from NetworkController', error);\n }\n }\n\n #updateFromNetworkState(networkState: NetworkState): void {\n const { networkConfigurationsByChainId, networksMetadata } = networkState;\n\n const chainStatuses: Record<ChainId, ChainStatus> = {};\n const activeChains: ChainId[] = [];\n\n for (const [hexChainId, config] of Object.entries(\n networkConfigurationsByChainId,\n )) {\n const decimalChainId = parseInt(hexChainId, 16);\n const caip2ChainId = `eip155:${decimalChainId}` as ChainId;\n\n const defaultRpcEndpoint =\n config.rpcEndpoints[config.defaultRpcEndpointIndex];\n if (!defaultRpcEndpoint) {\n continue;\n }\n\n const { networkClientId } = defaultRpcEndpoint;\n const metadata = networksMetadata[networkClientId];\n\n const status: NetworkStatus =\n metadata?.status ?? ('unknown' as NetworkStatus);\n\n chainStatuses[caip2ChainId] = {\n chainId: caip2ChainId,\n status,\n name: config.name,\n nativeCurrency: config.nativeCurrency,\n networkClientId,\n };\n\n if (status === 'available' || status === 'unknown') {\n activeChains.push(caip2ChainId);\n }\n }\n\n log('Network state updated', {\n configuredChains: Object.keys(chainStatuses),\n activeChains,\n });\n\n // Check if chains changed\n const previousChains = [...this.#activeChains];\n const previousSet = new Set(previousChains);\n const hasChanges =\n previousChains.length !== activeChains.length ||\n activeChains.some((chain) => !previousSet.has(chain));\n\n // Update internal state and data source state before notifying, so that\n // when the controller handles the callback and calls getActiveChainsSync(),\n // it receives the updated chains (same order as AbstractDataSource.updateActiveChains).\n this.#chainStatuses = chainStatuses;\n this.#activeChains = activeChains;\n this.state.activeChains = activeChains;\n\n if (hasChanges) {\n this.#onActiveChainsUpdated(this.getName(), activeChains, previousChains);\n }\n }\n\n #getProvider(chainId: ChainId): Web3Provider | undefined {\n const cached = this.#providerCache.get(chainId);\n if (cached) {\n return cached;\n }\n\n const chainStatus = this.#chainStatuses[chainId];\n if (!chainStatus) {\n return undefined;\n }\n\n try {\n const networkClient = this.#messenger.call(\n 'NetworkController:getNetworkClientById',\n chainStatus.networkClientId,\n );\n if (!networkClient?.provider) {\n return undefined;\n }\n const web3Provider = new Web3Provider(networkClient.provider);\n this.#providerCache.set(chainId, web3Provider);\n\n return web3Provider;\n } catch (error) {\n log('Failed to get provider for chain', { chainId, error });\n return undefined;\n }\n }\n\n /**\n * Get provider for MulticallClient using a hex chainId.\n *\n * @param hexChainId - The hex string representation of the chain id.\n * @returns An RpcProvider instance for the specified chain.\n */\n #getMulticallProvider(hexChainId: string): RpcProvider {\n const decimalChainId = parseInt(hexChainId, 16);\n const caip2ChainId = `eip155:${decimalChainId}` as ChainId;\n\n const web3Provider = this.#getProvider(caip2ChainId);\n\n if (!web3Provider) {\n throw new Error(`No provider available for chain ${hexChainId}`);\n }\n\n return {\n call: async (params: { to: string; data: string }): Promise<string> => {\n return web3Provider.call({\n to: params.to,\n data: params.data,\n });\n },\n getBalance: async (address: string): Promise<{ toString(): string }> => {\n const balance = await web3Provider.getBalance(address);\n return balance;\n },\n };\n }\n\n #clearProviderCache(): void {\n this.#providerCache.clear();\n }\n\n /**\n * Get the data source name.\n *\n * @returns The name of this data source.\n */\n /**\n * Get the status of all configured chains.\n *\n * @returns Record of chain statuses keyed by chain ID.\n */\n getChainStatuses(): Record<ChainId, ChainStatus> {\n return { ...this.#chainStatuses };\n }\n\n /**\n * Get the status of a specific chain.\n *\n * @param chainId - The chain ID to get status for.\n * @returns The chain status or undefined if not found.\n */\n getChainStatus(chainId: ChainId): ChainStatus | undefined {\n return this.#chainStatuses[chainId];\n }\n\n /**\n * Set the balance polling interval.\n *\n * @param interval - The polling interval in milliseconds.\n */\n setBalancePollingInterval(interval: number): void {\n log('Setting balance polling interval', { interval });\n this.#balanceFetcher.setIntervalLength(interval);\n }\n\n /**\n * Get the current balance polling interval.\n *\n * @returns The polling interval in milliseconds, or undefined if not set.\n */\n getBalancePollingInterval(): number | undefined {\n return this.#balanceFetcher.getIntervalLength();\n }\n\n /**\n * Set the token detection polling interval.\n *\n * @param interval - The polling interval in milliseconds.\n */\n setDetectionPollingInterval(interval: number): void {\n log('Setting detection polling interval', { interval });\n this.#tokenDetector.setIntervalLength(interval);\n }\n\n /**\n * Get the current token detection polling interval.\n *\n * @returns The polling interval in milliseconds, or undefined if not set.\n */\n getDetectionPollingInterval(): number | undefined {\n return this.#tokenDetector.getIntervalLength();\n }\n\n async fetch(request: DataRequest): Promise<DataResponse> {\n const response: DataResponse = {};\n\n const chainsToFetch = request.chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n\n log('Fetch requested', {\n accounts: request.accountsWithSupportedChains.map((a) => a.account.id),\n requestedChains: request.chainIds,\n chainsToFetch,\n });\n\n if (chainsToFetch.length === 0) {\n log('No active chains to fetch');\n return response;\n }\n\n const assetsBalance: Record<\n string,\n Record<Caip19AssetId, AssetBalance>\n > = {};\n const assetsInfo: Record<Caip19AssetId, AssetMetadata> = {};\n const failedChains: ChainId[] = [];\n\n // Fetch balances for each account and its supported chains (pre-computed in request)\n for (const {\n account,\n supportedChains,\n } of request.accountsWithSupportedChains) {\n const chainsForAccount = chainsToFetch.filter((chain) =>\n supportedChains.includes(chain),\n );\n if (chainsForAccount.length === 0) {\n continue;\n }\n\n const { address, id: accountId } = account;\n\n for (const chainId of chainsForAccount) {\n const hexChainId = caipChainIdToHex(chainId);\n\n try {\n // Use BalanceFetcher for batched balance fetching\n const result = await this.#balanceFetcher.fetchBalancesForTokens(\n hexChainId,\n accountId,\n address as Address,\n [], // Empty array means just native token\n { includeNative: true },\n );\n\n if (!assetsBalance[accountId]) {\n assetsBalance[accountId] = {};\n }\n\n // Collect metadata for all balances\n const balanceMetadata = this.#collectMetadataForBalances(\n result.balances,\n chainId,\n );\n Object.assign(assetsInfo, balanceMetadata);\n\n // Convert balances to human-readable format\n for (const balance of result.balances) {\n const metadata = assetsInfo[balance.assetId];\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = metadata?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n assetsBalance[accountId][balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n } catch (error) {\n log('Failed to fetch balance', { address, chainId, error });\n\n if (!assetsBalance[accountId]) {\n assetsBalance[accountId] = {};\n }\n const nativeAssetId = this.#buildNativeAssetId(chainId);\n assetsBalance[accountId][nativeAssetId] = { amount: '0' };\n\n // Even on error, include native token metadata\n const chainStatus = this.#chainStatuses[chainId];\n if (chainStatus) {\n assetsInfo[nativeAssetId] = {\n type: 'native',\n symbol: chainStatus.nativeCurrency,\n name: chainStatus.nativeCurrency,\n decimals: 18,\n };\n }\n\n if (!failedChains.includes(chainId)) {\n failedChains.push(chainId);\n }\n }\n }\n }\n\n if (failedChains.length > 0) {\n log('Fetch PARTIAL - some chains failed', {\n successChains: chainsToFetch.filter(\n (chain) => !failedChains.includes(chain),\n ),\n failedChains,\n });\n\n response.errors = {};\n for (const chainId of failedChains) {\n response.errors[chainId] = 'RPC fetch failed';\n }\n } else {\n log('Fetch SUCCESS', {\n chains: chainsToFetch,\n accountCount: Object.keys(assetsBalance).length,\n });\n }\n\n response.assetsBalance = assetsBalance;\n\n // Include metadata for native tokens if we have any\n if (Object.keys(assetsInfo).length > 0) {\n response.assetsInfo = assetsInfo;\n }\n\n return response;\n }\n\n /**\n * Run token detection for an account on a chain.\n *\n * @param chainId - The chain ID to detect tokens on.\n * @param account - The account to detect tokens for.\n * @returns Promise resolving to a DataResponse with detected assets.\n */\n async detectTokens(\n chainId: ChainId,\n account: InternalAccount,\n ): Promise<DataResponse> {\n if (!this.#tokenDetectionEnabled() || !this.#useExternalService()) {\n return {};\n }\n\n const hexChainId = caipChainIdToHex(chainId);\n const { address, id: accountId } = account;\n\n log('Running token detection', { chainId, accountId });\n\n try {\n const result = await this.#tokenDetector.detectTokens(\n hexChainId,\n accountId,\n address as Address,\n {\n tokenDetectionEnabled: this.#tokenDetectionEnabled(),\n useExternalService: this.#useExternalService(),\n },\n );\n\n if (result.detectedAssets.length === 0) {\n log('No new tokens detected');\n return {};\n }\n\n log('Detected new tokens', {\n count: result.detectedAssets.length,\n chainId,\n accountId,\n });\n\n // Convert detected assets to DataResponse format\n const balances: Record<Caip19AssetId, AssetBalance> = {};\n const assetsInfo: Record<Caip19AssetId, AssetMetadata> = {};\n\n // Build metadata from detected assets\n for (const asset of result.detectedAssets) {\n if (asset.symbol && asset.decimals !== undefined) {\n assetsInfo[asset.assetId] = {\n type: 'erc20',\n symbol: asset.symbol,\n name: asset.name ?? asset.symbol,\n decimals: asset.decimals,\n image: asset.image,\n };\n }\n }\n\n // Add balances for detected tokens (converted to human-readable format)\n for (const balance of result.detectedBalances) {\n const detectedAsset = result.detectedAssets.find(\n (asset) => asset.assetId === balance.assetId,\n );\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = detectedAsset?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n balances[balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n\n const response: DataResponse = {\n detectedAssets: {\n [accountId]: result.detectedAssets.map((asset) => asset.assetId),\n },\n assetsBalance: {\n [accountId]: balances,\n },\n };\n\n // Include metadata if we have any\n if (Object.keys(assetsInfo).length > 0) {\n response.assetsInfo = assetsInfo;\n }\n\n return response;\n } catch (error) {\n log('Token detection failed', { chainId, accountId, error });\n return {};\n }\n }\n\n get assetsMiddleware(): Middleware {\n return async (context, next) => {\n const { request } = context;\n\n const supportedChains = request.chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n\n if (supportedChains.length === 0) {\n return next(context);\n }\n\n let successfullyHandledChains: ChainId[] = [];\n\n log('Middleware fetching', {\n chains: supportedChains,\n accounts: request.accountsWithSupportedChains.map((a) => a.account.id),\n });\n\n const response = await this.fetch({\n ...request,\n chainIds: supportedChains,\n });\n\n if (response.assetsBalance) {\n context.response.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n context.response.assetsBalance[accountId] ??= {};\n context.response.assetsBalance[accountId] = {\n ...context.response.assetsBalance[accountId],\n ...accountBalances,\n };\n }\n }\n\n if (response.assetsInfo) {\n context.response.assetsInfo ??= {};\n context.response.assetsInfo = {\n ...context.response.assetsInfo,\n ...response.assetsInfo,\n };\n }\n\n const failedChains = new Set(Object.keys(response.errors ?? {}));\n successfullyHandledChains = supportedChains.filter(\n (chainId) => !failedChains.has(chainId),\n );\n\n if (successfullyHandledChains.length > 0) {\n const remainingChains = request.chainIds.filter(\n (chainId) => !successfullyHandledChains.includes(chainId),\n );\n\n return next({\n ...context,\n request: {\n ...request,\n chainIds: remainingChains,\n },\n });\n }\n\n return next(context);\n };\n }\n\n /**\n * Subscribe to updates for the given request.\n * Starts polling through BalanceFetcher and TokenDetector.\n *\n * @param subscriptionRequest - The subscription request details.\n */\n async subscribe(subscriptionRequest: SubscriptionRequest): Promise<void> {\n const { request, subscriptionId, isUpdate } = subscriptionRequest;\n\n const chainsToSubscribe = request.chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n\n log('Subscribe requested', {\n subscriptionId,\n isUpdate,\n accounts: request.accountsWithSupportedChains.map((a) => a.account.id),\n chainsToSubscribe,\n });\n\n if (chainsToSubscribe.length === 0) {\n log('No active chains to subscribe');\n return;\n }\n\n // Handle subscription update - restart polling for new chains\n if (isUpdate) {\n const existing = this.#activeSubscriptions.get(subscriptionId);\n if (existing) {\n log('Updating existing subscription - restarting polling', {\n subscriptionId,\n existingChains: existing.chains,\n newChains: chainsToSubscribe,\n });\n // Don't return early - continue to unsubscribe and restart polling\n }\n }\n\n // Clean up existing subscription (stops old polling)\n await this.unsubscribe(subscriptionId);\n\n // Start polling through BalanceFetcher and TokenDetector (use pre-computed supportedChains per account)\n const balancePollingTokens: string[] = [];\n const detectionPollingTokens: string[] = [];\n\n for (const {\n account,\n supportedChains,\n } of request.accountsWithSupportedChains) {\n const chainsForAccount = chainsToSubscribe.filter((chain) =>\n supportedChains.includes(chain),\n );\n if (chainsForAccount.length === 0) {\n continue;\n }\n\n const { address, id: accountId } = account;\n\n for (const chainId of chainsForAccount) {\n const hexChainId = caipChainIdToHex(chainId);\n\n // Start balance polling\n const balanceInput: BalancePollingInput = {\n chainId: hexChainId,\n accountId,\n accountAddress: address as Address,\n };\n const balanceToken = this.#balanceFetcher.startPolling(balanceInput);\n balancePollingTokens.push(balanceToken);\n\n // Start detection polling if enabled and external services allowed\n if (this.#tokenDetectionEnabled() && this.#useExternalService()) {\n const detectionInput: DetectionPollingInput = {\n chainId: hexChainId,\n accountId,\n accountAddress: address as Address,\n };\n const detectionToken =\n this.#tokenDetector.startPolling(detectionInput);\n detectionPollingTokens.push(detectionToken);\n }\n }\n }\n\n // Store subscription data\n const accounts = request.accountsWithSupportedChains.map(\n (entry) => entry.account,\n );\n this.#activeSubscriptions.set(subscriptionId, {\n balancePollingTokens,\n detectionPollingTokens,\n chains: chainsToSubscribe,\n accounts,\n onAssetsUpdate: subscriptionRequest.onAssetsUpdate,\n });\n\n log('Subscription SUCCESS', {\n subscriptionId,\n chains: chainsToSubscribe,\n balancePollingCount: balancePollingTokens.length,\n detectionPollingCount: detectionPollingTokens.length,\n });\n }\n\n /**\n * Unsubscribe from updates and stop polling.\n *\n * @param subscriptionId - The subscription ID to unsubscribe.\n */\n async unsubscribe(subscriptionId: string): Promise<void> {\n const subscription = this.#activeSubscriptions.get(subscriptionId);\n if (subscription) {\n // Stop balance polling\n for (const token of subscription.balancePollingTokens) {\n this.#balanceFetcher.stopPollingByPollingToken(token);\n }\n\n // Stop detection polling\n for (const token of subscription.detectionPollingTokens) {\n this.#tokenDetector.stopPollingByPollingToken(token);\n }\n\n this.#activeSubscriptions.delete(subscriptionId);\n log('Unsubscribed and stopped polling', { subscriptionId });\n }\n }\n\n /**\n * Build the native asset ID for a given chain using NetworkEnablementController state.\n *\n * @param chainId - The CAIP-2 chain ID (e.g., \"eip155:1\")\n * @returns The CAIP-19 native asset ID (e.g., \"eip155:1/slip44:60\")\n */\n #buildNativeAssetId(chainId: ChainId): Caip19AssetId {\n const { nativeAssetIdentifiers } = this.#messenger.call(\n 'NetworkEnablementController:getState',\n );\n\n return nativeAssetIdentifiers[chainId] ?? `${chainId}/slip44:60`;\n }\n\n /**\n * Get existing assets metadata from AssetsController state.\n * Used to include metadata for ERC20 tokens when returning balance updates.\n *\n * @returns Record of asset IDs to their metadata.\n */\n #getExistingAssetsMetadata(): Record<Caip19AssetId, AssetMetadata> {\n try {\n const state = this.#messenger.call('AssetsController:getState');\n return state.assetsInfo ?? {};\n } catch {\n // If AssetsController:getState fails, return empty metadata\n return {};\n }\n }\n\n /**\n * Get token metadata from TokenListController for an ERC20 token.\n * Used as a fallback when metadata is not in AssetsController state.\n *\n * @param assetId - The CAIP-19 asset ID (e.g., \"eip155:1/erc20:0x...\")\n * @returns Token metadata if found in token list, undefined otherwise.\n */\n #getTokenMetadataFromTokenList(\n assetId: Caip19AssetId,\n ): AssetMetadata | undefined {\n try {\n const parsed = parseCaipAssetType(assetId);\n if (parsed.assetNamespace !== 'erc20') {\n return undefined;\n }\n const tokenAddress = parsed.assetReference;\n const { reference } = parseCaipChainId(parsed.chainId);\n const hexChainId = numberToHex(parseInt(reference, 10));\n\n const tokenListState = this.#messenger.call(\n 'TokenListController:getState',\n );\n const chainCacheEntry = tokenListState?.tokensChainsCache?.[hexChainId];\n const chainTokenList = chainCacheEntry?.data;\n\n if (!chainTokenList) {\n return undefined;\n }\n\n // Look up token by address (case-insensitive)\n const lowerAddress = tokenAddress.toLowerCase();\n for (const [address, tokenData] of Object.entries(chainTokenList)) {\n if (address.toLowerCase() === lowerAddress) {\n const token = tokenData;\n if (token.symbol && token.decimals !== undefined) {\n return {\n type: 'erc20',\n symbol: token.symbol,\n name: token.name ?? token.symbol,\n decimals: token.decimals,\n image: token.iconUrl,\n };\n }\n }\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Destroy the data source and clean up resources.\n */\n destroy(): void {\n log('Destroying RpcDataSource');\n\n this.#unsubscribeTransactionConfirmed?.();\n this.#unsubscribeIncomingTransactions?.();\n\n // Stop all polling\n this.#balanceFetcher.stopAllPolling();\n this.#tokenDetector.stopAllPolling();\n\n // Clear subscriptions\n this.#activeSubscriptions.clear();\n\n // Clear caches\n this.#providerCache.clear();\n }\n}\n\nexport function createRpcDataSource(\n options: RpcDataSourceOptions,\n): RpcDataSource {\n return new RpcDataSource(options);\n}\n"]}
1
+ {"version":3,"file":"RpcDataSource.mjs","sourceRoot":"","sources":["../../src/data-sources/RpcDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type { GetTokenListState } from '@metamask/assets-controllers';\nimport { toHex } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkStatus,\n} from '@metamask/network-controller';\nimport type { NetworkEnablementControllerGetStateAction } from '@metamask/network-enablement-controller';\nimport type {\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerTransactionConfirmedEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport {\n isStrictHexString,\n isCaipChainId,\n numberToHex,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport BigNumberJS from 'bignumber.js';\n\nimport { AbstractDataSource } from './AbstractDataSource';\nimport type {\n DataSourceState,\n SubscriptionRequest,\n} from './AbstractDataSource';\nimport {\n BalanceFetcher,\n MulticallClient,\n TokenDetector,\n} from './evm-rpc-services';\nimport type {\n BalancePollingInput,\n DetectionPollingInput,\n} from './evm-rpc-services';\nimport type {\n Address,\n Provider as RpcProvider,\n TokenListState,\n BalanceFetchResult,\n TokenDetectionResult,\n} from './evm-rpc-services';\nimport type {\n AssetsControllerGetStateAction,\n AssetsControllerMessenger,\n} from '../AssetsController';\nimport { projectLogger, createModuleLogger } from '../logger';\nimport type {\n ChainId,\n Caip19AssetId,\n AssetBalance,\n AssetMetadata,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\n\nconst CONTROLLER_NAME = 'RpcDataSource';\nconst DEFAULT_BALANCE_INTERVAL = 30_000; // 30 seconds\nconst DEFAULT_DETECTION_INTERVAL = 180_000; // 3 minutes\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// Allowed actions that RpcDataSource can call\nexport type RpcDataSourceAllowedActions =\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | AssetsControllerGetStateAction\n | GetTokenListState\n | NetworkEnablementControllerGetStateAction;\n\n// Allowed events that RpcDataSource can subscribe to\nexport type RpcDataSourceAllowedEvents =\n | NetworkControllerStateChangeEvent\n | TransactionControllerTransactionConfirmedEvent\n | TransactionControllerIncomingTransactionsReceivedEvent;\n\n/** Network status for each chain */\nexport type ChainStatus = {\n chainId: ChainId;\n status: NetworkStatus;\n name: string;\n nativeCurrency: string;\n /** Network client ID for getting the provider */\n networkClientId: string;\n};\n\n/** RpcDataSource is stateless */\nexport type RpcDataSourceState = Record<never, never>;\n\n/** Optional configuration for RpcDataSource when the controller instantiates it. */\nexport type RpcDataSourceConfig = {\n balanceInterval?: number;\n detectionInterval?: number;\n /** Function returning whether token detection is enabled (avoids stale value) */\n tokenDetectionEnabled?: () => boolean;\n /** Function returning whether external services are allowed (avoids stale value; default: () => true) */\n useExternalService?: () => boolean;\n timeout?: number;\n};\n\nexport type RpcDataSourceOptions = {\n /** The AssetsController messenger (shared by all data sources). */\n messenger: AssetsControllerMessenger;\n /** Called when active chains are updated. Pass dataSourceName so the controller knows the source. */\n onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n /** Request timeout in ms */\n timeout?: number;\n /** Balance polling interval in ms (default: 30s) */\n balanceInterval?: number;\n /** Token detection polling interval in ms (default: 180s / 3 min) */\n detectionInterval?: number;\n /** Function returning whether token detection is enabled (avoids stale value) */\n tokenDetectionEnabled?: () => boolean;\n /** Function returning whether external services are allowed (avoids stale value; default: () => true) */\n useExternalService?: () => boolean;\n};\n\n/**\n * Subscription data stored for each active subscription.\n */\ntype SubscriptionData = {\n /** Polling tokens from BalanceFetcher */\n balancePollingTokens: string[];\n /** Polling tokens from TokenDetector */\n detectionPollingTokens: string[];\n /** Chain IDs being polled */\n chains: ChainId[];\n /** Accounts being polled */\n accounts: InternalAccount[];\n /** Callback to report asset updates to the controller */\n onAssetsUpdate: (response: DataResponse) => void | Promise<void>;\n};\n\n/**\n * Convert CAIP chain ID or hex chain ID to hex chain ID.\n *\n * @param chainId - CAIP chain ID or hex chain ID.\n * @returns Hex chain ID.\n */\nexport const caipChainIdToHex = (chainId: string): Hex => {\n if (isStrictHexString(chainId)) {\n return chainId;\n }\n\n if (isCaipChainId(chainId)) {\n return toHex(parseCaipChainId(chainId).reference);\n }\n\n throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');\n};\n\n/**\n * Data source for fetching balances via RPC calls.\n *\n * Orchestrates polling through BalanceFetcher and TokenDetector,\n * each of which handle their own polling intervals.\n *\n * Communicates with AssetsController via Messenger:\n *\n * Actions:\n * - RpcDataSource:getActiveChains\n * - RpcDataSource:fetch\n * - RpcDataSource:subscribe\n * - RpcDataSource:unsubscribe\n *\n * Events:\n * - RpcDataSource:activeChainsUpdated\n * - RpcDataSource:assetsUpdated\n */\nexport class RpcDataSource extends AbstractDataSource<\n typeof CONTROLLER_NAME,\n DataSourceState\n> {\n readonly #messenger: AssetsControllerMessenger;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n readonly #timeout: number;\n\n readonly #tokenDetectionEnabled: () => boolean;\n\n readonly #useExternalService: () => boolean;\n\n /** Currently active chains */\n #activeChains: ChainId[] = [];\n\n /** Network status for each active chain */\n #chainStatuses: Record<ChainId, ChainStatus> = {};\n\n /** Cache of Web3Provider instances by chainId */\n readonly #providerCache: Map<ChainId, Web3Provider> = new Map();\n\n /** Active subscriptions by ID */\n readonly #activeSubscriptions: Map<string, SubscriptionData> = new Map();\n\n #unsubscribeTransactionConfirmed: (() => void) | undefined = undefined;\n\n #unsubscribeIncomingTransactions: (() => void) | undefined = undefined;\n\n // Rpc-datasource components\n readonly #multicallClient: MulticallClient;\n\n readonly #balanceFetcher: BalanceFetcher;\n\n readonly #tokenDetector: TokenDetector;\n\n constructor(options: RpcDataSourceOptions) {\n super(CONTROLLER_NAME, { activeChains: [] });\n this.#messenger = options.messenger;\n this.#onActiveChainsUpdated = options.onActiveChainsUpdated;\n this.#timeout = options.timeout ?? 10_000;\n this.#tokenDetectionEnabled =\n options.tokenDetectionEnabled ?? ((): boolean => true);\n this.#useExternalService =\n options.useExternalService ?? ((): boolean => true);\n\n const balanceInterval = options.balanceInterval ?? DEFAULT_BALANCE_INTERVAL;\n const detectionInterval =\n options.detectionInterval ?? DEFAULT_DETECTION_INTERVAL;\n\n log('Initializing RpcDataSource', {\n timeout: this.#timeout,\n balanceInterval,\n detectionInterval,\n tokenDetectionEnabled: this.#tokenDetectionEnabled(),\n useExternalService: this.#useExternalService(),\n });\n\n // Initialize MulticallClient with a provider getter\n this.#multicallClient = new MulticallClient((hexChainId: string) => {\n return this.#getMulticallProvider(hexChainId);\n });\n\n // Create messenger adapters for BalanceFetcher and TokenDetector\n const balanceFetcherMessenger = {\n call: (\n _action: 'AssetsController:getState',\n ): {\n assetsBalance: Record<string, Record<string, { amount: string }>>;\n } => {\n const state = this.#messenger.call('AssetsController:getState');\n return {\n assetsBalance: (state.assetsBalance ?? {}) as Record<\n string,\n Record<string, { amount: string }>\n >,\n };\n },\n };\n\n const tokenDetectorMessenger = {\n call: (_action: 'TokenListController:getState'): TokenListState => {\n return this.#messenger.call('TokenListController:getState');\n },\n };\n\n // Initialize BalanceFetcher with polling interval\n this.#balanceFetcher = new BalanceFetcher(\n this.#multicallClient,\n balanceFetcherMessenger,\n { pollingInterval: balanceInterval },\n );\n this.#balanceFetcher.setOnBalanceUpdate(\n this.#handleBalanceUpdate.bind(this),\n );\n\n // Initialize TokenDetector with polling interval\n this.#tokenDetector = new TokenDetector(\n this.#multicallClient,\n tokenDetectorMessenger,\n {\n pollingInterval: detectionInterval,\n tokenDetectionEnabled: this.#tokenDetectionEnabled,\n useExternalService: this.#useExternalService,\n },\n );\n this.#tokenDetector.setOnDetectionUpdate(\n this.#handleDetectionUpdate.bind(this),\n );\n\n this.#subscribeToNetworkController();\n this.#subscribeToTransactionEvents();\n this.#initializeFromNetworkController();\n }\n\n /**\n * Convert a raw balance to human-readable format using decimals.\n *\n * @param rawBalance - The raw balance string.\n * @param decimals - The number of decimals for the token.\n * @returns The human-readable balance string.\n */\n #convertToHumanReadable(rawBalance: string, decimals: number): string {\n const rawAmount = new BigNumberJS(rawBalance);\n const divisor = new BigNumberJS(10).pow(decimals);\n return rawAmount.dividedBy(divisor).toString();\n }\n\n /**\n * Collect metadata for a list of balance entries.\n * For native tokens, generates metadata from chain status.\n * For ERC20 tokens, looks up from existing state or token list.\n *\n * @param balances - Array of balance entries with assetId.\n * @param chainId - The CAIP-2 chain ID.\n * @returns Record of asset metadata keyed by asset ID.\n */\n #collectMetadataForBalances(\n balances: { assetId: Caip19AssetId }[],\n chainId: ChainId,\n ): Record<Caip19AssetId, AssetMetadata> {\n const assetsInfo: Record<Caip19AssetId, AssetMetadata> = {};\n const existingMetadata = this.#getExistingAssetsMetadata();\n\n for (const balance of balances) {\n const isNative = balance.assetId.includes('/slip44:');\n if (isNative) {\n const chainStatus = this.#chainStatuses[chainId];\n\n if (chainStatus) {\n assetsInfo[balance.assetId] = {\n type: 'native',\n symbol: chainStatus.nativeCurrency,\n name: chainStatus.nativeCurrency,\n decimals: 18,\n };\n }\n } else {\n // For ERC20 tokens, try existing metadata from state first\n const existingMeta = existingMetadata[balance.assetId];\n\n if (existingMeta) {\n assetsInfo[balance.assetId] = existingMeta;\n } else {\n // Fallback to token list if not in state\n const tokenListMeta = this.#getTokenMetadataFromTokenList(\n balance.assetId,\n );\n if (tokenListMeta) {\n assetsInfo[balance.assetId] = tokenListMeta;\n } else {\n // Default metadata for unknown ERC20 tokens.\n // Use 18 decimals (the standard for most ERC20 tokens)\n // to ensure consistent human-readable balance format.\n assetsInfo[balance.assetId] = {\n type: 'erc20',\n symbol: '',\n name: '',\n decimals: 18,\n };\n }\n }\n }\n }\n\n return assetsInfo;\n }\n\n /**\n * Handle balance update from BalanceFetcher.\n *\n * @param result - The balance fetch result.\n */\n #handleBalanceUpdate(result: BalanceFetchResult): void {\n const newBalances: Record<string, { amount: string }> = {};\n\n // Convert hex chain ID to CAIP-2 format\n const chainIdDecimal = parseInt(result.chainId, 16);\n const caipChainId = `eip155:${chainIdDecimal}` as ChainId;\n\n // Collect metadata for all balances\n const assetsInfo = this.#collectMetadataForBalances(\n result.balances,\n caipChainId,\n );\n\n // Convert balances to human-readable format using metadata\n for (const balance of result.balances) {\n const metadata = assetsInfo[balance.assetId];\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = metadata?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n newBalances[balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n\n // Only send new data to AssetsController - it handles merging atomically\n // to avoid race conditions when concurrent updates occur for the same account\n const response: DataResponse = {\n assetsBalance: {\n [result.accountId]: newBalances,\n },\n assetsInfo,\n };\n\n log('Balance update response', {\n accountId: result.accountId,\n newBalanceCount: Object.keys(newBalances).length,\n });\n\n for (const subscription of this.#activeSubscriptions.values()) {\n subscription.onAssetsUpdate(response)?.catch((error) => {\n log('Failed to update assets', { error });\n });\n }\n }\n\n /**\n * Handle detection update from TokenDetector.\n *\n * @param result - The token detection result.\n */\n #handleDetectionUpdate(result: TokenDetectionResult): void {\n log('Detected new tokens', {\n count: result.detectedAssets.length,\n });\n\n // Build new metadata from detected assets\n const newMetadata: Record<Caip19AssetId, AssetMetadata> = {};\n if (result.detectedAssets.length > 0) {\n for (const asset of result.detectedAssets) {\n // Only include if we have metadata (symbol and decimals at minimum)\n if (asset.symbol && asset.decimals !== undefined) {\n newMetadata[asset.assetId] = {\n type: 'erc20',\n symbol: asset.symbol,\n name: asset.name ?? asset.symbol,\n decimals: asset.decimals,\n image: asset.image,\n };\n }\n }\n }\n\n // Build new balances from detected tokens\n const newBalances: Record<string, { amount: string }> = {};\n if (result.detectedBalances.length > 0) {\n for (const balance of result.detectedBalances) {\n // Get decimals from the detected asset metadata\n const detectedAsset = result.detectedAssets.find(\n (asset) => asset.assetId === balance.assetId,\n );\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = detectedAsset?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n newBalances[balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n }\n\n // Only send new data to AssetsController - it handles merging atomically\n // to avoid race conditions when concurrent updates occur for the same account\n const response: DataResponse = {\n detectedAssets: {\n [result.accountId]: result.detectedAssets.map((asset) => asset.assetId),\n },\n assetsInfo: newMetadata,\n assetsBalance: {\n [result.accountId]: newBalances,\n },\n };\n\n for (const subscription of this.#activeSubscriptions.values()) {\n subscription.onAssetsUpdate(response)?.catch((error) => {\n log('Failed to update detected assets', { error });\n });\n }\n }\n\n #subscribeToNetworkController(): void {\n this.#messenger.subscribe(\n 'NetworkController:stateChange',\n (networkState: NetworkState) => {\n log('NetworkController state changed');\n this.#clearProviderCache();\n this.#updateFromNetworkState(networkState);\n },\n );\n }\n\n #subscribeToTransactionEvents(): void {\n const unsubConfirmed = this.#messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n this.#onTransactionConfirmed.bind(this),\n );\n this.#unsubscribeTransactionConfirmed =\n typeof unsubConfirmed === 'function' ? unsubConfirmed : undefined;\n\n const unsubIncoming = this.#messenger.subscribe(\n 'TransactionController:incomingTransactionsReceived',\n this.#onIncomingTransactions.bind(this),\n );\n this.#unsubscribeIncomingTransactions =\n typeof unsubIncoming === 'function' ? unsubIncoming : undefined;\n }\n\n #onTransactionConfirmed(payload: TransactionMeta): void {\n const hexChainId = payload?.chainId;\n if (!hexChainId) {\n return;\n }\n const caipChainId = `eip155:${parseInt(hexChainId, 16)}` as ChainId;\n this.#refreshBalanceForChains([caipChainId]).catch((error) => {\n log('Failed to refresh balance after transaction confirmed', { error });\n });\n }\n\n #onIncomingTransactions(payload: TransactionMeta[]): void {\n const chainIds = Array.from(\n new Set(\n (payload ?? [])\n .map((item) => item?.chainId)\n .filter((id): id is Hex => Boolean(id)),\n ),\n );\n const caipChainIds = chainIds.map(\n (hexChainId) => `eip155:${parseInt(hexChainId, 16)}` as ChainId,\n );\n const toRefresh =\n caipChainIds.length > 0 ? caipChainIds : [...this.#activeChains];\n this.#refreshBalanceForChains(toRefresh).catch((error) => {\n log('Failed to refresh balance after incoming transactions', { error });\n });\n }\n\n /**\n * Fetch balances for the given chains across all active subscriptions and\n * push updates to the controller.\n *\n * @param chainIds - CAIP-2 chain IDs to refresh.\n */\n async #refreshBalanceForChains(chainIds: ChainId[]): Promise<void> {\n const chainIdsSet = new Set(chainIds);\n const chainsToFetch = chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n if (chainsToFetch.length === 0) {\n return;\n }\n\n for (const subscription of this.#activeSubscriptions.values()) {\n const subscriptionChains = subscription.chains.filter((chainId) =>\n chainIdsSet.has(chainId),\n );\n if (subscriptionChains.length === 0) {\n continue;\n }\n\n const request: DataRequest = {\n accountsWithSupportedChains: subscription.accounts.map((account) => ({\n account,\n supportedChains: subscriptionChains,\n })),\n chainIds: subscriptionChains,\n dataTypes: ['balance'],\n };\n\n try {\n const response = await this.fetch(request);\n if (\n response.assetsBalance &&\n Object.keys(response.assetsBalance).length > 0\n ) {\n subscription.onAssetsUpdate(response)?.catch((error) => {\n log('Failed to report balance update after transaction', {\n error,\n });\n });\n }\n } catch (error) {\n log('Failed to fetch balance after transaction', {\n chains: subscriptionChains,\n error,\n });\n }\n }\n }\n\n #initializeFromNetworkController(): void {\n log('Initializing from NetworkController');\n try {\n const networkState = this.#messenger.call('NetworkController:getState');\n this.#updateFromNetworkState(networkState);\n } catch (error) {\n log('Failed to initialize from NetworkController', error);\n }\n }\n\n #updateFromNetworkState(networkState: NetworkState): void {\n const { networkConfigurationsByChainId, networksMetadata } = networkState;\n\n const chainStatuses: Record<ChainId, ChainStatus> = {};\n const activeChains: ChainId[] = [];\n\n for (const [hexChainId, config] of Object.entries(\n networkConfigurationsByChainId,\n )) {\n const decimalChainId = parseInt(hexChainId, 16);\n const caip2ChainId = `eip155:${decimalChainId}` as ChainId;\n\n const defaultRpcEndpoint =\n config.rpcEndpoints[config.defaultRpcEndpointIndex];\n if (!defaultRpcEndpoint) {\n continue;\n }\n\n const { networkClientId } = defaultRpcEndpoint;\n const metadata = networksMetadata[networkClientId];\n\n const status: NetworkStatus =\n metadata?.status ?? ('unknown' as NetworkStatus);\n\n chainStatuses[caip2ChainId] = {\n chainId: caip2ChainId,\n status,\n name: config.name,\n nativeCurrency: config.nativeCurrency,\n networkClientId,\n };\n\n if (status === 'available' || status === 'unknown') {\n activeChains.push(caip2ChainId);\n }\n }\n\n log('Network state updated', {\n configuredChains: Object.keys(chainStatuses),\n activeChains,\n });\n\n // Check if chains changed\n const previousChains = [...this.#activeChains];\n const previousSet = new Set(previousChains);\n const hasChanges =\n previousChains.length !== activeChains.length ||\n activeChains.some((chain) => !previousSet.has(chain));\n\n // Update internal state and data source state before notifying, so that\n // when the controller handles the callback and calls getActiveChainsSync(),\n // it receives the updated chains (same order as AbstractDataSource.updateActiveChains).\n this.#chainStatuses = chainStatuses;\n this.#activeChains = activeChains;\n this.state.activeChains = activeChains;\n\n if (hasChanges) {\n this.#onActiveChainsUpdated(this.getName(), activeChains, previousChains);\n }\n }\n\n #getProvider(chainId: ChainId): Web3Provider | undefined {\n const cached = this.#providerCache.get(chainId);\n if (cached) {\n return cached;\n }\n\n const chainStatus = this.#chainStatuses[chainId];\n if (!chainStatus) {\n return undefined;\n }\n\n try {\n const networkClient = this.#messenger.call(\n 'NetworkController:getNetworkClientById',\n chainStatus.networkClientId,\n );\n if (!networkClient?.provider) {\n return undefined;\n }\n const web3Provider = new Web3Provider(networkClient.provider);\n this.#providerCache.set(chainId, web3Provider);\n\n return web3Provider;\n } catch (error) {\n log('Failed to get provider for chain', { chainId, error });\n return undefined;\n }\n }\n\n /**\n * Get provider for MulticallClient using a hex chainId.\n *\n * @param hexChainId - The hex string representation of the chain id.\n * @returns An RpcProvider instance for the specified chain.\n */\n #getMulticallProvider(hexChainId: string): RpcProvider {\n const decimalChainId = parseInt(hexChainId, 16);\n const caip2ChainId = `eip155:${decimalChainId}` as ChainId;\n\n const web3Provider = this.#getProvider(caip2ChainId);\n\n if (!web3Provider) {\n throw new Error(`No provider available for chain ${hexChainId}`);\n }\n\n return {\n call: async (params: { to: string; data: string }): Promise<string> => {\n return web3Provider.call({\n to: params.to,\n data: params.data,\n });\n },\n getBalance: async (address: string): Promise<{ toString(): string }> => {\n const balance = await web3Provider.getBalance(address);\n return balance;\n },\n };\n }\n\n #clearProviderCache(): void {\n this.#providerCache.clear();\n }\n\n /**\n * Get the data source name.\n *\n * @returns The name of this data source.\n */\n /**\n * Get the status of all configured chains.\n *\n * @returns Record of chain statuses keyed by chain ID.\n */\n getChainStatuses(): Record<ChainId, ChainStatus> {\n return { ...this.#chainStatuses };\n }\n\n /**\n * Get the status of a specific chain.\n *\n * @param chainId - The chain ID to get status for.\n * @returns The chain status or undefined if not found.\n */\n getChainStatus(chainId: ChainId): ChainStatus | undefined {\n return this.#chainStatuses[chainId];\n }\n\n /**\n * Set the balance polling interval.\n *\n * @param interval - The polling interval in milliseconds.\n */\n setBalancePollingInterval(interval: number): void {\n log('Setting balance polling interval', { interval });\n this.#balanceFetcher.setIntervalLength(interval);\n }\n\n /**\n * Get the current balance polling interval.\n *\n * @returns The polling interval in milliseconds, or undefined if not set.\n */\n getBalancePollingInterval(): number | undefined {\n return this.#balanceFetcher.getIntervalLength();\n }\n\n /**\n * Set the token detection polling interval.\n *\n * @param interval - The polling interval in milliseconds.\n */\n setDetectionPollingInterval(interval: number): void {\n log('Setting detection polling interval', { interval });\n this.#tokenDetector.setIntervalLength(interval);\n }\n\n /**\n * Get the current token detection polling interval.\n *\n * @returns The polling interval in milliseconds, or undefined if not set.\n */\n getDetectionPollingInterval(): number | undefined {\n return this.#tokenDetector.getIntervalLength();\n }\n\n async fetch(request: DataRequest): Promise<DataResponse> {\n const response: DataResponse = {};\n\n const chainsToFetch = request.chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n\n log('Fetch requested', {\n accounts: request.accountsWithSupportedChains.map((a) => a.account.id),\n requestedChains: request.chainIds,\n chainsToFetch,\n });\n\n if (chainsToFetch.length === 0) {\n log('No active chains to fetch');\n return response;\n }\n\n const assetsBalance: Record<\n string,\n Record<Caip19AssetId, AssetBalance>\n > = {};\n const assetsInfo: Record<Caip19AssetId, AssetMetadata> = {};\n const failedChains: ChainId[] = [];\n\n // Fetch balances for each account and its supported chains (pre-computed in request)\n for (const {\n account,\n supportedChains,\n } of request.accountsWithSupportedChains) {\n const chainsForAccount = chainsToFetch.filter((chain) =>\n supportedChains.includes(chain),\n );\n if (chainsForAccount.length === 0) {\n continue;\n }\n\n const { address, id: accountId } = account;\n\n for (const chainId of chainsForAccount) {\n const hexChainId = caipChainIdToHex(chainId);\n\n try {\n // Use BalanceFetcher for batched balance fetching\n const result = await this.#balanceFetcher.fetchBalancesForTokens(\n hexChainId,\n accountId,\n address as Address,\n [], // Empty array means just native token\n { includeNative: true },\n );\n\n if (!assetsBalance[accountId]) {\n assetsBalance[accountId] = {};\n }\n\n // Collect metadata for all balances\n const balanceMetadata = this.#collectMetadataForBalances(\n result.balances,\n chainId,\n );\n Object.assign(assetsInfo, balanceMetadata);\n\n // Convert balances to human-readable format\n for (const balance of result.balances) {\n const metadata = assetsInfo[balance.assetId];\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = metadata?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n assetsBalance[accountId][balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n } catch (error) {\n log('Failed to fetch balance', { address, chainId, error });\n\n if (!assetsBalance[accountId]) {\n assetsBalance[accountId] = {};\n }\n const nativeAssetId = this.#buildNativeAssetId(chainId);\n assetsBalance[accountId][nativeAssetId] = { amount: '0' };\n\n // Even on error, include native token metadata\n const chainStatus = this.#chainStatuses[chainId];\n if (chainStatus) {\n assetsInfo[nativeAssetId] = {\n type: 'native',\n symbol: chainStatus.nativeCurrency,\n name: chainStatus.nativeCurrency,\n decimals: 18,\n };\n }\n\n if (!failedChains.includes(chainId)) {\n failedChains.push(chainId);\n }\n }\n }\n }\n\n if (failedChains.length > 0) {\n log('Fetch PARTIAL - some chains failed', {\n successChains: chainsToFetch.filter(\n (chain) => !failedChains.includes(chain),\n ),\n failedChains,\n });\n\n response.errors = {};\n for (const chainId of failedChains) {\n response.errors[chainId] = 'RPC fetch failed';\n }\n } else {\n log('Fetch SUCCESS', {\n chains: chainsToFetch,\n accountCount: Object.keys(assetsBalance).length,\n });\n }\n\n response.assetsBalance = assetsBalance;\n\n // Include metadata for native tokens if we have any\n if (Object.keys(assetsInfo).length > 0) {\n response.assetsInfo = assetsInfo;\n }\n\n return response;\n }\n\n /**\n * Run token detection for an account on a chain.\n *\n * @param chainId - The chain ID to detect tokens on.\n * @param account - The account to detect tokens for.\n * @returns Promise resolving to a DataResponse with detected assets.\n */\n async detectTokens(\n chainId: ChainId,\n account: InternalAccount,\n ): Promise<DataResponse> {\n if (!this.#tokenDetectionEnabled() || !this.#useExternalService()) {\n return {};\n }\n\n const hexChainId = caipChainIdToHex(chainId);\n const { address, id: accountId } = account;\n\n log('Running token detection', { chainId, accountId });\n\n try {\n const result = await this.#tokenDetector.detectTokens(\n hexChainId,\n accountId,\n address as Address,\n {\n tokenDetectionEnabled: this.#tokenDetectionEnabled(),\n useExternalService: this.#useExternalService(),\n },\n );\n\n if (result.detectedAssets.length === 0) {\n log('No new tokens detected');\n return {};\n }\n\n log('Detected new tokens', {\n count: result.detectedAssets.length,\n chainId,\n accountId,\n });\n\n // Convert detected assets to DataResponse format\n const balances: Record<Caip19AssetId, AssetBalance> = {};\n const assetsInfo: Record<Caip19AssetId, AssetMetadata> = {};\n\n // Build metadata from detected assets\n for (const asset of result.detectedAssets) {\n if (asset.symbol && asset.decimals !== undefined) {\n assetsInfo[asset.assetId] = {\n type: 'erc20',\n symbol: asset.symbol,\n name: asset.name ?? asset.symbol,\n decimals: asset.decimals,\n image: asset.image,\n };\n }\n }\n\n // Add balances for detected tokens (converted to human-readable format)\n for (const balance of result.detectedBalances) {\n const detectedAsset = result.detectedAssets.find(\n (asset) => asset.assetId === balance.assetId,\n );\n // Default to 18 decimals (ERC20 standard) for consistent human-readable format\n const decimals = detectedAsset?.decimals ?? 18;\n const humanReadableAmount = this.#convertToHumanReadable(\n balance.balance,\n decimals,\n );\n\n balances[balance.assetId] = {\n amount: humanReadableAmount,\n };\n }\n\n const response: DataResponse = {\n detectedAssets: {\n [accountId]: result.detectedAssets.map((asset) => asset.assetId),\n },\n assetsBalance: {\n [accountId]: balances,\n },\n };\n\n // Include metadata if we have any\n if (Object.keys(assetsInfo).length > 0) {\n response.assetsInfo = assetsInfo;\n }\n\n return response;\n } catch (error) {\n log('Token detection failed', { chainId, accountId, error });\n return {};\n }\n }\n\n get assetsMiddleware(): Middleware {\n return async (context, next) => {\n const { request } = context;\n\n const supportedChains = request.chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n\n if (supportedChains.length === 0) {\n return next(context);\n }\n\n let successfullyHandledChains: ChainId[] = [];\n\n log('Middleware fetching', {\n chains: supportedChains,\n accounts: request.accountsWithSupportedChains.map((a) => a.account.id),\n });\n\n const response = await this.fetch({\n ...request,\n chainIds: supportedChains,\n });\n\n if (response.assetsBalance) {\n context.response.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n context.response.assetsBalance[accountId] ??= {};\n context.response.assetsBalance[accountId] = {\n ...context.response.assetsBalance[accountId],\n ...accountBalances,\n };\n }\n }\n\n if (response.assetsInfo) {\n context.response.assetsInfo ??= {};\n context.response.assetsInfo = {\n ...context.response.assetsInfo,\n ...response.assetsInfo,\n };\n }\n\n const failedChains = new Set(Object.keys(response.errors ?? {}));\n successfullyHandledChains = supportedChains.filter(\n (chainId) => !failedChains.has(chainId),\n );\n\n if (successfullyHandledChains.length > 0) {\n const remainingChains = request.chainIds.filter(\n (chainId) => !successfullyHandledChains.includes(chainId),\n );\n\n return next({\n ...context,\n request: {\n ...request,\n chainIds: remainingChains,\n },\n });\n }\n\n return next(context);\n };\n }\n\n /**\n * Subscribe to updates for the given request.\n * Starts polling through BalanceFetcher and TokenDetector.\n *\n * @param subscriptionRequest - The subscription request details.\n */\n async subscribe(subscriptionRequest: SubscriptionRequest): Promise<void> {\n const { request, subscriptionId, isUpdate } = subscriptionRequest;\n\n const chainsToSubscribe = request.chainIds.filter((chainId) =>\n this.#activeChains.includes(chainId),\n );\n\n log('Subscribe requested', {\n subscriptionId,\n isUpdate,\n accounts: request.accountsWithSupportedChains.map((a) => a.account.id),\n chainsToSubscribe,\n });\n\n if (chainsToSubscribe.length === 0) {\n log('No active chains to subscribe');\n return;\n }\n\n // Handle subscription update - restart polling for new chains\n if (isUpdate) {\n const existing = this.#activeSubscriptions.get(subscriptionId);\n if (existing) {\n log('Updating existing subscription - restarting polling', {\n subscriptionId,\n existingChains: existing.chains,\n newChains: chainsToSubscribe,\n });\n // Don't return early - continue to unsubscribe and restart polling\n }\n }\n\n // Clean up existing subscription (stops old polling)\n await this.unsubscribe(subscriptionId);\n\n // Start polling through BalanceFetcher and TokenDetector (use pre-computed supportedChains per account)\n const balancePollingTokens: string[] = [];\n const detectionPollingTokens: string[] = [];\n\n for (const {\n account,\n supportedChains,\n } of request.accountsWithSupportedChains) {\n const chainsForAccount = chainsToSubscribe.filter((chain) =>\n supportedChains.includes(chain),\n );\n if (chainsForAccount.length === 0) {\n continue;\n }\n\n const { address, id: accountId } = account;\n\n for (const chainId of chainsForAccount) {\n const hexChainId = caipChainIdToHex(chainId);\n\n // Start balance polling\n const balanceInput: BalancePollingInput = {\n chainId: hexChainId,\n accountId,\n accountAddress: address as Address,\n };\n const balanceToken = this.#balanceFetcher.startPolling(balanceInput);\n balancePollingTokens.push(balanceToken);\n\n // Start detection polling if enabled and external services allowed\n if (this.#tokenDetectionEnabled() && this.#useExternalService()) {\n const detectionInput: DetectionPollingInput = {\n chainId: hexChainId,\n accountId,\n accountAddress: address as Address,\n };\n const detectionToken =\n this.#tokenDetector.startPolling(detectionInput);\n detectionPollingTokens.push(detectionToken);\n }\n }\n }\n\n // Store subscription data\n const accounts = request.accountsWithSupportedChains.map(\n (entry) => entry.account,\n );\n this.#activeSubscriptions.set(subscriptionId, {\n balancePollingTokens,\n detectionPollingTokens,\n chains: chainsToSubscribe,\n accounts,\n onAssetsUpdate: subscriptionRequest.onAssetsUpdate,\n });\n\n log('Subscription SUCCESS', {\n subscriptionId,\n chains: chainsToSubscribe,\n balancePollingCount: balancePollingTokens.length,\n detectionPollingCount: detectionPollingTokens.length,\n });\n }\n\n /**\n * Unsubscribe from updates and stop polling.\n *\n * @param subscriptionId - The subscription ID to unsubscribe.\n */\n async unsubscribe(subscriptionId: string): Promise<void> {\n const subscription = this.#activeSubscriptions.get(subscriptionId);\n if (subscription) {\n // Stop balance polling\n for (const token of subscription.balancePollingTokens) {\n this.#balanceFetcher.stopPollingByPollingToken(token);\n }\n\n // Stop detection polling\n for (const token of subscription.detectionPollingTokens) {\n this.#tokenDetector.stopPollingByPollingToken(token);\n }\n\n this.#activeSubscriptions.delete(subscriptionId);\n log('Unsubscribed and stopped polling', { subscriptionId });\n }\n }\n\n /**\n * Build the native asset ID for a given chain using NetworkEnablementController state.\n *\n * @param chainId - The CAIP-2 chain ID (e.g., \"eip155:1\")\n * @returns The CAIP-19 native asset ID (e.g., \"eip155:1/slip44:60\")\n */\n #buildNativeAssetId(chainId: ChainId): Caip19AssetId {\n const { nativeAssetIdentifiers } = this.#messenger.call(\n 'NetworkEnablementController:getState',\n );\n\n return nativeAssetIdentifiers[chainId] ?? `${chainId}/slip44:60`;\n }\n\n /**\n * Get existing assets metadata from AssetsController state.\n * Used to include metadata for ERC20 tokens when returning balance updates.\n *\n * @returns Record of asset IDs to their metadata.\n */\n #getExistingAssetsMetadata(): Record<Caip19AssetId, AssetMetadata> {\n try {\n const state = this.#messenger.call('AssetsController:getState');\n return state.assetsInfo ?? {};\n } catch {\n // If AssetsController:getState fails, return empty metadata\n return {};\n }\n }\n\n /**\n * Get token metadata from TokenListController for an ERC20 token.\n * Used as a fallback when metadata is not in AssetsController state.\n *\n * @param assetId - The CAIP-19 asset ID (e.g., \"eip155:1/erc20:0x...\")\n * @returns Token metadata if found in token list, undefined otherwise.\n */\n #getTokenMetadataFromTokenList(\n assetId: Caip19AssetId,\n ): AssetMetadata | undefined {\n try {\n const parsed = parseCaipAssetType(assetId);\n if (parsed.assetNamespace !== 'erc20') {\n return undefined;\n }\n const tokenAddress = parsed.assetReference;\n const { reference } = parseCaipChainId(parsed.chainId);\n const hexChainId = numberToHex(parseInt(reference, 10));\n\n const tokenListState = this.#messenger.call(\n 'TokenListController:getState',\n );\n const chainCacheEntry = tokenListState?.tokensChainsCache?.[hexChainId];\n const chainTokenList = chainCacheEntry?.data;\n\n if (!chainTokenList) {\n return undefined;\n }\n\n // Look up token by address (case-insensitive)\n const lowerAddress = tokenAddress.toLowerCase();\n for (const [address, tokenData] of Object.entries(chainTokenList)) {\n if (address.toLowerCase() === lowerAddress) {\n const token = tokenData;\n if (token.symbol && token.decimals !== undefined) {\n return {\n type: 'erc20',\n symbol: token.symbol,\n name: token.name ?? token.symbol,\n decimals: token.decimals,\n image: token.iconUrl,\n };\n }\n }\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Destroy the data source and clean up resources.\n */\n destroy(): void {\n log('Destroying RpcDataSource');\n\n this.#unsubscribeTransactionConfirmed?.();\n this.#unsubscribeIncomingTransactions?.();\n\n // Stop all polling\n this.#balanceFetcher.stopAllPolling();\n this.#tokenDetector.stopAllPolling();\n\n // Clear subscriptions\n this.#activeSubscriptions.clear();\n\n // Clear caches\n this.#providerCache.clear();\n }\n}\n\nexport function createRpcDataSource(\n options: RpcDataSourceOptions,\n): RpcDataSource {\n return new RpcDataSource(options);\n}\n"]}
@@ -120,12 +120,11 @@ class SnapDataSource extends AbstractDataSource_1.AbstractDataSource {
120
120
  return {};
121
121
  }
122
122
  if (!request?.accountsWithSupportedChains?.length) {
123
- return { assetsBalance: {}, assetsInfo: {}, updateMode: 'full' };
123
+ return { assetsBalance: {}, assetsInfo: {} };
124
124
  }
125
125
  const results = {
126
126
  assetsBalance: {},
127
127
  assetsInfo: {},
128
- updateMode: 'full',
129
128
  };
130
129
  // Fetch balances for each account using its snap ID from metadata
131
130
  for (const { account } of request.accountsWithSupportedChains) {
@@ -376,7 +375,7 @@ _SnapDataSource_messenger = new WeakMap(), _SnapDataSource_onActiveChainsUpdated
376
375
  }
377
376
  // Only report if we have snap-related updates
378
377
  if (assetsBalance) {
379
- const response = { assetsBalance, updateMode: 'merge' };
378
+ const response = { assetsBalance };
380
379
  for (const subscription of this.activeSubscriptions.values()) {
381
380
  subscription.onAssetsUpdate(response)?.catch(console.error);
382
381
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SnapDataSource.cjs","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,uEAA8D;AAa9D,uDAAoE;AACpE,2CAAqD;AAGrD,iEAA0D;AAM1D,0CAA8D;AAqC9D,MAAM,GAAG,GAAG,IAAA,2BAAkB,EAAC,sBAAa,EAAE,gBAAgB,CAAC,CAAC;AAEhE,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAElE,QAAA,qBAAqB,GAAG,gBAAgB,CAAC;AAEtD,qDAAqD;AACxC,QAAA,kBAAkB,GAAG,mBAAmB,CAAC;AAEtD,wEAAwE;AAC3D,QAAA,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAC/B,UAAiC;IAEjC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CACpC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,4BAAc,CAAC,QAAQ,CACpB,CAAC;IAE1C,OAAO,MAAM,CAAC,CAAC,CAAE,MAAM,CAAC,KAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAZD,8CAYC;AAED;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,OAAe;IACrD,MAAM,MAAM,GAAG,IAAA,0BAAkB,EAAC,OAAwB,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAHD,0DAGC;AAkBD,MAAM,gBAAgB,GAAwB;IAC5C,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,EAAE;CAChB,CAAC;AAuCF,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAa,cAAe,SAAQ,uCAGnC;IAmBC,YAAY,OAA8B;QACxC,KAAK,CAAC,6BAAqB,EAAE;YAC3B,GAAG,gBAAgB;YACnB,GAAG,OAAO,CAAC,KAAK;SACjB,CAAC,CAAC;;QAtBI,4CAAsC;QAEtC,wDAIC;QAEV,yEAAyE;QAChE,iEAEC;QAED,mEAA8C;QAEvD,6EAA6E;QACpE,6CAAkD,IAAI,GAAG,EAAE,EAAC;QAQnE,uBAAA,IAAI,6BAAc,OAAO,CAAC,SAAS,MAAA,CAAC;QACpC,uBAAA,IAAI,yCAA0B,OAAO,CAAC,qBAAqB,MAAA,CAAC;QAE5D,yCAAyC;QACzC,uBAAA,IAAI,kDAAmC,uBAAA,IAAI,4EAA2B,CAAC,IAAI,CACzE,IAAI,CACoD,MAAA,CAAC;QAC3D,uBAAA,IAAI,oDACF,uBAAA,IAAI,uEAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAA,CAAC;QAExC,uBAAA,IAAI,oEAAmB,MAAvB,IAAI,CAAqB,CAAC;QAE1B,uEAAuE;QACvE,uBAAA,IAAI,uEAAsB,MAA1B,IAAI,CAAwB,CAAC;IAC/B,CAAC;IAgMD,+EAA+E;IAC/E,QAAQ;IACR,+EAA+E;IAE/E,KAAK,CAAC,KAAK,CAAC,OAAoB;;QAC9B,kCAAkC;QAClC,gFAAgF;QAChF,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,2BAA2B,EAAE,MAAM,EAAE,CAAC;YAClD,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QACnE,CAAC;QAED,MAAM,OAAO,GAAiB;YAC5B,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,MAAM;SACnB,CAAC;QAEF,kEAAkE;QAClE,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,OAAO,CAAC,2BAA2B,EAAE,CAAC;YAC9D,0DAA0D;YAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,SAAS;YACX,CAAC;YAED,uEAAuE;YACvE,MAAM,2BAA2B,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CACvD,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,MAAM,CACxD,CAAC;YACF,IAAI,CAAC,2BAA2B,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,EAAmB,MAAM,CAAC,CAAC;gBAE9C,kDAAkD;gBAClD,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAEhE,qCAAqC;gBACrC,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjD,SAAS;gBACX,CAAC;gBAED,iDAAiD;gBACjD,MAAM,QAAQ,GACZ,MAAM,MAAM,CAAC,kBAAkB,CAC7B,SAAS,EACT,aAAgC,CACjC,CAAC;gBAEJ,oDAAoD;gBACpD,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;oBACtE,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC1D,MAAA,OAAO,CAAC,aAAa,EAAC,SAAS,SAAT,SAAS,IAAM,EAAE,EAAC;wBACxC,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;wBACzD,IAAI,eAAe,EAAE,CAAC;4BACnB,eAA2C,CAAC,OAAO,CAAC,GAAG;gCACtD,MAAM,EAAE,OAAO,CAAC,MAAM;6BACvB,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,oDAAoD;YACtD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+EAA+E;IAC/E,aAAa;IACb,+EAA+E;IAE/E;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB;QAClB,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;;YAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;YAE5B,6CAA6C;YAC7C,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1D,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC1C,CAAC;YAEF,2DAA2D;YAC3D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,yBAAyB,GAAc,EAAE,CAAC;YAE9C,IAAI,CAAC;gBACH,6BAA6B;gBAC7B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;oBAChC,GAAG,OAAO;oBACV,QAAQ,EAAE,eAAe;iBAC1B,CAAC,CAAC;gBAEH,8BAA8B;gBAC9B,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;oBAC3B,MAAA,OAAO,CAAC,QAAQ,EAAC,aAAa,QAAb,aAAa,GAAK,EAAE,EAAC;oBACtC,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CACvD,QAAQ,CAAC,aAAa,CACvB,EAAE,CAAC;wBACF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG;4BAC1C,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;4BAC5C,GAAG,eAAe;yBACnB,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;oBACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,GAAG;wBAC5B,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU;wBAC9B,GAAG,QAAQ,CAAC,UAAU;qBACvB,CAAC;gBACJ,CAAC;gBACD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG;wBAC7B,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW;wBAC/B,GAAG,QAAQ,CAAC,WAAW;qBACxB,CAAC;gBACJ,CAAC;gBAED,yDAAyD;gBACzD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;gBACjE,yBAAyB,GAAG,eAAe,CAAC,MAAM,CAChD,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CACxC,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC1C,yBAAyB,GAAG,EAAE,CAAC;YACjC,CAAC;YAED,sCAAsC;YACtC,IAAI,WAAW,GAAG,OAAO,CAAC;YAC1B,IAAI,yBAAyB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzC,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAC7C,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,yBAAyB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC1D,CAAC;gBACF,WAAW,GAAG;oBACZ,GAAG,OAAO;oBACV,OAAO,EAAE;wBACP,GAAG,OAAO;wBACV,QAAQ,EAAE,eAAe;qBAC1B;iBACF,CAAC;YACJ,CAAC;YAED,uBAAuB;YACvB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,4CAA4C;IAC5C,+EAA+E;IAE/E,KAAK,CAAC,SAAS,CAAC,mBAAwC;QACtD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC;QAElE,8CAA8C;QAC9C,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,sCAAsC;QACtC,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1D,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,OAAO,CAAC,CACtC,CAAC;QAEF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC9D,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,MAAM,GAAG,eAAe,CAAC;gBAClC,uDAAuD;gBACvD,IAAI,CAAC,KAAK,CAAC;oBACT,GAAG,OAAO;oBACV,QAAQ,EAAE,eAAe;iBAC1B,CAAC;qBACC,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;oBAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC9D,MAAM,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;oBAC/C,CAAC;oBACD,OAAO,aAAa,CAAC;gBACvB,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,GAAG,CAAC,kCAAkC,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;gBACrE,CAAC,CAAC,CAAC;gBACL,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAEvC,gFAAgF;QAChF,iEAAiE;QACjE,sEAAsE;QAEtE,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,EAAE;YAC3C,OAAO,EAAE,GAAG,EAAE;gBACZ,iDAAiD;YACnD,CAAC;YACD,MAAM,EAAE,eAAe;YACvB,cAAc,EAAE,mBAAmB,CAAC,cAAc;SACnD,CAAC,CAAC;QAEH,wCAAwC;QACxC,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;gBACrC,GAAG,OAAO;gBACV,QAAQ,EAAE,eAAe;aAC1B,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAClE,IACE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;gBACzD,YAAY,EACZ,CAAC;gBACD,MAAM,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,sBAAsB,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAqCD,+EAA+E;IAC/E,UAAU;IACV,+EAA+E;IAE/E,OAAO;QACL,8DAA8D;QAC9D,MAAM,SAAS,GAAG,uBAAA,IAAI,iCAAkB,CAAC;QAEzC,uCAAuC;QACvC,IAAI,CAAC;YACH,SAAS,CAAC,WAAW,CACnB,2CAA2C,EAC3C,uBAAA,IAAI,sDAAgC,CACrC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,gDAAgD,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC;YACH,SAAS,CAAC,WAAW,CACnB,kCAAkC,EAClC,uBAAA,IAAI,wDAAkC,CACvC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,+CAA+C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,CAAC;QAED,gCAAgC;QAChC,KAAK,MAAM,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACxD,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC1C,wBAAwB;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,6BAA6B;QAC7B,uBAAA,IAAI,0CAAoB,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC;CACF;AAviBD,wCAuiBC;;IAtfG,2FAA2F;IAC3F,8DAA8D;IAC9D,MAAM,SAAS,GAAG,uBAAA,IAAI,iCAAkB,CAAC;IACzC,SAAS,CAAC,SAAS,CACjB,2CAA2C,EAC3C,uBAAA,IAAI,sDAAgC,CACrC,CAAC;IACF,SAAS,CAAC,SAAS,CACjB,kCAAkC,EAClC,uBAAA,IAAI,wDAAkC,CACvC,CAAC;AACJ,CAAC,iGASC,OAA2C;IAE3C,4DAA4D;IAC5D,IAAI,aAAqE,CAAC;IAE1E,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnE,IAAI,aAA8D,CAAC;QAEnE,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,IAAI,OAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,8CAA8C,EAAE;oBAClD,OAAO;oBACP,KAAK;iBACN,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,IAAI,uBAAA,IAAI,yEAAwB,MAA5B,IAAI,EAAyB,OAAO,CAAC,EAAE,CAAC;gBAC1C,aAAa,KAAb,aAAa,GAAK,EAAE,EAAC;gBACrB,aAAa,CAAC,OAAwB,CAAC,GAAG;oBACxC,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,KAAb,aAAa,GAAK,EAAE,EAAC;YACrB,aAAa,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QACtE,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7D,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;AACH,CAAC,2FAQuB,OAAgB;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC;IAaC,IAAI,CAAC;QACH,8DAA8D;QAC9D,OAAQ,uBAAA,IAAI,iCAAmB,CAAC,IAAI,CAClC,iCAAiC,CACxB,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QAC3C,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,mFASC,MAAc;IAEd,IAAI,CAAC;QACH,8DAA8D;QAC9D,OAAQ,uBAAA,IAAI,iCAAmB,CAAC,IAAI,CAClC,qCAAqC,EACrC,MAAM,CACqC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,oCAAoC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;IAkBC,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,uBAAA,IAAI,mEAAkB,MAAtB,IAAI,CAAoB,CAAC;QAC/C,MAAM,WAAW,GAA4B,EAAE,CAAC;QAChD,MAAM,eAAe,GAAc,EAAE,CAAC;QAEtC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,WAAW,GAAG,uBAAA,IAAI,qEAAoB,MAAxB,IAAI,EAAqB,IAAI,CAAC,EAAE,CAAC,CAAC;YACtD,8DAA8D;YAC9D,IAAI,CAAC,WAAW,EAAE,CAAC,0BAAkB,CAAC,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,0EAA0E;YAC1E,8CAA8C;YAC9C,MAAM,gBAAgB,GAAG,WAAW,CAAC,yBAAiB,CAAC,CAAC;YACxD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;YAErD,+EAA+E;YAC/E,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,IAAI,CAAC,CAAC,OAAO,IAAI,WAAW,CAAC,EAAE,CAAC;wBAC9B,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;wBAC/B,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAChC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;QAErC,2BAA2B;QAC3B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC9C,IAAI,CAAC,kBAAkB,CAAC,eAAe,EAAE,CAAC,aAAa,EAAE,EAAE;gBACzD,uBAAA,IAAI,6CAAuB,MAA3B,IAAI,EAAwB,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,+BAA+B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC9C,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,CAAC,aAAa,EAAE,EAAE;gBAC5C,uBAAA,IAAI,6CAAuB,MAA3B,IAAI,EAAwB,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;AACH,CAAC,+EAiQiB,MAAc;IAC9B,MAAM,YAAY,GAAG,uBAAA,IAAI,0CAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,mCAAa,CAAC;QAC/B,IAAI,EAAE,KAAK,EAAE,OAAuB,EAAiB,EAAE,CACrD,MACE,uBAAA,IAAI,iCAGL,CAAC,IAAI,CAAC,8BAA8B,EAAE;YACrC,MAAM,EAAE,MAAgB;YACxB,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,yBAAW,CAAC,gBAAgB;YACrC,OAAO;SACR,CAAC;KACL,CAAC,CAAC;IAEH,uBAAA,IAAI,0CAAoB,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AA0CH,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,SAAgB,oBAAoB,CAClC,OAA8B;IAE9B,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAJD,oDAIC","sourcesContent":["import type { Balance, CaipAssetType } from '@metamask/keyring-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type {\n Caveat,\n GetPermissions,\n PermissionConstraint,\n PermissionControllerStateChange,\n SubjectPermissions,\n} from '@metamask/permission-controller';\nimport type {\n GetRunnableSnaps,\n HandleSnapRequest,\n} from '@metamask/snaps-controllers';\nimport type { Snap, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType, SnapCaveatType } from '@metamask/snaps-utils';\nimport { parseCaipAssetType } from '@metamask/utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { AbstractDataSource } from './AbstractDataSource';\nimport type {\n DataSourceState,\n SubscriptionRequest,\n} from './AbstractDataSource';\nimport type { AssetsControllerMessenger } from '../AssetsController';\nimport { projectLogger, createModuleLogger } from '../logger';\nimport type {\n AssetBalance,\n ChainId,\n Caip19AssetId,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\n\n// ============================================================================\n// SNAP KEYRING EVENT TYPES\n// ============================================================================\n\n/**\n * Payload for AccountsController:accountBalancesUpdated event.\n * Re-published from SnapKeyring:accountBalancesUpdated.\n */\nexport type AccountBalancesUpdatedEventPayload = {\n balances: {\n [accountId: string]: {\n [assetId: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Event from AccountsController when snap balances are updated.\n */\nexport type AccountsControllerAccountBalancesUpdatedEvent = {\n type: 'AccountsController:accountBalancesUpdated';\n payload: [AccountBalancesUpdatedEventPayload];\n};\n\nconst log = createModuleLogger(projectLogger, 'SnapDataSource');\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nexport const SNAP_DATA_SOURCE_NAME = 'SnapDataSource';\n\n/** The permission name for snap keyring endowment */\nexport const KEYRING_PERMISSION = 'endowment:keyring';\n\n/** The permission name for snap assets endowment (contains chainIds) */\nexport const ASSETS_PERMISSION = 'endowment:assets';\n\n// ============================================================================\n// PERMISSION UTILITIES\n// ============================================================================\n\n/**\n * Getter function to get the chainIds caveat from a permission.\n *\n * This does basic validation of the caveat, but does not validate the type or\n * value of the namespaces object itself, as this is handled by the\n * `PermissionsController` when the permission is requested.\n *\n * @param permission - The permission to get the `chainIds` caveat from.\n * @returns An array of `chainIds` that the snap supports, or null if none.\n */\nexport function getChainIdsCaveat(\n permission?: PermissionConstraint,\n): ChainId[] | null {\n if (!permission?.caveats) {\n return null;\n }\n\n const caveat = permission.caveats.find(\n (permCaveat) => permCaveat.type === SnapCaveatType.ChainIds,\n ) as Caveat<string, string[]> | undefined;\n\n return caveat ? (caveat.value as ChainId[]) : null;\n}\n\n/**\n * Extracts the CAIP-2 chain ID from a CAIP-19 asset ID.\n * e.g., \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501\" -> \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n * Uses @metamask/utils parseCaipAssetType for CAIP parsing.\n *\n * @param assetId - The CAIP-19 asset ID to extract chain from.\n * @returns The CAIP-2 chain ID portion of the asset ID.\n */\nexport function extractChainFromAssetId(assetId: string): ChainId {\n const parsed = parseCaipAssetType(assetId as CaipAssetType);\n return parsed.chainId;\n}\n\n// ============================================================================\n// STATE\n// ============================================================================\n\n/**\n * State for the SnapDataSource.\n * Uses dynamic snap discovery - chains are populated from PermissionController.\n */\nexport type SnapDataSourceState = {\n /**\n * Mapping of chain IDs to snap IDs that support them.\n * Used to filter which accounts to process for a given chain request.\n */\n chainToSnap: Record<ChainId, string>;\n} & DataSourceState;\n\nconst defaultSnapState: SnapDataSourceState = {\n activeChains: [],\n chainToSnap: {},\n};\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\n/**\n * Allowed events that SnapDataSource can subscribe to.\n */\nexport type SnapDataSourceAllowedEvents =\n | AccountsControllerAccountBalancesUpdatedEvent\n | PermissionControllerStateChange;\n\nexport type SnapDataSourceAllowedActions =\n | GetRunnableSnaps\n | HandleSnapRequest\n | GetPermissions;\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type SnapDataSourceOptions = {\n /** The AssetsController messenger (shared by all data sources). */\n messenger: AssetsControllerMessenger;\n /** Called when this data source's active chains change. Pass dataSourceName so the controller knows the source. */\n onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n /** Configured networks to support (defaults to all snap networks) */\n configuredNetworks?: ChainId[];\n /** Default polling interval in ms for subscriptions */\n pollInterval?: number;\n /** Initial state */\n state?: Partial<SnapDataSourceState>;\n};\n\n// ============================================================================\n// SNAP DATA SOURCE\n// ============================================================================\n\n/**\n * Unified Snap data source that routes requests to the appropriate wallet snap\n * based on the chain ID prefix.\n *\n * @example\n * ```typescript\n * const snapDataSource = new SnapDataSource({\n * messenger,\n * onActiveChainsUpdated: (chains) => { /* ... *\\/ },\n * });\n *\n * // Fetch will automatically route to the correct snap\n * await snapDataSource.fetch({\n * chainIds: ['solana:mainnet', 'bip122:000000000019d6689c085ae165831e93'],\n * accountIds: ['account1'],\n * });\n * ```\n */\nexport class SnapDataSource extends AbstractDataSource<\n typeof SNAP_DATA_SOURCE_NAME,\n SnapDataSourceState\n> {\n readonly #messenger: AssetsControllerMessenger;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n /** Bound handler for snap keyring balance updates, stored for cleanup */\n readonly #handleSnapBalancesUpdatedBound: (\n payload: AccountBalancesUpdatedEventPayload,\n ) => void;\n\n readonly #handlePermissionStateChangeBound: () => void;\n\n /** Cache of KeyringClient instances per snap ID to avoid re-instantiation */\n readonly #keyringClientCache: Map<string, KeyringClient> = new Map();\n\n constructor(options: SnapDataSourceOptions) {\n super(SNAP_DATA_SOURCE_NAME, {\n ...defaultSnapState,\n ...options.state,\n });\n\n this.#messenger = options.messenger;\n this.#onActiveChainsUpdated = options.onActiveChainsUpdated;\n\n // Bind handlers for cleanup in destroy()\n this.#handleSnapBalancesUpdatedBound = this.#handleSnapBalancesUpdated.bind(\n this,\n ) as (payload: AccountBalancesUpdatedEventPayload) => void;\n this.#handlePermissionStateChangeBound =\n this.#discoverKeyringSnaps.bind(this);\n\n this.#subscribeToEvents();\n\n // Discover keyring-capable snaps and populate activeChains dynamically\n this.#discoverKeyringSnaps();\n }\n\n /**\n * Subscribe to all events needed by SnapDataSource.\n * Groups snap keyring events and permission change events.\n */\n #subscribeToEvents(): void {\n // Subscribe to snap keyring events and permission changes (not in AssetsControllerEvents).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const messenger = this.#messenger as any;\n messenger.subscribe(\n 'AccountsController:accountBalancesUpdated',\n this.#handleSnapBalancesUpdatedBound,\n );\n messenger.subscribe(\n 'PermissionController:stateChange',\n this.#handlePermissionStateChangeBound,\n );\n }\n\n /**\n * Handle snap balance updates from the keyring.\n * Transforms the payload and publishes to AssetsController.\n *\n * @param payload - The balance update payload from AccountsController.\n */\n #handleSnapBalancesUpdated(\n payload: AccountBalancesUpdatedEventPayload,\n ): void {\n // Transform the snap keyring payload to DataResponse format\n let assetsBalance: NonNullable<DataResponse['assetsBalance']> | undefined;\n\n for (const [accountId, assets] of Object.entries(payload.balances)) {\n let accountAssets: Record<Caip19AssetId, AssetBalance> | undefined;\n\n for (const [assetId, balance] of Object.entries(assets)) {\n let chainId: ChainId;\n try {\n chainId = extractChainFromAssetId(assetId);\n } catch (error) {\n log('Skipping snap balance for malformed asset ID', {\n assetId,\n error,\n });\n continue;\n }\n if (this.#isChainSupportedBySnap(chainId)) {\n accountAssets ??= {};\n accountAssets[assetId as Caip19AssetId] = {\n amount: balance.amount,\n };\n }\n }\n\n if (accountAssets) {\n assetsBalance ??= {};\n assetsBalance[accountId] = accountAssets;\n }\n }\n\n // Only report if we have snap-related updates\n if (assetsBalance) {\n const response: DataResponse = { assetsBalance, updateMode: 'merge' };\n for (const subscription of this.activeSubscriptions.values()) {\n subscription.onAssetsUpdate(response)?.catch(console.error);\n }\n }\n }\n\n /**\n * Check if a chain ID is supported by any discovered snap.\n *\n * @param chainId - The CAIP-2 chain ID to check.\n * @returns True if we have a snap that supports this chain.\n */\n #isChainSupportedBySnap(chainId: ChainId): boolean {\n return this.state.activeChains.includes(chainId);\n }\n\n // ============================================================================\n // SNAP DISCOVERY (Dynamic via PermissionController)\n // ============================================================================\n\n /**\n * Get all runnable snaps from SnapController.\n * Runnable snaps are enabled and not blocked.\n *\n * @returns Array of runnable snaps.\n */\n #getRunnableSnaps(): Snap[] {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (this.#messenger as any).call(\n 'SnapController:getRunnableSnaps',\n ) as Snap[];\n } catch (error) {\n log('Failed to get runnable snaps', error);\n return [];\n }\n }\n\n /**\n * Get permissions for a snap from PermissionController.\n *\n * @param snapId - The snap ID to get permissions for.\n * @returns The snap's permissions, or undefined if none.\n */\n #getSnapPermissions(\n snapId: string,\n ): SubjectPermissions<PermissionConstraint> | undefined {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (this.#messenger as any).call(\n 'PermissionController:getPermissions',\n snapId,\n ) as SubjectPermissions<PermissionConstraint>;\n } catch (error) {\n log('Failed to get permissions for snap', { snapId, error });\n return undefined;\n }\n }\n\n /**\n * Discover all snaps with keyring capabilities and their supported chains.\n * Uses PermissionController to find snaps with endowment:keyring permission.\n * Updates chainToSnap mapping and activeChains.\n *\n * Called on initialization and whenever PermissionController state changes\n * (e.g., new snaps installed, permissions granted/revoked).\n *\n * @remarks\n * **Known limitation:** If discovery fails (e.g., SnapController not ready),\n * the data source continues with empty chainToSnap. This means no snap\n * chains will be supported until a re-discovery is triggered by a permission\n * change. Callers should be aware that initialization may complete with no\n * active chains.\n */\n #discoverKeyringSnaps(): void {\n try {\n const runnableSnaps = this.#getRunnableSnaps();\n const chainToSnap: Record<ChainId, string> = {};\n const supportedChains: ChainId[] = [];\n\n for (const snap of runnableSnaps) {\n const permissions = this.#getSnapPermissions(snap.id);\n // Must have endowment:keyring permission to be a keyring snap\n if (!permissions?.[KEYRING_PERMISSION]) {\n continue;\n }\n\n // Get chainIds caveat from the assets permission (not keyring permission)\n // The chainIds are stored in endowment:assets\n const assetsPermission = permissions[ASSETS_PERMISSION];\n const chainIds = getChainIdsCaveat(assetsPermission);\n\n // Map each chain to this snap (first snap wins if multiple support same chain)\n if (chainIds) {\n for (const chainId of chainIds) {\n if (!(chainId in chainToSnap)) {\n chainToSnap[chainId] = snap.id;\n supportedChains.push(chainId);\n }\n }\n }\n }\n\n // Update chainToSnap mapping\n this.state.chainToSnap = chainToSnap;\n\n // Notify if chains changed\n try {\n const previous = [...this.state.activeChains];\n this.updateActiveChains(supportedChains, (updatedChains) => {\n this.#onActiveChainsUpdated(this.getName(), updatedChains, previous);\n });\n } catch {\n // AssetsController not ready yet - expected during initialization\n }\n } catch (error) {\n log('Keyring snap discovery failed', { error });\n this.state.chainToSnap = {};\n try {\n const previous = [...this.state.activeChains];\n this.updateActiveChains([], (updatedChains) => {\n this.#onActiveChainsUpdated(this.getName(), updatedChains, previous);\n });\n } catch {\n // AssetsController not ready yet - expected during initialization\n }\n }\n }\n\n // ============================================================================\n // FETCH\n // ============================================================================\n\n async fetch(request: DataRequest): Promise<DataResponse> {\n // Guard against undefined request\n // Note: chainIds filtering is done by middleware/subscribe before calling fetch\n if (!request?.chainIds?.length) {\n return {};\n }\n if (!request?.accountsWithSupportedChains?.length) {\n return { assetsBalance: {}, assetsInfo: {}, updateMode: 'full' };\n }\n\n const results: DataResponse = {\n assetsBalance: {},\n assetsInfo: {},\n updateMode: 'full',\n };\n\n // Fetch balances for each account using its snap ID from metadata\n for (const { account } of request.accountsWithSupportedChains) {\n // Skip accounts without snap metadata (non-snap accounts)\n const snapId = account.metadata.snap?.id;\n if (!snapId) {\n continue;\n }\n\n // Skip accounts whose snap doesn't support any of the requested chains\n const snapSupportsRequestedChains = request.chainIds.some(\n (chainId) => this.state.chainToSnap[chainId] === snapId,\n );\n if (!snapSupportsRequestedChains) {\n continue;\n }\n\n const accountId = account.id;\n try {\n const client = this.#getKeyringClient(snapId);\n\n // Step 1: Get the list of assets for this account\n const accountAssets = await client.listAccountAssets(accountId);\n\n // If no assets, skip to next account\n if (!accountAssets || accountAssets.length === 0) {\n continue;\n }\n\n // Step 2: Get balances for those specific assets\n const balances: Record<CaipAssetType, Balance> =\n await client.getAccountBalances(\n accountId,\n accountAssets as CaipAssetType[],\n );\n\n // Transform keyring response to DataResponse format\n if (balances && typeof balances === 'object' && results.assetsBalance) {\n for (const [assetId, balance] of Object.entries(balances)) {\n results.assetsBalance[accountId] ??= {};\n const accountBalances = results.assetsBalance[accountId];\n if (accountBalances) {\n (accountBalances as Record<string, unknown>)[assetId] = {\n amount: balance.amount,\n };\n }\n }\n }\n } catch {\n // Expected when account doesn't belong to this snap\n }\n }\n\n return results;\n }\n\n // ============================================================================\n // MIDDLEWARE\n // ============================================================================\n\n /**\n * Get the middleware for fetching balances via Snaps.\n * This middleware:\n * - Supports multiple accounts in a single request\n * - Filters request to only chains this data source supports\n * - Fetches balances for those chains for all accounts\n * - Merges response into context\n * - Removes handled chains from request for next middleware\n *\n * @returns The middleware function for the assets pipeline.\n */\n get assetsMiddleware(): Middleware {\n return async (context, next) => {\n const { request } = context;\n\n // Filter to chains this data source supports\n const supportedChains = request.chainIds.filter((chainId) =>\n this.state.activeChains.includes(chainId),\n );\n\n // If no supported chains, skip and pass to next middleware\n if (supportedChains.length === 0) {\n return next(context);\n }\n\n let successfullyHandledChains: ChainId[] = [];\n\n try {\n // Fetch for supported chains\n const response = await this.fetch({\n ...request,\n chainIds: supportedChains,\n });\n\n // Merge response into context\n if (response.assetsBalance) {\n context.response.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n context.response.assetsBalance[accountId] = {\n ...context.response.assetsBalance[accountId],\n ...accountBalances,\n };\n }\n }\n if (response.assetsInfo) {\n context.response.assetsInfo = {\n ...context.response.assetsInfo,\n ...response.assetsInfo,\n };\n }\n if (response.assetsPrice) {\n context.response.assetsPrice = {\n ...context.response.assetsPrice,\n ...response.assetsPrice,\n };\n }\n\n // Determine successfully handled chains (exclude errors)\n const failedChains = new Set(Object.keys(response.errors ?? {}));\n successfullyHandledChains = supportedChains.filter(\n (chainId) => !failedChains.has(chainId),\n );\n } catch (error) {\n log('Middleware fetch failed', { error });\n successfullyHandledChains = [];\n }\n\n // Prepare context for next middleware\n let nextContext = context;\n if (successfullyHandledChains.length > 0) {\n const remainingChains = request.chainIds.filter(\n (chainId) => !successfullyHandledChains.includes(chainId),\n );\n nextContext = {\n ...context,\n request: {\n ...request,\n chainIds: remainingChains,\n },\n };\n }\n\n // Call next middleware\n return next(nextContext);\n };\n }\n\n // ============================================================================\n // SUBSCRIBE - Routes to appropriate snap(s)\n // ============================================================================\n\n async subscribe(subscriptionRequest: SubscriptionRequest): Promise<void> {\n const { request, subscriptionId, isUpdate } = subscriptionRequest;\n\n // Guard against undefined request or chainIds\n if (!request?.chainIds) {\n return;\n }\n\n // Filter to chains we have a snap for\n const supportedChains = request.chainIds.filter((chainId) =>\n this.#isChainSupportedBySnap(chainId),\n );\n\n if (supportedChains.length === 0) {\n return;\n }\n\n if (isUpdate) {\n const existing = this.activeSubscriptions.get(subscriptionId);\n if (existing) {\n existing.chains = supportedChains;\n // Do a fetch to get latest data on subscription update\n this.fetch({\n ...request,\n chainIds: supportedChains,\n })\n .then(async (fetchResponse) => {\n if (Object.keys(fetchResponse.assetsBalance ?? {}).length > 0) {\n await existing.onAssetsUpdate(fetchResponse);\n }\n return fetchResponse;\n })\n .catch((error) => {\n log('Subscription update fetch failed', { subscriptionId, error });\n });\n return;\n }\n }\n\n await this.unsubscribe(subscriptionId);\n\n // Snaps provide real-time updates via AccountsController:accountBalancesUpdated\n // We only need to track the subscription and do an initial fetch\n // No polling needed - updates come through #handleSnapBalancesUpdated\n\n this.activeSubscriptions.set(subscriptionId, {\n cleanup: () => {\n // No timer to clear - we use event-based updates\n },\n chains: supportedChains,\n onAssetsUpdate: subscriptionRequest.onAssetsUpdate,\n });\n\n // Initial fetch to get current balances\n try {\n const fetchResponse = await this.fetch({\n ...request,\n chainIds: supportedChains,\n });\n\n const subscription = this.activeSubscriptions.get(subscriptionId);\n if (\n Object.keys(fetchResponse.assetsBalance ?? {}).length > 0 &&\n subscription\n ) {\n await subscription.onAssetsUpdate(fetchResponse);\n }\n } catch (error) {\n log('Initial fetch failed', { subscriptionId, error });\n }\n }\n\n // ============================================================================\n // KEYRING CLIENT\n // ============================================================================\n\n /**\n * Gets a `KeyringClient` for a Snap.\n * Caches clients per snap ID to avoid re-instantiation across multiple calls.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getKeyringClient(snapId: string): KeyringClient {\n const cachedClient = this.#keyringClientCache.get(snapId);\n if (cachedClient) {\n return cachedClient;\n }\n\n const client = new KeyringClient({\n send: async (request: JsonRpcRequest): Promise<Json> =>\n await (\n this.#messenger as unknown as {\n call: (action: string, ...args: unknown[]) => Promise<Json> | Json;\n }\n ).call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n }),\n });\n\n this.#keyringClientCache.set(snapId, client);\n return client;\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const messenger = this.#messenger as any;\n\n // Unsubscribe from snap keyring events\n try {\n messenger.unsubscribe(\n 'AccountsController:accountBalancesUpdated',\n this.#handleSnapBalancesUpdatedBound,\n );\n } catch (error) {\n log('Failed to unsubscribe from snap keyring events', { error });\n }\n\n // Unsubscribe from permission changes\n try {\n messenger.unsubscribe(\n 'PermissionController:stateChange',\n this.#handlePermissionStateChangeBound,\n );\n } catch (error) {\n log('Failed to unsubscribe from permission changes', { error });\n }\n\n // Clean up active subscriptions\n for (const [subscriptionId] of this.activeSubscriptions) {\n this.unsubscribe(subscriptionId).catch(() => {\n // Ignore cleanup errors\n });\n }\n\n // Clear keyring client cache\n this.#keyringClientCache.clear();\n }\n}\n\n// ============================================================================\n// FACTORY\n// ============================================================================\n\nexport function createSnapDataSource(\n options: SnapDataSourceOptions,\n): SnapDataSource {\n return new SnapDataSource(options);\n}\n"]}
1
+ {"version":3,"file":"SnapDataSource.cjs","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Balance, CaipAssetType } from '@metamask/keyring-api';\nimport { KeyringClient } from '@metamask/keyring-snap-client';\nimport type {\n Caveat,\n GetPermissions,\n PermissionConstraint,\n PermissionControllerStateChange,\n SubjectPermissions,\n} from '@metamask/permission-controller';\nimport type {\n GetRunnableSnaps,\n HandleSnapRequest,\n} from '@metamask/snaps-controllers';\nimport type { Snap, SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType, SnapCaveatType } from '@metamask/snaps-utils';\nimport { parseCaipAssetType } from '@metamask/utils';\nimport type { Json, JsonRpcRequest } from '@metamask/utils';\n\nimport { AbstractDataSource } from './AbstractDataSource';\nimport type {\n DataSourceState,\n SubscriptionRequest,\n} from './AbstractDataSource';\nimport type { AssetsControllerMessenger } from '../AssetsController';\nimport { projectLogger, createModuleLogger } from '../logger';\nimport type {\n AssetBalance,\n ChainId,\n Caip19AssetId,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\n\n// ============================================================================\n// SNAP KEYRING EVENT TYPES\n// ============================================================================\n\n/**\n * Payload for AccountsController:accountBalancesUpdated event.\n * Re-published from SnapKeyring:accountBalancesUpdated.\n */\nexport type AccountBalancesUpdatedEventPayload = {\n balances: {\n [accountId: string]: {\n [assetId: string]: {\n amount: string;\n unit: string;\n };\n };\n };\n};\n\n/**\n * Event from AccountsController when snap balances are updated.\n */\nexport type AccountsControllerAccountBalancesUpdatedEvent = {\n type: 'AccountsController:accountBalancesUpdated';\n payload: [AccountBalancesUpdatedEventPayload];\n};\n\nconst log = createModuleLogger(projectLogger, 'SnapDataSource');\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nexport const SNAP_DATA_SOURCE_NAME = 'SnapDataSource';\n\n/** The permission name for snap keyring endowment */\nexport const KEYRING_PERMISSION = 'endowment:keyring';\n\n/** The permission name for snap assets endowment (contains chainIds) */\nexport const ASSETS_PERMISSION = 'endowment:assets';\n\n// ============================================================================\n// PERMISSION UTILITIES\n// ============================================================================\n\n/**\n * Getter function to get the chainIds caveat from a permission.\n *\n * This does basic validation of the caveat, but does not validate the type or\n * value of the namespaces object itself, as this is handled by the\n * `PermissionsController` when the permission is requested.\n *\n * @param permission - The permission to get the `chainIds` caveat from.\n * @returns An array of `chainIds` that the snap supports, or null if none.\n */\nexport function getChainIdsCaveat(\n permission?: PermissionConstraint,\n): ChainId[] | null {\n if (!permission?.caveats) {\n return null;\n }\n\n const caveat = permission.caveats.find(\n (permCaveat) => permCaveat.type === SnapCaveatType.ChainIds,\n ) as Caveat<string, string[]> | undefined;\n\n return caveat ? (caveat.value as ChainId[]) : null;\n}\n\n/**\n * Extracts the CAIP-2 chain ID from a CAIP-19 asset ID.\n * e.g., \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501\" -> \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n * Uses @metamask/utils parseCaipAssetType for CAIP parsing.\n *\n * @param assetId - The CAIP-19 asset ID to extract chain from.\n * @returns The CAIP-2 chain ID portion of the asset ID.\n */\nexport function extractChainFromAssetId(assetId: string): ChainId {\n const parsed = parseCaipAssetType(assetId as CaipAssetType);\n return parsed.chainId;\n}\n\n// ============================================================================\n// STATE\n// ============================================================================\n\n/**\n * State for the SnapDataSource.\n * Uses dynamic snap discovery - chains are populated from PermissionController.\n */\nexport type SnapDataSourceState = {\n /**\n * Mapping of chain IDs to snap IDs that support them.\n * Used to filter which accounts to process for a given chain request.\n */\n chainToSnap: Record<ChainId, string>;\n} & DataSourceState;\n\nconst defaultSnapState: SnapDataSourceState = {\n activeChains: [],\n chainToSnap: {},\n};\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\n/**\n * Allowed events that SnapDataSource can subscribe to.\n */\nexport type SnapDataSourceAllowedEvents =\n | AccountsControllerAccountBalancesUpdatedEvent\n | PermissionControllerStateChange;\n\nexport type SnapDataSourceAllowedActions =\n | GetRunnableSnaps\n | HandleSnapRequest\n | GetPermissions;\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type SnapDataSourceOptions = {\n /** The AssetsController messenger (shared by all data sources). */\n messenger: AssetsControllerMessenger;\n /** Called when this data source's active chains change. Pass dataSourceName so the controller knows the source. */\n onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n /** Configured networks to support (defaults to all snap networks) */\n configuredNetworks?: ChainId[];\n /** Default polling interval in ms for subscriptions */\n pollInterval?: number;\n /** Initial state */\n state?: Partial<SnapDataSourceState>;\n};\n\n// ============================================================================\n// SNAP DATA SOURCE\n// ============================================================================\n\n/**\n * Unified Snap data source that routes requests to the appropriate wallet snap\n * based on the chain ID prefix.\n *\n * @example\n * ```typescript\n * const snapDataSource = new SnapDataSource({\n * messenger,\n * onActiveChainsUpdated: (chains) => { /* ... *\\/ },\n * });\n *\n * // Fetch will automatically route to the correct snap\n * await snapDataSource.fetch({\n * chainIds: ['solana:mainnet', 'bip122:000000000019d6689c085ae165831e93'],\n * accountIds: ['account1'],\n * });\n * ```\n */\nexport class SnapDataSource extends AbstractDataSource<\n typeof SNAP_DATA_SOURCE_NAME,\n SnapDataSourceState\n> {\n readonly #messenger: AssetsControllerMessenger;\n\n readonly #onActiveChainsUpdated: (\n dataSourceName: string,\n chains: ChainId[],\n previousChains: ChainId[],\n ) => void;\n\n /** Bound handler for snap keyring balance updates, stored for cleanup */\n readonly #handleSnapBalancesUpdatedBound: (\n payload: AccountBalancesUpdatedEventPayload,\n ) => void;\n\n readonly #handlePermissionStateChangeBound: () => void;\n\n /** Cache of KeyringClient instances per snap ID to avoid re-instantiation */\n readonly #keyringClientCache: Map<string, KeyringClient> = new Map();\n\n constructor(options: SnapDataSourceOptions) {\n super(SNAP_DATA_SOURCE_NAME, {\n ...defaultSnapState,\n ...options.state,\n });\n\n this.#messenger = options.messenger;\n this.#onActiveChainsUpdated = options.onActiveChainsUpdated;\n\n // Bind handlers for cleanup in destroy()\n this.#handleSnapBalancesUpdatedBound = this.#handleSnapBalancesUpdated.bind(\n this,\n ) as (payload: AccountBalancesUpdatedEventPayload) => void;\n this.#handlePermissionStateChangeBound =\n this.#discoverKeyringSnaps.bind(this);\n\n this.#subscribeToEvents();\n\n // Discover keyring-capable snaps and populate activeChains dynamically\n this.#discoverKeyringSnaps();\n }\n\n /**\n * Subscribe to all events needed by SnapDataSource.\n * Groups snap keyring events and permission change events.\n */\n #subscribeToEvents(): void {\n // Subscribe to snap keyring events and permission changes (not in AssetsControllerEvents).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const messenger = this.#messenger as any;\n messenger.subscribe(\n 'AccountsController:accountBalancesUpdated',\n this.#handleSnapBalancesUpdatedBound,\n );\n messenger.subscribe(\n 'PermissionController:stateChange',\n this.#handlePermissionStateChangeBound,\n );\n }\n\n /**\n * Handle snap balance updates from the keyring.\n * Transforms the payload and publishes to AssetsController.\n *\n * @param payload - The balance update payload from AccountsController.\n */\n #handleSnapBalancesUpdated(\n payload: AccountBalancesUpdatedEventPayload,\n ): void {\n // Transform the snap keyring payload to DataResponse format\n let assetsBalance: NonNullable<DataResponse['assetsBalance']> | undefined;\n\n for (const [accountId, assets] of Object.entries(payload.balances)) {\n let accountAssets: Record<Caip19AssetId, AssetBalance> | undefined;\n\n for (const [assetId, balance] of Object.entries(assets)) {\n let chainId: ChainId;\n try {\n chainId = extractChainFromAssetId(assetId);\n } catch (error) {\n log('Skipping snap balance for malformed asset ID', {\n assetId,\n error,\n });\n continue;\n }\n if (this.#isChainSupportedBySnap(chainId)) {\n accountAssets ??= {};\n accountAssets[assetId as Caip19AssetId] = {\n amount: balance.amount,\n };\n }\n }\n\n if (accountAssets) {\n assetsBalance ??= {};\n assetsBalance[accountId] = accountAssets;\n }\n }\n\n // Only report if we have snap-related updates\n if (assetsBalance) {\n const response: DataResponse = { assetsBalance };\n for (const subscription of this.activeSubscriptions.values()) {\n subscription.onAssetsUpdate(response)?.catch(console.error);\n }\n }\n }\n\n /**\n * Check if a chain ID is supported by any discovered snap.\n *\n * @param chainId - The CAIP-2 chain ID to check.\n * @returns True if we have a snap that supports this chain.\n */\n #isChainSupportedBySnap(chainId: ChainId): boolean {\n return this.state.activeChains.includes(chainId);\n }\n\n // ============================================================================\n // SNAP DISCOVERY (Dynamic via PermissionController)\n // ============================================================================\n\n /**\n * Get all runnable snaps from SnapController.\n * Runnable snaps are enabled and not blocked.\n *\n * @returns Array of runnable snaps.\n */\n #getRunnableSnaps(): Snap[] {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (this.#messenger as any).call(\n 'SnapController:getRunnableSnaps',\n ) as Snap[];\n } catch (error) {\n log('Failed to get runnable snaps', error);\n return [];\n }\n }\n\n /**\n * Get permissions for a snap from PermissionController.\n *\n * @param snapId - The snap ID to get permissions for.\n * @returns The snap's permissions, or undefined if none.\n */\n #getSnapPermissions(\n snapId: string,\n ): SubjectPermissions<PermissionConstraint> | undefined {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (this.#messenger as any).call(\n 'PermissionController:getPermissions',\n snapId,\n ) as SubjectPermissions<PermissionConstraint>;\n } catch (error) {\n log('Failed to get permissions for snap', { snapId, error });\n return undefined;\n }\n }\n\n /**\n * Discover all snaps with keyring capabilities and their supported chains.\n * Uses PermissionController to find snaps with endowment:keyring permission.\n * Updates chainToSnap mapping and activeChains.\n *\n * Called on initialization and whenever PermissionController state changes\n * (e.g., new snaps installed, permissions granted/revoked).\n *\n * @remarks\n * **Known limitation:** If discovery fails (e.g., SnapController not ready),\n * the data source continues with empty chainToSnap. This means no snap\n * chains will be supported until a re-discovery is triggered by a permission\n * change. Callers should be aware that initialization may complete with no\n * active chains.\n */\n #discoverKeyringSnaps(): void {\n try {\n const runnableSnaps = this.#getRunnableSnaps();\n const chainToSnap: Record<ChainId, string> = {};\n const supportedChains: ChainId[] = [];\n\n for (const snap of runnableSnaps) {\n const permissions = this.#getSnapPermissions(snap.id);\n // Must have endowment:keyring permission to be a keyring snap\n if (!permissions?.[KEYRING_PERMISSION]) {\n continue;\n }\n\n // Get chainIds caveat from the assets permission (not keyring permission)\n // The chainIds are stored in endowment:assets\n const assetsPermission = permissions[ASSETS_PERMISSION];\n const chainIds = getChainIdsCaveat(assetsPermission);\n\n // Map each chain to this snap (first snap wins if multiple support same chain)\n if (chainIds) {\n for (const chainId of chainIds) {\n if (!(chainId in chainToSnap)) {\n chainToSnap[chainId] = snap.id;\n supportedChains.push(chainId);\n }\n }\n }\n }\n\n // Update chainToSnap mapping\n this.state.chainToSnap = chainToSnap;\n\n // Notify if chains changed\n try {\n const previous = [...this.state.activeChains];\n this.updateActiveChains(supportedChains, (updatedChains) => {\n this.#onActiveChainsUpdated(this.getName(), updatedChains, previous);\n });\n } catch {\n // AssetsController not ready yet - expected during initialization\n }\n } catch (error) {\n log('Keyring snap discovery failed', { error });\n this.state.chainToSnap = {};\n try {\n const previous = [...this.state.activeChains];\n this.updateActiveChains([], (updatedChains) => {\n this.#onActiveChainsUpdated(this.getName(), updatedChains, previous);\n });\n } catch {\n // AssetsController not ready yet - expected during initialization\n }\n }\n }\n\n // ============================================================================\n // FETCH\n // ============================================================================\n\n async fetch(request: DataRequest): Promise<DataResponse> {\n // Guard against undefined request\n // Note: chainIds filtering is done by middleware/subscribe before calling fetch\n if (!request?.chainIds?.length) {\n return {};\n }\n if (!request?.accountsWithSupportedChains?.length) {\n return { assetsBalance: {}, assetsInfo: {} };\n }\n\n const results: DataResponse = {\n assetsBalance: {},\n assetsInfo: {},\n };\n\n // Fetch balances for each account using its snap ID from metadata\n for (const { account } of request.accountsWithSupportedChains) {\n // Skip accounts without snap metadata (non-snap accounts)\n const snapId = account.metadata.snap?.id;\n if (!snapId) {\n continue;\n }\n\n // Skip accounts whose snap doesn't support any of the requested chains\n const snapSupportsRequestedChains = request.chainIds.some(\n (chainId) => this.state.chainToSnap[chainId] === snapId,\n );\n if (!snapSupportsRequestedChains) {\n continue;\n }\n\n const accountId = account.id;\n try {\n const client = this.#getKeyringClient(snapId);\n\n // Step 1: Get the list of assets for this account\n const accountAssets = await client.listAccountAssets(accountId);\n\n // If no assets, skip to next account\n if (!accountAssets || accountAssets.length === 0) {\n continue;\n }\n\n // Step 2: Get balances for those specific assets\n const balances: Record<CaipAssetType, Balance> =\n await client.getAccountBalances(\n accountId,\n accountAssets as CaipAssetType[],\n );\n\n // Transform keyring response to DataResponse format\n if (balances && typeof balances === 'object' && results.assetsBalance) {\n for (const [assetId, balance] of Object.entries(balances)) {\n results.assetsBalance[accountId] ??= {};\n const accountBalances = results.assetsBalance[accountId];\n if (accountBalances) {\n (accountBalances as Record<string, unknown>)[assetId] = {\n amount: balance.amount,\n };\n }\n }\n }\n } catch {\n // Expected when account doesn't belong to this snap\n }\n }\n\n return results;\n }\n\n // ============================================================================\n // MIDDLEWARE\n // ============================================================================\n\n /**\n * Get the middleware for fetching balances via Snaps.\n * This middleware:\n * - Supports multiple accounts in a single request\n * - Filters request to only chains this data source supports\n * - Fetches balances for those chains for all accounts\n * - Merges response into context\n * - Removes handled chains from request for next middleware\n *\n * @returns The middleware function for the assets pipeline.\n */\n get assetsMiddleware(): Middleware {\n return async (context, next) => {\n const { request } = context;\n\n // Filter to chains this data source supports\n const supportedChains = request.chainIds.filter((chainId) =>\n this.state.activeChains.includes(chainId),\n );\n\n // If no supported chains, skip and pass to next middleware\n if (supportedChains.length === 0) {\n return next(context);\n }\n\n let successfullyHandledChains: ChainId[] = [];\n\n try {\n // Fetch for supported chains\n const response = await this.fetch({\n ...request,\n chainIds: supportedChains,\n });\n\n // Merge response into context\n if (response.assetsBalance) {\n context.response.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n context.response.assetsBalance[accountId] = {\n ...context.response.assetsBalance[accountId],\n ...accountBalances,\n };\n }\n }\n if (response.assetsInfo) {\n context.response.assetsInfo = {\n ...context.response.assetsInfo,\n ...response.assetsInfo,\n };\n }\n if (response.assetsPrice) {\n context.response.assetsPrice = {\n ...context.response.assetsPrice,\n ...response.assetsPrice,\n };\n }\n\n // Determine successfully handled chains (exclude errors)\n const failedChains = new Set(Object.keys(response.errors ?? {}));\n successfullyHandledChains = supportedChains.filter(\n (chainId) => !failedChains.has(chainId),\n );\n } catch (error) {\n log('Middleware fetch failed', { error });\n successfullyHandledChains = [];\n }\n\n // Prepare context for next middleware\n let nextContext = context;\n if (successfullyHandledChains.length > 0) {\n const remainingChains = request.chainIds.filter(\n (chainId) => !successfullyHandledChains.includes(chainId),\n );\n nextContext = {\n ...context,\n request: {\n ...request,\n chainIds: remainingChains,\n },\n };\n }\n\n // Call next middleware\n return next(nextContext);\n };\n }\n\n // ============================================================================\n // SUBSCRIBE - Routes to appropriate snap(s)\n // ============================================================================\n\n async subscribe(subscriptionRequest: SubscriptionRequest): Promise<void> {\n const { request, subscriptionId, isUpdate } = subscriptionRequest;\n\n // Guard against undefined request or chainIds\n if (!request?.chainIds) {\n return;\n }\n\n // Filter to chains we have a snap for\n const supportedChains = request.chainIds.filter((chainId) =>\n this.#isChainSupportedBySnap(chainId),\n );\n\n if (supportedChains.length === 0) {\n return;\n }\n\n if (isUpdate) {\n const existing = this.activeSubscriptions.get(subscriptionId);\n if (existing) {\n existing.chains = supportedChains;\n // Do a fetch to get latest data on subscription update\n this.fetch({\n ...request,\n chainIds: supportedChains,\n })\n .then(async (fetchResponse) => {\n if (Object.keys(fetchResponse.assetsBalance ?? {}).length > 0) {\n await existing.onAssetsUpdate(fetchResponse);\n }\n return fetchResponse;\n })\n .catch((error) => {\n log('Subscription update fetch failed', { subscriptionId, error });\n });\n return;\n }\n }\n\n await this.unsubscribe(subscriptionId);\n\n // Snaps provide real-time updates via AccountsController:accountBalancesUpdated\n // We only need to track the subscription and do an initial fetch\n // No polling needed - updates come through #handleSnapBalancesUpdated\n\n this.activeSubscriptions.set(subscriptionId, {\n cleanup: () => {\n // No timer to clear - we use event-based updates\n },\n chains: supportedChains,\n onAssetsUpdate: subscriptionRequest.onAssetsUpdate,\n });\n\n // Initial fetch to get current balances\n try {\n const fetchResponse = await this.fetch({\n ...request,\n chainIds: supportedChains,\n });\n\n const subscription = this.activeSubscriptions.get(subscriptionId);\n if (\n Object.keys(fetchResponse.assetsBalance ?? {}).length > 0 &&\n subscription\n ) {\n await subscription.onAssetsUpdate(fetchResponse);\n }\n } catch (error) {\n log('Initial fetch failed', { subscriptionId, error });\n }\n }\n\n // ============================================================================\n // KEYRING CLIENT\n // ============================================================================\n\n /**\n * Gets a `KeyringClient` for a Snap.\n * Caches clients per snap ID to avoid re-instantiation across multiple calls.\n *\n * @param snapId - ID of the Snap to get the client for.\n * @returns A `KeyringClient` for the Snap.\n */\n #getKeyringClient(snapId: string): KeyringClient {\n const cachedClient = this.#keyringClientCache.get(snapId);\n if (cachedClient) {\n return cachedClient;\n }\n\n const client = new KeyringClient({\n send: async (request: JsonRpcRequest): Promise<Json> =>\n await (\n this.#messenger as unknown as {\n call: (action: string, ...args: unknown[]) => Promise<Json> | Json;\n }\n ).call('SnapController:handleRequest', {\n snapId: snapId as SnapId,\n origin: 'metamask',\n handler: HandlerType.OnKeyringRequest,\n request,\n }),\n });\n\n this.#keyringClientCache.set(snapId, client);\n return client;\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const messenger = this.#messenger as any;\n\n // Unsubscribe from snap keyring events\n try {\n messenger.unsubscribe(\n 'AccountsController:accountBalancesUpdated',\n this.#handleSnapBalancesUpdatedBound,\n );\n } catch (error) {\n log('Failed to unsubscribe from snap keyring events', { error });\n }\n\n // Unsubscribe from permission changes\n try {\n messenger.unsubscribe(\n 'PermissionController:stateChange',\n this.#handlePermissionStateChangeBound,\n );\n } catch (error) {\n log('Failed to unsubscribe from permission changes', { error });\n }\n\n // Clean up active subscriptions\n for (const [subscriptionId] of this.activeSubscriptions) {\n this.unsubscribe(subscriptionId).catch(() => {\n // Ignore cleanup errors\n });\n }\n\n // Clear keyring client cache\n this.#keyringClientCache.clear();\n }\n}\n\n// ============================================================================\n// FACTORY\n// ============================================================================\n\nexport function createSnapDataSource(\n options: SnapDataSourceOptions,\n): SnapDataSource {\n return new SnapDataSource(options);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SnapDataSource.d.cts","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EACd,oBAAoB,EACpB,+BAA+B,EAEhC,wCAAwC;AACzC,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EAClB,oCAAoC;AAMrC,OAAO,EAAE,kBAAkB,EAAE,iCAA6B;AAC1D,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,iCAA6B;AAC9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,gCAA4B;AAErE,OAAO,KAAK,EAEV,OAAO,EAEP,WAAW,EACX,YAAY,EACZ,UAAU,EACX,qBAAiB;AAMlB;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,EAAE;QACR,CAAC,SAAS,EAAE,MAAM,GAAG;YACnB,CAAC,OAAO,EAAE,MAAM,GAAG;gBACjB,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,CAAC,kCAAkC,CAAC,CAAC;CAC/C,CAAC;AAQF,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AAEtD,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAEtD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAMpD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,EAAE,GAAG,IAAI,CAUlB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGhE;AAMD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACtC,GAAG,eAAe,CAAC;AAWpB;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,6CAA6C,GAC7C,+BAA+B,CAAC;AAEpC,MAAM,MAAM,4BAA4B,GACpC,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,CAAC;AAMnB,MAAM,MAAM,qBAAqB,GAAG;IAClC,mEAAmE;IACnE,SAAS,EAAE,yBAAyB,CAAC;IACrC,mHAAmH;IACnH,qBAAqB,EAAE,CACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,EAAE,EACjB,cAAc,EAAE,OAAO,EAAE,KACtB,IAAI,CAAC;IACV,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC,CAAC;AAMF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,SAAQ,kBAAkB,CACpD,OAAO,qBAAqB,EAC5B,mBAAmB,CACpB;;gBAmBa,OAAO,EAAE,qBAAqB;IAwNpC,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA2ExD;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB,IAAI,UAAU,CA4EjC;IAMK,SAAS,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+GxE,OAAO,IAAI,IAAI;CAkChB;AAMD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,cAAc,CAEhB"}
1
+ {"version":3,"file":"SnapDataSource.d.cts","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EACd,oBAAoB,EACpB,+BAA+B,EAEhC,wCAAwC;AACzC,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EAClB,oCAAoC;AAMrC,OAAO,EAAE,kBAAkB,EAAE,iCAA6B;AAC1D,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,iCAA6B;AAC9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,gCAA4B;AAErE,OAAO,KAAK,EAEV,OAAO,EAEP,WAAW,EACX,YAAY,EACZ,UAAU,EACX,qBAAiB;AAMlB;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,EAAE;QACR,CAAC,SAAS,EAAE,MAAM,GAAG;YACnB,CAAC,OAAO,EAAE,MAAM,GAAG;gBACjB,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,CAAC,kCAAkC,CAAC,CAAC;CAC/C,CAAC;AAQF,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AAEtD,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAEtD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAMpD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,EAAE,GAAG,IAAI,CAUlB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGhE;AAMD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACtC,GAAG,eAAe,CAAC;AAWpB;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,6CAA6C,GAC7C,+BAA+B,CAAC;AAEpC,MAAM,MAAM,4BAA4B,GACpC,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,CAAC;AAMnB,MAAM,MAAM,qBAAqB,GAAG;IAClC,mEAAmE;IACnE,SAAS,EAAE,yBAAyB,CAAC;IACrC,mHAAmH;IACnH,qBAAqB,EAAE,CACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,EAAE,EACjB,cAAc,EAAE,OAAO,EAAE,KACtB,IAAI,CAAC;IACV,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC,CAAC;AAMF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,SAAQ,kBAAkB,CACpD,OAAO,qBAAqB,EAC5B,mBAAmB,CACpB;;gBAmBa,OAAO,EAAE,qBAAqB;IAwNpC,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA0ExD;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB,IAAI,UAAU,CA4EjC;IAMK,SAAS,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+GxE,OAAO,IAAI,IAAI;CAkChB;AAMD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,cAAc,CAEhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"SnapDataSource.d.mts","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EACd,oBAAoB,EACpB,+BAA+B,EAEhC,wCAAwC;AACzC,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EAClB,oCAAoC;AAMrC,OAAO,EAAE,kBAAkB,EAAE,iCAA6B;AAC1D,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,iCAA6B;AAC9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,gCAA4B;AAErE,OAAO,KAAK,EAEV,OAAO,EAEP,WAAW,EACX,YAAY,EACZ,UAAU,EACX,qBAAiB;AAMlB;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,EAAE;QACR,CAAC,SAAS,EAAE,MAAM,GAAG;YACnB,CAAC,OAAO,EAAE,MAAM,GAAG;gBACjB,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,CAAC,kCAAkC,CAAC,CAAC;CAC/C,CAAC;AAQF,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AAEtD,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAEtD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAMpD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,EAAE,GAAG,IAAI,CAUlB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGhE;AAMD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACtC,GAAG,eAAe,CAAC;AAWpB;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,6CAA6C,GAC7C,+BAA+B,CAAC;AAEpC,MAAM,MAAM,4BAA4B,GACpC,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,CAAC;AAMnB,MAAM,MAAM,qBAAqB,GAAG;IAClC,mEAAmE;IACnE,SAAS,EAAE,yBAAyB,CAAC;IACrC,mHAAmH;IACnH,qBAAqB,EAAE,CACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,EAAE,EACjB,cAAc,EAAE,OAAO,EAAE,KACtB,IAAI,CAAC;IACV,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC,CAAC;AAMF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,SAAQ,kBAAkB,CACpD,OAAO,qBAAqB,EAC5B,mBAAmB,CACpB;;gBAmBa,OAAO,EAAE,qBAAqB;IAwNpC,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA2ExD;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB,IAAI,UAAU,CA4EjC;IAMK,SAAS,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+GxE,OAAO,IAAI,IAAI;CAkChB;AAMD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,cAAc,CAEhB"}
1
+ {"version":3,"file":"SnapDataSource.d.mts","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EACd,oBAAoB,EACpB,+BAA+B,EAEhC,wCAAwC;AACzC,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EAClB,oCAAoC;AAMrC,OAAO,EAAE,kBAAkB,EAAE,iCAA6B;AAC1D,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,iCAA6B;AAC9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,gCAA4B;AAErE,OAAO,KAAK,EAEV,OAAO,EAEP,WAAW,EACX,YAAY,EACZ,UAAU,EACX,qBAAiB;AAMlB;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,EAAE;QACR,CAAC,SAAS,EAAE,MAAM,GAAG;YACnB,CAAC,OAAO,EAAE,MAAM,GAAG;gBACjB,MAAM,EAAE,MAAM,CAAC;gBACf,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,2CAA2C,CAAC;IAClD,OAAO,EAAE,CAAC,kCAAkC,CAAC,CAAC;CAC/C,CAAC;AAQF,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AAEtD,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAEtD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAMpD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,CAAC,EAAE,oBAAoB,GAChC,OAAO,EAAE,GAAG,IAAI,CAUlB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGhE;AAMD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACtC,GAAG,eAAe,CAAC;AAWpB;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,6CAA6C,GAC7C,+BAA+B,CAAC;AAEpC,MAAM,MAAM,4BAA4B,GACpC,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,CAAC;AAMnB,MAAM,MAAM,qBAAqB,GAAG;IAClC,mEAAmE;IACnE,SAAS,EAAE,yBAAyB,CAAC;IACrC,mHAAmH;IACnH,qBAAqB,EAAE,CACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,EAAE,EACjB,cAAc,EAAE,OAAO,EAAE,KACtB,IAAI,CAAC;IACV,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC,CAAC;AAMF;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAe,SAAQ,kBAAkB,CACpD,OAAO,qBAAqB,EAC5B,mBAAmB,CACpB;;gBAmBa,OAAO,EAAE,qBAAqB;IAwNpC,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA0ExD;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB,IAAI,UAAU,CA4EjC;IAMK,SAAS,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+GxE,OAAO,IAAI,IAAI;CAkChB;AAMD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,cAAc,CAEhB"}
@@ -115,12 +115,11 @@ export class SnapDataSource extends AbstractDataSource {
115
115
  return {};
116
116
  }
117
117
  if (!request?.accountsWithSupportedChains?.length) {
118
- return { assetsBalance: {}, assetsInfo: {}, updateMode: 'full' };
118
+ return { assetsBalance: {}, assetsInfo: {} };
119
119
  }
120
120
  const results = {
121
121
  assetsBalance: {},
122
122
  assetsInfo: {},
123
- updateMode: 'full',
124
123
  };
125
124
  // Fetch balances for each account using its snap ID from metadata
126
125
  for (const { account } of request.accountsWithSupportedChains) {
@@ -370,7 +369,7 @@ _SnapDataSource_messenger = new WeakMap(), _SnapDataSource_onActiveChainsUpdated
370
369
  }
371
370
  // Only report if we have snap-related updates
372
371
  if (assetsBalance) {
373
- const response = { assetsBalance, updateMode: 'merge' };
372
+ const response = { assetsBalance };
374
373
  for (const subscription of this.activeSubscriptions.values()) {
375
374
  subscription.onAssetsUpdate(response)?.catch(console.error);
376
375
  }