@metamask-previews/assets-controller 2.4.0-preview-3685bfb → 2.4.0-preview-45f35b773

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 (36) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/AssetsController.cjs +26 -12
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +6 -20
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +6 -20
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +26 -12
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +2 -2
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts +2 -2
  14. package/dist/index.d.mts.map +1 -1
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/middlewares/ParallelMiddleware.cjs +56 -16
  17. package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
  18. package/dist/middlewares/ParallelMiddleware.d.cts +3 -7
  19. package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
  20. package/dist/middlewares/ParallelMiddleware.d.mts +3 -7
  21. package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
  22. package/dist/middlewares/ParallelMiddleware.mjs +56 -16
  23. package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
  24. package/dist/middlewares/index.cjs.map +1 -1
  25. package/dist/middlewares/index.d.cts +2 -1
  26. package/dist/middlewares/index.d.cts.map +1 -1
  27. package/dist/middlewares/index.d.mts +2 -1
  28. package/dist/middlewares/index.d.mts.map +1 -1
  29. package/dist/middlewares/index.mjs.map +1 -1
  30. package/dist/types.cjs.map +1 -1
  31. package/dist/types.d.cts +15 -0
  32. package/dist/types.d.cts.map +1 -1
  33. package/dist/types.d.mts +15 -0
  34. package/dist/types.d.mts.map +1 -1
  35. package/dist/types.mjs.map +1 -1
  36. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,2DAG4B;AAF1B,oHAAA,gBAAgB,OAAA;AAChB,mIAAA,+BAA+B,OAAA;AAsFjC,sCAAsC;AACtC,yDAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAI3B,6BAA6B;AAC7B,yDAAuD;AAA9C,qHAAA,qBAAqB,OAAA;AAS9B,kCAAkC;AAClC,yDAGwB;AAFtB,0HAAA,0BAA0B,OAAA;AAC1B,gIAAA,gCAAgC,OAAA;AAUlC,qBAAqB;AACrB,yDAAoE;AAA3D,6GAAA,aAAa,OAAA;AAAE,mHAAA,mBAAmB,OAAA;AAW3C,gFAAgF;AAChF,yDASwB;AARtB,8GAAA,cAAc,OAAA;AACd,oHAAA,oBAAoB,OAAA;AACpB,qHAAA,qBAAqB,OAAA;AACrB,YAAY;AACZ,kHAAA,kBAAkB,OAAA;AAClB,oBAAoB;AACpB,iHAAA,iBAAiB,OAAA;AACjB,uHAAA,uBAAuB,OAAA;AAUzB,0BAA0B;AAC1B,yDAAkE;AAAzD,+GAAA,eAAe,OAAA;AAAE,+GAAA,eAAe,OAAA;AASzC,cAAc;AACd,uDAAoD;AAA3C,kHAAA,mBAAmB,OAAA;AAE5B,YAAY;AACZ,2CAIiB;AAHf,yGAAA,gBAAgB,OAAA;AAChB,qHAAA,4BAA4B,OAAA;AAC5B,qHAAA,4BAA4B,OAAA;AAS9B,YAAY;AACZ,mDAI6B;AAH3B,yHAAA,8BAA8B,OAAA;AAC9B,+GAAA,oBAAoB,OAAA;AACpB,sHAAA,2BAA2B,OAAA","sourcesContent":["// Main controller export\nexport {\n AssetsController,\n getDefaultAssetsControllerState,\n} from './AssetsController';\nexport type { PendingTokenMetadata } from './AssetsController';\n\n// State and messenger types\nexport type {\n AssetsControllerState,\n AssetsControllerMessenger,\n AssetsControllerOptions,\n AssetsControllerFirstInitFetchMetaMetricsPayload,\n AssetsControllerGetStateAction,\n AssetsControllerActions,\n AssetsControllerStateChangeEvent,\n AssetsControllerBalanceChangedEvent,\n AssetsControllerPriceChangedEvent,\n AssetsControllerAssetsDetectedEvent,\n AssetsControllerEvents,\n} from './AssetsController';\nexport type {\n AssetsControllerGetAssetsAction,\n AssetsControllerGetAssetsBalanceAction,\n AssetsControllerGetAssetMetadataAction,\n AssetsControllerGetAssetsPriceAction,\n AssetsControllerAddCustomAssetAction,\n AssetsControllerRemoveCustomAssetAction,\n AssetsControllerGetCustomAssetsAction,\n AssetsControllerHideAssetAction,\n AssetsControllerUnhideAssetAction,\n AssetsControllerGetExchangeRatesForBridgeAction,\n AssetsControllerGetStateForTransactionPayAction,\n AssetsControllerMethodActions,\n} from './AssetsController-method-action-types';\n\n// Core types\nexport type {\n // CAIP types\n Caip19AssetId,\n AccountId,\n ChainId,\n // Asset types\n AssetType,\n TokenStandard,\n // Contract data types\n TokenFees,\n HoneypotStatus,\n StorageSlots,\n LocalizedDescription,\n // Metadata types\n BaseAssetMetadata,\n FungibleAssetMetadata,\n ERC721AssetMetadata,\n ERC1155AssetMetadata,\n AssetMetadata,\n // Price types\n BaseAssetPrice,\n FungibleAssetPrice,\n NFTAssetPrice,\n AssetPrice,\n // Balance types\n FungibleAssetBalance,\n ERC721AssetBalance,\n ERC1155AssetBalance,\n AssetBalance,\n // Data source types\n AccountWithSupportedChains,\n DataType,\n DataRequest,\n DataResponse,\n AssetsUpdateMode,\n // Middleware types\n Context,\n NextFunction,\n Middleware,\n FetchContext,\n FetchNextFunction,\n FetchMiddleware,\n SubscriptionResponse,\n // Combined asset type\n Asset,\n // Event types\n BalanceChangeEvent,\n PriceChangeEvent,\n MetadataChangeEvent,\n AssetsDetectedEvent,\n} from './types';\n\n// Data sources - base class and types\nexport { AbstractDataSource } from './data-sources';\n\nexport type { DataSourceState, SubscriptionRequest } from './data-sources';\n\n// Data sources - AccountsApi\nexport { AccountsApiDataSource } from './data-sources';\n\nexport type {\n AccountsApiDataSourceConfig,\n AccountsApiDataSourceOptions,\n AccountsApiDataSourceState,\n AccountsApiDataSourceAllowedActions,\n} from './data-sources';\n\n// Data sources - BackendWebsocket\nexport {\n BackendWebsocketDataSource,\n createBackendWebsocketDataSource,\n} from './data-sources';\n\nexport type {\n BackendWebsocketDataSourceOptions,\n BackendWebsocketDataSourceState,\n BackendWebsocketDataSourceAllowedActions,\n BackendWebsocketDataSourceAllowedEvents,\n} from './data-sources';\n\n// Data sources - RPC\nexport { RpcDataSource, createRpcDataSource } from './data-sources';\n\nexport type {\n RpcDataSourceConfig,\n RpcDataSourceOptions,\n RpcDataSourceState,\n RpcDataSourceAllowedActions,\n RpcDataSourceAllowedEvents,\n ChainStatus,\n} from './data-sources';\n\n// Data sources - Unified Snap Data Source (dynamically discovers keyring snaps)\nexport {\n SnapDataSource,\n createSnapDataSource,\n SNAP_DATA_SOURCE_NAME,\n // Constants\n KEYRING_PERMISSION,\n // Utility functions\n getChainIdsCaveat,\n extractChainFromAssetId,\n} from './data-sources';\n\nexport type {\n SnapDataSourceState,\n SnapDataSourceOptions,\n SnapDataSourceAllowedActions,\n SnapDataSourceAllowedEvents,\n} from './data-sources';\n\n// Enrichment data sources\nexport { TokenDataSource, PriceDataSource } from './data-sources';\n\nexport type {\n TokenDataSourceOptions,\n TokenDataSourceAllowedActions,\n PriceDataSourceConfig,\n PriceDataSourceOptions,\n} from './data-sources';\n\n// Middlewares\nexport { DetectionMiddleware } from './middlewares';\n\n// Utilities\nexport {\n normalizeAssetId,\n formatExchangeRatesForBridge,\n formatStateForTransactionPay,\n} from './utils';\nexport type {\n AccountForLegacyFormat,\n BridgeExchangeRatesFormat,\n LegacyToken,\n TransactionPayLegacyFormat,\n} from './utils';\n\n// Selectors\nexport {\n getAggregatedBalanceForAccount,\n getGroupIdForAccount,\n getInternalAccountsForGroup,\n} from './selectors/balance';\n\nexport type {\n AccountsById,\n AggregatedBalanceEntry,\n AggregatedBalanceForAccount,\n EnabledNetworkMap,\n} from './selectors/balance';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,2DAG4B;AAF1B,oHAAA,gBAAgB,OAAA;AAChB,mIAAA,+BAA+B,OAAA;AAsFjC,sCAAsC;AACtC,yDAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAI3B,6BAA6B;AAC7B,yDAAuD;AAA9C,qHAAA,qBAAqB,OAAA;AAS9B,kCAAkC;AAClC,yDAGwB;AAFtB,0HAAA,0BAA0B,OAAA;AAC1B,gIAAA,gCAAgC,OAAA;AAUlC,qBAAqB;AACrB,yDAAoE;AAA3D,6GAAA,aAAa,OAAA;AAAE,mHAAA,mBAAmB,OAAA;AAW3C,gFAAgF;AAChF,yDASwB;AARtB,8GAAA,cAAc,OAAA;AACd,oHAAA,oBAAoB,OAAA;AACpB,qHAAA,qBAAqB,OAAA;AACrB,YAAY;AACZ,kHAAA,kBAAkB,OAAA;AAClB,oBAAoB;AACpB,iHAAA,iBAAiB,OAAA;AACjB,uHAAA,uBAAuB,OAAA;AAUzB,0BAA0B;AAC1B,yDAAkE;AAAzD,+GAAA,eAAe,OAAA;AAAE,+GAAA,eAAe,OAAA;AASzC,cAAc;AACd,uDAAoD;AAA3C,kHAAA,mBAAmB,OAAA;AAE5B,YAAY;AACZ,2CAIiB;AAHf,yGAAA,gBAAgB,OAAA;AAChB,qHAAA,4BAA4B,OAAA;AAC5B,qHAAA,4BAA4B,OAAA;AAS9B,YAAY;AACZ,mDAI6B;AAH3B,yHAAA,8BAA8B,OAAA;AAC9B,+GAAA,oBAAoB,OAAA;AACpB,sHAAA,2BAA2B,OAAA","sourcesContent":["// Main controller export\nexport {\n AssetsController,\n getDefaultAssetsControllerState,\n} from './AssetsController';\nexport type { PendingTokenMetadata } from './AssetsController';\n\n// State and messenger types\nexport type {\n AssetsControllerState,\n AssetsControllerMessenger,\n AssetsControllerOptions,\n AssetsControllerGetStateAction,\n AssetsControllerActions,\n AssetsControllerStateChangeEvent,\n AssetsControllerBalanceChangedEvent,\n AssetsControllerPriceChangedEvent,\n AssetsControllerAssetsDetectedEvent,\n AssetsControllerEvents,\n} from './AssetsController';\nexport type {\n AssetsControllerGetAssetsAction,\n AssetsControllerGetAssetsBalanceAction,\n AssetsControllerGetAssetMetadataAction,\n AssetsControllerGetAssetsPriceAction,\n AssetsControllerAddCustomAssetAction,\n AssetsControllerRemoveCustomAssetAction,\n AssetsControllerGetCustomAssetsAction,\n AssetsControllerHideAssetAction,\n AssetsControllerUnhideAssetAction,\n AssetsControllerGetExchangeRatesForBridgeAction,\n AssetsControllerGetStateForTransactionPayAction,\n AssetsControllerMethodActions,\n} from './AssetsController-method-action-types';\n\n// Core types\nexport type {\n // CAIP types\n Caip19AssetId,\n AccountId,\n ChainId,\n // Asset types\n AssetType,\n TokenStandard,\n // Contract data types\n TokenFees,\n HoneypotStatus,\n StorageSlots,\n LocalizedDescription,\n // Metadata types\n BaseAssetMetadata,\n FungibleAssetMetadata,\n ERC721AssetMetadata,\n ERC1155AssetMetadata,\n AssetMetadata,\n // Price types\n BaseAssetPrice,\n FungibleAssetPrice,\n NFTAssetPrice,\n AssetPrice,\n // Balance types\n FungibleAssetBalance,\n ERC721AssetBalance,\n ERC1155AssetBalance,\n AssetBalance,\n // Data source types\n AccountWithSupportedChains,\n DataType,\n DataRequest,\n DataResponse,\n AssetsUpdateMode,\n // Middleware types\n Context,\n NextFunction,\n Middleware,\n AssetsDataSource,\n FetchContext,\n FetchNextFunction,\n FetchMiddleware,\n SubscriptionResponse,\n // Combined asset type\n Asset,\n // Event types\n BalanceChangeEvent,\n PriceChangeEvent,\n MetadataChangeEvent,\n AssetsDetectedEvent,\n} from './types';\n\n// Data sources - base class and types\nexport { AbstractDataSource } from './data-sources';\n\nexport type { DataSourceState, SubscriptionRequest } from './data-sources';\n\n// Data sources - AccountsApi\nexport { AccountsApiDataSource } from './data-sources';\n\nexport type {\n AccountsApiDataSourceConfig,\n AccountsApiDataSourceOptions,\n AccountsApiDataSourceState,\n AccountsApiDataSourceAllowedActions,\n} from './data-sources';\n\n// Data sources - BackendWebsocket\nexport {\n BackendWebsocketDataSource,\n createBackendWebsocketDataSource,\n} from './data-sources';\n\nexport type {\n BackendWebsocketDataSourceOptions,\n BackendWebsocketDataSourceState,\n BackendWebsocketDataSourceAllowedActions,\n BackendWebsocketDataSourceAllowedEvents,\n} from './data-sources';\n\n// Data sources - RPC\nexport { RpcDataSource, createRpcDataSource } from './data-sources';\n\nexport type {\n RpcDataSourceConfig,\n RpcDataSourceOptions,\n RpcDataSourceState,\n RpcDataSourceAllowedActions,\n RpcDataSourceAllowedEvents,\n ChainStatus,\n} from './data-sources';\n\n// Data sources - Unified Snap Data Source (dynamically discovers keyring snaps)\nexport {\n SnapDataSource,\n createSnapDataSource,\n SNAP_DATA_SOURCE_NAME,\n // Constants\n KEYRING_PERMISSION,\n // Utility functions\n getChainIdsCaveat,\n extractChainFromAssetId,\n} from './data-sources';\n\nexport type {\n SnapDataSourceState,\n SnapDataSourceOptions,\n SnapDataSourceAllowedActions,\n SnapDataSourceAllowedEvents,\n} from './data-sources';\n\n// Enrichment data sources\nexport { TokenDataSource, PriceDataSource } from './data-sources';\n\nexport type {\n TokenDataSourceOptions,\n TokenDataSourceAllowedActions,\n PriceDataSourceConfig,\n PriceDataSourceOptions,\n} from './data-sources';\n\n// Middlewares\nexport { DetectionMiddleware } from './middlewares';\n\n// Utilities\nexport {\n normalizeAssetId,\n formatExchangeRatesForBridge,\n formatStateForTransactionPay,\n} from './utils';\nexport type {\n AccountForLegacyFormat,\n BridgeExchangeRatesFormat,\n LegacyToken,\n TransactionPayLegacyFormat,\n} from './utils';\n\n// Selectors\nexport {\n getAggregatedBalanceForAccount,\n getGroupIdForAccount,\n getInternalAccountsForGroup,\n} from './selectors/balance';\n\nexport type {\n AccountsById,\n AggregatedBalanceEntry,\n AggregatedBalanceForAccount,\n EnabledNetworkMap,\n} from './selectors/balance';\n"]}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { AssetsController, getDefaultAssetsControllerState, } from "./AssetsController.cjs";
