@metamask-previews/assets-controller 0.0.0-preview-903db2da → 0.0.0-preview-3ec2a74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/AssetsController.cjs +1028 -61
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +229 -83
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +229 -83
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +1024 -59
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AbstractDataSource.cjs +103 -0
- package/dist/data-sources/AbstractDataSource.cjs.map +1 -0
- package/dist/data-sources/AbstractDataSource.d.cts +92 -0
- package/dist/data-sources/AbstractDataSource.d.cts.map +1 -0
- package/dist/data-sources/AbstractDataSource.d.mts +92 -0
- package/dist/data-sources/AbstractDataSource.d.mts.map +1 -0
- package/dist/data-sources/AbstractDataSource.mjs +99 -0
- package/dist/data-sources/AbstractDataSource.mjs.map +1 -0
- package/dist/data-sources/AccountsApiDataSource.cjs +421 -0
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -0
- package/dist/data-sources/AccountsApiDataSource.d.cts +103 -0
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -0
- package/dist/data-sources/AccountsApiDataSource.d.mts +103 -0
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -0
- package/dist/data-sources/AccountsApiDataSource.mjs +416 -0
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -0
- package/dist/data-sources/BackendWebsocketDataSource.cjs +388 -0
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +95 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +95 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -0
- package/dist/data-sources/BackendWebsocketDataSource.mjs +383 -0
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -0
- package/dist/data-sources/PriceDataSource.cjs +350 -0
- package/dist/data-sources/PriceDataSource.cjs.map +1 -0
- package/dist/data-sources/PriceDataSource.d.cts +153 -0
- package/dist/data-sources/PriceDataSource.d.cts.map +1 -0
- package/dist/data-sources/PriceDataSource.d.mts +153 -0
- package/dist/data-sources/PriceDataSource.d.mts.map +1 -0
- package/dist/data-sources/PriceDataSource.mjs +346 -0
- package/dist/data-sources/PriceDataSource.mjs.map +1 -0
- package/dist/data-sources/RpcDataSource.cjs +410 -0
- package/dist/data-sources/RpcDataSource.cjs.map +1 -0
- package/dist/data-sources/RpcDataSource.d.cts +154 -0
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -0
- package/dist/data-sources/RpcDataSource.d.mts +154 -0
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -0
- package/dist/data-sources/RpcDataSource.mjs +405 -0
- package/dist/data-sources/RpcDataSource.mjs.map +1 -0
- package/dist/data-sources/SnapDataSource.cjs +734 -0
- package/dist/data-sources/SnapDataSource.cjs.map +1 -0
- package/dist/data-sources/SnapDataSource.d.cts +217 -0
- package/dist/data-sources/SnapDataSource.d.cts.map +1 -0
- package/dist/data-sources/SnapDataSource.d.mts +217 -0
- package/dist/data-sources/SnapDataSource.d.mts.map +1 -0
- package/dist/data-sources/SnapDataSource.mjs +723 -0
- package/dist/data-sources/SnapDataSource.mjs.map +1 -0
- package/dist/data-sources/TokenDataSource.cjs +179 -0
- package/dist/data-sources/TokenDataSource.cjs.map +1 -0
- package/dist/data-sources/TokenDataSource.d.cts +62 -0
- package/dist/data-sources/TokenDataSource.d.cts.map +1 -0
- package/dist/data-sources/TokenDataSource.d.mts +62 -0
- package/dist/data-sources/TokenDataSource.d.mts.map +1 -0
- package/dist/data-sources/TokenDataSource.mjs +175 -0
- package/dist/data-sources/TokenDataSource.mjs.map +1 -0
- package/dist/data-sources/index.cjs +62 -0
- package/dist/data-sources/index.cjs.map +1 -0
- package/dist/data-sources/index.d.cts +9 -0
- package/dist/data-sources/index.d.cts.map +1 -0
- package/dist/data-sources/index.d.mts +9 -0
- package/dist/data-sources/index.d.mts.map +1 -0
- package/dist/data-sources/index.mjs +23 -0
- package/dist/data-sources/index.mjs.map +1 -0
- package/dist/data-sources/initDataSources.cjs +199 -0
- package/dist/data-sources/initDataSources.cjs.map +1 -0
- package/dist/data-sources/initDataSources.d.cts +123 -0
- package/dist/data-sources/initDataSources.d.cts.map +1 -0
- package/dist/data-sources/initDataSources.d.mts +123 -0
- package/dist/data-sources/initDataSources.d.mts.map +1 -0
- package/dist/data-sources/initDataSources.mjs +194 -0
- package/dist/data-sources/initDataSources.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.cjs +638 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.d.cts +47 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.d.mts +47 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.mjs +632 -0
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/index.cjs +8 -0
- package/dist/data-sources/rpc-datasource/clients/index.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/index.d.cts +3 -0
- package/dist/data-sources/rpc-datasource/clients/index.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/index.d.mts +3 -0
- package/dist/data-sources/rpc-datasource/clients/index.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/clients/index.mjs +2 -0
- package/dist/data-sources/rpc-datasource/clients/index.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/index.cjs +9 -0
- package/dist/data-sources/rpc-datasource/index.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/index.d.cts +4 -0
- package/dist/data-sources/rpc-datasource/index.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/index.d.mts +4 -0
- package/dist/data-sources/rpc-datasource/index.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/index.mjs +3 -0
- package/dist/data-sources/rpc-datasource/index.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.cjs +167 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.cts +16 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.mts +16 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.mjs +163 -0
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.cjs +173 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.cts +14 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.mts +14 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.mjs +169 -0
- package/dist/data-sources/rpc-datasource/services/TokenDetector.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/services/index.cjs +8 -0
- package/dist/data-sources/rpc-datasource/services/index.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/services/index.d.cts +3 -0
- package/dist/data-sources/rpc-datasource/services/index.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/services/index.d.mts +3 -0
- package/dist/data-sources/rpc-datasource/services/index.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/services/index.mjs +3 -0
- package/dist/data-sources/rpc-datasource/services/index.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/assets.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/assets.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/assets.d.cts +53 -0
- package/dist/data-sources/rpc-datasource/types/assets.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/assets.d.mts +53 -0
- package/dist/data-sources/rpc-datasource/types/assets.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/assets.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/assets.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/config.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/config.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/config.d.cts +18 -0
- package/dist/data-sources/rpc-datasource/types/config.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/config.d.mts +18 -0
- package/dist/data-sources/rpc-datasource/types/config.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/config.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/config.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/core.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/core.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/core.d.cts +19 -0
- package/dist/data-sources/rpc-datasource/types/core.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/core.d.mts +19 -0
- package/dist/data-sources/rpc-datasource/types/core.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/core.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/core.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/index.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/index.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/index.d.cts +7 -0
- package/dist/data-sources/rpc-datasource/types/index.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/index.d.mts +7 -0
- package/dist/data-sources/rpc-datasource/types/index.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/index.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/index.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/multicall.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/multicall.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/multicall.d.cts +24 -0
- package/dist/data-sources/rpc-datasource/types/multicall.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/multicall.d.mts +24 -0
- package/dist/data-sources/rpc-datasource/types/multicall.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/multicall.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/multicall.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/services.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/services.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/services.d.cts +74 -0
- package/dist/data-sources/rpc-datasource/types/services.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/services.d.mts +74 -0
- package/dist/data-sources/rpc-datasource/types/services.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/services.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/services.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/state.cjs +3 -0
- package/dist/data-sources/rpc-datasource/types/state.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/types/state.d.cts +67 -0
- package/dist/data-sources/rpc-datasource/types/state.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/state.d.mts +67 -0
- package/dist/data-sources/rpc-datasource/types/state.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/types/state.mjs +2 -0
- package/dist/data-sources/rpc-datasource/types/state.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/batch.cjs +45 -0
- package/dist/data-sources/rpc-datasource/utils/batch.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/batch.d.cts +28 -0
- package/dist/data-sources/rpc-datasource/utils/batch.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/batch.d.mts +28 -0
- package/dist/data-sources/rpc-datasource/utils/batch.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/batch.mjs +40 -0
- package/dist/data-sources/rpc-datasource/utils/batch.mjs.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/index.cjs +7 -0
- package/dist/data-sources/rpc-datasource/utils/index.cjs.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/index.d.cts +2 -0
- package/dist/data-sources/rpc-datasource/utils/index.d.cts.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/index.d.mts +2 -0
- package/dist/data-sources/rpc-datasource/utils/index.d.mts.map +1 -0
- package/dist/data-sources/rpc-datasource/utils/index.mjs +2 -0
- package/dist/data-sources/rpc-datasource/utils/index.mjs.map +1 -0
- package/dist/index.cjs +70 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +19 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +31 -0
- package/dist/index.mjs.map +1 -1
- package/dist/logger.cjs +7 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +5 -0
- package/dist/logger.d.cts.map +1 -0
- package/dist/logger.d.mts +5 -0
- package/dist/logger.d.mts.map +1 -0
- package/dist/logger.mjs +4 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/middlewares/DetectionMiddleware.cjs +101 -0
- package/dist/middlewares/DetectionMiddleware.cjs.map +1 -0
- package/dist/middlewares/DetectionMiddleware.d.cts +54 -0
- package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -0
- package/dist/middlewares/DetectionMiddleware.d.mts +54 -0
- package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -0
- package/dist/middlewares/DetectionMiddleware.mjs +97 -0
- package/dist/middlewares/DetectionMiddleware.mjs.map +1 -0
- package/dist/middlewares/index.cjs +6 -0
- package/dist/middlewares/index.cjs.map +1 -0
- package/dist/middlewares/index.d.cts +2 -0
- package/dist/middlewares/index.d.cts.map +1 -0
- package/dist/middlewares/index.d.mts +2 -0
- package/dist/middlewares/index.d.mts.map +1 -0
- package/dist/middlewares/index.mjs +2 -0
- package/dist/middlewares/index.mjs.map +1 -0
- package/dist/types.cjs +39 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +360 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +360 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +35 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils.cjs +28 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +13 -0
- package/dist/utils.d.cts.map +1 -0
- package/dist/utils.d.mts +13 -0
- package/dist/utils.d.mts.map +1 -0
- package/dist/utils.mjs +24 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +15 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SnapDataSource.mjs","sourceRoot":"","sources":["../../src/data-sources/SnapDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\n\nimport { AbstractDataSource } from './AbstractDataSource';\nimport type {\n DataSourceState,\n SubscriptionRequest,\n} from './AbstractDataSource';\nimport { projectLogger, createModuleLogger } from '../logger';\nimport type {\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// Snap IDs\nexport const SOLANA_SNAP_ID = 'npm:@metamask/solana-wallet-snap';\nexport const BITCOIN_SNAP_ID = 'npm:@metamask/bitcoin-wallet-snap';\nexport const TRON_SNAP_ID = 'npm:@metamask/tron-wallet-snap';\n\n// Chain prefixes for detection\nexport const SOLANA_CHAIN_PREFIX = 'solana:';\nexport const BITCOIN_CHAIN_PREFIX = 'bip122:';\nexport const TRON_CHAIN_PREFIX = 'tron:';\n\n// Default networks\nexport const SOLANA_MAINNET =\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' as ChainId;\nexport const SOLANA_DEVNET =\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1' as ChainId;\nexport const SOLANA_TESTNET =\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z' as ChainId;\n\nexport const BITCOIN_MAINNET =\n 'bip122:000000000019d6689c085ae165831e93' as ChainId;\nexport const BITCOIN_TESTNET =\n 'bip122:000000000933ea01ad0ee984209779ba' as ChainId;\n\nexport const TRON_MAINNET = 'tron:728126428' as ChainId;\nexport const TRON_SHASTA = 'tron:2494104990' as ChainId;\nexport const TRON_NILE = 'tron:3448148188' as ChainId;\n// Hex format alternatives for Tron\nexport const TRON_MAINNET_HEX = 'tron:0x2b6653dc' as ChainId;\nexport const TRON_SHASTA_HEX = 'tron:0x94a9059e' as ChainId;\nexport const TRON_NILE_HEX = 'tron:0xcd8690dc' as ChainId;\n\n// Default poll intervals\nexport const DEFAULT_SOLANA_POLL_INTERVAL = 30_000; // 30 seconds\nexport const DEFAULT_BITCOIN_POLL_INTERVAL = 60_000; // 1 minute\nexport const DEFAULT_TRON_POLL_INTERVAL = 30_000; // 30 seconds\nexport const DEFAULT_SNAP_POLL_INTERVAL = 30_000; // Default for unknown snaps\n\n// All default networks\nexport const ALL_DEFAULT_NETWORKS: ChainId[] = [\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n BITCOIN_MAINNET,\n BITCOIN_TESTNET,\n TRON_MAINNET,\n TRON_SHASTA,\n TRON_NILE,\n TRON_MAINNET_HEX,\n TRON_SHASTA_HEX,\n TRON_NILE_HEX,\n];\n\n// ============================================================================\n// SNAP ROUTING\n// ============================================================================\n\nexport type SnapType = 'solana' | 'bitcoin' | 'tron';\n\nexport type SnapInfo = {\n snapId: string;\n chainPrefix: string;\n pollInterval: number;\n version: string | null;\n available: boolean;\n};\n\nexport const SNAP_REGISTRY: Record<\n SnapType,\n Omit<SnapInfo, 'version' | 'available'>\n> = {\n solana: {\n snapId: SOLANA_SNAP_ID,\n chainPrefix: SOLANA_CHAIN_PREFIX,\n pollInterval: DEFAULT_SOLANA_POLL_INTERVAL,\n },\n bitcoin: {\n snapId: BITCOIN_SNAP_ID,\n chainPrefix: BITCOIN_CHAIN_PREFIX,\n pollInterval: DEFAULT_BITCOIN_POLL_INTERVAL,\n },\n tron: {\n snapId: TRON_SNAP_ID,\n chainPrefix: TRON_CHAIN_PREFIX,\n pollInterval: DEFAULT_TRON_POLL_INTERVAL,\n },\n};\n\n/**\n * Get the snap type for a chain ID based on its prefix.\n *\n * @param chainId - The CAIP-2 chain ID to check.\n * @returns The snap type for the chain, or null if not supported.\n */\nexport function getSnapTypeForChain(chainId: ChainId): SnapType | null {\n if (chainId.startsWith(SOLANA_CHAIN_PREFIX)) {\n return 'solana';\n }\n if (chainId.startsWith(BITCOIN_CHAIN_PREFIX)) {\n return 'bitcoin';\n }\n if (chainId.startsWith(TRON_CHAIN_PREFIX)) {\n return 'tron';\n }\n return null;\n}\n\n/**\n * Check if a chain ID is supported by a snap.\n *\n * @param chainId - The CAIP-2 chain ID to check.\n * @returns True if the chain is supported by a snap.\n */\nexport function isSnapSupportedChain(chainId: ChainId): boolean {\n return getSnapTypeForChain(chainId) !== null;\n}\n\n/**\n * Extract chain ID from a CAIP-19 asset ID.\n * e.g., \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501\" -> \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\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 parts = assetId.split('/');\n return parts[0] as ChainId;\n}\n\n// Helper functions for specific chain types\nexport function isSolanaChain(chainId: ChainId): boolean {\n return chainId.startsWith(SOLANA_CHAIN_PREFIX);\n}\n\nexport function isBitcoinChain(chainId: ChainId): boolean {\n return chainId.startsWith(BITCOIN_CHAIN_PREFIX);\n}\n\nexport function isTronChain(chainId: ChainId): boolean {\n return chainId.startsWith(TRON_CHAIN_PREFIX);\n}\n\n// ============================================================================\n// STATE\n// ============================================================================\n\nexport type SnapDataSourceState = {\n /** Snap availability and versions */\n snaps: Record<SnapType, { version: string | null; available: boolean }>;\n} & DataSourceState;\n\nconst defaultSnapState: SnapDataSourceState = {\n activeChains: ALL_DEFAULT_NETWORKS,\n snaps: {\n solana: { version: null, available: false },\n bitcoin: { version: null, available: false },\n tron: { version: null, available: false },\n },\n};\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\nexport type SnapDataSourceGetAssetsMiddlewareAction = {\n type: 'SnapDataSource:getAssetsMiddleware';\n handler: () => Middleware;\n};\n\nexport type SnapDataSourceGetActiveChainsAction = {\n type: 'SnapDataSource:getActiveChains';\n handler: () => Promise<ChainId[]>;\n};\n\nexport type SnapDataSourceFetchAction = {\n type: 'SnapDataSource:fetch';\n handler: (request: DataRequest) => Promise<DataResponse>;\n};\n\nexport type SnapDataSourceSubscribeAction = {\n type: 'SnapDataSource:subscribe';\n handler: (request: SubscriptionRequest) => Promise<void>;\n};\n\nexport type SnapDataSourceUnsubscribeAction = {\n type: 'SnapDataSource:unsubscribe';\n handler: (subscriptionId: string) => Promise<void>;\n};\n\nexport type SnapDataSourceActions =\n | SnapDataSourceGetAssetsMiddlewareAction\n | SnapDataSourceGetActiveChainsAction\n | SnapDataSourceFetchAction\n | SnapDataSourceSubscribeAction\n | SnapDataSourceUnsubscribeAction;\n\nexport type SnapDataSourceActiveChainsChangedEvent = {\n type: 'SnapDataSource:activeChainsUpdated';\n payload: [ChainId[]];\n};\n\nexport type SnapDataSourceAssetsUpdatedEvent = {\n type: 'SnapDataSource:assetsUpdated';\n payload: [DataResponse, string | undefined];\n};\n\nexport type SnapDataSourceEvents =\n | SnapDataSourceActiveChainsChangedEvent\n | SnapDataSourceAssetsUpdatedEvent;\n\n/**\n * Allowed events that SnapDataSource can subscribe to.\n */\nexport type SnapDataSourceAllowedEvents =\n AccountsControllerAccountBalancesUpdatedEvent;\n\n// Actions to report to AssetsController\ntype AssetsControllerActiveChainsUpdateAction = {\n type: 'AssetsController:activeChainsUpdate';\n handler: (dataSourceId: string, activeChains: ChainId[]) => void;\n};\n\ntype AssetsControllerAssetsUpdateAction = {\n type: 'AssetsController:assetsUpdate';\n handler: (response: DataResponse, sourceId: string) => Promise<void>;\n};\n\nexport type SnapDataSourceAllowedActions =\n | AssetsControllerActiveChainsUpdateAction\n | AssetsControllerAssetsUpdateAction;\n\nexport type SnapDataSourceMessenger = Messenger<\n typeof SNAP_DATA_SOURCE_NAME,\n SnapDataSourceActions | SnapDataSourceAllowedActions,\n SnapDataSourceEvents | SnapDataSourceAllowedEvents\n>;\n\n// ============================================================================\n// SNAP PROVIDER INTERFACE\n// ============================================================================\n\nexport type SnapProvider = {\n request<ResponseType>(args: {\n method: string;\n params?: unknown;\n }): Promise<ResponseType>;\n};\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type SnapDataSourceOptions = {\n /** Messenger for this data source */\n messenger: SnapDataSourceMessenger;\n /**\n * Snap provider for communicating with snaps.\n */\n snapProvider: SnapProvider;\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 * Supports:\n * - Solana chains (solana:*) → @metamask/solana-wallet-snap\n * - Bitcoin chains (bip122:*) → @metamask/bitcoin-wallet-snap\n * - Tron chains (tron:*) → @metamask/tron-wallet-snap\n *\n * @example\n * ```typescript\n * const snapDataSource = new SnapDataSource({\n * messenger,\n * snapProvider: metamaskProvider,\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: SnapDataSourceMessenger;\n\n readonly #snapProvider: SnapProvider;\n\n constructor(options: SnapDataSourceOptions) {\n const configuredNetworks =\n options.configuredNetworks ?? ALL_DEFAULT_NETWORKS;\n\n super(SNAP_DATA_SOURCE_NAME, {\n ...defaultSnapState,\n ...options.state,\n activeChains: configuredNetworks,\n });\n\n this.#messenger = options.messenger;\n this.#snapProvider = options.snapProvider;\n\n this.#registerActionHandlers();\n this.#subscribeToSnapKeyringEvents();\n\n // Check availability for all snaps on initialization\n this.#checkAllSnapsAvailability().catch(() => {\n // Silently ignore availability check failures on init\n });\n }\n\n /**\n * Subscribe to snap keyring events for real-time balance updates.\n * The snaps emit AccountBalancesUpdated events when balances change,\n * which are re-published by AccountsController.\n */\n #subscribeToSnapKeyringEvents(): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const messenger = this.#messenger as any;\n\n try {\n messenger.subscribe(\n 'AccountsController:accountBalancesUpdated',\n (payload: AccountBalancesUpdatedEventPayload) => {\n this.#handleSnapBalancesUpdated(payload);\n },\n );\n } catch (error) {\n log('Failed to subscribe to snap keyring events', { error });\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 const response: DataResponse = {\n assetsBalance: {},\n };\n\n for (const [accountId, assets] of Object.entries(payload.balances)) {\n if (response.assetsBalance) {\n response.assetsBalance[accountId] = {};\n\n for (const [assetId, balance] of Object.entries(assets)) {\n // Only include snap-supported assets (solana, bitcoin, tron)\n if (isSnapSupportedChain(extractChainFromAssetId(assetId))) {\n response.assetsBalance[accountId][assetId as Caip19AssetId] = {\n amount: balance.amount,\n };\n }\n }\n\n // Remove account if no snap assets\n if (Object.keys(response.assetsBalance[accountId]).length === 0) {\n delete response.assetsBalance[accountId];\n }\n }\n }\n\n // Only report if we have snap-related updates\n if (Object.keys(response.assetsBalance ?? {}).length > 0) {\n this.#messenger\n .call('AssetsController:assetsUpdate', response, SNAP_DATA_SOURCE_NAME)\n .catch(console.error);\n }\n }\n\n #registerActionHandlers(): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const messenger = this.#messenger as any;\n\n messenger.registerActionHandler(\n 'SnapDataSource:getAssetsMiddleware',\n () => this.assetsMiddleware,\n );\n\n messenger.registerActionHandler(\n 'SnapDataSource:getActiveChains',\n async () => this.getActiveChains(),\n );\n\n messenger.registerActionHandler(\n 'SnapDataSource:fetch',\n async (request: DataRequest) => this.fetch(request),\n );\n\n messenger.registerActionHandler(\n 'SnapDataSource:subscribe',\n async (request: SubscriptionRequest) => this.subscribe(request),\n );\n\n messenger.registerActionHandler(\n 'SnapDataSource:unsubscribe',\n async (subscriptionId: string) => this.unsubscribe(subscriptionId),\n );\n }\n\n // ============================================================================\n // SNAP AVAILABILITY\n // ============================================================================\n\n /**\n * Get all installed snaps from the snap provider.\n *\n * @returns A map of snap IDs to their versions.\n */\n async #getInstalledSnaps(): Promise<Record<string, { version: string }>> {\n try {\n const snaps = await this.#snapProvider.request<\n Record<string, { version: string }>\n >({\n method: 'wallet_getSnaps',\n params: {},\n });\n\n return snaps;\n } catch (error) {\n log('Failed to get installed snaps', error);\n return {};\n }\n }\n\n /**\n * Check availability for a single snap type on-demand.\n * This is called before each fetch to ensure we have the latest availability status.\n *\n * @param snapType - The snap type to check (solana, bitcoin, tron)\n * @returns True if the snap is available, false otherwise\n */\n async #checkSnapAvailabilityOnDemand(snapType: SnapType): Promise<boolean> {\n const config = SNAP_REGISTRY[snapType];\n const currentState = this.state.snaps[snapType];\n\n // If already marked as available, return true (snap was found previously)\n if (currentState.available) {\n return true;\n }\n\n // Check if snap is now available (handles timing issues where snap wasn't ready at init)\n try {\n const snaps = await this.#getInstalledSnaps();\n const snap = snaps[config.snapId];\n\n if (snap) {\n // Snap is now available - update state\n this.state.snaps[snapType] = {\n version: snap.version,\n available: true,\n };\n return true;\n }\n\n return false;\n } catch {\n return false;\n }\n }\n\n async #checkAllSnapsAvailability(): Promise<void> {\n try {\n const snaps = await this.#getInstalledSnaps();\n\n for (const [snapType, config] of Object.entries(SNAP_REGISTRY)) {\n const snap = snaps[config.snapId];\n\n if (snap) {\n this.state.snaps[snapType as SnapType] = {\n version: snap.version,\n available: true,\n };\n } else {\n this.state.snaps[snapType as SnapType] = {\n version: null,\n available: false,\n };\n }\n }\n } catch {\n // Mark all snaps as unavailable on error\n for (const snapType of Object.keys(SNAP_REGISTRY)) {\n this.state.snaps[snapType as SnapType] = {\n version: null,\n available: false,\n };\n }\n }\n }\n\n /**\n * Get info about all snaps.\n *\n * @returns Record of snap info keyed by snap type.\n */\n getSnapsInfo(): Record<SnapType, SnapInfo> {\n const result: Record<SnapType, SnapInfo> = {} as Record<SnapType, SnapInfo>;\n\n for (const [snapType, config] of Object.entries(SNAP_REGISTRY)) {\n const state = this.state.snaps[snapType as SnapType];\n result[snapType as SnapType] = {\n ...config,\n version: state.version,\n available: state.available,\n };\n }\n\n return result;\n }\n\n /**\n * Check if a specific snap is available.\n *\n * @param snapType - The snap type to check (solana, bitcoin, tron).\n * @returns True if the snap is available.\n */\n isSnapAvailable(snapType: SnapType): boolean {\n return this.state.snaps[snapType]?.available ?? false;\n }\n\n /**\n * Force refresh snap availability check.\n */\n async refreshSnapsStatus(): Promise<void> {\n await this.#checkAllSnapsAvailability();\n }\n\n // ============================================================================\n // CHAIN MANAGEMENT\n // ============================================================================\n\n addNetworks(chainIds: ChainId[]): void {\n const snapChains = chainIds.filter(isSnapSupportedChain);\n const newChains = snapChains.filter(\n (chain) => !this.state.activeChains.includes(chain),\n );\n\n if (newChains.length > 0) {\n const updated = [...this.state.activeChains, ...newChains];\n this.updateActiveChains(updated, (updatedChains) =>\n this.#messenger.call(\n 'AssetsController:activeChainsUpdate',\n SNAP_DATA_SOURCE_NAME,\n updatedChains,\n ),\n );\n }\n }\n\n removeNetworks(chainIds: ChainId[]): void {\n const chainSet = new Set(chainIds);\n const updated = this.state.activeChains.filter(\n (chain) => !chainSet.has(chain),\n );\n if (updated.length !== this.state.activeChains.length) {\n this.updateActiveChains(updated, (updatedChains) =>\n this.#messenger.call(\n 'AssetsController:activeChainsUpdate',\n SNAP_DATA_SOURCE_NAME,\n updatedChains,\n ),\n );\n }\n }\n\n // ============================================================================\n // ACCOUNT SCOPE HELPERS\n // ============================================================================\n\n /**\n * Check if an account supports a specific chain based on its scopes.\n * For snap chains (Solana, Bitcoin, Tron), we check for the appropriate namespace.\n *\n * @param account - The account to check\n * @param chainId - The chain ID to check (e.g., \"solana:...\", \"bip122:...\", \"tron:...\")\n * @returns True if the account supports the chain\n */\n #accountSupportsChain(account: InternalAccount, chainId: ChainId): boolean {\n const scopes = account.scopes ?? [];\n\n // If no scopes defined, assume it supports the chain (backward compatibility)\n if (scopes.length === 0) {\n return true;\n }\n\n // Extract namespace and reference from chainId\n const [chainNamespace, chainReference] = chainId.split(':');\n\n for (const scope of scopes) {\n const [scopeNamespace, scopeReference] = (scope as string).split(':');\n\n // Check if namespaces match\n if (scopeNamespace !== chainNamespace) {\n continue;\n }\n\n // Wildcard scope (e.g., \"solana:0\" means all chains in that namespace)\n if (scopeReference === '0') {\n return true;\n }\n\n // Exact match check\n if (scopeReference === chainReference) {\n return true;\n }\n }\n\n return false;\n }\n\n // ============================================================================\n // FETCH - Routes to appropriate snap(s)\n // ============================================================================\n\n async fetch(request: DataRequest): Promise<DataResponse> {\n // Guard against undefined request or chainIds\n if (!request?.chainIds) {\n return {};\n }\n\n // Filter to only snap-supported chains\n const snapChains = request.chainIds.filter(isSnapSupportedChain);\n\n if (snapChains.length === 0) {\n return {};\n }\n\n // Group chains by snap type\n const chainsBySnap = this.#groupChainsBySnap(snapChains);\n\n // Fetch from each snap in parallel\n const results = await Promise.all(\n Object.entries(chainsBySnap).map(async ([snapType, chains]) => {\n return this.#fetchFromSnap(snapType as SnapType, {\n ...request,\n chainIds: chains,\n });\n }),\n );\n\n // Merge all results\n const mergedResponse: DataResponse = {};\n\n for (const result of results) {\n if (result.assetsBalance) {\n mergedResponse.assetsBalance = {\n ...mergedResponse.assetsBalance,\n ...result.assetsBalance,\n };\n }\n if (result.assetsMetadata) {\n mergedResponse.assetsMetadata = {\n ...mergedResponse.assetsMetadata,\n ...result.assetsMetadata,\n };\n }\n if (result.assetsPrice) {\n mergedResponse.assetsPrice = {\n ...mergedResponse.assetsPrice,\n ...result.assetsPrice,\n };\n }\n if (result.errors) {\n mergedResponse.errors = { ...mergedResponse.errors, ...result.errors };\n }\n }\n\n return mergedResponse;\n }\n\n #groupChainsBySnap(\n chainIds: ChainId[],\n ): Partial<Record<SnapType, ChainId[]>> {\n const groups: Partial<Record<SnapType, ChainId[]>> = {};\n\n for (const chainId of chainIds) {\n const snapType = getSnapTypeForChain(chainId);\n if (snapType) {\n groups[snapType] ??= [];\n const snapChains = groups[snapType];\n if (snapChains) {\n snapChains.push(chainId);\n }\n }\n }\n\n return groups;\n }\n\n async #fetchFromSnap(\n snapType: SnapType,\n request: DataRequest,\n ): Promise<DataResponse> {\n const config = SNAP_REGISTRY[snapType];\n\n // Check snap availability on-demand - handles timing issues where snap\n // wasn't ready during initialization but is now available\n const isAvailable = await this.#checkSnapAvailabilityOnDemand(snapType);\n if (!isAvailable) {\n log(`${snapType} snap not available, skipping fetch`);\n // Return errors for these chains so they can fallback to other data sources\n const errors: Record<ChainId, string> = {};\n for (const chainId of request.chainIds) {\n errors[chainId] = `${snapType} snap not available`;\n }\n return { errors };\n }\n\n const results: DataResponse = {\n assetsBalance: {},\n assetsMetadata: {},\n };\n\n // Fetch balances for each account using Keyring API\n // Important: Must first get account assets, then request balances for those specific assets\n for (const account of request.accounts) {\n // Filter to only process accounts that support the chains being fetched\n const accountSupportedChains = request.chainIds.filter((chainId) =>\n this.#accountSupportsChain(account, chainId),\n );\n\n // Skip accounts that don't support any of the requested chains\n if (accountSupportedChains.length === 0) {\n continue;\n }\n\n const accountId = account.id;\n try {\n // Step 1: Get the list of assets for this account\n log(`${snapType} snap calling keyring_listAccountAssets`, {\n snapId: config.snapId,\n accountId,\n });\n\n const accountAssets = await this.#snapProvider.request<string[]>({\n method: 'wallet_invokeSnap',\n params: {\n snapId: config.snapId,\n request: {\n method: 'keyring_listAccountAssets',\n params: {\n id: accountId, // Account UUID\n },\n },\n },\n });\n\n log(`${snapType} snap keyring_listAccountAssets response`, {\n accountId,\n assetCount: accountAssets?.length ?? 0,\n assets: accountAssets,\n });\n\n // If no assets, skip to next account\n if (!accountAssets || accountAssets.length === 0) {\n log(\n `${snapType} snap: account has no assets, skipping balance fetch`,\n {\n accountId,\n },\n );\n continue;\n }\n\n // Step 2: Get balances for those specific assets\n log(`${snapType} snap calling keyring_getAccountBalances`, {\n snapId: config.snapId,\n accountId,\n requestedAssets: accountAssets.length,\n });\n\n const balances = await this.#snapProvider.request<\n Record<string, { amount: string; unit: string; rawAmount?: string }>\n >({\n method: 'wallet_invokeSnap',\n params: {\n snapId: config.snapId,\n request: {\n method: 'keyring_getAccountBalances',\n params: {\n id: accountId, // Account UUID (the keyring API uses 'id' not 'accountId')\n assets: accountAssets, // Must pass specific asset types from listAccountAssets\n },\n },\n },\n });\n\n log(`${snapType} snap keyring_getAccountBalances response`, {\n accountId,\n balances,\n balancesType: typeof balances,\n isNull: balances === null,\n isUndefined: balances === undefined,\n assetCount: balances ? Object.keys(balances).length : 0,\n });\n\n // Transform keyring response to DataResponse format\n // Note: snap may return null/undefined if account doesn't belong to this snap\n if (balances && typeof balances === 'object' && results.assetsBalance) {\n const balanceEntries = Object.entries(balances);\n log(\n `${snapType} snap processing ${balanceEntries.length} balances for account ${accountId}`,\n );\n\n for (const [assetId, balance] of balanceEntries) {\n // Initialize account balances if not exists\n results.assetsBalance[accountId] ??= {};\n // Store raw balance for this asset\n // Use rawAmount if available (preferred - smallest unit), fall back to amount\n // Note: Snaps should return rawAmount in smallest unit (satoshis, lamports, etc.)\n const accountBalances = results.assetsBalance[accountId];\n if (accountBalances) {\n (accountBalances as Record<string, unknown>)[assetId] = {\n amount: balance.rawAmount ?? balance.amount,\n };\n }\n }\n } else if (!balances) {\n log(\n `${snapType} snap returned empty/null for account (account may not belong to this snap)`,\n {\n accountId,\n balances,\n },\n );\n }\n } catch (error) {\n // This is expected when querying a snap with an account it doesn't manage\n log(`${snapType} snap fetch FAILED for account`, {\n accountId,\n error: error instanceof Error ? error.message : String(error),\n errorStack: error instanceof Error ? error.stack : undefined,\n });\n }\n }\n\n log(`${snapType} snap fetch completed`, {\n chains: request.chainIds.length,\n accountsWithBalances: Object.keys(results.assetsBalance ?? {}).length,\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.assetsMetadata) {\n context.response.assetsMetadata = {\n ...context.response.assetsMetadata,\n ...response.assetsMetadata,\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 only snap-supported chains\n const snapChains = request.chainIds.filter(isSnapSupportedChain);\n\n if (snapChains.length === 0) {\n return;\n }\n\n if (isUpdate) {\n const existing = this.activeSubscriptions.get(subscriptionId);\n if (existing) {\n existing.chains = snapChains;\n // Do a fetch to get latest data on subscription update\n this.fetch({\n ...request,\n chainIds: snapChains,\n })\n .then(async (fetchResponse) => {\n if (Object.keys(fetchResponse.assetsBalance ?? {}).length > 0) {\n await this.#messenger.call(\n 'AssetsController:assetsUpdate',\n fetchResponse,\n SNAP_DATA_SOURCE_NAME,\n );\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: snapChains,\n });\n\n // Initial fetch to get current balances\n try {\n const fetchResponse = await this.fetch({\n ...request,\n chainIds: snapChains,\n });\n\n if (Object.keys(fetchResponse.assetsBalance ?? {}).length > 0) {\n await this.#messenger.call(\n 'AssetsController:assetsUpdate',\n fetchResponse,\n SNAP_DATA_SOURCE_NAME,\n );\n }\n } catch (error) {\n log('Initial fetch failed', { subscriptionId, error });\n }\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n for (const [subscriptionId] of this.activeSubscriptions) {\n this.unsubscribe(subscriptionId).catch(() => {\n // Ignore cleanup errors\n });\n }\n }\n}\n\n// ============================================================================\n// FACTORY\n// ============================================================================\n\nexport function createSnapDataSource(\n options: SnapDataSourceOptions,\n): SnapDataSource {\n return new SnapDataSource(options);\n}\n"]}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _TokenDataSource_instances, _TokenDataSource_messenger, _TokenDataSource_apiClient, _TokenDataSource_getSupportedNetworks, _TokenDataSource_filterAssetsByNetwork, _TokenDataSource_registerActionHandlers;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.TokenDataSource = void 0;
|
|
16
|
+
const core_backend_1 = require("@metamask/core-backend");
|
|
17
|
+
const utils_1 = require("@metamask/utils");
|
|
18
|
+
const logger_1 = require("../logger.cjs");
|
|
19
|
+
const types_1 = require("../types.cjs");
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// CONSTANTS
|
|
22
|
+
// ============================================================================
|
|
23
|
+
const CONTROLLER_NAME = 'TokenDataSource';
|
|
24
|
+
const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, CONTROLLER_NAME);
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// HELPER FUNCTIONS
|
|
27
|
+
// ============================================================================
|
|
28
|
+
function transformV3AssetResponseToMetadata(assetId, assetData) {
|
|
29
|
+
const parsed = (0, utils_1.parseCaipAssetType)(assetId);
|
|
30
|
+
let tokenType = 'erc20';
|
|
31
|
+
if (parsed.assetNamespace === 'slip44') {
|
|
32
|
+
tokenType = 'native';
|
|
33
|
+
}
|
|
34
|
+
else if (parsed.assetNamespace === 'spl') {
|
|
35
|
+
tokenType = 'spl';
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
type: tokenType,
|
|
39
|
+
name: assetData.name,
|
|
40
|
+
symbol: assetData.symbol,
|
|
41
|
+
decimals: assetData.decimals,
|
|
42
|
+
image: assetData.iconUrl ?? assetData.iconUrlThumbnail,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// TOKEN DATA SOURCE
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* TokenDataSource enriches responses with token metadata from the Tokens API.
|
|
50
|
+
*
|
|
51
|
+
* This middleware-based data source:
|
|
52
|
+
* - Checks detected assets for missing metadata/images
|
|
53
|
+
* - Fetches metadata from Tokens API v3 for assets needing enrichment
|
|
54
|
+
* - Merges fetched metadata into the response
|
|
55
|
+
*
|
|
56
|
+
* Usage:
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Create and initialize (registers messenger actions)
|
|
59
|
+
* const tokenDataSource = new TokenDataSource({ messenger, queryApiClient });
|
|
60
|
+
*
|
|
61
|
+
* // Later, get middleware via messenger
|
|
62
|
+
* const middleware = messenger.call('TokenDataSource:getAssetsMiddleware');
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
class TokenDataSource {
|
|
66
|
+
constructor(options) {
|
|
67
|
+
_TokenDataSource_instances.add(this);
|
|
68
|
+
this.name = CONTROLLER_NAME;
|
|
69
|
+
_TokenDataSource_messenger.set(this, void 0);
|
|
70
|
+
/** ApiPlatformClient for cached API calls */
|
|
71
|
+
_TokenDataSource_apiClient.set(this, void 0);
|
|
72
|
+
__classPrivateFieldSet(this, _TokenDataSource_messenger, options.messenger, "f");
|
|
73
|
+
__classPrivateFieldSet(this, _TokenDataSource_apiClient, options.queryApiClient, "f");
|
|
74
|
+
__classPrivateFieldGet(this, _TokenDataSource_instances, "m", _TokenDataSource_registerActionHandlers).call(this);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the middleware for enriching responses with token metadata.
|
|
78
|
+
*
|
|
79
|
+
* This middleware:
|
|
80
|
+
* 1. Extracts the response from context
|
|
81
|
+
* 2. Fetches metadata for detected assets (assets without metadata)
|
|
82
|
+
* 3. Enriches the response with fetched metadata
|
|
83
|
+
* 4. Calls next() at the end to continue the middleware chain
|
|
84
|
+
*
|
|
85
|
+
* @returns The middleware function for the assets pipeline.
|
|
86
|
+
*/
|
|
87
|
+
get assetsMiddleware() {
|
|
88
|
+
return (0, types_1.forDataTypes)(['metadata'], async (ctx, next) => {
|
|
89
|
+
// Extract response from context
|
|
90
|
+
const { response } = ctx;
|
|
91
|
+
// Only fetch metadata for detected assets (assets without metadata)
|
|
92
|
+
if (!response.detectedAssets) {
|
|
93
|
+
return next(ctx);
|
|
94
|
+
}
|
|
95
|
+
const { assetsMetadata: stateMetadata } = ctx.getAssetsState();
|
|
96
|
+
const assetIdsNeedingMetadata = new Set();
|
|
97
|
+
for (const detectedIds of Object.values(response.detectedAssets)) {
|
|
98
|
+
for (const assetId of detectedIds) {
|
|
99
|
+
// Skip if response already has metadata with image
|
|
100
|
+
const responseMetadata = response.assetsMetadata?.[assetId];
|
|
101
|
+
if (responseMetadata?.image) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Skip if state already has metadata with image
|
|
105
|
+
const existingMetadata = stateMetadata[assetId];
|
|
106
|
+
if (existingMetadata?.image) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
assetIdsNeedingMetadata.add(assetId);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (assetIdsNeedingMetadata.size === 0) {
|
|
113
|
+
return next(ctx);
|
|
114
|
+
}
|
|
115
|
+
// Filter asset IDs to only include supported networks
|
|
116
|
+
const supportedNetworks = await __classPrivateFieldGet(this, _TokenDataSource_instances, "m", _TokenDataSource_getSupportedNetworks).call(this);
|
|
117
|
+
const supportedAssetIds = __classPrivateFieldGet(this, _TokenDataSource_instances, "m", _TokenDataSource_filterAssetsByNetwork).call(this, [...assetIdsNeedingMetadata], supportedNetworks);
|
|
118
|
+
if (supportedAssetIds.length === 0) {
|
|
119
|
+
return next(ctx);
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
// Use ApiPlatformClient for fetching asset metadata
|
|
123
|
+
// API returns an array with assetId as a property on each item
|
|
124
|
+
const metadataResponse = await __classPrivateFieldGet(this, _TokenDataSource_apiClient, "f").tokens.fetchV3Assets(supportedAssetIds);
|
|
125
|
+
response.assetsMetadata ?? (response.assetsMetadata = {});
|
|
126
|
+
for (const assetData of metadataResponse) {
|
|
127
|
+
const caipAssetId = assetData.assetId;
|
|
128
|
+
response.assetsMetadata[caipAssetId] =
|
|
129
|
+
transformV3AssetResponseToMetadata(assetData.assetId, assetData);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
log('Failed to fetch metadata', { error });
|
|
134
|
+
}
|
|
135
|
+
// Call next() at the end to continue the middleware chain
|
|
136
|
+
return next(ctx);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.TokenDataSource = TokenDataSource;
|
|
141
|
+
_TokenDataSource_messenger = new WeakMap(), _TokenDataSource_apiClient = new WeakMap(), _TokenDataSource_instances = new WeakSet(), _TokenDataSource_getSupportedNetworks =
|
|
142
|
+
/**
|
|
143
|
+
* Gets the supported networks from the API.
|
|
144
|
+
* Caching is handled by ApiPlatformClient.
|
|
145
|
+
*
|
|
146
|
+
* @returns Set of supported chain IDs in CAIP format
|
|
147
|
+
*/
|
|
148
|
+
async function _TokenDataSource_getSupportedNetworks() {
|
|
149
|
+
try {
|
|
150
|
+
// Use v2/supportedNetworks which returns CAIP chain IDs
|
|
151
|
+
// ApiPlatformClient handles caching
|
|
152
|
+
const response = await __classPrivateFieldGet(this, _TokenDataSource_apiClient, "f").tokens.fetchTokenV2SupportedNetworks();
|
|
153
|
+
// Combine full and partial support networks
|
|
154
|
+
const allNetworks = [...response.fullSupport, ...response.partialSupport];
|
|
155
|
+
return new Set(allNetworks);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
log('Failed to fetch supported networks', { error });
|
|
159
|
+
return new Set();
|
|
160
|
+
}
|
|
161
|
+
}, _TokenDataSource_filterAssetsByNetwork = function _TokenDataSource_filterAssetsByNetwork(assetIds, supportedNetworks) {
|
|
162
|
+
return assetIds.filter((assetId) => {
|
|
163
|
+
try {
|
|
164
|
+
const parsed = (0, utils_1.parseCaipAssetType)(assetId);
|
|
165
|
+
// chainId is in format "eip155:1" or "tron:728126428"
|
|
166
|
+
// parsed.chain has namespace and reference properties
|
|
167
|
+
const chainId = `${parsed.chain.namespace}:${parsed.chain.reference}`;
|
|
168
|
+
return supportedNetworks.has(chainId);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// If we can't parse the asset ID, filter it out
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}, _TokenDataSource_registerActionHandlers = function _TokenDataSource_registerActionHandlers() {
|
|
176
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
177
|
+
__classPrivateFieldGet(this, _TokenDataSource_messenger, "f").registerActionHandler('TokenDataSource:getAssetsMiddleware', () => this.assetsMiddleware);
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=TokenDataSource.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenDataSource.cjs","sourceRoot":"","sources":["../../src/data-sources/TokenDataSource.ts"],"names":[],"mappings":"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","sourcesContent":["import type { V3AssetResponse } from '@metamask/core-backend';\nimport { ApiPlatformClient } from '@metamask/core-backend';\nimport type { Messenger } from '@metamask/messenger';\nimport { parseCaipAssetType } from '@metamask/utils';\nimport type { CaipAssetType } from '@metamask/utils';\n\nimport { projectLogger, createModuleLogger } from '../logger';\nimport { forDataTypes } from '../types';\nimport type { Caip19AssetId, AssetMetadata, Middleware } from '../types';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst CONTROLLER_NAME = 'TokenDataSource';\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\n/**\n * Action to get the TokenDataSource middleware.\n */\nexport type TokenDataSourceGetAssetsMiddlewareAction = {\n type: `${typeof CONTROLLER_NAME}:getAssetsMiddleware`;\n handler: () => Middleware;\n};\n\n/**\n * All actions exposed by TokenDataSource.\n */\nexport type TokenDataSourceActions = TokenDataSourceGetAssetsMiddlewareAction;\n\n/**\n * TokenDataSource no longer needs external BackendApiClient actions.\n * It uses ApiPlatformClient directly.\n */\nexport type TokenDataSourceAllowedActions = never;\n\nexport type TokenDataSourceMessenger = Messenger<\n typeof CONTROLLER_NAME,\n TokenDataSourceActions,\n never\n>;\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type TokenDataSourceOptions = {\n messenger: TokenDataSourceMessenger;\n /** ApiPlatformClient for API calls with caching */\n queryApiClient: ApiPlatformClient;\n};\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nfunction transformV3AssetResponseToMetadata(\n assetId: string,\n assetData: V3AssetResponse,\n): AssetMetadata {\n const parsed = parseCaipAssetType(assetId as CaipAssetType);\n let tokenType: 'native' | 'erc20' | 'spl' = 'erc20';\n\n if (parsed.assetNamespace === 'slip44') {\n tokenType = 'native';\n } else if (parsed.assetNamespace === 'spl') {\n tokenType = 'spl';\n }\n\n return {\n type: tokenType,\n name: assetData.name,\n symbol: assetData.symbol,\n decimals: assetData.decimals,\n image: assetData.iconUrl ?? assetData.iconUrlThumbnail,\n };\n}\n\n// ============================================================================\n// TOKEN DATA SOURCE\n// ============================================================================\n\n/**\n * TokenDataSource enriches responses with token metadata from the Tokens API.\n *\n * This middleware-based data source:\n * - Checks detected assets for missing metadata/images\n * - Fetches metadata from Tokens API v3 for assets needing enrichment\n * - Merges fetched metadata into the response\n *\n * Usage:\n * ```typescript\n * // Create and initialize (registers messenger actions)\n * const tokenDataSource = new TokenDataSource({ messenger, queryApiClient });\n *\n * // Later, get middleware via messenger\n * const middleware = messenger.call('TokenDataSource:getAssetsMiddleware');\n * ```\n */\nexport class TokenDataSource {\n readonly name = CONTROLLER_NAME;\n\n readonly #messenger: TokenDataSourceMessenger;\n\n /** ApiPlatformClient for cached API calls */\n readonly #apiClient: ApiPlatformClient;\n\n constructor(options: TokenDataSourceOptions) {\n this.#messenger = options.messenger;\n this.#apiClient = options.queryApiClient;\n this.#registerActionHandlers();\n }\n\n /**\n * Gets the supported networks from the API.\n * Caching is handled by ApiPlatformClient.\n *\n * @returns Set of supported chain IDs in CAIP format\n */\n async #getSupportedNetworks(): Promise<Set<string>> {\n try {\n // Use v2/supportedNetworks which returns CAIP chain IDs\n // ApiPlatformClient handles caching\n const response =\n await this.#apiClient.tokens.fetchTokenV2SupportedNetworks();\n\n // Combine full and partial support networks\n const allNetworks = [...response.fullSupport, ...response.partialSupport];\n\n return new Set(allNetworks);\n } catch (error) {\n log('Failed to fetch supported networks', { error });\n return new Set();\n }\n }\n\n /**\n * Filters asset IDs to only include those from supported networks.\n *\n * @param assetIds - Array of CAIP-19 asset IDs\n * @param supportedNetworks - Set of supported chain IDs\n * @returns Array of asset IDs from supported networks\n */\n #filterAssetsByNetwork(\n assetIds: string[],\n supportedNetworks: Set<string>,\n ): string[] {\n return assetIds.filter((assetId) => {\n try {\n const parsed = parseCaipAssetType(assetId as CaipAssetType);\n // chainId is in format \"eip155:1\" or \"tron:728126428\"\n // parsed.chain has namespace and reference properties\n const chainId = `${parsed.chain.namespace}:${parsed.chain.reference}`;\n return supportedNetworks.has(chainId);\n } catch {\n // If we can't parse the asset ID, filter it out\n return false;\n }\n });\n }\n\n #registerActionHandlers(): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.#messenger as any).registerActionHandler(\n 'TokenDataSource:getAssetsMiddleware',\n () => this.assetsMiddleware,\n );\n }\n\n /**\n * Get the middleware for enriching responses with token metadata.\n *\n * This middleware:\n * 1. Extracts the response from context\n * 2. Fetches metadata for detected assets (assets without metadata)\n * 3. Enriches the response with fetched metadata\n * 4. Calls next() at the end to continue the middleware chain\n *\n * @returns The middleware function for the assets pipeline.\n */\n get assetsMiddleware(): Middleware {\n return forDataTypes(['metadata'], async (ctx, next) => {\n // Extract response from context\n const { response } = ctx;\n\n // Only fetch metadata for detected assets (assets without metadata)\n if (!response.detectedAssets) {\n return next(ctx);\n }\n\n const { assetsMetadata: stateMetadata } = ctx.getAssetsState();\n const assetIdsNeedingMetadata = new Set<string>();\n\n for (const detectedIds of Object.values(response.detectedAssets)) {\n for (const assetId of detectedIds) {\n // Skip if response already has metadata with image\n const responseMetadata = response.assetsMetadata?.[assetId];\n if (responseMetadata?.image) {\n continue;\n }\n\n // Skip if state already has metadata with image\n const existingMetadata = stateMetadata[assetId];\n if (existingMetadata?.image) {\n continue;\n }\n\n assetIdsNeedingMetadata.add(assetId);\n }\n }\n\n if (assetIdsNeedingMetadata.size === 0) {\n return next(ctx);\n }\n\n // Filter asset IDs to only include supported networks\n const supportedNetworks = await this.#getSupportedNetworks();\n const supportedAssetIds = this.#filterAssetsByNetwork(\n [...assetIdsNeedingMetadata],\n supportedNetworks,\n );\n\n if (supportedAssetIds.length === 0) {\n return next(ctx);\n }\n\n try {\n // Use ApiPlatformClient for fetching asset metadata\n // API returns an array with assetId as a property on each item\n const metadataResponse =\n await this.#apiClient.tokens.fetchV3Assets(supportedAssetIds);\n\n response.assetsMetadata ??= {};\n\n for (const assetData of metadataResponse) {\n const caipAssetId = assetData.assetId as Caip19AssetId;\n response.assetsMetadata[caipAssetId] =\n transformV3AssetResponseToMetadata(assetData.assetId, assetData);\n }\n } catch (error) {\n log('Failed to fetch metadata', { error });\n }\n\n // Call next() at the end to continue the middleware chain\n return next(ctx);\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ApiPlatformClient } from "@metamask/core-backend";
|
|
2
|
+
import type { Messenger } from "@metamask/messenger";
|
|
3
|
+
import type { Middleware } from "../types.cjs";
|
|
4
|
+
declare const CONTROLLER_NAME = "TokenDataSource";
|
|
5
|
+
/**
|
|
6
|
+
* Action to get the TokenDataSource middleware.
|
|
7
|
+
*/
|
|
8
|
+
export type TokenDataSourceGetAssetsMiddlewareAction = {
|
|
9
|
+
type: `${typeof CONTROLLER_NAME}:getAssetsMiddleware`;
|
|
10
|
+
handler: () => Middleware;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* All actions exposed by TokenDataSource.
|
|
14
|
+
*/
|
|
15
|
+
export type TokenDataSourceActions = TokenDataSourceGetAssetsMiddlewareAction;
|
|
16
|
+
/**
|
|
17
|
+
* TokenDataSource no longer needs external BackendApiClient actions.
|
|
18
|
+
* It uses ApiPlatformClient directly.
|
|
19
|
+
*/
|
|
20
|
+
export type TokenDataSourceAllowedActions = never;
|
|
21
|
+
export type TokenDataSourceMessenger = Messenger<typeof CONTROLLER_NAME, TokenDataSourceActions, never>;
|
|
22
|
+
export type TokenDataSourceOptions = {
|
|
23
|
+
messenger: TokenDataSourceMessenger;
|
|
24
|
+
/** ApiPlatformClient for API calls with caching */
|
|
25
|
+
queryApiClient: ApiPlatformClient;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* TokenDataSource enriches responses with token metadata from the Tokens API.
|
|
29
|
+
*
|
|
30
|
+
* This middleware-based data source:
|
|
31
|
+
* - Checks detected assets for missing metadata/images
|
|
32
|
+
* - Fetches metadata from Tokens API v3 for assets needing enrichment
|
|
33
|
+
* - Merges fetched metadata into the response
|
|
34
|
+
*
|
|
35
|
+
* Usage:
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Create and initialize (registers messenger actions)
|
|
38
|
+
* const tokenDataSource = new TokenDataSource({ messenger, queryApiClient });
|
|
39
|
+
*
|
|
40
|
+
* // Later, get middleware via messenger
|
|
41
|
+
* const middleware = messenger.call('TokenDataSource:getAssetsMiddleware');
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class TokenDataSource {
|
|
45
|
+
#private;
|
|
46
|
+
readonly name = "TokenDataSource";
|
|
47
|
+
constructor(options: TokenDataSourceOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Get the middleware for enriching responses with token metadata.
|
|
50
|
+
*
|
|
51
|
+
* This middleware:
|
|
52
|
+
* 1. Extracts the response from context
|
|
53
|
+
* 2. Fetches metadata for detected assets (assets without metadata)
|
|
54
|
+
* 3. Enriches the response with fetched metadata
|
|
55
|
+
* 4. Calls next() at the end to continue the middleware chain
|
|
56
|
+
*
|
|
57
|
+
* @returns The middleware function for the assets pipeline.
|
|
58
|
+
*/
|
|
59
|
+
get assetsMiddleware(): Middleware;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=TokenDataSource.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenDataSource.d.cts","sourceRoot":"","sources":["../../src/data-sources/TokenDataSource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,+BAA+B;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAMrD,OAAO,KAAK,EAAgC,UAAU,EAAE,qBAAiB;AAMzE,QAAA,MAAM,eAAe,oBAAoB,CAAC;AAQ1C;;GAEG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,GAAG,OAAO,eAAe,sBAAsB,CAAC;IACtD,OAAO,EAAE,MAAM,UAAU,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,wCAAwC,CAAC;AAE9E;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,eAAe,EACtB,sBAAsB,EACtB,KAAK,CACN,CAAC;AAMF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,wBAAwB,CAAC;IACpC,mDAAmD;IACnD,cAAc,EAAE,iBAAiB,CAAC;CACnC,CAAC;AAgCF;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;;IAC1B,QAAQ,CAAC,IAAI,qBAAmB;gBAOpB,OAAO,EAAE,sBAAsB;IA8D3C;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB,IAAI,UAAU,CAkEjC;CACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ApiPlatformClient } from "@metamask/core-backend";
|
|
2
|
+
import type { Messenger } from "@metamask/messenger";
|
|
3
|
+
import type { Middleware } from "../types.mjs";
|
|
4
|
+
declare const CONTROLLER_NAME = "TokenDataSource";
|
|
5
|
+
/**
|
|
6
|
+
* Action to get the TokenDataSource middleware.
|
|
7
|
+
*/
|
|
8
|
+
export type TokenDataSourceGetAssetsMiddlewareAction = {
|
|
9
|
+
type: `${typeof CONTROLLER_NAME}:getAssetsMiddleware`;
|
|
10
|
+
handler: () => Middleware;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* All actions exposed by TokenDataSource.
|
|
14
|
+
*/
|
|
15
|
+
export type TokenDataSourceActions = TokenDataSourceGetAssetsMiddlewareAction;
|
|
16
|
+
/**
|
|
17
|
+
* TokenDataSource no longer needs external BackendApiClient actions.
|
|
18
|
+
* It uses ApiPlatformClient directly.
|
|
19
|
+
*/
|
|
20
|
+
export type TokenDataSourceAllowedActions = never;
|
|
21
|
+
export type TokenDataSourceMessenger = Messenger<typeof CONTROLLER_NAME, TokenDataSourceActions, never>;
|
|
22
|
+
export type TokenDataSourceOptions = {
|
|
23
|
+
messenger: TokenDataSourceMessenger;
|
|
24
|
+
/** ApiPlatformClient for API calls with caching */
|
|
25
|
+
queryApiClient: ApiPlatformClient;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* TokenDataSource enriches responses with token metadata from the Tokens API.
|
|
29
|
+
*
|
|
30
|
+
* This middleware-based data source:
|
|
31
|
+
* - Checks detected assets for missing metadata/images
|
|
32
|
+
* - Fetches metadata from Tokens API v3 for assets needing enrichment
|
|
33
|
+
* - Merges fetched metadata into the response
|
|
34
|
+
*
|
|
35
|
+
* Usage:
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Create and initialize (registers messenger actions)
|
|
38
|
+
* const tokenDataSource = new TokenDataSource({ messenger, queryApiClient });
|
|
39
|
+
*
|
|
40
|
+
* // Later, get middleware via messenger
|
|
41
|
+
* const middleware = messenger.call('TokenDataSource:getAssetsMiddleware');
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class TokenDataSource {
|
|
45
|
+
#private;
|
|
46
|
+
readonly name = "TokenDataSource";
|
|
47
|
+
constructor(options: TokenDataSourceOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Get the middleware for enriching responses with token metadata.
|
|
50
|
+
*
|
|
51
|
+
* This middleware:
|
|
52
|
+
* 1. Extracts the response from context
|
|
53
|
+
* 2. Fetches metadata for detected assets (assets without metadata)
|
|
54
|
+
* 3. Enriches the response with fetched metadata
|
|
55
|
+
* 4. Calls next() at the end to continue the middleware chain
|
|
56
|
+
*
|
|
57
|
+
* @returns The middleware function for the assets pipeline.
|
|
58
|
+
*/
|
|
59
|
+
get assetsMiddleware(): Middleware;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=TokenDataSource.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenDataSource.d.mts","sourceRoot":"","sources":["../../src/data-sources/TokenDataSource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,+BAA+B;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAMrD,OAAO,KAAK,EAAgC,UAAU,EAAE,qBAAiB;AAMzE,QAAA,MAAM,eAAe,oBAAoB,CAAC;AAQ1C;;GAEG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,GAAG,OAAO,eAAe,sBAAsB,CAAC;IACtD,OAAO,EAAE,MAAM,UAAU,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,wCAAwC,CAAC;AAE9E;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,SAAS,CAC9C,OAAO,eAAe,EACtB,sBAAsB,EACtB,KAAK,CACN,CAAC;AAMF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,wBAAwB,CAAC;IACpC,mDAAmD;IACnD,cAAc,EAAE,iBAAiB,CAAC;CACnC,CAAC;AAgCF;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;;IAC1B,QAAQ,CAAC,IAAI,qBAAmB;gBAOpB,OAAO,EAAE,sBAAsB;IA8D3C;;;;;;;;;;OAUG;IACH,IAAI,gBAAgB,IAAI,UAAU,CAkEjC;CACF"}
|