2
2
  export type { PendingTokenMetadata } from "./AssetsController.cjs";
3
- export type { AssetsControllerState, AssetsControllerMessenger, AssetsControllerOptions, AssetsControllerFirstInitFetchMetaMetricsPayload, AssetsControllerGetStateAction, AssetsControllerActions, AssetsControllerStateChangeEvent, AssetsControllerBalanceChangedEvent, AssetsControllerPriceChangedEvent, AssetsControllerAssetsDetectedEvent, AssetsControllerEvents, } from "./AssetsController.cjs";
3
+ export type { AssetsControllerState, AssetsControllerMessenger, AssetsControllerOptions, AssetsControllerGetStateAction, AssetsControllerActions, AssetsControllerStateChangeEvent, AssetsControllerBalanceChangedEvent, AssetsControllerPriceChangedEvent, AssetsControllerAssetsDetectedEvent, AssetsControllerEvents, } from "./AssetsController.cjs";
4
4
  export type { AssetsControllerGetAssetsAction, AssetsControllerGetAssetsBalanceAction, AssetsControllerGetAssetMetadataAction, AssetsControllerGetAssetsPriceAction, AssetsControllerAddCustomAssetAction, AssetsControllerRemoveCustomAssetAction, AssetsControllerGetCustomAssetsAction, AssetsControllerHideAssetAction, AssetsControllerUnhideAssetAction, AssetsControllerGetExchangeRatesForBridgeAction, AssetsControllerGetStateForTransactionPayAction, AssetsControllerMethodActions, } from "./AssetsController-method-action-types.cjs";
5
- export type { Caip19AssetId, AccountId, ChainId, AssetType, TokenStandard, TokenFees, HoneypotStatus, StorageSlots, LocalizedDescription, BaseAssetMetadata, FungibleAssetMetadata, ERC721AssetMetadata, ERC1155AssetMetadata, AssetMetadata, BaseAssetPrice, FungibleAssetPrice, NFTAssetPrice, AssetPrice, FungibleAssetBalance, ERC721AssetBalance, ERC1155AssetBalance, AssetBalance, AccountWithSupportedChains, DataType, DataRequest, DataResponse, AssetsUpdateMode, Context, NextFunction, Middleware, FetchContext, FetchNextFunction, FetchMiddleware, SubscriptionResponse, Asset, BalanceChangeEvent, PriceChangeEvent, MetadataChangeEvent, AssetsDetectedEvent, } from "./types.cjs";
5
+ export type { Caip19AssetId, AccountId, ChainId, AssetType, TokenStandard, TokenFees, HoneypotStatus, StorageSlots, LocalizedDescription, BaseAssetMetadata, FungibleAssetMetadata, ERC721AssetMetadata, ERC1155AssetMetadata, AssetMetadata, BaseAssetPrice, FungibleAssetPrice, NFTAssetPrice, AssetPrice, FungibleAssetBalance, ERC721AssetBalance, ERC1155AssetBalance, AssetBalance, AccountWithSupportedChains, DataType, DataRequest, DataResponse, AssetsUpdateMode, Context, NextFunction, Middleware, AssetsDataSource, FetchContext, FetchNextFunction, FetchMiddleware, SubscriptionResponse, Asset, BalanceChangeEvent, PriceChangeEvent, MetadataChangeEvent, AssetsDetectedEvent, } from "./types.cjs";
6
6
  export { AbstractDataSource } from "./data-sources/index.cjs";
7
7
  export type { DataSourceState, SubscriptionRequest } from "./data-sources/index.cjs";
8
8
  export { AccountsApiDataSource } from "./data-sources/index.cjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA2B;AAC5B,YAAY,EAAE,oBAAoB,EAAE,+BAA2B;AAG/D,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,gDAAgD,EAChD,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,mCAAmC,EACnC,iCAAiC,EACjC,mCAAmC,EACnC,sBAAsB,GACvB,+BAA2B;AAC5B,YAAY,EACV,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,qCAAqC,EACrC,+BAA+B,EAC/B,iCAAiC,EACjC,+CAA+C,EAC/C,+CAA+C,EAC/C,6BAA6B,GAC9B,mDAA+C;AAGhD,YAAY,EAEV,aAAa,EACb,SAAS,EACT,OAAO,EAEP,SAAS,EACT,aAAa,EAEb,SAAS,EACT,cAAc,EACd,YAAY,EACZ,oBAAoB,EAEpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EAEb,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EAEV,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EAEZ,0BAA0B,EAC1B,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAEhB,OAAO,EACP,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAEpB,KAAK,EAEL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,oBAAgB;AAGjB,OAAO,EAAE,kBAAkB,EAAE,iCAAuB;AAEpD,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iCAAuB;AAG3E,OAAO,EAAE,qBAAqB,EAAE,iCAAuB;AAEvD,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,mCAAmC,GACpC,iCAAuB;AAGxB,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,iCAAuB;AAExB,YAAY,EACV,iCAAiC,EACjC,+BAA+B,EAC/B,wCAAwC,EACxC,uCAAuC,GACxC,iCAAuB;AAGxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iCAAuB;AAEpE,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,0BAA0B,EAC1B,WAAW,GACZ,iCAAuB;AAGxB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EAErB,kBAAkB,EAElB,iBAAiB,EACjB,uBAAuB,GACxB,iCAAuB;AAExB,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,iCAAuB;AAGxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iCAAuB;AAElE,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,sBAAsB,GACvB,iCAAuB;AAGxB,OAAO,EAAE,mBAAmB,EAAE,gCAAsB;AAGpD,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,0BAAgB;AACjB,YAAY,EACV,sBAAsB,EACtB,yBAAyB,EACzB,WAAW,EACX,0BAA0B,GAC3B,0BAAgB;AAGjB,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,GAC5B,gCAA4B;AAE7B,YAAY,EACV,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,GAClB,gCAA4B"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA2B;AAC5B,YAAY,EAAE,oBAAoB,EAAE,+BAA2B;AAG/D,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,mCAAmC,EACnC,iCAAiC,EACjC,mCAAmC,EACnC,sBAAsB,GACvB,+BAA2B;AAC5B,YAAY,EACV,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,qCAAqC,EACrC,+BAA+B,EAC/B,iCAAiC,EACjC,+CAA+C,EAC/C,+CAA+C,EAC/C,6BAA6B,GAC9B,mDAA+C;AAGhD,YAAY,EAEV,aAAa,EACb,SAAS,EACT,OAAO,EAEP,SAAS,EACT,aAAa,EAEb,SAAS,EACT,cAAc,EACd,YAAY,EACZ,oBAAoB,EAEpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EAEb,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EAEV,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EAEZ,0BAA0B,EAC1B,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAEhB,OAAO,EACP,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAEpB,KAAK,EAEL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,oBAAgB;AAGjB,OAAO,EAAE,kBAAkB,EAAE,iCAAuB;AAEpD,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iCAAuB;AAG3E,OAAO,EAAE,qBAAqB,EAAE,iCAAuB;AAEvD,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,mCAAmC,GACpC,iCAAuB;AAGxB,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,iCAAuB;AAExB,YAAY,EACV,iCAAiC,EACjC,+BAA+B,EAC/B,wCAAwC,EACxC,uCAAuC,GACxC,iCAAuB;AAGxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iCAAuB;AAEpE,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,0BAA0B,EAC1B,WAAW,GACZ,iCAAuB;AAGxB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EAErB,kBAAkB,EAElB,iBAAiB,EACjB,uBAAuB,GACxB,iCAAuB;AAExB,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,iCAAuB;AAGxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iCAAuB;AAElE,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,sBAAsB,GACvB,iCAAuB;AAGxB,OAAO,EAAE,mBAAmB,EAAE,gCAAsB;AAGpD,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,0BAAgB;AACjB,YAAY,EACV,sBAAsB,EACtB,yBAAyB,EACzB,WAAW,EACX,0BAA0B,GAC3B,0BAAgB;AAGjB,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,GAC5B,gCAA4B;AAE7B,YAAY,EACV,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,GAClB,gCAA4B"}
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { AssetsController, getDefaultAssetsControllerState, } from "./AssetsController.mjs";
2
2
  export type { PendingTokenMetadata } from "./AssetsController.mjs";
3
- export type { AssetsControllerState, AssetsControllerMessenger, AssetsControllerOptions, AssetsControllerFirstInitFetchMetaMetricsPayload, AssetsControllerGetStateAction, AssetsControllerActions, AssetsControllerStateChangeEvent, AssetsControllerBalanceChangedEvent, AssetsControllerPriceChangedEvent, AssetsControllerAssetsDetectedEvent, AssetsControllerEvents, } from "./AssetsController.mjs";
3
+ export type { AssetsControllerState, AssetsControllerMessenger, AssetsControllerOptions, AssetsControllerGetStateAction, AssetsControllerActions, AssetsControllerStateChangeEvent, AssetsControllerBalanceChangedEvent, AssetsControllerPriceChangedEvent, AssetsControllerAssetsDetectedEvent, AssetsControllerEvents, } from "./AssetsController.mjs";
4
4
  export type { AssetsControllerGetAssetsAction, AssetsControllerGetAssetsBalanceAction, AssetsControllerGetAssetMetadataAction, AssetsControllerGetAssetsPriceAction, AssetsControllerAddCustomAssetAction, AssetsControllerRemoveCustomAssetAction, AssetsControllerGetCustomAssetsAction, AssetsControllerHideAssetAction, AssetsControllerUnhideAssetAction, AssetsControllerGetExchangeRatesForBridgeAction, AssetsControllerGetStateForTransactionPayAction, AssetsControllerMethodActions, } from "./AssetsController-method-action-types.mjs";
5
- export type { Caip19AssetId, AccountId, ChainId, AssetType, TokenStandard, TokenFees, HoneypotStatus, StorageSlots, LocalizedDescription, BaseAssetMetadata, FungibleAssetMetadata, ERC721AssetMetadata, ERC1155AssetMetadata, AssetMetadata, BaseAssetPrice, FungibleAssetPrice, NFTAssetPrice, AssetPrice, FungibleAssetBalance, ERC721AssetBalance, ERC1155AssetBalance, AssetBalance, AccountWithSupportedChains, DataType, DataRequest, DataResponse, AssetsUpdateMode, Context, NextFunction, Middleware, FetchContext, FetchNextFunction, FetchMiddleware, SubscriptionResponse, Asset, BalanceChangeEvent, PriceChangeEvent, MetadataChangeEvent, AssetsDetectedEvent, } from "./types.mjs";
5
+ export type { Caip19AssetId, AccountId, ChainId, AssetType, TokenStandard, TokenFees, HoneypotStatus, StorageSlots, LocalizedDescription, BaseAssetMetadata, FungibleAssetMetadata, ERC721AssetMetadata, ERC1155AssetMetadata, AssetMetadata, BaseAssetPrice, FungibleAssetPrice, NFTAssetPrice, AssetPrice, FungibleAssetBalance, ERC721AssetBalance, ERC1155AssetBalance, AssetBalance, AccountWithSupportedChains, DataType, DataRequest, DataResponse, AssetsUpdateMode, Context, NextFunction, Middleware, AssetsDataSource, FetchContext, FetchNextFunction, FetchMiddleware, SubscriptionResponse, Asset, BalanceChangeEvent, PriceChangeEvent, MetadataChangeEvent, AssetsDetectedEvent, } from "./types.mjs";
6
6
  export { AbstractDataSource } from "./data-sources/index.mjs";
7
7
  export type { DataSourceState, SubscriptionRequest } from "./data-sources/index.mjs";
8
8
  export { AccountsApiDataSource } from "./data-sources/index.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA2B;AAC5B,YAAY,EAAE,oBAAoB,EAAE,+BAA2B;AAG/D,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,gDAAgD,EAChD,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,mCAAmC,EACnC,iCAAiC,EACjC,mCAAmC,EACnC,sBAAsB,GACvB,+BAA2B;AAC5B,YAAY,EACV,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,qCAAqC,EACrC,+BAA+B,EAC/B,iCAAiC,EACjC,+CAA+C,EAC/C,+CAA+C,EAC/C,6BAA6B,GAC9B,mDAA+C;AAGhD,YAAY,EAEV,aAAa,EACb,SAAS,EACT,OAAO,EAEP,SAAS,EACT,aAAa,EAEb,SAAS,EACT,cAAc,EACd,YAAY,EACZ,oBAAoB,EAEpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EAEb,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EAEV,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EAEZ,0BAA0B,EAC1B,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAEhB,OAAO,EACP,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAEpB,KAAK,EAEL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,oBAAgB;AAGjB,OAAO,EAAE,kBAAkB,EAAE,iCAAuB;AAEpD,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iCAAuB;AAG3E,OAAO,EAAE,qBAAqB,EAAE,iCAAuB;AAEvD,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,mCAAmC,GACpC,iCAAuB;AAGxB,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,iCAAuB;AAExB,YAAY,EACV,iCAAiC,EACjC,+BAA+B,EAC/B,wCAAwC,EACxC,uCAAuC,GACxC,iCAAuB;AAGxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iCAAuB;AAEpE,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,0BAA0B,EAC1B,WAAW,GACZ,iCAAuB;AAGxB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EAErB,kBAAkB,EAElB,iBAAiB,EACjB,uBAAuB,GACxB,iCAAuB;AAExB,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,iCAAuB;AAGxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iCAAuB;AAElE,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,sBAAsB,GACvB,iCAAuB;AAGxB,OAAO,EAAE,mBAAmB,EAAE,gCAAsB;AAGpD,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,0BAAgB;AACjB,YAAY,EACV,sBAAsB,EACtB,yBAAyB,EACzB,WAAW,EACX,0BAA0B,GAC3B,0BAAgB;AAGjB,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,GAC5B,gCAA4B;AAE7B,YAAY,EACV,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,GAClB,gCAA4B"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA2B;AAC5B,YAAY,EAAE,oBAAoB,EAAE,+BAA2B;AAG/D,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,mCAAmC,EACnC,iCAAiC,EACjC,mCAAmC,EACnC,sBAAsB,GACvB,+BAA2B;AAC5B,YAAY,EACV,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,qCAAqC,EACrC,+BAA+B,EAC/B,iCAAiC,EACjC,+CAA+C,EAC/C,+CAA+C,EAC/C,6BAA6B,GAC9B,mDAA+C;AAGhD,YAAY,EAEV,aAAa,EACb,SAAS,EACT,OAAO,EAEP,SAAS,EACT,aAAa,EAEb,SAAS,EACT,cAAc,EACd,YAAY,EACZ,oBAAoB,EAEpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EAEb,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EAEV,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EAEZ,0BAA0B,EAC1B,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAEhB,OAAO,EACP,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EAEpB,KAAK,EAEL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,oBAAgB;AAGjB,OAAO,EAAE,kBAAkB,EAAE,iCAAuB;AAEpD,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iCAAuB;AAG3E,OAAO,EAAE,qBAAqB,EAAE,iCAAuB;AAEvD,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,mCAAmC,GACpC,iCAAuB;AAGxB,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,GACjC,iCAAuB;AAExB,YAAY,EACV,iCAAiC,EACjC,+BAA+B,EAC/B,wCAAwC,EACxC,uCAAuC,GACxC,iCAAuB;AAGxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iCAAuB;AAEpE,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,0BAA0B,EAC1B,WAAW,GACZ,iCAAuB;AAGxB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EAErB,kBAAkB,EAElB,iBAAiB,EACjB,uBAAuB,GACxB,iCAAuB;AAExB,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,iCAAuB;AAGxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iCAAuB;AAElE,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,sBAAsB,GACvB,iCAAuB;AAGxB,OAAO,EAAE,mBAAmB,EAAE,gCAAsB;AAGpD,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,0BAAgB;AACjB,YAAY,EACV,sBAAsB,EACtB,yBAAyB,EACzB,WAAW,EACX,0BAA0B,GAC3B,0BAAgB;AAGjB,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,GAC5B,gCAA4B;AAE7B,YAAY,EACV,YAAY,EACZ,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,GAClB,gCAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAChC,+BAA2B;AAqF5B,sCAAsC;AACtC,OAAO,EAAE,kBAAkB,EAAE,iCAAuB;AAIpD,6BAA6B;AAC7B,OAAO,EAAE,qBAAqB,EAAE,iCAAuB;AASvD,kCAAkC;AAClC,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EACjC,iCAAuB;AASxB,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iCAAuB;AAWpE,gFAAgF;AAChF,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB;AACrB,YAAY;AACZ,kBAAkB;AAClB,oBAAoB;AACpB,iBAAiB,EACjB,uBAAuB,EACxB,iCAAuB;AASxB,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iCAAuB;AASlE,cAAc;AACd,OAAO,EAAE,mBAAmB,EAAE,gCAAsB;AAEpD,YAAY;AACZ,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,EAC7B,0BAAgB;AAQjB,YAAY;AACZ,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC5B,gCAA4B","sourcesContent":["// Main controller export\nexport {\n AssetsController,\n getDefaultAssetsControllerState,\n} from './AssetsController';\nexport type { PendingTokenMetadata } from './AssetsController';\n\n// State and messenger types\nexport type {\n AssetsControllerState,\n AssetsControllerMessenger,\n AssetsControllerOptions,\n AssetsControllerFirstInitFetchMetaMetricsPayload,\n AssetsControllerGetStateAction,\n AssetsControllerActions,\n AssetsControllerStateChangeEvent,\n AssetsControllerBalanceChangedEvent,\n AssetsControllerPriceChangedEvent,\n AssetsControllerAssetsDetectedEvent,\n AssetsControllerEvents,\n} from './AssetsController';\nexport type {\n AssetsControllerGetAssetsAction,\n AssetsControllerGetAssetsBalanceAction,\n AssetsControllerGetAssetMetadataAction,\n AssetsControllerGetAssetsPriceAction,\n AssetsControllerAddCustomAssetAction,\n AssetsControllerRemoveCustomAssetAction,\n AssetsControllerGetCustomAssetsAction,\n AssetsControllerHideAssetAction,\n AssetsControllerUnhideAssetAction,\n AssetsControllerGetExchangeRatesForBridgeAction,\n AssetsControllerGetStateForTransactionPayAction,\n AssetsControllerMethodActions,\n} from './AssetsController-method-action-types';\n\n// Core types\nexport type {\n // CAIP types\n Caip19AssetId,\n AccountId,\n ChainId,\n // Asset types\n AssetType,\n TokenStandard,\n // Contract data types\n TokenFees,\n HoneypotStatus,\n StorageSlots,\n LocalizedDescription,\n // Metadata types\n BaseAssetMetadata,\n FungibleAssetMetadata,\n ERC721AssetMetadata,\n ERC1155AssetMetadata,\n AssetMetadata,\n // Price types\n BaseAssetPrice,\n FungibleAssetPrice,\n NFTAssetPrice,\n AssetPrice,\n // Balance types\n FungibleAssetBalance,\n ERC721AssetBalance,\n ERC1155AssetBalance,\n AssetBalance,\n // Data source types\n AccountWithSupportedChains,\n DataType,\n DataRequest,\n DataResponse,\n AssetsUpdateMode,\n // Middleware types\n Context,\n NextFunction,\n Middleware,\n FetchContext,\n FetchNextFunction,\n FetchMiddleware,\n SubscriptionResponse,\n // Combined asset type\n Asset,\n // Event types\n BalanceChangeEvent,\n PriceChangeEvent,\n MetadataChangeEvent,\n AssetsDetectedEvent,\n} from './types';\n\n// Data sources - base class and types\nexport { AbstractDataSource } from './data-sources';\n\nexport type { DataSourceState, SubscriptionRequest } from './data-sources';\n\n// Data sources - AccountsApi\nexport { AccountsApiDataSource } from './data-sources';\n\nexport type {\n AccountsApiDataSourceConfig,\n AccountsApiDataSourceOptions,\n AccountsApiDataSourceState,\n AccountsApiDataSourceAllowedActions,\n} from './data-sources';\n\n// Data sources - BackendWebsocket\nexport {\n BackendWebsocketDataSource,\n createBackendWebsocketDataSource,\n} from './data-sources';\n\nexport type {\n BackendWebsocketDataSourceOptions,\n BackendWebsocketDataSourceState,\n BackendWebsocketDataSourceAllowedActions,\n BackendWebsocketDataSourceAllowedEvents,\n} from './data-sources';\n\n// Data sources - RPC\nexport { RpcDataSource, createRpcDataSource } from './data-sources';\n\nexport type {\n RpcDataSourceConfig,\n RpcDataSourceOptions,\n RpcDataSourceState,\n RpcDataSourceAllowedActions,\n RpcDataSourceAllowedEvents,\n ChainStatus,\n} from './data-sources';\n\n// Data sources - Unified Snap Data Source (dynamically discovers keyring snaps)\nexport {\n SnapDataSource,\n createSnapDataSource,\n SNAP_DATA_SOURCE_NAME,\n // Constants\n KEYRING_PERMISSION,\n // Utility functions\n getChainIdsCaveat,\n extractChainFromAssetId,\n} from './data-sources';\n\nexport type {\n SnapDataSourceState,\n SnapDataSourceOptions,\n SnapDataSourceAllowedActions,\n SnapDataSourceAllowedEvents,\n} from './data-sources';\n\n// Enrichment data sources\nexport { TokenDataSource, PriceDataSource } from './data-sources';\n\nexport type {\n TokenDataSourceOptions,\n TokenDataSourceAllowedActions,\n PriceDataSourceConfig,\n PriceDataSourceOptions,\n} from './data-sources';\n\n// Middlewares\nexport { DetectionMiddleware } from './middlewares';\n\n// Utilities\nexport {\n normalizeAssetId,\n formatExchangeRatesForBridge,\n formatStateForTransactionPay,\n} from './utils';\nexport type {\n AccountForLegacyFormat,\n BridgeExchangeRatesFormat,\n LegacyToken,\n TransactionPayLegacyFormat,\n} from './utils';\n\n// Selectors\nexport {\n getAggregatedBalanceForAccount,\n getGroupIdForAccount,\n getInternalAccountsForGroup,\n} from './selectors/balance';\n\nexport type {\n AccountsById,\n AggregatedBalanceEntry,\n AggregatedBalanceForAccount,\n EnabledNetworkMap,\n} from './selectors/balance';\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAChC,+BAA2B;AAqF5B,sCAAsC;AACtC,OAAO,EAAE,kBAAkB,EAAE,iCAAuB;AAIpD,6BAA6B;AAC7B,OAAO,EAAE,qBAAqB,EAAE,iCAAuB;AASvD,kCAAkC;AAClC,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EACjC,iCAAuB;AASxB,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iCAAuB;AAWpE,gFAAgF;AAChF,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB;AACrB,YAAY;AACZ,kBAAkB;AAClB,oBAAoB;AACpB,iBAAiB,EACjB,uBAAuB,EACxB,iCAAuB;AASxB,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iCAAuB;AASlE,cAAc;AACd,OAAO,EAAE,mBAAmB,EAAE,gCAAsB;AAEpD,YAAY;AACZ,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,EAC7B,0BAAgB;AAQjB,YAAY;AACZ,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC5B,gCAA4B","sourcesContent":["// Main controller export\nexport {\n AssetsController,\n getDefaultAssetsControllerState,\n} from './AssetsController';\nexport type { PendingTokenMetadata } from './AssetsController';\n\n// State and messenger types\nexport type {\n AssetsControllerState,\n AssetsControllerMessenger,\n AssetsControllerOptions,\n AssetsControllerGetStateAction,\n AssetsControllerActions,\n AssetsControllerStateChangeEvent,\n AssetsControllerBalanceChangedEvent,\n AssetsControllerPriceChangedEvent,\n AssetsControllerAssetsDetectedEvent,\n AssetsControllerEvents,\n} from './AssetsController';\nexport type {\n AssetsControllerGetAssetsAction,\n AssetsControllerGetAssetsBalanceAction,\n AssetsControllerGetAssetMetadataAction,\n AssetsControllerGetAssetsPriceAction,\n AssetsControllerAddCustomAssetAction,\n AssetsControllerRemoveCustomAssetAction,\n AssetsControllerGetCustomAssetsAction,\n AssetsControllerHideAssetAction,\n AssetsControllerUnhideAssetAction,\n AssetsControllerGetExchangeRatesForBridgeAction,\n AssetsControllerGetStateForTransactionPayAction,\n AssetsControllerMethodActions,\n} from './AssetsController-method-action-types';\n\n// Core types\nexport type {\n // CAIP types\n Caip19AssetId,\n AccountId,\n ChainId,\n // Asset types\n AssetType,\n TokenStandard,\n // Contract data types\n TokenFees,\n HoneypotStatus,\n StorageSlots,\n LocalizedDescription,\n // Metadata types\n BaseAssetMetadata,\n FungibleAssetMetadata,\n ERC721AssetMetadata,\n ERC1155AssetMetadata,\n AssetMetadata,\n // Price types\n BaseAssetPrice,\n FungibleAssetPrice,\n NFTAssetPrice,\n AssetPrice,\n // Balance types\n FungibleAssetBalance,\n ERC721AssetBalance,\n ERC1155AssetBalance,\n AssetBalance,\n // Data source types\n AccountWithSupportedChains,\n DataType,\n DataRequest,\n DataResponse,\n AssetsUpdateMode,\n // Middleware types\n Context,\n NextFunction,\n Middleware,\n AssetsDataSource,\n FetchContext,\n FetchNextFunction,\n FetchMiddleware,\n SubscriptionResponse,\n // Combined asset type\n Asset,\n // Event types\n BalanceChangeEvent,\n PriceChangeEvent,\n MetadataChangeEvent,\n AssetsDetectedEvent,\n} from './types';\n\n// Data sources - base class and types\nexport { AbstractDataSource } from './data-sources';\n\nexport type { DataSourceState, SubscriptionRequest } from './data-sources';\n\n// Data sources - AccountsApi\nexport { AccountsApiDataSource } from './data-sources';\n\nexport type {\n AccountsApiDataSourceConfig,\n AccountsApiDataSourceOptions,\n AccountsApiDataSourceState,\n AccountsApiDataSourceAllowedActions,\n} from './data-sources';\n\n// Data sources - BackendWebsocket\nexport {\n BackendWebsocketDataSource,\n createBackendWebsocketDataSource,\n} from './data-sources';\n\nexport type {\n BackendWebsocketDataSourceOptions,\n BackendWebsocketDataSourceState,\n BackendWebsocketDataSourceAllowedActions,\n BackendWebsocketDataSourceAllowedEvents,\n} from './data-sources';\n\n// Data sources - RPC\nexport { RpcDataSource, createRpcDataSource } from './data-sources';\n\nexport type {\n RpcDataSourceConfig,\n RpcDataSourceOptions,\n RpcDataSourceState,\n RpcDataSourceAllowedActions,\n RpcDataSourceAllowedEvents,\n ChainStatus,\n} from './data-sources';\n\n// Data sources - Unified Snap Data Source (dynamically discovers keyring snaps)\nexport {\n SnapDataSource,\n createSnapDataSource,\n SNAP_DATA_SOURCE_NAME,\n // Constants\n KEYRING_PERMISSION,\n // Utility functions\n getChainIdsCaveat,\n extractChainFromAssetId,\n} from './data-sources';\n\nexport type {\n SnapDataSourceState,\n SnapDataSourceOptions,\n SnapDataSourceAllowedActions,\n SnapDataSourceAllowedEvents,\n} from './data-sources';\n\n// Enrichment data sources\nexport { TokenDataSource, PriceDataSource } from './data-sources';\n\nexport type {\n TokenDataSourceOptions,\n TokenDataSourceAllowedActions,\n PriceDataSourceConfig,\n PriceDataSourceOptions,\n} from './data-sources';\n\n// Middlewares\nexport { DetectionMiddleware } from './middlewares';\n\n// Utilities\nexport {\n normalizeAssetId,\n formatExchangeRatesForBridge,\n formatStateForTransactionPay,\n} from './utils';\nexport type {\n AccountForLegacyFormat,\n BridgeExchangeRatesFormat,\n LegacyToken,\n TransactionPayLegacyFormat,\n} from './utils';\n\n// Selectors\nexport {\n getAggregatedBalanceForAccount,\n getGroupIdForAccount,\n getInternalAccountsForGroup,\n} from './selectors/balance';\n\nexport type {\n AccountsById,\n AggregatedBalanceEntry,\n AggregatedBalanceForAccount,\n EnabledNetworkMap,\n} from './selectors/balance';\n"]}
@@ -128,11 +128,25 @@ function createParallelBalanceMiddleware(sources) {
128
128
  const limit = (0, p_limit_1.default)(BALANCE_CONCURRENCY);
129
129
  // Round 1: partition chains (no overlap), run with limited concurrency
130
130
  const requests = partitionChainsBySource(context.request, sources);
131
- const results = await Promise.all(sources.map((source, i) => limit(() => source.assetsMiddleware({
132
- request: requests[i],
133
- response: {},
134
- getAssetsState: context.getAssetsState,
135
- }, noopNext))));
131
+ const round1Timed = await Promise.all(sources.map((source, i) => limit(async () => {
132
+ const start = Date.now();
133
+ const result = await source.assetsMiddleware({
134
+ request: requests[i],
135
+ response: {},
136
+ getAssetsState: context.getAssetsState,
137
+ }, noopNext);
138
+ const durationMs = Date.now() - start;
139
+ return { result, sourceName: source.getName(), durationMs };
140
+ })));
141
+ const results = round1Timed.map((entry) => entry.result);
142
+ const durationByDataSource = {
143
+ ...context.durationByDataSource,
144
+ };
145
+ for (const { sourceName, durationMs } of round1Timed) {
146
+ const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;
147
+ durationByDataSource[key] =
148
+ (durationByDataSource[key] ?? 0) + durationMs;
149
+ }
136
150
  let mergedResponse = mergeDataResponses(results.map((result) => result.response));
137
151
  // Fallback: chains that failed (in errors) get re-partitioned and tried again
138
152
  const failedChainIds = getFailedChainIds(requests, results);
@@ -142,11 +156,22 @@ function createParallelBalanceMiddleware(sources) {
142
156
  chainIds: [...failedChainIds],
143
157
  };
144
158
  const fallbackRequests = partitionChainsBySource(fallbackRequest, sources);
145
- const fallbackResults = await Promise.all(sources.map((source, i) => limit(() => source.assetsMiddleware({
146
- request: fallbackRequests[i],
147
- response: {},
148
- getAssetsState: context.getAssetsState,
149
- }, noopNext))));
159
+ const fallbackTimed = await Promise.all(sources.map((source, i) => limit(async () => {
160
+ const start = Date.now();
161
+ const result = await source.assetsMiddleware({
162
+ request: fallbackRequests[i],
163
+ response: {},
164
+ getAssetsState: context.getAssetsState,
165
+ }, noopNext);
166
+ const durationMs = Date.now() - start;
167
+ return { result, sourceName: source.getName(), durationMs };
168
+ })));
169
+ const fallbackResults = fallbackTimed.map((entry) => entry.result);
170
+ for (const { sourceName, durationMs } of fallbackTimed) {
171
+ const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;
172
+ durationByDataSource[key] =
173
+ (durationByDataSource[key] ?? 0) + durationMs;
174
+ }
150
175
  const fallbackMerged = mergeDataResponses(fallbackResults.map((result) => result.response));
151
176
  mergedResponse = mergeDataResponses([mergedResponse, fallbackMerged]);
152
177
  // Remove errors for chains we successfully got balance for in fallback
@@ -168,6 +193,7 @@ function createParallelBalanceMiddleware(sources) {
168
193
  return next({
169
194
  ...context,
170
195
  response: mergeDataResponses([context.response, mergedResponse]),
196
+ durationByDataSource,
171
197
  });
172
198
  },
173
199
  };
@@ -185,7 +211,7 @@ const CONCURRENCY = 2;
185
211
  * that assetsInfo (token metadata) and assetsPrice are combined. Use this to
186
212
  * fetch token and price data concurrently instead of sequentially.
187
213
  *
188
- * @param sources - Array of sources with getName() and assetsMiddleware.
214
+ * @param sources - Array of named middleware sources (getName + assetsMiddleware).
189
215
  * @returns A single middleware that runs all sources in parallel and merges responses.
190
216
  */
191
217
  function createParallelMiddleware(sources) {
@@ -199,15 +225,29 @@ function createParallelMiddleware(sources) {
199
225
  }
200
226
  const noopNext = async (ctx) => ctx;
201
227
  const limit = (0, p_limit_1.default)(CONCURRENCY);
202
- const results = await Promise.all(sources.map((source) => limit(() => source.assetsMiddleware({
203
- request: context.request,
204
- response: { ...context.response },
205
- getAssetsState: context.getAssetsState,
206
- }, noopNext))));
228
+ const timedResults = await Promise.all(sources.map((source) => limit(async () => {
229
+ const start = Date.now();
230
+ const result = await source.assetsMiddleware({
231
+ request: context.request,
232
+ response: { ...context.response },
233
+ getAssetsState: context.getAssetsState,
234
+ }, noopNext);
235
+ const durationMs = Date.now() - start;
236
+ return { result, sourceName: source.getName(), durationMs };
237
+ })));
238
+ const results = timedResults.map((entry) => entry.result);
207
239
  const mergedResponse = mergeDataResponses(results.map((result) => result.response));
240
+ const durationByDataSource = {
241
+ ...context.durationByDataSource,
242
+ };
243
+ for (const { sourceName, durationMs } of timedResults) {
244
+ durationByDataSource[`${PARALLEL_MIDDLEWARE_NAME}.${sourceName}`] =
245
+ durationMs;
246
+ }
208
247
  return next({
209
248
  ...context,
210
249
  response: mergeDataResponses([context.response, mergedResponse]),
250
+ durationByDataSource,
211
251
  });
212
252
  },
213
253
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ParallelMiddleware.cjs","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"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","sourcesContent":["import pLimit from 'p-limit';\n\nimport type {\n ChainId,\n Context,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\n\n// ============================================================================\n// MERGE HELPER\n// ============================================================================\n\n/**\n * Deep-merge multiple DataResponses into one.\n * Used when running balance data sources in parallel.\n *\n * @param responses - Array of DataResponse from each source.\n * @returns Single merged DataResponse.\n */\nexport function mergeDataResponses(responses: DataResponse[]): DataResponse {\n const merged: DataResponse = {};\n\n for (const response of responses) {\n if (response.assetsBalance) {\n merged.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n merged.assetsBalance[accountId] = {\n ...(merged.assetsBalance[accountId] ?? {}),\n ...accountBalances,\n };\n }\n }\n if (response.assetsInfo) {\n merged.assetsInfo = {\n ...(merged.assetsInfo ?? {}),\n ...response.assetsInfo,\n };\n }\n if (response.assetsPrice) {\n merged.assetsPrice = {\n ...(merged.assetsPrice ?? {}),\n ...response.assetsPrice,\n };\n }\n if (response.errors) {\n merged.errors = {\n ...(merged.errors ?? {}),\n ...response.errors,\n };\n }\n if (response.detectedAssets) {\n merged.detectedAssets = {\n ...(merged.detectedAssets ?? {}),\n ...response.detectedAssets,\n };\n }\n if (response.updateMode === 'full') {\n merged.updateMode = 'full';\n }\n }\n merged.updateMode ??= 'merge';\n\n return merged;\n}\n\n// ============================================================================\n// PARALLEL BALANCE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_BALANCE_MIDDLEWARE_NAME = 'ParallelBalanceMiddleware';\n\n/** Max concurrent balance source calls (round 1 and fallback). */\nconst BALANCE_CONCURRENCY = 3;\n\nexport type BalanceSource = {\n getName(): string;\n /** Chains this source can fetch (e.g. from getActiveChainsSync()). Used to partition chains with no overlap. */\n getActiveChainsSync(): ChainId[];\n assetsMiddleware: Middleware;\n};\n\n/**\n * Partition request.chainIds so each chain is assigned to exactly one source\n * (by source order: first source that supports the chain gets it). Ensures no\n * chain overlap across data source calls.\n *\n * @param request - The data request with chainIds to partition.\n * @param sources - Balance sources in priority order (e.g. AccountsAPI, Snap, Rpc).\n * @returns Array of requests, one per source, each with only that source's assigned chainIds.\n */\nfunction partitionChainsBySource(\n request: DataRequest,\n sources: BalanceSource[],\n): DataRequest[] {\n const { chainIds } = request;\n const assigned = new Set<ChainId>();\n\n return sources.map((source) => {\n const supported = new Set(source.getActiveChainsSync());\n const chainsForSource = chainIds.filter(\n (id) => supported.has(id) && !assigned.has(id),\n );\n chainsForSource.forEach((id) => assigned.add(id));\n\n return {\n ...request,\n chainIds: chainsForSource,\n };\n });\n}\n\n/**\n * Collect chain IDs that failed in the first round (present in response.errors).\n * Used to run a fallback round with remaining sources.\n *\n * @param requests - Partitioned requests, one per source (same order as results).\n * @param results - Results from each source; chain IDs in requests[i] that have errors in results[i].response.errors are considered failed.\n * @returns Set of chain IDs that had errors in the first round.\n */\nfunction getFailedChainIds(\n requests: DataRequest[],\n results: { response: DataResponse }[],\n): Set<ChainId> {\n const failed = new Set<ChainId>();\n for (let i = 0; i < results.length; i++) {\n const errors = results[i].response.errors ?? {};\n for (const chainId of requests[i].chainIds) {\n if (errors[chainId]) {\n failed.add(chainId);\n }\n }\n }\n return failed;\n}\n\n/**\n * Middleware that runs multiple balance data source middlewares in parallel,\n * with no chain overlap. Chains that fail (response.errors) are re-partitioned\n * and fetched again in a fallback round so lower-priority sources can try them.\n *\n * @param sources - Array of balance sources in priority order (each with getName(), getActiveChainsSync(), assetsMiddleware).\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelBalanceMiddleware(sources: BalanceSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_BALANCE_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(BALANCE_CONCURRENCY);\n\n // Round 1: partition chains (no overlap), run with limited concurrency\n const requests = partitionChainsBySource(context.request, sources);\n const results = await Promise.all(\n sources.map((source, i) =>\n limit(() =>\n source.assetsMiddleware(\n {\n request: requests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n ),\n ),\n ),\n );\n\n let mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n // Fallback: chains that failed (in errors) get re-partitioned and tried again\n const failedChainIds = getFailedChainIds(requests, results);\n if (failedChainIds.size > 0) {\n const fallbackRequest: DataRequest = {\n ...context.request,\n chainIds: [...failedChainIds],\n };\n const fallbackRequests = partitionChainsBySource(\n fallbackRequest,\n sources,\n );\n const fallbackResults = await Promise.all(\n sources.map((source, i) =>\n limit(() =>\n source.assetsMiddleware(\n {\n request: fallbackRequests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n ),\n ),\n ),\n );\n const fallbackMerged = mergeDataResponses(\n fallbackResults.map((result) => result.response),\n );\n mergedResponse = mergeDataResponses([mergedResponse, fallbackMerged]);\n // Remove errors for chains we successfully got balance for in fallback\n if (mergedResponse.errors && mergedResponse.assetsBalance) {\n const chainsWithBalance = new Set<ChainId>();\n for (const accountBalances of Object.values(\n mergedResponse.assetsBalance,\n )) {\n for (const assetId of Object.keys(accountBalances)) {\n const chainId = assetId.split('/')[0] as ChainId;\n chainsWithBalance.add(chainId);\n }\n }\n for (const chainId of failedChainIds) {\n if (chainsWithBalance.has(chainId)) {\n delete mergedResponse.errors[chainId];\n }\n }\n }\n }\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n });\n },\n };\n}\n\n// ============================================================================\n// PARALLEL TOKEN/PRICE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_MIDDLEWARE_NAME = 'ParallelMiddleware';\n\n/** Max concurrent token/price source calls. */\nconst CONCURRENCY = 2;\n\nexport type TokenPriceSource = {\n getName(): string;\n assetsMiddleware: Middleware;\n};\n\n/**\n * Middleware that runs multiple data source middlewares (e.g. TokenDataSource,\n * PriceDataSource) in parallel with the same request. Responses are merged so\n * that assetsInfo (token metadata) and assetsPrice are combined. Use this to\n * fetch token and price data concurrently instead of sequentially.\n *\n * @param sources - Array of sources with getName() and assetsMiddleware.\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelMiddleware(sources: TokenPriceSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(CONCURRENCY);\n\n const results = await Promise.all(\n sources.map((source) =>\n limit(() =>\n source.assetsMiddleware(\n {\n request: context.request,\n response: { ...context.response },\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n ),\n ),\n ),\n );\n\n const mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n });\n },\n };\n}\n"]}
1
+ {"version":3,"file":"ParallelMiddleware.cjs","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"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","sourcesContent":["import pLimit from 'p-limit';\n\nimport type {\n ChainId,\n Context,\n DataRequest,\n DataResponse,\n Middleware,\n AssetsDataSource,\n} from '../types';\n\n// ============================================================================\n// MERGE HELPER\n// ============================================================================\n\n/**\n * Deep-merge multiple DataResponses into one.\n * Used when running balance data sources in parallel.\n *\n * @param responses - Array of DataResponse from each source.\n * @returns Single merged DataResponse.\n */\nexport function mergeDataResponses(responses: DataResponse[]): DataResponse {\n const merged: DataResponse = {};\n\n for (const response of responses) {\n if (response.assetsBalance) {\n merged.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n merged.assetsBalance[accountId] = {\n ...(merged.assetsBalance[accountId] ?? {}),\n ...accountBalances,\n };\n }\n }\n if (response.assetsInfo) {\n merged.assetsInfo = {\n ...(merged.assetsInfo ?? {}),\n ...response.assetsInfo,\n };\n }\n if (response.assetsPrice) {\n merged.assetsPrice = {\n ...(merged.assetsPrice ?? {}),\n ...response.assetsPrice,\n };\n }\n if (response.errors) {\n merged.errors = {\n ...(merged.errors ?? {}),\n ...response.errors,\n };\n }\n if (response.detectedAssets) {\n merged.detectedAssets = {\n ...(merged.detectedAssets ?? {}),\n ...response.detectedAssets,\n };\n }\n if (response.updateMode === 'full') {\n merged.updateMode = 'full';\n }\n }\n merged.updateMode ??= 'merge';\n\n return merged;\n}\n\n// ============================================================================\n// PARALLEL BALANCE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_BALANCE_MIDDLEWARE_NAME = 'ParallelBalanceMiddleware';\n\n/** Max concurrent balance source calls (round 1 and fallback). */\nconst BALANCE_CONCURRENCY = 3;\n\nexport type BalanceSource = {\n getName(): string;\n /** Chains this source can fetch (e.g. from getActiveChainsSync()). Used to partition chains with no overlap. */\n getActiveChainsSync(): ChainId[];\n assetsMiddleware: Middleware;\n};\n\n/**\n * Partition request.chainIds so each chain is assigned to exactly one source\n * (by source order: first source that supports the chain gets it). Ensures no\n * chain overlap across data source calls.\n *\n * @param request - The data request with chainIds to partition.\n * @param sources - Balance sources in priority order (e.g. AccountsAPI, Snap, Rpc).\n * @returns Array of requests, one per source, each with only that source's assigned chainIds.\n */\nfunction partitionChainsBySource(\n request: DataRequest,\n sources: BalanceSource[],\n): DataRequest[] {\n const { chainIds } = request;\n const assigned = new Set<ChainId>();\n\n return sources.map((source) => {\n const supported = new Set(source.getActiveChainsSync());\n const chainsForSource = chainIds.filter(\n (id) => supported.has(id) && !assigned.has(id),\n );\n chainsForSource.forEach((id) => assigned.add(id));\n\n return {\n ...request,\n chainIds: chainsForSource,\n };\n });\n}\n\n/**\n * Collect chain IDs that failed in the first round (present in response.errors).\n * Used to run a fallback round with remaining sources.\n *\n * @param requests - Partitioned requests, one per source (same order as results).\n * @param results - Results from each source; chain IDs in requests[i] that have errors in results[i].response.errors are considered failed.\n * @returns Set of chain IDs that had errors in the first round.\n */\nfunction getFailedChainIds(\n requests: DataRequest[],\n results: { response: DataResponse }[],\n): Set<ChainId> {\n const failed = new Set<ChainId>();\n for (let i = 0; i < results.length; i++) {\n const errors = results[i].response.errors ?? {};\n for (const chainId of requests[i].chainIds) {\n if (errors[chainId]) {\n failed.add(chainId);\n }\n }\n }\n return failed;\n}\n\n/**\n * Middleware that runs multiple balance data source middlewares in parallel,\n * with no chain overlap. Chains that fail (response.errors) are re-partitioned\n * and fetched again in a fallback round so lower-priority sources can try them.\n *\n * @param sources - Array of balance sources in priority order (each with getName(), getActiveChainsSync(), assetsMiddleware).\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelBalanceMiddleware(sources: BalanceSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_BALANCE_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(BALANCE_CONCURRENCY);\n\n // Round 1: partition chains (no overlap), run with limited concurrency\n const requests = partitionChainsBySource(context.request, sources);\n const round1Timed = await Promise.all(\n sources.map((source, i) =>\n limit(async () => {\n const start = Date.now();\n const result = await source.assetsMiddleware(\n {\n request: requests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n );\n const durationMs = Date.now() - start;\n return { result, sourceName: source.getName(), durationMs };\n }),\n ),\n );\n const results = round1Timed.map((entry) => entry.result);\n\n const durationByDataSource: Record<string, number> = {\n ...context.durationByDataSource,\n };\n for (const { sourceName, durationMs } of round1Timed) {\n const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;\n durationByDataSource[key] =\n (durationByDataSource[key] ?? 0) + durationMs;\n }\n\n let mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n // Fallback: chains that failed (in errors) get re-partitioned and tried again\n const failedChainIds = getFailedChainIds(requests, results);\n if (failedChainIds.size > 0) {\n const fallbackRequest: DataRequest = {\n ...context.request,\n chainIds: [...failedChainIds],\n };\n const fallbackRequests = partitionChainsBySource(\n fallbackRequest,\n sources,\n );\n const fallbackTimed = await Promise.all(\n sources.map((source, i) =>\n limit(async () => {\n const start = Date.now();\n const result = await source.assetsMiddleware(\n {\n request: fallbackRequests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n );\n const durationMs = Date.now() - start;\n return { result, sourceName: source.getName(), durationMs };\n }),\n ),\n );\n const fallbackResults = fallbackTimed.map((entry) => entry.result);\n for (const { sourceName, durationMs } of fallbackTimed) {\n const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;\n durationByDataSource[key] =\n (durationByDataSource[key] ?? 0) + durationMs;\n }\n const fallbackMerged = mergeDataResponses(\n fallbackResults.map((result) => result.response),\n );\n mergedResponse = mergeDataResponses([mergedResponse, fallbackMerged]);\n // Remove errors for chains we successfully got balance for in fallback\n if (mergedResponse.errors && mergedResponse.assetsBalance) {\n const chainsWithBalance = new Set<ChainId>();\n for (const accountBalances of Object.values(\n mergedResponse.assetsBalance,\n )) {\n for (const assetId of Object.keys(accountBalances)) {\n const chainId = assetId.split('/')[0] as ChainId;\n chainsWithBalance.add(chainId);\n }\n }\n for (const chainId of failedChainIds) {\n if (chainsWithBalance.has(chainId)) {\n delete mergedResponse.errors[chainId];\n }\n }\n }\n }\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n durationByDataSource,\n });\n },\n };\n}\n\n// ============================================================================\n// PARALLEL TOKEN/PRICE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_MIDDLEWARE_NAME = 'ParallelMiddleware';\n\n/** Max concurrent token/price source calls. */\nconst CONCURRENCY = 2;\n\n/**\n * Middleware that runs multiple data source middlewares (e.g. TokenDataSource,\n * PriceDataSource) in parallel with the same request. Responses are merged so\n * that assetsInfo (token metadata) and assetsPrice are combined. Use this to\n * fetch token and price data concurrently instead of sequentially.\n *\n * @param sources - Array of named middleware sources (getName + assetsMiddleware).\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelMiddleware(sources: AssetsDataSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(CONCURRENCY);\n\n const timedResults = await Promise.all(\n sources.map((source) =>\n limit(async () => {\n const start = Date.now();\n const result = await source.assetsMiddleware(\n {\n request: context.request,\n response: { ...context.response },\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n );\n const durationMs = Date.now() - start;\n return { result, sourceName: source.getName(), durationMs };\n }),\n ),\n );\n\n const results = timedResults.map((entry) => entry.result);\n const mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n const durationByDataSource: Record<string, number> = {\n ...context.durationByDataSource,\n };\n for (const { sourceName, durationMs } of timedResults) {\n durationByDataSource[`${PARALLEL_MIDDLEWARE_NAME}.${sourceName}`] =\n durationMs;\n }\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n durationByDataSource,\n });\n },\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { ChainId, DataResponse, Middleware } from "../types.cjs";
1
+ import type { ChainId, DataResponse, Middleware, AssetsDataSource } from "../types.cjs";
2
2
  /**
3
3
  * Deep-merge multiple DataResponses into one.
4
4
  * Used when running balance data sources in parallel.
@@ -25,20 +25,16 @@ export declare function createParallelBalanceMiddleware(sources: BalanceSource[]
25
25
  getName(): string;
26
26
  assetsMiddleware: Middleware;
27
27
  };
28
- export type TokenPriceSource = {
29
- getName(): string;
30
- assetsMiddleware: Middleware;
31
- };
32
28
  /**
33
29
  * Middleware that runs multiple data source middlewares (e.g. TokenDataSource,
34
30
  * PriceDataSource) in parallel with the same request. Responses are merged so
35
31
  * that assetsInfo (token metadata) and assetsPrice are combined. Use this to
36
32
  * fetch token and price data concurrently instead of sequentially.
37
33
  *
38
- * @param sources - Array of sources with getName() and assetsMiddleware.
34
+ * @param sources - Array of named middleware sources (getName + assetsMiddleware).
39
35
  * @returns A single middleware that runs all sources in parallel and merges responses.
40
36
  */
41
- export declare function createParallelMiddleware(sources: TokenPriceSource[]): {
37
+ export declare function createParallelMiddleware(sources: AssetsDataSource[]): {
42
38
  getName(): string;
43
39
  assetsMiddleware: Middleware;
44
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ParallelMiddleware.d.cts","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EAGP,YAAY,EACZ,UAAU,EACX,qBAAiB;AAMlB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,YAAY,CA8C1E;AAWD,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,IAAI,MAAM,CAAC;IAClB,gHAAgH;IAChH,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAwDF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG;IACzE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CA0FA;AAWD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG;IACrE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAwCA"}
1
+ {"version":3,"file":"ParallelMiddleware.d.cts","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EAGP,YAAY,EACZ,UAAU,EACV,gBAAgB,EACjB,qBAAiB;AAMlB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,YAAY,CA8C1E;AAWD,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,IAAI,MAAM,CAAC;IAClB,gHAAgH;IAChH,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAwDF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG;IACzE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAiHA;AAWD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG;IACrE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAqDA"}
@@ -1,4 +1,4 @@
1
- import type { ChainId, DataResponse, Middleware } from "../types.mjs";
1
+ import type { ChainId, DataResponse, Middleware, AssetsDataSource } from "../types.mjs";
2
2
  /**
3
3
  * Deep-merge multiple DataResponses into one.
4
4
  * Used when running balance data sources in parallel.
@@ -25,20 +25,16 @@ export declare function createParallelBalanceMiddleware(sources: BalanceSource[]
25
25
  getName(): string;
26
26
  assetsMiddleware: Middleware;
27
27
  };
28
- export type TokenPriceSource = {
29
- getName(): string;
30
- assetsMiddleware: Middleware;
31
- };
32
28
  /**
33
29
  * Middleware that runs multiple data source middlewares (e.g. TokenDataSource,
34
30
  * PriceDataSource) in parallel with the same request. Responses are merged so
35
31
  * that assetsInfo (token metadata) and assetsPrice are combined. Use this to
36
32
  * fetch token and price data concurrently instead of sequentially.
37
33
  *
38
- * @param sources - Array of sources with getName() and assetsMiddleware.
34
+ * @param sources - Array of named middleware sources (getName + assetsMiddleware).
39
35
  * @returns A single middleware that runs all sources in parallel and merges responses.
40
36
  */
41
- export declare function createParallelMiddleware(sources: TokenPriceSource[]): {
37
+ export declare function createParallelMiddleware(sources: AssetsDataSource[]): {
42
38
  getName(): string;
43
39
  assetsMiddleware: Middleware;
44
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ParallelMiddleware.d.mts","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EAGP,YAAY,EACZ,UAAU,EACX,qBAAiB;AAMlB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,YAAY,CA8C1E;AAWD,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,IAAI,MAAM,CAAC;IAClB,gHAAgH;IAChH,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAwDF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG;IACzE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CA0FA;AAWD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG;IACrE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAwCA"}
1
+ {"version":3,"file":"ParallelMiddleware.d.mts","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EAGP,YAAY,EACZ,UAAU,EACV,gBAAgB,EACjB,qBAAiB;AAMlB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,YAAY,CA8C1E;AAWD,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,IAAI,MAAM,CAAC;IAClB,gHAAgH;IAChH,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAwDF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG;IACzE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAiHA;AAWD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG;IACrE,OAAO,IAAI,MAAM,CAAC;IAClB,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAqDA"}
@@ -128,11 +128,25 @@ export function createParallelBalanceMiddleware(sources) {
128
128
  const limit = pLimit(BALANCE_CONCURRENCY);
129
129
  // Round 1: partition chains (no overlap), run with limited concurrency
130
130
  const requests = partitionChainsBySource(context.request, sources);
131
- const results = await Promise.all(sources.map((source, i) => limit(() => source.assetsMiddleware({
132
- request: requests[i],
133
- response: {},
134
- getAssetsState: context.getAssetsState,
135
- }, noopNext))));
131
+ const round1Timed = await Promise.all(sources.map((source, i) => limit(async () => {
132
+ const start = Date.now();
133
+ const result = await source.assetsMiddleware({
134
+ request: requests[i],
135
+ response: {},
136
+ getAssetsState: context.getAssetsState,
137
+ }, noopNext);
138
+ const durationMs = Date.now() - start;
139
+ return { result, sourceName: source.getName(), durationMs };
140
+ })));
141
+ const results = round1Timed.map((entry) => entry.result);
142
+ const durationByDataSource = {
143
+ ...context.durationByDataSource,
144
+ };
145
+ for (const { sourceName, durationMs } of round1Timed) {
146
+ const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;
147
+ durationByDataSource[key] =
148
+ (durationByDataSource[key] ?? 0) + durationMs;
149
+ }
136
150
  let mergedResponse = mergeDataResponses(results.map((result) => result.response));
137
151
  // Fallback: chains that failed (in errors) get re-partitioned and tried again
138
152
  const failedChainIds = getFailedChainIds(requests, results);
@@ -142,11 +156,22 @@ export function createParallelBalanceMiddleware(sources) {
142
156
  chainIds: [...failedChainIds],
143
157
  };
144
158
  const fallbackRequests = partitionChainsBySource(fallbackRequest, sources);
145
- const fallbackResults = await Promise.all(sources.map((source, i) => limit(() => source.assetsMiddleware({
146
- request: fallbackRequests[i],
147
- response: {},
148
- getAssetsState: context.getAssetsState,
149
- }, noopNext))));
159
+ const fallbackTimed = await Promise.all(sources.map((source, i) => limit(async () => {
160
+ const start = Date.now();
161
+ const result = await source.assetsMiddleware({
162
+ request: fallbackRequests[i],
163
+ response: {},
164
+ getAssetsState: context.getAssetsState,
165
+ }, noopNext);
166
+ const durationMs = Date.now() - start;
167
+ return { result, sourceName: source.getName(), durationMs };
168
+ })));
169
+ const fallbackResults = fallbackTimed.map((entry) => entry.result);
170
+ for (const { sourceName, durationMs } of fallbackTimed) {
171
+ const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;
172
+ durationByDataSource[key] =
173
+ (durationByDataSource[key] ?? 0) + durationMs;
174
+ }
150
175
  const fallbackMerged = mergeDataResponses(fallbackResults.map((result) => result.response));
151
176
  mergedResponse = mergeDataResponses([mergedResponse, fallbackMerged]);
152
177
  // Remove errors for chains we successfully got balance for in fallback
@@ -168,6 +193,7 @@ export function createParallelBalanceMiddleware(sources) {
168
193
  return next({
169
194
  ...context,
170
195
  response: mergeDataResponses([context.response, mergedResponse]),
196
+ durationByDataSource,
171
197
  });
172
198
  },
173
199
  };
@@ -184,7 +210,7 @@ const CONCURRENCY = 2;
184
210
  * that assetsInfo (token metadata) and assetsPrice are combined. Use this to
185
211
  * fetch token and price data concurrently instead of sequentially.
186
212
  *
187
- * @param sources - Array of sources with getName() and assetsMiddleware.
213
+ * @param sources - Array of named middleware sources (getName + assetsMiddleware).
188
214
  * @returns A single middleware that runs all sources in parallel and merges responses.
189
215
  */
190
216
  export function createParallelMiddleware(sources) {
@@ -198,15 +224,29 @@ export function createParallelMiddleware(sources) {
198
224
  }
199
225
  const noopNext = async (ctx) => ctx;
200
226
  const limit = pLimit(CONCURRENCY);
201
- const results = await Promise.all(sources.map((source) => limit(() => source.assetsMiddleware({
202
- request: context.request,
203
- response: { ...context.response },
204
- getAssetsState: context.getAssetsState,
205
- }, noopNext))));
227
+ const timedResults = await Promise.all(sources.map((source) => limit(async () => {
228
+ const start = Date.now();
229
+ const result = await source.assetsMiddleware({
230
+ request: context.request,
231
+ response: { ...context.response },
232
+ getAssetsState: context.getAssetsState,
233
+ }, noopNext);
234
+ const durationMs = Date.now() - start;
235
+ return { result, sourceName: source.getName(), durationMs };
236
+ })));
237
+ const results = timedResults.map((entry) => entry.result);
206
238
  const mergedResponse = mergeDataResponses(results.map((result) => result.response));
239
+ const durationByDataSource = {
240
+ ...context.durationByDataSource,
241
+ };
242
+ for (const { sourceName, durationMs } of timedResults) {
243
+ durationByDataSource[`${PARALLEL_MIDDLEWARE_NAME}.${sourceName}`] =
244
+ durationMs;
245
+ }
207
246
  return next({
208
247
  ...context,
209
248
  response: mergeDataResponses([context.response, mergedResponse]),
249
+ durationByDataSource,
210
250
  });
211
251
  },
212
252
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ParallelMiddleware.mjs","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,OAAM,yBAAgB;;AAU7B,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAyB;IAC1D,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3B,MAAM,CAAC,aAAa,KAApB,MAAM,CAAC,aAAa,GAAK,EAAE,EAAC;YAC5B,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CACvD,QAAQ,CAAC,aAAa,CACvB,EAAE,CAAC;gBACF,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG;oBAChC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;oBAC1C,GAAG,eAAe;iBACnB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;YACxB,MAAM,CAAC,UAAU,GAAG;gBAClB,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;gBAC5B,GAAG,QAAQ,CAAC,UAAU;aACvB,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,CAAC,WAAW,GAAG;gBACnB,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;gBAC7B,GAAG,QAAQ,CAAC,WAAW;aACxB,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,GAAG;gBACd,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACxB,GAAG,QAAQ,CAAC,MAAM;aACnB,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC5B,MAAM,CAAC,cAAc,GAAG;gBACtB,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;gBAChC,GAAG,QAAQ,CAAC,cAAc;aAC3B,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YACnC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,MAAM,CAAC,UAAU,KAAjB,MAAM,CAAC,UAAU,GAAK,OAAO,EAAC;IAE9B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,MAAM,gCAAgC,GAAG,2BAA2B,CAAC;AAErE,kEAAkE;AAClE,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAS9B;;;;;;;;GAQG;AACH,SAAS,uBAAuB,CAC9B,OAAoB,EACpB,OAAwB;IAExB,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;IAEpC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC5B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACxD,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CACrC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAC/C,CAAC;QACF,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAElD,OAAO;YACL,GAAG,OAAO;YACV,QAAQ,EAAE,eAAe;SAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CACxB,QAAuB,EACvB,OAAqC;IAErC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAW,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;QAChD,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B,CAAC,OAAwB;IAItE,OAAO;QACL,OAAO;YACL,OAAO,gCAAgC,CAAC;QAC1C,CAAC;QAED,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAoB,EAAE;YAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;YAED,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAmB,EAA2B,EAAE,CACtE,GAAG,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAE1C,uEAAuE;YACvE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CACxB,KAAK,CAAC,GAAG,EAAE,CACT,MAAM,CAAC,gBAAgB,CACrB;gBACE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACpB,QAAQ,EAAE,EAAE;gBACZ,cAAc,EAAE,OAAO,CAAC,cAAc;aACvC,EACD,QAAQ,CACT,CACF,CACF,CACF,CAAC;YAEF,IAAI,cAAc,GAAG,kBAAkB,CACrC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACzC,CAAC;YAEF,8EAA8E;YAC9E,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC5D,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,eAAe,GAAgB;oBACnC,GAAG,OAAO,CAAC,OAAO;oBAClB,QAAQ,EAAE,CAAC,GAAG,cAAc,CAAC;iBAC9B,CAAC;gBACF,MAAM,gBAAgB,GAAG,uBAAuB,CAC9C,eAAe,EACf,OAAO,CACR,CAAC;gBACF,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,GAAG,CACvC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CACxB,KAAK,CAAC,GAAG,EAAE,CACT,MAAM,CAAC,gBAAgB,CACrB;oBACE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;oBAC5B,QAAQ,EAAE,EAAE;oBACZ,cAAc,EAAE,OAAO,CAAC,cAAc;iBACvC,EACD,QAAQ,CACT,CACF,CACF,CACF,CAAC;gBACF,MAAM,cAAc,GAAG,kBAAkB,CACvC,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACjD,CAAC;gBACF,cAAc,GAAG,kBAAkB,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC;gBACtE,uEAAuE;gBACvE,IAAI,cAAc,CAAC,MAAM,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC;oBAC1D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAW,CAAC;oBAC7C,KAAK,MAAM,eAAe,IAAI,MAAM,CAAC,MAAM,CACzC,cAAc,CAAC,aAAa,CAC7B,EAAE,CAAC;wBACF,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;4BACnD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAY,CAAC;4BACjD,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACjC,CAAC;oBACH,CAAC;oBACD,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;wBACrC,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;4BACnC,OAAO,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBACxC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;gBACV,GAAG,OAAO;gBACV,QAAQ,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;aACjE,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,kCAAkC;AAClC,+EAA+E;AAE/E,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,WAAW,GAAG,CAAC,CAAC;AAOtB;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAA2B;IAIlE,OAAO;QACL,OAAO;YACL,OAAO,wBAAwB,CAAC;QAClC,CAAC;QAED,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAoB,EAAE;YAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;YAED,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAmB,EAA2B,EAAE,CACtE,GAAG,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YAElC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACrB,KAAK,CAAC,GAAG,EAAE,CACT,MAAM,CAAC,gBAAgB,CACrB;gBACE,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE;gBACjC,cAAc,EAAE,OAAO,CAAC,cAAc;aACvC,EACD,QAAQ,CACT,CACF,CACF,CACF,CAAC;YAEF,MAAM,cAAc,GAAG,kBAAkB,CACvC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACzC,CAAC;YAEF,OAAO,IAAI,CAAC;gBACV,GAAG,OAAO;gBACV,QAAQ,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;aACjE,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import pLimit from 'p-limit';\n\nimport type {\n ChainId,\n Context,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\n\n// ============================================================================\n// MERGE HELPER\n// ============================================================================\n\n/**\n * Deep-merge multiple DataResponses into one.\n * Used when running balance data sources in parallel.\n *\n * @param responses - Array of DataResponse from each source.\n * @returns Single merged DataResponse.\n */\nexport function mergeDataResponses(responses: DataResponse[]): DataResponse {\n const merged: DataResponse = {};\n\n for (const response of responses) {\n if (response.assetsBalance) {\n merged.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n merged.assetsBalance[accountId] = {\n ...(merged.assetsBalance[accountId] ?? {}),\n ...accountBalances,\n };\n }\n }\n if (response.assetsInfo) {\n merged.assetsInfo = {\n ...(merged.assetsInfo ?? {}),\n ...response.assetsInfo,\n };\n }\n if (response.assetsPrice) {\n merged.assetsPrice = {\n ...(merged.assetsPrice ?? {}),\n ...response.assetsPrice,\n };\n }\n if (response.errors) {\n merged.errors = {\n ...(merged.errors ?? {}),\n ...response.errors,\n };\n }\n if (response.detectedAssets) {\n merged.detectedAssets = {\n ...(merged.detectedAssets ?? {}),\n ...response.detectedAssets,\n };\n }\n if (response.updateMode === 'full') {\n merged.updateMode = 'full';\n }\n }\n merged.updateMode ??= 'merge';\n\n return merged;\n}\n\n// ============================================================================\n// PARALLEL BALANCE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_BALANCE_MIDDLEWARE_NAME = 'ParallelBalanceMiddleware';\n\n/** Max concurrent balance source calls (round 1 and fallback). */\nconst BALANCE_CONCURRENCY = 3;\n\nexport type BalanceSource = {\n getName(): string;\n /** Chains this source can fetch (e.g. from getActiveChainsSync()). Used to partition chains with no overlap. */\n getActiveChainsSync(): ChainId[];\n assetsMiddleware: Middleware;\n};\n\n/**\n * Partition request.chainIds so each chain is assigned to exactly one source\n * (by source order: first source that supports the chain gets it). Ensures no\n * chain overlap across data source calls.\n *\n * @param request - The data request with chainIds to partition.\n * @param sources - Balance sources in priority order (e.g. AccountsAPI, Snap, Rpc).\n * @returns Array of requests, one per source, each with only that source's assigned chainIds.\n */\nfunction partitionChainsBySource(\n request: DataRequest,\n sources: BalanceSource[],\n): DataRequest[] {\n const { chainIds } = request;\n const assigned = new Set<ChainId>();\n\n return sources.map((source) => {\n const supported = new Set(source.getActiveChainsSync());\n const chainsForSource = chainIds.filter(\n (id) => supported.has(id) && !assigned.has(id),\n );\n chainsForSource.forEach((id) => assigned.add(id));\n\n return {\n ...request,\n chainIds: chainsForSource,\n };\n });\n}\n\n/**\n * Collect chain IDs that failed in the first round (present in response.errors).\n * Used to run a fallback round with remaining sources.\n *\n * @param requests - Partitioned requests, one per source (same order as results).\n * @param results - Results from each source; chain IDs in requests[i] that have errors in results[i].response.errors are considered failed.\n * @returns Set of chain IDs that had errors in the first round.\n */\nfunction getFailedChainIds(\n requests: DataRequest[],\n results: { response: DataResponse }[],\n): Set<ChainId> {\n const failed = new Set<ChainId>();\n for (let i = 0; i < results.length; i++) {\n const errors = results[i].response.errors ?? {};\n for (const chainId of requests[i].chainIds) {\n if (errors[chainId]) {\n failed.add(chainId);\n }\n }\n }\n return failed;\n}\n\n/**\n * Middleware that runs multiple balance data source middlewares in parallel,\n * with no chain overlap. Chains that fail (response.errors) are re-partitioned\n * and fetched again in a fallback round so lower-priority sources can try them.\n *\n * @param sources - Array of balance sources in priority order (each with getName(), getActiveChainsSync(), assetsMiddleware).\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelBalanceMiddleware(sources: BalanceSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_BALANCE_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(BALANCE_CONCURRENCY);\n\n // Round 1: partition chains (no overlap), run with limited concurrency\n const requests = partitionChainsBySource(context.request, sources);\n const results = await Promise.all(\n sources.map((source, i) =>\n limit(() =>\n source.assetsMiddleware(\n {\n request: requests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n ),\n ),\n ),\n );\n\n let mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n // Fallback: chains that failed (in errors) get re-partitioned and tried again\n const failedChainIds = getFailedChainIds(requests, results);\n if (failedChainIds.size > 0) {\n const fallbackRequest: DataRequest = {\n ...context.request,\n chainIds: [...failedChainIds],\n };\n const fallbackRequests = partitionChainsBySource(\n fallbackRequest,\n sources,\n );\n const fallbackResults = await Promise.all(\n sources.map((source, i) =>\n limit(() =>\n source.assetsMiddleware(\n {\n request: fallbackRequests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n ),\n ),\n ),\n );\n const fallbackMerged = mergeDataResponses(\n fallbackResults.map((result) => result.response),\n );\n mergedResponse = mergeDataResponses([mergedResponse, fallbackMerged]);\n // Remove errors for chains we successfully got balance for in fallback\n if (mergedResponse.errors && mergedResponse.assetsBalance) {\n const chainsWithBalance = new Set<ChainId>();\n for (const accountBalances of Object.values(\n mergedResponse.assetsBalance,\n )) {\n for (const assetId of Object.keys(accountBalances)) {\n const chainId = assetId.split('/')[0] as ChainId;\n chainsWithBalance.add(chainId);\n }\n }\n for (const chainId of failedChainIds) {\n if (chainsWithBalance.has(chainId)) {\n delete mergedResponse.errors[chainId];\n }\n }\n }\n }\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n });\n },\n };\n}\n\n// ============================================================================\n// PARALLEL TOKEN/PRICE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_MIDDLEWARE_NAME = 'ParallelMiddleware';\n\n/** Max concurrent token/price source calls. */\nconst CONCURRENCY = 2;\n\nexport type TokenPriceSource = {\n getName(): string;\n assetsMiddleware: Middleware;\n};\n\n/**\n * Middleware that runs multiple data source middlewares (e.g. TokenDataSource,\n * PriceDataSource) in parallel with the same request. Responses are merged so\n * that assetsInfo (token metadata) and assetsPrice are combined. Use this to\n * fetch token and price data concurrently instead of sequentially.\n *\n * @param sources - Array of sources with getName() and assetsMiddleware.\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelMiddleware(sources: TokenPriceSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(CONCURRENCY);\n\n const results = await Promise.all(\n sources.map((source) =>\n limit(() =>\n source.assetsMiddleware(\n {\n request: context.request,\n response: { ...context.response },\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n ),\n ),\n ),\n );\n\n const mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n });\n },\n };\n}\n"]}
1
+ {"version":3,"file":"ParallelMiddleware.mjs","sourceRoot":"","sources":["../../src/middlewares/ParallelMiddleware.ts"],"names":[],"mappings":"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","sourcesContent":["import pLimit from 'p-limit';\n\nimport type {\n ChainId,\n Context,\n DataRequest,\n DataResponse,\n Middleware,\n AssetsDataSource,\n} from '../types';\n\n// ============================================================================\n// MERGE HELPER\n// ============================================================================\n\n/**\n * Deep-merge multiple DataResponses into one.\n * Used when running balance data sources in parallel.\n *\n * @param responses - Array of DataResponse from each source.\n * @returns Single merged DataResponse.\n */\nexport function mergeDataResponses(responses: DataResponse[]): DataResponse {\n const merged: DataResponse = {};\n\n for (const response of responses) {\n if (response.assetsBalance) {\n merged.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n merged.assetsBalance[accountId] = {\n ...(merged.assetsBalance[accountId] ?? {}),\n ...accountBalances,\n };\n }\n }\n if (response.assetsInfo) {\n merged.assetsInfo = {\n ...(merged.assetsInfo ?? {}),\n ...response.assetsInfo,\n };\n }\n if (response.assetsPrice) {\n merged.assetsPrice = {\n ...(merged.assetsPrice ?? {}),\n ...response.assetsPrice,\n };\n }\n if (response.errors) {\n merged.errors = {\n ...(merged.errors ?? {}),\n ...response.errors,\n };\n }\n if (response.detectedAssets) {\n merged.detectedAssets = {\n ...(merged.detectedAssets ?? {}),\n ...response.detectedAssets,\n };\n }\n if (response.updateMode === 'full') {\n merged.updateMode = 'full';\n }\n }\n merged.updateMode ??= 'merge';\n\n return merged;\n}\n\n// ============================================================================\n// PARALLEL BALANCE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_BALANCE_MIDDLEWARE_NAME = 'ParallelBalanceMiddleware';\n\n/** Max concurrent balance source calls (round 1 and fallback). */\nconst BALANCE_CONCURRENCY = 3;\n\nexport type BalanceSource = {\n getName(): string;\n /** Chains this source can fetch (e.g. from getActiveChainsSync()). Used to partition chains with no overlap. */\n getActiveChainsSync(): ChainId[];\n assetsMiddleware: Middleware;\n};\n\n/**\n * Partition request.chainIds so each chain is assigned to exactly one source\n * (by source order: first source that supports the chain gets it). Ensures no\n * chain overlap across data source calls.\n *\n * @param request - The data request with chainIds to partition.\n * @param sources - Balance sources in priority order (e.g. AccountsAPI, Snap, Rpc).\n * @returns Array of requests, one per source, each with only that source's assigned chainIds.\n */\nfunction partitionChainsBySource(\n request: DataRequest,\n sources: BalanceSource[],\n): DataRequest[] {\n const { chainIds } = request;\n const assigned = new Set<ChainId>();\n\n return sources.map((source) => {\n const supported = new Set(source.getActiveChainsSync());\n const chainsForSource = chainIds.filter(\n (id) => supported.has(id) && !assigned.has(id),\n );\n chainsForSource.forEach((id) => assigned.add(id));\n\n return {\n ...request,\n chainIds: chainsForSource,\n };\n });\n}\n\n/**\n * Collect chain IDs that failed in the first round (present in response.errors).\n * Used to run a fallback round with remaining sources.\n *\n * @param requests - Partitioned requests, one per source (same order as results).\n * @param results - Results from each source; chain IDs in requests[i] that have errors in results[i].response.errors are considered failed.\n * @returns Set of chain IDs that had errors in the first round.\n */\nfunction getFailedChainIds(\n requests: DataRequest[],\n results: { response: DataResponse }[],\n): Set<ChainId> {\n const failed = new Set<ChainId>();\n for (let i = 0; i < results.length; i++) {\n const errors = results[i].response.errors ?? {};\n for (const chainId of requests[i].chainIds) {\n if (errors[chainId]) {\n failed.add(chainId);\n }\n }\n }\n return failed;\n}\n\n/**\n * Middleware that runs multiple balance data source middlewares in parallel,\n * with no chain overlap. Chains that fail (response.errors) are re-partitioned\n * and fetched again in a fallback round so lower-priority sources can try them.\n *\n * @param sources - Array of balance sources in priority order (each with getName(), getActiveChainsSync(), assetsMiddleware).\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelBalanceMiddleware(sources: BalanceSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_BALANCE_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(BALANCE_CONCURRENCY);\n\n // Round 1: partition chains (no overlap), run with limited concurrency\n const requests = partitionChainsBySource(context.request, sources);\n const round1Timed = await Promise.all(\n sources.map((source, i) =>\n limit(async () => {\n const start = Date.now();\n const result = await source.assetsMiddleware(\n {\n request: requests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n );\n const durationMs = Date.now() - start;\n return { result, sourceName: source.getName(), durationMs };\n }),\n ),\n );\n const results = round1Timed.map((entry) => entry.result);\n\n const durationByDataSource: Record<string, number> = {\n ...context.durationByDataSource,\n };\n for (const { sourceName, durationMs } of round1Timed) {\n const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;\n durationByDataSource[key] =\n (durationByDataSource[key] ?? 0) + durationMs;\n }\n\n let mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n // Fallback: chains that failed (in errors) get re-partitioned and tried again\n const failedChainIds = getFailedChainIds(requests, results);\n if (failedChainIds.size > 0) {\n const fallbackRequest: DataRequest = {\n ...context.request,\n chainIds: [...failedChainIds],\n };\n const fallbackRequests = partitionChainsBySource(\n fallbackRequest,\n sources,\n );\n const fallbackTimed = await Promise.all(\n sources.map((source, i) =>\n limit(async () => {\n const start = Date.now();\n const result = await source.assetsMiddleware(\n {\n request: fallbackRequests[i],\n response: {},\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n );\n const durationMs = Date.now() - start;\n return { result, sourceName: source.getName(), durationMs };\n }),\n ),\n );\n const fallbackResults = fallbackTimed.map((entry) => entry.result);\n for (const { sourceName, durationMs } of fallbackTimed) {\n const key = `${PARALLEL_BALANCE_MIDDLEWARE_NAME}.${sourceName}`;\n durationByDataSource[key] =\n (durationByDataSource[key] ?? 0) + durationMs;\n }\n const fallbackMerged = mergeDataResponses(\n fallbackResults.map((result) => result.response),\n );\n mergedResponse = mergeDataResponses([mergedResponse, fallbackMerged]);\n // Remove errors for chains we successfully got balance for in fallback\n if (mergedResponse.errors && mergedResponse.assetsBalance) {\n const chainsWithBalance = new Set<ChainId>();\n for (const accountBalances of Object.values(\n mergedResponse.assetsBalance,\n )) {\n for (const assetId of Object.keys(accountBalances)) {\n const chainId = assetId.split('/')[0] as ChainId;\n chainsWithBalance.add(chainId);\n }\n }\n for (const chainId of failedChainIds) {\n if (chainsWithBalance.has(chainId)) {\n delete mergedResponse.errors[chainId];\n }\n }\n }\n }\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n durationByDataSource,\n });\n },\n };\n}\n\n// ============================================================================\n// PARALLEL TOKEN/PRICE MIDDLEWARE\n// ============================================================================\n\nconst PARALLEL_MIDDLEWARE_NAME = 'ParallelMiddleware';\n\n/** Max concurrent token/price source calls. */\nconst CONCURRENCY = 2;\n\n/**\n * Middleware that runs multiple data source middlewares (e.g. TokenDataSource,\n * PriceDataSource) in parallel with the same request. Responses are merged so\n * that assetsInfo (token metadata) and assetsPrice are combined. Use this to\n * fetch token and price data concurrently instead of sequentially.\n *\n * @param sources - Array of named middleware sources (getName + assetsMiddleware).\n * @returns A single middleware that runs all sources in parallel and merges responses.\n */\nexport function createParallelMiddleware(sources: AssetsDataSource[]): {\n getName(): string;\n assetsMiddleware: Middleware;\n} {\n return {\n getName(): string {\n return PARALLEL_MIDDLEWARE_NAME;\n },\n\n assetsMiddleware: async (context, next): Promise<Context> => {\n if (sources.length === 0) {\n return next(context);\n }\n\n const noopNext = async (ctx: typeof context): Promise<typeof context> =>\n ctx;\n const limit = pLimit(CONCURRENCY);\n\n const timedResults = await Promise.all(\n sources.map((source) =>\n limit(async () => {\n const start = Date.now();\n const result = await source.assetsMiddleware(\n {\n request: context.request,\n response: { ...context.response },\n getAssetsState: context.getAssetsState,\n },\n noopNext,\n );\n const durationMs = Date.now() - start;\n return { result, sourceName: source.getName(), durationMs };\n }),\n ),\n );\n\n const results = timedResults.map((entry) => entry.result);\n const mergedResponse = mergeDataResponses(\n results.map((result) => result.response),\n );\n\n const durationByDataSource: Record<string, number> = {\n ...context.durationByDataSource,\n };\n for (const { sourceName, durationMs } of timedResults) {\n durationByDataSource[`${PARALLEL_MIDDLEWARE_NAME}.${sourceName}`] =\n durationMs;\n }\n\n return next({\n ...context,\n response: mergeDataResponses([context.response, mergedResponse]),\n durationByDataSource,\n });\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":";;;AAAA,iEAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,+DAI8B;AAH5B,qIAAA,+BAA+B,OAAA;AAC/B,8HAAA,wBAAwB,OAAA;AACxB,wHAAA,kBAAkB,OAAA","sourcesContent":["export { DetectionMiddleware } from './DetectionMiddleware';\nexport {\n createParallelBalanceMiddleware,\n createParallelMiddleware,\n mergeDataResponses,\n} from './ParallelMiddleware';\nexport type { BalanceSource, TokenPriceSource } from './ParallelMiddleware';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":";;;AAAA,iEAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,+DAI8B;AAH5B,qIAAA,+BAA+B,OAAA;AAC/B,8HAAA,wBAAwB,OAAA;AACxB,wHAAA,kBAAkB,OAAA","sourcesContent":["export { DetectionMiddleware } from './DetectionMiddleware';\nexport {\n createParallelBalanceMiddleware,\n createParallelMiddleware,\n mergeDataResponses,\n} from './ParallelMiddleware';\nexport type { BalanceSource } from './ParallelMiddleware';\nexport type { AssetsDataSource } from '../types';\n"]}
@@ -1,4 +1,5 @@
1
1
  export { DetectionMiddleware } from "./DetectionMiddleware.cjs";
2
2
  export { createParallelBalanceMiddleware, createParallelMiddleware, mergeDataResponses, } from "./ParallelMiddleware.cjs";
3
- export type { BalanceSource, TokenPriceSource } from "./ParallelMiddleware.cjs";
3
+ export type { BalanceSource } from "./ParallelMiddleware.cjs";
4
+ export type { AssetsDataSource } from "../types.cjs";
4
5
  //# sourceMappingURL=index.d.cts.map