@metamask-previews/perps-controller 2.0.0-preview-a37be9342 → 2.0.0-preview-26cb9fc

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 (112) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/PerpsController.cjs.map +1 -1
  3. package/dist/PerpsController.d.cts.map +1 -1
  4. package/dist/PerpsController.d.mts.map +1 -1
  5. package/dist/PerpsController.mjs.map +1 -1
  6. package/dist/constants/eventNames.cjs +1 -0
  7. package/dist/constants/eventNames.cjs.map +1 -1
  8. package/dist/constants/eventNames.d.cts +1 -0
  9. package/dist/constants/eventNames.d.cts.map +1 -1
  10. package/dist/constants/eventNames.d.mts +1 -0
  11. package/dist/constants/eventNames.d.mts.map +1 -1
  12. package/dist/constants/eventNames.mjs +1 -0
  13. package/dist/constants/eventNames.mjs.map +1 -1
  14. package/dist/constants/perpsConfig.cjs +3 -0
  15. package/dist/constants/perpsConfig.cjs.map +1 -1
  16. package/dist/constants/perpsConfig.d.cts +1 -0
  17. package/dist/constants/perpsConfig.d.cts.map +1 -1
  18. package/dist/constants/perpsConfig.d.mts +1 -0
  19. package/dist/constants/perpsConfig.d.mts.map +1 -1
  20. package/dist/constants/perpsConfig.mjs +3 -0
  21. package/dist/constants/perpsConfig.mjs.map +1 -1
  22. package/dist/index.cjs +50 -56
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +2 -1
  25. package/dist/index.d.cts.map +1 -1
  26. package/dist/index.d.mts +2 -1
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +1 -1
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/providers/HyperLiquidProvider.cjs +18 -6
  31. package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
  32. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
  33. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
  34. package/dist/providers/HyperLiquidProvider.mjs +18 -6
  35. package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
  36. package/dist/services/HyperLiquidClientService.cjs +39 -16
  37. package/dist/services/HyperLiquidClientService.cjs.map +1 -1
  38. package/dist/services/HyperLiquidClientService.d.cts +2 -0
  39. package/dist/services/HyperLiquidClientService.d.cts.map +1 -1
  40. package/dist/services/HyperLiquidClientService.d.mts +2 -0
  41. package/dist/services/HyperLiquidClientService.d.mts.map +1 -1
  42. package/dist/services/HyperLiquidClientService.mjs +39 -16
  43. package/dist/services/HyperLiquidClientService.mjs.map +1 -1
  44. package/dist/services/HyperLiquidSubscriptionService.cjs +78 -13
  45. package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
  46. package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
  47. package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
  48. package/dist/services/HyperLiquidSubscriptionService.mjs +78 -13
  49. package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
  50. package/dist/services/TradingService.cjs +0 -1
  51. package/dist/services/TradingService.cjs.map +1 -1
  52. package/dist/services/TradingService.d.cts.map +1 -1
  53. package/dist/services/TradingService.d.mts.map +1 -1
  54. package/dist/services/TradingService.mjs +0 -1
  55. package/dist/services/TradingService.mjs.map +1 -1
  56. package/dist/types/index.cjs +3 -2
  57. package/dist/types/index.cjs.map +1 -1
  58. package/dist/types/index.d.cts.map +1 -1
  59. package/dist/types/index.d.mts.map +1 -1
  60. package/dist/types/index.mjs +3 -2
  61. package/dist/types/index.mjs.map +1 -1
  62. package/dist/types/transactionTypes.cjs +5 -4
  63. package/dist/types/transactionTypes.cjs.map +1 -1
  64. package/dist/types/transactionTypes.d.cts +0 -4
  65. package/dist/types/transactionTypes.d.cts.map +1 -1
  66. package/dist/types/transactionTypes.d.mts +0 -4
  67. package/dist/types/transactionTypes.d.mts.map +1 -1
  68. package/dist/types/transactionTypes.mjs +3 -2
  69. package/dist/types/transactionTypes.mjs.map +1 -1
  70. package/dist/utils/errorUtils.cjs +4 -3
  71. package/dist/utils/errorUtils.cjs.map +1 -1
  72. package/dist/utils/errorUtils.d.cts +0 -4
  73. package/dist/utils/errorUtils.d.cts.map +1 -1
  74. package/dist/utils/errorUtils.d.mts +0 -4
  75. package/dist/utils/errorUtils.d.mts.map +1 -1
  76. package/dist/utils/errorUtils.mjs +2 -1
  77. package/dist/utils/errorUtils.mjs.map +1 -1
  78. package/dist/utils/hyperLiquidAdapter.cjs +3 -2
  79. package/dist/utils/hyperLiquidAdapter.cjs.map +1 -1
  80. package/dist/utils/hyperLiquidAdapter.d.cts.map +1 -1
  81. package/dist/utils/hyperLiquidAdapter.d.mts.map +1 -1
  82. package/dist/utils/hyperLiquidAdapter.mjs +4 -3
  83. package/dist/utils/hyperLiquidAdapter.mjs.map +1 -1
  84. package/dist/utils/hyperLiquidValidation.cjs +4 -0
  85. package/dist/utils/hyperLiquidValidation.cjs.map +1 -1
  86. package/dist/utils/hyperLiquidValidation.d.cts.map +1 -1
  87. package/dist/utils/hyperLiquidValidation.d.mts.map +1 -1
  88. package/dist/utils/hyperLiquidValidation.mjs +4 -0
  89. package/dist/utils/hyperLiquidValidation.mjs.map +1 -1
  90. package/dist/utils/index.cjs +0 -1
  91. package/dist/utils/index.cjs.map +1 -1
  92. package/dist/utils/index.d.cts +0 -1
  93. package/dist/utils/index.d.cts.map +1 -1
  94. package/dist/utils/index.d.mts +0 -1
  95. package/dist/utils/index.d.mts.map +1 -1
  96. package/dist/utils/index.mjs +0 -1
  97. package/dist/utils/index.mjs.map +1 -1
  98. package/dist/utils/marketDataTransform.cjs +2 -1
  99. package/dist/utils/marketDataTransform.cjs.map +1 -1
  100. package/dist/utils/marketDataTransform.d.cts.map +1 -1
  101. package/dist/utils/marketDataTransform.d.mts.map +1 -1
  102. package/dist/utils/marketDataTransform.mjs +2 -1
  103. package/dist/utils/marketDataTransform.mjs.map +1 -1
  104. package/dist/utils/perpsConnectionAttemptContext.cjs +20 -0
  105. package/dist/utils/perpsConnectionAttemptContext.cjs.map +1 -0
  106. package/dist/utils/perpsConnectionAttemptContext.d.cts +7 -0
  107. package/dist/utils/perpsConnectionAttemptContext.d.cts.map +1 -0
  108. package/dist/utils/perpsConnectionAttemptContext.d.mts +7 -0
  109. package/dist/utils/perpsConnectionAttemptContext.d.mts.map +1 -0
  110. package/dist/utils/perpsConnectionAttemptContext.mjs +15 -0
  111. package/dist/utils/perpsConnectionAttemptContext.mjs.map +1 -0
  112. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"HyperLiquidClientService.mjs","sourceRoot":"","sources":["../../src/services/HyperLiquidClientService.ts"],"names":[],"mappings":"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","sourcesContent":["import { Hex } from '@metamask/utils';\nimport {\n ExchangeClient,\n HttpTransport,\n InfoClient,\n SubscriptionClient,\n WebSocketTransport,\n} from '@nktkas/hyperliquid';\n\nimport { CandlePeriod, calculateCandleCount } from '../constants/chartConfig';\nimport { HYPERLIQUID_TRANSPORT_CONFIG } from '../constants/hyperLiquidConfig';\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig';\nimport { PERPS_ERROR_CODES } from '../perpsErrorCodes';\nimport { WebSocketConnectionState } from '../types';\nimport type {\n SubscribeCandlesParams,\n PerpsPlatformDependencies,\n} from '../types';\nimport type { HyperLiquidNetwork } from '../types/config';\nimport type { CandleData } from '../types/perps-types';\nimport { ensureError } from '../utils/errorUtils';\n\n/**\n * Maximum number of reconnection attempts before giving up.\n */\nconst maxReconnectionAttempts = 10;\n\n/**\n * Valid time intervals for historical candle data\n * Uses CandlePeriod enum for type safety\n */\nexport type ValidCandleInterval = CandlePeriod;\n\n/**\n * Wallet interface for HyperLiquid SDK operations.\n * Extracted for reuse across initialize(), toggleTestnet(), and ensureSubscriptionClient() methods.\n */\nexport type HyperLiquidWalletParams = {\n signTypedData: (params: {\n domain: {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: Hex;\n };\n types: {\n [key: string]: { name: string; type: string }[];\n };\n primaryType: string;\n message: Record<string, unknown>;\n }) => Promise<Hex>;\n getChainId?: () => Promise<number>;\n};\n\n// WebSocketConnectionState is now imported from controllers/types\n// Re-export for backward compatibility with existing consumers\nexport { WebSocketConnectionState } from '../types';\n\n/**\n * Service for managing HyperLiquid SDK clients\n * Handles initialization, transport creation, and client lifecycle\n */\nexport class HyperLiquidClientService {\n #exchangeClient?: ExchangeClient;\n\n #infoClient?: InfoClient; // WebSocket transport (default)\n\n #infoClientHttp?: InfoClient; // HTTP transport (fallback)\n\n #subscriptionClient?: SubscriptionClient<{\n transport: WebSocketTransport;\n }>;\n\n #wsTransport?: WebSocketTransport;\n\n #httpTransport?: HttpTransport;\n\n #isTestnet: boolean;\n\n #connectionState: WebSocketConnectionState =\n WebSocketConnectionState.Disconnected;\n\n #disconnectionPromise: Promise<void> | null = null;\n\n // Callback for SDK terminate event (fired when all reconnection attempts exhausted)\n #onTerminateCallback: ((error: Error) => void) | null = null;\n\n #onReconnectCallback?: () => Promise<void>;\n\n // Reconnection attempt counter\n #reconnectionAttempt = 0;\n\n // Connection state change listeners for event-based notifications\n readonly #connectionStateListeners: Set<\n (state: WebSocketConnectionState, reconnectionAttempt: number) => void\n > = new Set();\n\n // Timeout reference for reconnection retry, tracked to enable cancellation on disconnect\n #reconnectionRetryTimeout: ReturnType<typeof setTimeout> | null = null;\n\n // Platform dependencies for logging\n readonly #deps: PerpsPlatformDependencies;\n\n constructor(\n deps: PerpsPlatformDependencies,\n options: { isTestnet?: boolean } = {},\n ) {\n this.#deps = deps;\n this.#isTestnet = options.isTestnet ?? false;\n }\n\n /**\n * Initialize all HyperLiquid SDK clients\n *\n * IMPORTANT: This method awaits transport.ready() to ensure the WebSocket is\n * in OPEN state before marking initialization complete. This prevents race\n * conditions where subscriptions are attempted before the WebSocket handshake\n * completes (which would cause \"subscribe error: undefined\" errors).\n *\n * @param wallet - The wallet parameters for signing typed data.\n */\n public async initialize(wallet: HyperLiquidWalletParams): Promise<void> {\n try {\n this.#updateConnectionState(WebSocketConnectionState.Connecting);\n this.#createTransports();\n\n // Ensure transports are created\n if (!this.#httpTransport || !this.#wsTransport) {\n throw new Error('Failed to create transports');\n }\n\n // Wallet adapter implements AbstractViemJsonRpcAccount interface with signTypedData method\n // ExchangeClient uses HTTP transport for write operations (orders, approvals, etc.)\n this.#exchangeClient = new ExchangeClient({\n wallet: wallet as any, // eslint-disable-line @typescript-eslint/no-explicit-any -- Type widening for SDK compatibility\n transport: this.#httpTransport,\n });\n\n // InfoClient with WebSocket transport (default) - multiplexed requests over single connection\n this.#infoClient = new InfoClient({ transport: this.#wsTransport });\n\n // InfoClient with HTTP transport (fallback) - for specific calls if WebSocket has issues\n this.#infoClientHttp = new InfoClient({ transport: this.#httpTransport });\n\n // SubscriptionClient uses WebSocket transport for real-time pub/sub (price feeds, position updates)\n this.#subscriptionClient = new SubscriptionClient({\n transport: this.#wsTransport,\n });\n\n // Wait for WebSocket to actually be ready before setting CONNECTED\n // This ensures we have a real connection, not just client objects\n await this.#wsTransport.ready();\n\n this.#updateConnectionState(WebSocketConnectionState.Connected);\n\n this.#deps.debugLogger.log('HyperLiquid SDK clients initialized', {\n testnet: this.#isTestnet,\n timestamp: new Date().toISOString(),\n connectionState: this.#connectionState,\n note: 'Using WebSocket for InfoClient (default), HTTP fallback available',\n });\n } catch (error) {\n // Cleanup on failure to prevent leaks and ensure isInitialized() returns false\n // Clear clients first, then transports\n this.#subscriptionClient = undefined;\n this.#infoClient = undefined;\n this.#infoClientHttp = undefined;\n this.#exchangeClient = undefined;\n\n // Close WebSocket transport to release resources and event listeners\n if (this.#wsTransport) {\n try {\n await this.#wsTransport.close();\n } catch {\n // Ignore cleanup errors\n }\n this.#wsTransport = undefined;\n }\n this.#httpTransport = undefined;\n\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.initialize',\n );\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n\n // Log to Sentry: initialization failure blocks all Perps functionality\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'sdk_initialization',\n data: {\n operation: 'initialize',\n isTestnet: this.#isTestnet,\n },\n },\n });\n\n throw error;\n }\n }\n\n /**\n * Create HTTP and WebSocket transports\n * - HTTP for InfoClient and ExchangeClient (request/response operations)\n * - WebSocket for SubscriptionClient (real-time pub/sub)\n *\n * Both transports use SDK's built-in endpoint resolution via isTestnet flag\n *\n * @returns The created WebSocket transport instance.\n */\n #createTransports(): WebSocketTransport {\n // Prevent duplicate transport creation and listener accumulation\n // This guards against re-entry if initialize() is called multiple times\n // (e.g., after a failed initialization attempt that didn't properly clean up)\n if (this.#wsTransport && this.#httpTransport) {\n this.#deps.debugLogger.log(\n 'HyperLiquid: Transports already exist, skipping creation',\n );\n return this.#wsTransport;\n }\n\n this.#deps.debugLogger.log('HyperLiquid: Creating transports', {\n isTestnet: this.#isTestnet,\n timestamp: new Date().toISOString(),\n note: 'SDK will auto-select endpoints based on isTestnet flag',\n });\n\n // HTTP transport for request/response operations (InfoClient, ExchangeClient)\n // SDK automatically selects: mainnet (https://api.hyperliquid.xyz) or testnet (https://api.hyperliquid-testnet.xyz)\n this.#httpTransport = new HttpTransport({\n isTestnet: this.#isTestnet,\n timeout: HYPERLIQUID_TRANSPORT_CONFIG.timeout,\n });\n\n // WebSocket transport for real-time subscriptions (SubscriptionClient)\n // SDK automatically selects: mainnet (wss://api.hyperliquid.xyz/ws) or testnet (wss://api.hyperliquid-testnet.xyz/ws)\n this.#wsTransport = new WebSocketTransport({\n isTestnet: this.#isTestnet,\n ...HYPERLIQUID_TRANSPORT_CONFIG,\n reconnect: {\n ...HYPERLIQUID_TRANSPORT_CONFIG.reconnect,\n WebSocket: globalThis.WebSocket, // Use React Native's global WebSocket\n },\n });\n\n // Listen for WebSocket termination (fired when SDK exhausts all reconnection attempts)\n this.#wsTransport.socket.addEventListener('terminate', (event: Event) => {\n const customEvent = event as CustomEvent;\n this.#deps.debugLogger.log('HyperLiquid: WebSocket terminated', {\n reason: customEvent.detail?.code,\n timestamp: new Date().toISOString(),\n });\n\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n\n if (this.#onTerminateCallback) {\n const error =\n customEvent.detail instanceof Error\n ? customEvent.detail\n : new Error(\n `WebSocket terminated: ${customEvent.detail?.code ?? 'unknown'}`,\n );\n this.#onTerminateCallback(error);\n }\n });\n\n return this.#wsTransport;\n }\n\n /**\n * Toggle testnet mode and reinitialize clients\n *\n * @param wallet - The wallet parameters for signing typed data.\n * @returns The new network name after toggling.\n */\n public async toggleTestnet(\n wallet: HyperLiquidWalletParams,\n ): Promise<HyperLiquidNetwork> {\n this.#isTestnet = !this.#isTestnet;\n await this.initialize(wallet);\n return this.#isTestnet ? 'testnet' : 'mainnet';\n }\n\n /**\n * Check if clients are properly initialized\n *\n * @returns True if all SDK clients are initialized.\n */\n public isInitialized(): boolean {\n return Boolean(\n this.#exchangeClient &&\n this.#infoClient &&\n this.#infoClientHttp &&\n this.#subscriptionClient,\n );\n }\n\n /**\n * Ensure clients are initialized, throw if not\n */\n public ensureInitialized(): void {\n if (!this.isInitialized()) {\n throw new Error(PERPS_ERROR_CODES.CLIENT_NOT_INITIALIZED);\n }\n }\n\n /**\n * Recreate subscription client if needed (for reconnection scenarios)\n *\n * @param wallet - The wallet parameters for signing typed data.\n */\n public async ensureSubscriptionClient(\n wallet: HyperLiquidWalletParams,\n ): Promise<void> {\n if (!this.#subscriptionClient) {\n this.#deps.debugLogger.log(\n 'HyperLiquid: Recreating subscription client after disconnect',\n );\n await this.initialize(wallet);\n }\n }\n\n /**\n * Get the exchange client\n *\n * @returns The initialized ExchangeClient instance.\n */\n public getExchangeClient(): ExchangeClient {\n this.ensureInitialized();\n if (!this.#exchangeClient) {\n throw new Error(PERPS_ERROR_CODES.EXCHANGE_CLIENT_NOT_AVAILABLE);\n }\n return this.#exchangeClient;\n }\n\n /**\n * Get the info client\n *\n * @param options - The options for selecting the transport.\n * @param options.useHttp - Force HTTP transport instead of WebSocket (default: false).\n * @returns InfoClient instance with the selected transport.\n */\n public getInfoClient(options?: { useHttp?: boolean }): InfoClient {\n this.ensureInitialized();\n\n if (options?.useHttp) {\n if (!this.#infoClientHttp) {\n throw new Error(PERPS_ERROR_CODES.INFO_CLIENT_NOT_AVAILABLE);\n }\n return this.#infoClientHttp;\n }\n\n if (!this.#infoClient) {\n throw new Error(PERPS_ERROR_CODES.INFO_CLIENT_NOT_AVAILABLE);\n }\n return this.#infoClient;\n }\n\n /**\n * Get the subscription client\n *\n * @returns The SubscriptionClient instance, or undefined if not initialized.\n */\n public getSubscriptionClient():\n | SubscriptionClient<{ transport: WebSocketTransport }>\n | undefined {\n if (!this.#subscriptionClient) {\n this.#deps.debugLogger.log('SubscriptionClient not initialized');\n return undefined;\n }\n return this.#subscriptionClient;\n }\n\n /**\n * Ensures the WebSocket transport is in OPEN state and ready for subscriptions.\n * This MUST be called before any subscription operations to prevent race conditions.\n *\n * The SDK's `transport.ready()` method:\n * - Returns immediately if WebSocket is already in OPEN state\n * - Waits for the \"open\" event if WebSocket is in CONNECTING state\n * - Supports AbortSignal for timeout/cancellation\n *\n * @param options - The options for transport readiness check.\n * @param options.timeoutMs - Maximum time to wait for transport ready (default 5000ms).\n * @throws Error if transport not ready within timeout or subscription client unavailable.\n */\n public async ensureTransportReady(\n options: { timeoutMs?: number } = {},\n ): Promise<void> {\n const { timeoutMs = 5000 } = options;\n const subscriptionClient = this.getSubscriptionClient();\n if (!subscriptionClient) {\n throw new Error('Subscription client not initialized');\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () =>\n controller.abort(\n new Error(`WebSocket transport ready timeout after ${timeoutMs}ms`),\n ),\n timeoutMs,\n );\n\n try {\n await subscriptionClient.config_.transport.ready(controller.signal);\n } catch (error) {\n if (controller.signal.aborted) {\n throw new Error(\n `WebSocket transport ready timeout after ${timeoutMs}ms`,\n );\n }\n throw ensureError(error, 'HyperLiquidClientService.ensureTransportReady');\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Get current network state\n *\n * @returns The current HyperLiquid network (mainnet or testnet).\n */\n public getNetwork(): HyperLiquidNetwork {\n return this.#isTestnet ? 'testnet' : 'mainnet';\n }\n\n /**\n * Check if running on testnet\n *\n * @returns True if the service is in testnet mode.\n */\n public isTestnetMode(): boolean {\n return this.#isTestnet;\n }\n\n /**\n * Update testnet mode\n *\n * @param isTestnet - Whether to enable testnet mode.\n */\n public setTestnetMode(isTestnet: boolean): void {\n this.#isTestnet = isTestnet;\n }\n\n /**\n * Fetch historical candle data using the HyperLiquid SDK\n *\n * @param options - The candle fetch configuration.\n * @param options.symbol - The asset symbol (e.g., \"BTC\", \"ETH\").\n * @param options.interval - The candle interval (e.g., \"1m\", \"5m\", \"15m\", \"1h\", \"1d\").\n * @param options.limit - Number of candles to fetch (default: 100).\n * @param options.endTime - End timestamp in milliseconds (default: now).\n * @returns The historical candle data, or null if no data is available.\n */\n public async fetchHistoricalCandles(options: {\n symbol: string;\n interval: ValidCandleInterval;\n limit?: number;\n endTime?: number;\n }): Promise<CandleData | null> {\n const { symbol, interval, limit = 100, endTime } = options;\n this.ensureInitialized();\n\n try {\n // Calculate start and end times based on interval and limit\n const now = endTime ?? Date.now();\n const intervalMs = this.#getIntervalMilliseconds(interval);\n const startTime = now - limit * intervalMs;\n\n // Use the SDK's InfoClient to fetch candle data\n // HyperLiquid SDK uses 'coin' terminology\n const infoClient = this.getInfoClient();\n const data = await infoClient.candleSnapshot({\n coin: symbol, // Map to HyperLiquid SDK's 'coin' parameter\n interval,\n startTime,\n endTime: now,\n });\n\n // Transform API response to match expected format\n if (Array.isArray(data) && data.length > 0) {\n const candles = data.map((candle) => ({\n time: candle.t, // open time\n open: candle.o.toString(),\n high: candle.h.toString(),\n low: candle.l.toString(),\n close: candle.c.toString(),\n volume: candle.v.toString(),\n }));\n\n return {\n symbol,\n interval,\n candles,\n };\n }\n\n return {\n symbol,\n interval,\n candles: [],\n };\n } catch (error) {\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.fetchHistoricalCandles',\n );\n\n // Log to Sentry: prevents initial chart data load\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'historical_candles_api',\n data: {\n operation: 'fetchHistoricalCandles',\n symbol,\n interval,\n limit,\n hasEndTime: endTime !== undefined,\n },\n },\n });\n\n throw error;\n }\n }\n\n /**\n * Subscribe to candle updates via WebSocket\n *\n * @param root0 - The subscription parameters.\n * @param root0.symbol - The asset symbol (e.g., \"BTC\", \"ETH\").\n * @param root0.interval - The candle interval (e.g., \"1m\", \"5m\", \"15m\").\n * @param root0.duration - Optional time duration for calculating initial fetch size.\n * @param root0.callback - Function called with updated candle data.\n * @param root0.onError - Optional function called if subscription initialization fails.\n * @returns Cleanup function to unsubscribe.\n */\n public subscribeToCandles({\n symbol,\n interval,\n duration,\n callback,\n onError,\n }: SubscribeCandlesParams): () => void {\n this.ensureInitialized();\n\n const subscriptionClient = this.getSubscriptionClient();\n if (!subscriptionClient) {\n throw new Error(PERPS_ERROR_CODES.SUBSCRIPTION_CLIENT_NOT_AVAILABLE);\n }\n\n let currentCandleData: CandleData | null = null;\n let wsUnsubscribe: (() => void) | null = null;\n let isUnsubscribed = false;\n // Store the subscription promise to enable cleanup even when pending\n // This fixes a race condition where component unmounts before subscription resolves\n let subscriptionPromise: Promise<{ unsubscribe: () => void }> | null = null;\n\n // Calculate initial fetch size dynamically based on duration and interval\n // Match main branch behavior: up to 500 candles initially\n const initialLimit = duration\n ? Math.min(calculateCandleCount(duration, interval), 500)\n : 100; // Default to 100 if no duration provided\n\n // 1. Fetch initial historical data, then subscribe to WebSocket updates\n // Using an async IIFE to avoid nested promises and callback-in-promise issues\n const initAndSubscribe = async (): Promise<void> => {\n try {\n const initialData = await this.fetchHistoricalCandles({\n symbol,\n interval,\n limit: initialLimit,\n });\n\n // Don't proceed if already unsubscribed\n if (isUnsubscribed) {\n return;\n }\n\n currentCandleData = initialData;\n if (currentCandleData) {\n callback(currentCandleData);\n }\n\n // 2. Subscribe to WebSocket for new candles\n // HyperLiquid SDK uses 'coin' terminology\n // Store the promise so cleanup can wait for it if needed\n subscriptionPromise = subscriptionClient.candle(\n { coin: symbol, interval }, // Map to HyperLiquid SDK's 'coin' parameter\n (candleEvent) => {\n // Don't process events if already unsubscribed\n if (isUnsubscribed) {\n return;\n }\n\n // Transform SDK CandleEvent to our Candle format\n const newCandle = {\n time: candleEvent.t,\n open: candleEvent.o.toString(),\n high: candleEvent.h.toString(),\n low: candleEvent.l.toString(),\n close: candleEvent.c.toString(),\n volume: candleEvent.v.toString(),\n };\n\n if (currentCandleData) {\n // Check if this is an update to the last candle or a new candle\n const { candles } = currentCandleData;\n const lastCandle = candles[candles.length - 1];\n\n if (lastCandle?.time === newCandle.time) {\n // Update existing candle (live candle update)\n // Create new array with updated last element to trigger React re-render\n currentCandleData = {\n ...currentCandleData,\n candles: [...candles.slice(0, -1), newCandle],\n };\n } else {\n // New candle (completed candle)\n // Create new array with added element to trigger React re-render\n currentCandleData = {\n ...currentCandleData,\n candles: [...candles, newCandle],\n };\n }\n } else {\n currentCandleData = {\n symbol,\n interval,\n candles: [newCandle],\n };\n }\n\n callback(currentCandleData);\n },\n );\n\n // Store cleanup function when subscription resolves\n try {\n const sub = await subscriptionPromise;\n wsUnsubscribe = (): void => sub.unsubscribe();\n // If already unsubscribed while waiting, clean up immediately\n if (isUnsubscribed) {\n wsUnsubscribe();\n wsUnsubscribe = null;\n }\n } catch (error) {\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.subscribeToCandles',\n );\n\n // Log to Sentry: WebSocket subscription failure prevents live updates\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'websocket_subscription',\n data: {\n operation: 'subscribeToCandles',\n symbol,\n interval,\n phase: 'ws_subscription',\n },\n },\n });\n\n // Notify caller of error\n onError?.(errorInstance);\n }\n } catch (error) {\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.subscribeToCandles',\n );\n\n // Log to Sentry: initial fetch failure blocks chart completely\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'initial_candles_fetch',\n data: {\n operation: 'subscribeToCandles',\n symbol,\n interval,\n phase: 'initial_fetch',\n initialLimit,\n },\n },\n });\n\n // Notify caller of error\n onError?.(errorInstance);\n }\n };\n\n // Fire-and-forget the async initialization\n initAndSubscribe().catch(() => {\n // Error already handled inside initAndSubscribe\n });\n\n // Return cleanup function\n return () => {\n isUnsubscribed = true;\n if (wsUnsubscribe) {\n // Subscription already resolved - unsubscribe directly\n wsUnsubscribe();\n wsUnsubscribe = null;\n } else if (subscriptionPromise) {\n // Subscription promise still pending - wait for it and clean up\n // This prevents WebSocket subscription leaks when component unmounts\n // before the subscription promise resolves\n subscriptionPromise\n .then((sub) => sub.unsubscribe())\n .catch(() => {\n // Ignore errors during cleanup - subscription may have failed\n });\n subscriptionPromise = null;\n }\n };\n }\n\n /**\n * Convert interval string to milliseconds\n *\n * @param interval - The candle period interval to convert.\n * @returns The interval duration in milliseconds.\n */\n #getIntervalMilliseconds(interval: CandlePeriod): number {\n const intervalMap: Record<CandlePeriod, number> = {\n [CandlePeriod.OneMinute]: 1 * 60 * 1000,\n [CandlePeriod.ThreeMinutes]: 3 * 60 * 1000,\n [CandlePeriod.FiveMinutes]: 5 * 60 * 1000,\n [CandlePeriod.FifteenMinutes]: 15 * 60 * 1000,\n [CandlePeriod.ThirtyMinutes]: 30 * 60 * 1000,\n [CandlePeriod.OneHour]: 60 * 60 * 1000,\n [CandlePeriod.TwoHours]: 2 * 60 * 60 * 1000,\n [CandlePeriod.FourHours]: 4 * 60 * 60 * 1000,\n [CandlePeriod.EightHours]: 8 * 60 * 60 * 1000,\n [CandlePeriod.TwelveHours]: 12 * 60 * 60 * 1000,\n [CandlePeriod.OneDay]: 24 * 60 * 60 * 1000,\n [CandlePeriod.ThreeDays]: 3 * 24 * 60 * 60 * 1000,\n [CandlePeriod.OneWeek]: 7 * 24 * 60 * 60 * 1000,\n [CandlePeriod.OneMonth]: 30 * 24 * 60 * 60 * 1000, // Approximate\n };\n\n return intervalMap[interval];\n }\n\n /**\n * Disconnect and cleanup all clients\n *\n * @returns A promise that resolves when disconnection is complete.\n */\n public async disconnect(): Promise<void> {\n // Await existing promise if already disconnecting\n if (this.#disconnectionPromise) {\n await this.#disconnectionPromise;\n return;\n }\n\n // If already disconnected, return immediately\n if (this.#connectionState === WebSocketConnectionState.Disconnected) {\n return;\n }\n\n // Create and store the disconnection promise\n this.#disconnectionPromise = this.#performDisconnection();\n\n try {\n await this.#disconnectionPromise;\n } finally {\n this.#disconnectionPromise = null;\n }\n }\n\n async #performDisconnection(): Promise<void> {\n try {\n this.#updateConnectionState(WebSocketConnectionState.Disconnecting);\n\n this.#deps.debugLogger.log('HyperLiquid: Disconnecting SDK clients', {\n isTestnet: this.#isTestnet,\n timestamp: new Date().toISOString(),\n connectionState: this.#connectionState,\n });\n\n // Clear callbacks\n this.#onReconnectCallback = undefined;\n this.#onTerminateCallback = null;\n\n // Cancel any pending reconnection retry timeout\n if (this.#reconnectionRetryTimeout) {\n clearTimeout(this.#reconnectionRetryTimeout);\n this.#reconnectionRetryTimeout = null;\n }\n\n // Clear connection state listeners to prevent stale callbacks\n this.#connectionStateListeners.clear();\n\n // Reset reconnection flag to allow future manual retries\n // This prevents a race condition where disconnecting during an active\n // reconnection attempt could leave the flag stuck, blocking subsequent retries\n this.#isReconnecting = false;\n\n // Close WebSocket transport only (HTTP is stateless)\n if (this.#wsTransport) {\n try {\n await this.#wsTransport.close();\n this.#deps.debugLogger.log(\n 'HyperLiquid: Closed WebSocket transport',\n {\n timestamp: new Date().toISOString(),\n },\n );\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'HyperLiquidClientService.performDisconnection'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'HyperLiquidClientService.performDisconnection',\n data: { action: 'close_transport' },\n },\n },\n );\n }\n }\n\n // Clear client references\n this.#subscriptionClient = undefined;\n this.#exchangeClient = undefined;\n this.#infoClient = undefined;\n this.#infoClientHttp = undefined;\n this.#wsTransport = undefined;\n this.#httpTransport = undefined;\n\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n\n this.#deps.debugLogger.log(\n 'HyperLiquid: SDK clients fully disconnected',\n {\n timestamp: new Date().toISOString(),\n connectionState: this.#connectionState,\n },\n );\n } catch (error) {\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n this.#deps.logger.error(\n ensureError(error, 'HyperLiquidClientService.performDisconnection'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'HyperLiquidClientService.performDisconnection',\n data: { action: 'outer_catch' },\n },\n },\n );\n throw error;\n }\n }\n\n /**\n * Get current WebSocket connection state\n *\n * @returns The current WebSocket connection state.\n */\n public getConnectionState(): WebSocketConnectionState {\n return this.#connectionState;\n }\n\n /**\n * Check if WebSocket is fully disconnected\n *\n * @returns True if the WebSocket is in disconnected state.\n */\n public isDisconnected(): boolean {\n return this.#connectionState === WebSocketConnectionState.Disconnected;\n }\n\n /**\n * Set callback to be invoked when reconnection is needed\n * This allows the service to notify external components (like PerpsConnectionManager)\n * when a connection drop is detected\n *\n * @param callback - The async callback to invoke when reconnection is needed.\n */\n public setOnReconnectCallback(callback: () => Promise<void>): void {\n this.#onReconnectCallback = callback;\n }\n\n /**\n * Set callback for WebSocket termination events\n * Called when the SDK exhausts all reconnection attempts\n *\n * @param callback - The callback to invoke on termination, or null to clear.\n */\n public setOnTerminateCallback(\n callback: ((error: Error) => void) | null,\n ): void {\n this.#onTerminateCallback = callback;\n }\n\n /**\n * Subscribe to connection state changes.\n * The listener will be called immediately with the current state and whenever the state changes.\n *\n * @param listener - Callback function that receives the new connection state and reconnection attempt\n * @returns Unsubscribe function to remove the listener\n */\n public subscribeToConnectionState(\n listener: (\n state: WebSocketConnectionState,\n reconnectionAttempt: number,\n ) => void,\n ): () => void {\n this.#connectionStateListeners.add(listener);\n\n // Immediately notify with current state\n // Wrap in try-catch to match notifyConnectionStateListeners behavior\n // This ensures the unsubscribe function is always returned even if listener throws\n try {\n listener(this.#connectionState, this.#reconnectionAttempt);\n } catch {\n // Ignore errors in listeners to prevent breaking subscription mechanism\n // If listener throws, it will be removed when unsubscribe is called\n }\n\n // Return unsubscribe function\n return () => {\n this.#connectionStateListeners.delete(listener);\n };\n }\n\n /**\n * Update connection state and notify all listeners\n * Always notifies if state changes OR if we're in CONNECTING state (to update attempt count)\n *\n * @param newState - The new WebSocket connection state.\n */\n #updateConnectionState(newState: WebSocketConnectionState): void {\n const previousState = this.#connectionState;\n const stateChanged = previousState !== newState;\n const isReconnectionAttempt =\n newState === WebSocketConnectionState.Connecting &&\n this.#reconnectionAttempt > 0;\n\n this.#connectionState = newState;\n\n // Reset reconnection attempt counter when successfully connected\n if (newState === WebSocketConnectionState.Connected) {\n this.#reconnectionAttempt = 0;\n }\n\n // Notify if state changed OR if this is a reconnection attempt (to update attempt count)\n if (stateChanged || isReconnectionAttempt) {\n this.#notifyConnectionStateListeners();\n }\n }\n\n /**\n * Notify all connection state listeners of the current state\n */\n #notifyConnectionStateListeners(): void {\n this.#connectionStateListeners.forEach((listener) => {\n try {\n listener(this.#connectionState, this.#reconnectionAttempt);\n } catch {\n // Ignore errors in listeners to prevent breaking other listeners\n }\n });\n }\n\n // Flag to prevent concurrent reconnection attempts\n #isReconnecting = false;\n\n /**\n * Manually trigger a reconnection attempt.\n * This is exposed for UI retry buttons when user wants to force reconnection.\n * Resets the reconnection attempt counter to allow retrying after max attempts.\n */\n public async reconnect(): Promise<void> {\n this.#deps.debugLogger.log(\n '[HyperLiquidClientService] reconnect() called',\n {\n previousAttempt: this.#reconnectionAttempt,\n currentState: this.#connectionState,\n },\n );\n // Reset attempt counter when user manually triggers retry\n this.#reconnectionAttempt = 0;\n await this.#handleConnectionDrop();\n this.#deps.debugLogger.log(\n '[HyperLiquidClientService] reconnect() completed',\n {\n newState: this.#connectionState,\n },\n );\n }\n\n /**\n * Handle detected connection drop\n * Recreates WebSocket transport and notifies callback to restore subscriptions\n * Will give up after maxReconnectionAttempts and mark status as disconnected\n */\n async #handleConnectionDrop(): Promise<void> {\n // Prevent multiple simultaneous reconnection attempts\n if (this.#isReconnecting) {\n return;\n }\n\n this.#isReconnecting = true;\n\n // Increment reconnection attempt counter\n this.#reconnectionAttempt += 1;\n\n // Check if we've exceeded max retry attempts\n if (this.#reconnectionAttempt > maxReconnectionAttempts) {\n this.#isReconnecting = false;\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n return;\n }\n\n try {\n this.#updateConnectionState(WebSocketConnectionState.Connecting);\n\n // Close existing WebSocket transport and clear references\n // so createTransports() will create fresh ones\n if (this.#wsTransport) {\n try {\n await this.#wsTransport.close();\n } catch {\n // Ignore errors during close - transport may already be dead\n }\n }\n this.#wsTransport = undefined;\n this.#httpTransport = undefined;\n\n // Recreate WebSocket transport - returns the new transport for type safety\n const newWsTransport = this.#createTransports();\n\n // Recreate clients that use WebSocket transport\n this.#infoClient = new InfoClient({ transport: newWsTransport });\n this.#subscriptionClient = new SubscriptionClient({\n transport: newWsTransport,\n });\n\n await newWsTransport.ready();\n\n this.#deps.debugLogger.log(\n 'HyperLiquid: Transport ready, restoring subscriptions',\n { timestamp: new Date().toISOString() },\n );\n\n // NOW safe to restore subscriptions\n if (this.#onReconnectCallback) {\n await this.#onReconnectCallback();\n }\n\n // Cancel any pending retry timeout from previous failed attempts\n if (this.#reconnectionRetryTimeout) {\n clearTimeout(this.#reconnectionRetryTimeout);\n this.#reconnectionRetryTimeout = null;\n }\n\n this.#updateConnectionState(WebSocketConnectionState.Connected);\n this.#isReconnecting = false;\n } catch {\n // Reset flag before scheduling retry so the next attempt can proceed\n this.#isReconnecting = false;\n\n // Check if we've exceeded max retry attempts\n if (this.#reconnectionAttempt >= maxReconnectionAttempts) {\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n return;\n }\n\n // Reconnection failed - schedule a retry after a delay\n // Store timeout reference so it can be cancelled on intentional disconnect\n this.#reconnectionRetryTimeout = setTimeout(() => {\n this.#reconnectionRetryTimeout = null; // Clear reference after execution\n // Only retry if we haven't been intentionally disconnected\n // and no manual reconnect() is already in progress\n // Note: State may be CONNECTING or DISCONNECTED (if terminate event fired during reconnect)\n if (\n (this.#connectionState === WebSocketConnectionState.Connecting ||\n this.#connectionState === WebSocketConnectionState.Disconnected) &&\n !this.#disconnectionPromise &&\n !this.#isReconnecting\n ) {\n this.#handleConnectionDrop().catch(() => {\n // Error already handled inside #handleConnectionDrop\n });\n }\n }, PERPS_CONSTANTS.ReconnectionRetryDelayMs);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"HyperLiquidClientService.mjs","sourceRoot":"","sources":["../../src/services/HyperLiquidClientService.ts"],"names":[],"mappings":"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","sourcesContent":["import { Hex } from '@metamask/utils';\nimport {\n ExchangeClient,\n HttpTransport,\n InfoClient,\n SubscriptionClient,\n WebSocketTransport,\n} from '@nktkas/hyperliquid';\n\nimport { CandlePeriod, calculateCandleCount } from '../constants/chartConfig';\nimport { HYPERLIQUID_TRANSPORT_CONFIG } from '../constants/hyperLiquidConfig';\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig';\nimport { PERPS_ERROR_CODES } from '../perpsErrorCodes';\nimport { WebSocketConnectionState } from '../types';\nimport type {\n SubscribeCandlesParams,\n PerpsPlatformDependencies,\n} from '../types';\nimport type { HyperLiquidNetwork } from '../types/config';\nimport type { CandleData } from '../types/perps-types';\nimport { ensureError } from '../utils/errorUtils';\nimport { getPerpsConnectionAttemptContext } from '../utils/perpsConnectionAttemptContext';\n\n/**\n * Maximum number of reconnection attempts before giving up.\n */\nconst maxReconnectionAttempts = 10;\n\n/**\n * Valid time intervals for historical candle data\n * Uses CandlePeriod enum for type safety\n */\nexport type ValidCandleInterval = CandlePeriod;\n\n/**\n * Wallet interface for HyperLiquid SDK operations.\n * Extracted for reuse across initialize(), toggleTestnet(), and ensureSubscriptionClient() methods.\n */\nexport type HyperLiquidWalletParams = {\n signTypedData: (params: {\n domain: {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: Hex;\n };\n types: {\n [key: string]: { name: string; type: string }[];\n };\n primaryType: string;\n message: Record<string, unknown>;\n }) => Promise<Hex>;\n getChainId?: () => Promise<number>;\n};\n\n// WebSocketConnectionState is now imported from controllers/types\n// Re-export for backward compatibility with existing consumers\nexport { WebSocketConnectionState } from '../types';\n\n/**\n * Service for managing HyperLiquid SDK clients\n * Handles initialization, transport creation, and client lifecycle\n */\nexport class HyperLiquidClientService {\n #exchangeClient?: ExchangeClient;\n\n #infoClient?: InfoClient; // WebSocket transport (default)\n\n #infoClientHttp?: InfoClient; // HTTP transport (fallback)\n\n #subscriptionClient?: SubscriptionClient<{\n transport: WebSocketTransport;\n }>;\n\n #wsTransport?: WebSocketTransport;\n\n #httpTransport?: HttpTransport;\n\n #isTestnet: boolean;\n\n #connectionState: WebSocketConnectionState =\n WebSocketConnectionState.Disconnected;\n\n #disconnectionPromise: Promise<void> | null = null;\n\n // Callback for SDK terminate event (fired when all reconnection attempts exhausted)\n #onTerminateCallback: ((error: Error) => void) | null = null;\n\n #onReconnectCallback?: () => Promise<void>;\n\n // Reconnection attempt counter\n #reconnectionAttempt = 0;\n\n // Connection state change listeners for event-based notifications\n readonly #connectionStateListeners: Set<\n (state: WebSocketConnectionState, reconnectionAttempt: number) => void\n > = new Set();\n\n // Timeout reference for reconnection retry, tracked to enable cancellation on disconnect\n #reconnectionRetryTimeout: ReturnType<typeof setTimeout> | null = null;\n\n // Platform dependencies for logging\n readonly #deps: PerpsPlatformDependencies;\n\n constructor(\n deps: PerpsPlatformDependencies,\n options: { isTestnet?: boolean } = {},\n ) {\n this.#deps = deps;\n this.#isTestnet = options.isTestnet ?? false;\n }\n\n /**\n * Initialize all HyperLiquid SDK clients\n *\n * IMPORTANT: This method awaits transport.ready() to ensure the WebSocket is\n * in OPEN state before marking initialization complete. This prevents race\n * conditions where subscriptions are attempted before the WebSocket handshake\n * completes (which would cause \"subscribe error: undefined\" errors).\n *\n * @param wallet - The wallet parameters for signing typed data.\n */\n public async initialize(wallet: HyperLiquidWalletParams): Promise<void> {\n const network = this.#isTestnet ? 'testnet' : 'mainnet';\n const attemptContext = getPerpsConnectionAttemptContext();\n\n try {\n this.#updateConnectionState(WebSocketConnectionState.Connecting);\n this.#createTransports();\n\n // Ensure transports are created\n if (!this.#httpTransport || !this.#wsTransport) {\n throw new Error('Failed to create transports');\n }\n\n // Wallet adapter implements AbstractViemJsonRpcAccount interface with signTypedData method\n // ExchangeClient uses HTTP transport for write operations (orders, approvals, etc.)\n this.#exchangeClient = new ExchangeClient({\n wallet: wallet as any, // eslint-disable-line @typescript-eslint/no-explicit-any -- Type widening for SDK compatibility\n transport: this.#httpTransport,\n });\n\n // InfoClient with WebSocket transport (default) - multiplexed requests over single connection\n this.#infoClient = new InfoClient({ transport: this.#wsTransport });\n\n // InfoClient with HTTP transport (fallback) - for specific calls if WebSocket has issues\n this.#infoClientHttp = new InfoClient({ transport: this.#httpTransport });\n\n // SubscriptionClient uses WebSocket transport for real-time pub/sub (price feeds, position updates)\n this.#subscriptionClient = new SubscriptionClient({\n transport: this.#wsTransport,\n });\n\n // Wait for WebSocket to actually be ready before setting CONNECTED\n // This ensures we have a real connection, not just client objects\n await this.#wsTransport.ready();\n\n this.#updateConnectionState(WebSocketConnectionState.Connected);\n\n this.#deps.debugLogger.log('HyperLiquid SDK clients initialized', {\n testnet: this.#isTestnet,\n timestamp: new Date().toISOString(),\n connectionState: this.#connectionState,\n note: 'Using WebSocket for InfoClient (default), HTTP fallback available',\n });\n } catch (error) {\n // Cleanup on failure to prevent leaks and ensure isInitialized() returns false\n // Clear clients first, then transports\n this.#subscriptionClient = undefined;\n this.#infoClient = undefined;\n this.#infoClientHttp = undefined;\n this.#exchangeClient = undefined;\n\n // Close WebSocket transport to release resources and event listeners\n if (this.#wsTransport) {\n try {\n await this.#wsTransport.close();\n } catch {\n // Ignore cleanup errors\n }\n this.#wsTransport = undefined;\n }\n this.#httpTransport = undefined;\n\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.initialize',\n );\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n\n if (attemptContext?.suppressError) {\n this.#deps.debugLogger.log(\n 'HyperLiquid initialize failed during suppressed startup attempt',\n {\n error: errorInstance.message,\n network,\n source: attemptContext.source,\n },\n );\n } else {\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network,\n },\n context: {\n name: 'sdk_initialization',\n data: {\n operation: 'initialize',\n isTestnet: this.#isTestnet,\n source: attemptContext?.source ?? 'unspecified',\n },\n },\n });\n }\n\n throw error;\n }\n }\n\n /**\n * Create HTTP and WebSocket transports\n * - HTTP for InfoClient and ExchangeClient (request/response operations)\n * - WebSocket for SubscriptionClient (real-time pub/sub)\n *\n * Both transports use SDK's built-in endpoint resolution via isTestnet flag\n *\n * @returns The created WebSocket transport instance.\n */\n #createTransports(): WebSocketTransport {\n // Prevent duplicate transport creation and listener accumulation\n // This guards against re-entry if initialize() is called multiple times\n // (e.g., after a failed initialization attempt that didn't properly clean up)\n if (this.#wsTransport && this.#httpTransport) {\n this.#deps.debugLogger.log(\n 'HyperLiquid: Transports already exist, skipping creation',\n );\n return this.#wsTransport;\n }\n\n this.#deps.debugLogger.log('HyperLiquid: Creating transports', {\n isTestnet: this.#isTestnet,\n timestamp: new Date().toISOString(),\n note: 'SDK will auto-select endpoints based on isTestnet flag',\n });\n\n // HTTP transport for request/response operations (InfoClient, ExchangeClient)\n // SDK automatically selects: mainnet (https://api.hyperliquid.xyz) or testnet (https://api.hyperliquid-testnet.xyz)\n this.#httpTransport = new HttpTransport({\n isTestnet: this.#isTestnet,\n timeout: HYPERLIQUID_TRANSPORT_CONFIG.timeout,\n });\n\n // WebSocket transport for real-time subscriptions (SubscriptionClient)\n // SDK automatically selects: mainnet (wss://api.hyperliquid.xyz/ws) or testnet (wss://api.hyperliquid-testnet.xyz/ws)\n this.#wsTransport = new WebSocketTransport({\n isTestnet: this.#isTestnet,\n ...HYPERLIQUID_TRANSPORT_CONFIG,\n reconnect: {\n ...HYPERLIQUID_TRANSPORT_CONFIG.reconnect,\n WebSocket: globalThis.WebSocket, // Use React Native's global WebSocket\n },\n });\n\n // Listen for WebSocket termination (fired when SDK exhausts all reconnection attempts)\n this.#wsTransport.socket.addEventListener('terminate', (event: Event) => {\n const customEvent = event as CustomEvent;\n this.#deps.debugLogger.log('HyperLiquid: WebSocket terminated', {\n reason: customEvent.detail?.code,\n timestamp: new Date().toISOString(),\n });\n\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n\n if (this.#onTerminateCallback) {\n const error =\n customEvent.detail instanceof Error\n ? customEvent.detail\n : new Error(\n `WebSocket terminated: ${customEvent.detail?.code ?? 'unknown'}`,\n );\n this.#onTerminateCallback(error);\n }\n });\n\n return this.#wsTransport;\n }\n\n /**\n * Toggle testnet mode and reinitialize clients\n *\n * @param wallet - The wallet parameters for signing typed data.\n * @returns The new network name after toggling.\n */\n public async toggleTestnet(\n wallet: HyperLiquidWalletParams,\n ): Promise<HyperLiquidNetwork> {\n this.#isTestnet = !this.#isTestnet;\n await this.initialize(wallet);\n return this.#isTestnet ? 'testnet' : 'mainnet';\n }\n\n /**\n * Check if clients are properly initialized\n *\n * @returns True if all SDK clients are initialized.\n */\n public isInitialized(): boolean {\n return Boolean(\n this.#exchangeClient &&\n this.#infoClient &&\n this.#infoClientHttp &&\n this.#subscriptionClient,\n );\n }\n\n /**\n * Ensure clients are initialized, throw if not\n */\n public ensureInitialized(): void {\n if (!this.isInitialized()) {\n throw new Error(PERPS_ERROR_CODES.CLIENT_NOT_INITIALIZED);\n }\n }\n\n /**\n * Recreate subscription client if needed (for reconnection scenarios)\n *\n * @param wallet - The wallet parameters for signing typed data.\n */\n public async ensureSubscriptionClient(\n wallet: HyperLiquidWalletParams,\n ): Promise<void> {\n if (!this.#subscriptionClient) {\n this.#deps.debugLogger.log(\n 'HyperLiquid: Recreating subscription client after disconnect',\n );\n await this.initialize(wallet);\n }\n }\n\n /**\n * Get the exchange client\n *\n * @returns The initialized ExchangeClient instance.\n */\n public getExchangeClient(): ExchangeClient {\n this.ensureInitialized();\n if (!this.#exchangeClient) {\n throw new Error(PERPS_ERROR_CODES.EXCHANGE_CLIENT_NOT_AVAILABLE);\n }\n return this.#exchangeClient;\n }\n\n /**\n * Get the info client\n *\n * @param options - The options for selecting the transport.\n * @param options.useHttp - Force HTTP transport instead of WebSocket (default: false).\n * @returns InfoClient instance with the selected transport.\n */\n public getInfoClient(options?: { useHttp?: boolean }): InfoClient {\n this.ensureInitialized();\n\n if (options?.useHttp) {\n if (!this.#infoClientHttp) {\n throw new Error(PERPS_ERROR_CODES.INFO_CLIENT_NOT_AVAILABLE);\n }\n return this.#infoClientHttp;\n }\n\n if (!this.#infoClient) {\n throw new Error(PERPS_ERROR_CODES.INFO_CLIENT_NOT_AVAILABLE);\n }\n return this.#infoClient;\n }\n\n /**\n * Get the subscription client\n *\n * @returns The SubscriptionClient instance, or undefined if not initialized.\n */\n public getSubscriptionClient():\n | SubscriptionClient<{ transport: WebSocketTransport }>\n | undefined {\n if (!this.#subscriptionClient) {\n this.#deps.debugLogger.log('SubscriptionClient not initialized');\n return undefined;\n }\n return this.#subscriptionClient;\n }\n\n /**\n * Ensures the WebSocket transport is in OPEN state and ready for subscriptions.\n * This MUST be called before any subscription operations to prevent race conditions.\n *\n * The SDK's `transport.ready()` method:\n * - Returns immediately if WebSocket is already in OPEN state\n * - Waits for the \"open\" event if WebSocket is in CONNECTING state\n * - Supports AbortSignal for timeout/cancellation\n *\n * @param options - The options for transport readiness check.\n * @param options.timeoutMs - Maximum time to wait for transport ready (default 5000ms).\n * @throws Error if transport not ready within timeout or subscription client unavailable.\n */\n public async ensureTransportReady(\n options: { timeoutMs?: number } = {},\n ): Promise<void> {\n const { timeoutMs = 5000 } = options;\n const subscriptionClient = this.getSubscriptionClient();\n if (!subscriptionClient) {\n throw new Error('Subscription client not initialized');\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(\n () =>\n controller.abort(\n new Error(`WebSocket transport ready timeout after ${timeoutMs}ms`),\n ),\n timeoutMs,\n );\n\n try {\n await subscriptionClient.config_.transport.ready(controller.signal);\n } catch (error) {\n if (controller.signal.aborted) {\n throw new Error(\n `WebSocket transport ready timeout after ${timeoutMs}ms`,\n );\n }\n throw ensureError(error, 'HyperLiquidClientService.ensureTransportReady');\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Get current network state\n *\n * @returns The current HyperLiquid network (mainnet or testnet).\n */\n public getNetwork(): HyperLiquidNetwork {\n return this.#isTestnet ? 'testnet' : 'mainnet';\n }\n\n /**\n * Check if running on testnet\n *\n * @returns True if the service is in testnet mode.\n */\n public isTestnetMode(): boolean {\n return this.#isTestnet;\n }\n\n /**\n * Update testnet mode\n *\n * @param isTestnet - Whether to enable testnet mode.\n */\n public setTestnetMode(isTestnet: boolean): void {\n this.#isTestnet = isTestnet;\n }\n\n /**\n * Fetch historical candle data using the HyperLiquid SDK\n *\n * @param options - The candle fetch configuration.\n * @param options.symbol - The asset symbol (e.g., \"BTC\", \"ETH\").\n * @param options.interval - The candle interval (e.g., \"1m\", \"5m\", \"15m\", \"1h\", \"1d\").\n * @param options.limit - Number of candles to fetch (default: 100).\n * @param options.endTime - End timestamp in milliseconds (default: now).\n * @param options.signal - Optional AbortSignal to cancel the fetch.\n * @returns The historical candle data, or null if no data is available.\n */\n public async fetchHistoricalCandles(options: {\n symbol: string;\n interval: ValidCandleInterval;\n limit?: number;\n endTime?: number;\n signal?: AbortSignal;\n }): Promise<CandleData | null> {\n const { symbol, interval, limit = 100, endTime, signal } = options;\n this.ensureInitialized();\n\n try {\n // Calculate start and end times based on interval and limit\n const now = endTime ?? Date.now();\n const intervalMs = this.#getIntervalMilliseconds(interval);\n const startTime = now - limit * intervalMs;\n\n // Use the SDK's InfoClient to fetch candle data\n // HyperLiquid SDK uses 'coin' terminology\n const infoClient = this.getInfoClient();\n const data = await infoClient.candleSnapshot(\n {\n coin: symbol, // Map to HyperLiquid SDK's 'coin' parameter\n interval,\n startTime,\n endTime: now,\n },\n signal,\n );\n\n // Transform API response to match expected format\n if (Array.isArray(data) && data.length > 0) {\n const candles = data.map((candle) => ({\n time: candle.t, // open time\n open: candle.o.toString(),\n high: candle.h.toString(),\n low: candle.l.toString(),\n close: candle.c.toString(),\n volume: candle.v.toString(),\n }));\n\n return {\n symbol,\n interval,\n candles,\n };\n }\n\n return {\n symbol,\n interval,\n candles: [],\n };\n } catch (error) {\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.fetchHistoricalCandles',\n );\n\n // Log to Sentry: prevents initial chart data load\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'historical_candles_api',\n data: {\n operation: 'fetchHistoricalCandles',\n symbol,\n interval,\n limit,\n hasEndTime: endTime !== undefined,\n },\n },\n });\n\n throw error;\n }\n }\n\n /**\n * Subscribe to candle updates via WebSocket\n *\n * @param root0 - The subscription parameters.\n * @param root0.symbol - The asset symbol (e.g., \"BTC\", \"ETH\").\n * @param root0.interval - The candle interval (e.g., \"1m\", \"5m\", \"15m\").\n * @param root0.duration - Optional time duration for calculating initial fetch size.\n * @param root0.callback - Function called with updated candle data.\n * @param root0.onError - Optional function called if subscription initialization fails.\n * @returns Cleanup function to unsubscribe.\n */\n public subscribeToCandles({\n symbol,\n interval,\n duration,\n callback,\n onError,\n }: SubscribeCandlesParams): () => void {\n this.ensureInitialized();\n\n const subscriptionClient = this.getSubscriptionClient();\n if (!subscriptionClient) {\n throw new Error(PERPS_ERROR_CODES.SUBSCRIPTION_CLIENT_NOT_AVAILABLE);\n }\n\n let currentCandleData: CandleData | null = null;\n let wsUnsubscribe: (() => void) | null = null;\n let isUnsubscribed = false;\n // Store the subscription promise to enable cleanup even when pending\n // This fixes a race condition where component unmounts before subscription resolves\n let subscriptionPromise: Promise<{ unsubscribe: () => void }> | null = null;\n\n // AbortController to cancel in-flight REST calls (candleSnapshot) on cleanup.\n // Prevents rate limit exhaustion when rapidly switching markets (#28141).\n const abortController = new AbortController();\n\n // Calculate initial fetch size dynamically based on duration and interval\n // Match main branch behavior: up to 500 candles initially\n const initialLimit = duration\n ? Math.min(calculateCandleCount(duration, interval), 500)\n : 100; // Default to 100 if no duration provided\n\n // 1. Fetch initial historical data, then subscribe to WebSocket updates\n // Using an async IIFE to avoid nested promises and callback-in-promise issues\n const initAndSubscribe = async (): Promise<void> => {\n try {\n const initialData = await this.fetchHistoricalCandles({\n symbol,\n interval,\n limit: initialLimit,\n signal: abortController.signal,\n });\n\n // Don't proceed if already unsubscribed\n if (isUnsubscribed) {\n return;\n }\n\n currentCandleData = initialData;\n if (currentCandleData) {\n callback(currentCandleData);\n }\n\n // 2. Subscribe to WebSocket for new candles\n // HyperLiquid SDK uses 'coin' terminology\n // Store the promise so cleanup can wait for it if needed\n subscriptionPromise = subscriptionClient.candle(\n { coin: symbol, interval }, // Map to HyperLiquid SDK's 'coin' parameter\n (candleEvent) => {\n // Don't process events if already unsubscribed\n if (isUnsubscribed) {\n return;\n }\n\n // Transform SDK CandleEvent to our Candle format\n const newCandle = {\n time: candleEvent.t,\n open: candleEvent.o.toString(),\n high: candleEvent.h.toString(),\n low: candleEvent.l.toString(),\n close: candleEvent.c.toString(),\n volume: candleEvent.v.toString(),\n };\n\n if (currentCandleData) {\n // Check if this is an update to the last candle or a new candle\n const { candles } = currentCandleData;\n const lastCandle = candles[candles.length - 1];\n\n if (lastCandle?.time === newCandle.time) {\n // Update existing candle (live candle update)\n // Create new array with updated last element to trigger React re-render\n currentCandleData = {\n ...currentCandleData,\n candles: [...candles.slice(0, -1), newCandle],\n };\n } else {\n // New candle (completed candle)\n // Create new array with added element to trigger React re-render\n currentCandleData = {\n ...currentCandleData,\n candles: [...candles, newCandle],\n };\n }\n } else {\n currentCandleData = {\n symbol,\n interval,\n candles: [newCandle],\n };\n }\n\n callback(currentCandleData);\n },\n );\n\n // Store cleanup function when subscription resolves\n try {\n const sub = await subscriptionPromise;\n wsUnsubscribe = (): void => sub.unsubscribe();\n // If already unsubscribed while waiting, clean up immediately\n if (isUnsubscribed) {\n wsUnsubscribe();\n wsUnsubscribe = null;\n }\n } catch (error) {\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.subscribeToCandles',\n );\n\n // Log to Sentry: WebSocket subscription failure prevents live updates\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'websocket_subscription',\n data: {\n operation: 'subscribeToCandles',\n symbol,\n interval,\n phase: 'ws_subscription',\n },\n },\n });\n\n // Notify caller of error\n onError?.(errorInstance);\n }\n } catch (error) {\n // Skip logging and notification for intentional abort (user navigated away)\n if (abortController.signal.aborted) {\n return;\n }\n\n const errorInstance = ensureError(\n error,\n 'HyperLiquidClientService.subscribeToCandles',\n );\n\n // Log to Sentry: initial fetch failure blocks chart completely\n this.#deps.logger.error(errorInstance, {\n tags: {\n feature: PERPS_CONSTANTS.FeatureName,\n service: 'HyperLiquidClientService',\n network: this.#isTestnet ? 'testnet' : 'mainnet',\n },\n context: {\n name: 'initial_candles_fetch',\n data: {\n operation: 'subscribeToCandles',\n symbol,\n interval,\n phase: 'initial_fetch',\n initialLimit,\n },\n },\n });\n\n // Notify caller of error\n onError?.(errorInstance);\n }\n };\n\n // Fire-and-forget the async initialization\n initAndSubscribe().catch(() => {\n // Error already handled inside initAndSubscribe\n });\n\n // Return cleanup function\n return () => {\n isUnsubscribed = true;\n // Cancel any in-flight REST calls (candleSnapshot) to conserve rate limit budget (#28141)\n abortController.abort();\n if (wsUnsubscribe) {\n // Subscription already resolved - unsubscribe directly\n wsUnsubscribe();\n wsUnsubscribe = null;\n } else if (subscriptionPromise) {\n // Subscription promise still pending - wait for it and clean up\n // This prevents WebSocket subscription leaks when component unmounts\n // before the subscription promise resolves\n subscriptionPromise\n .then((sub) => sub.unsubscribe())\n .catch(() => {\n // Ignore errors during cleanup - subscription may have failed\n });\n subscriptionPromise = null;\n }\n };\n }\n\n /**\n * Convert interval string to milliseconds\n *\n * @param interval - The candle period interval to convert.\n * @returns The interval duration in milliseconds.\n */\n #getIntervalMilliseconds(interval: CandlePeriod): number {\n const intervalMap: Record<CandlePeriod, number> = {\n [CandlePeriod.OneMinute]: 1 * 60 * 1000,\n [CandlePeriod.ThreeMinutes]: 3 * 60 * 1000,\n [CandlePeriod.FiveMinutes]: 5 * 60 * 1000,\n [CandlePeriod.FifteenMinutes]: 15 * 60 * 1000,\n [CandlePeriod.ThirtyMinutes]: 30 * 60 * 1000,\n [CandlePeriod.OneHour]: 60 * 60 * 1000,\n [CandlePeriod.TwoHours]: 2 * 60 * 60 * 1000,\n [CandlePeriod.FourHours]: 4 * 60 * 60 * 1000,\n [CandlePeriod.EightHours]: 8 * 60 * 60 * 1000,\n [CandlePeriod.TwelveHours]: 12 * 60 * 60 * 1000,\n [CandlePeriod.OneDay]: 24 * 60 * 60 * 1000,\n [CandlePeriod.ThreeDays]: 3 * 24 * 60 * 60 * 1000,\n [CandlePeriod.OneWeek]: 7 * 24 * 60 * 60 * 1000,\n [CandlePeriod.OneMonth]: 30 * 24 * 60 * 60 * 1000, // Approximate\n };\n\n return intervalMap[interval];\n }\n\n /**\n * Disconnect and cleanup all clients\n *\n * @returns A promise that resolves when disconnection is complete.\n */\n public async disconnect(): Promise<void> {\n // Await existing promise if already disconnecting\n if (this.#disconnectionPromise) {\n await this.#disconnectionPromise;\n return;\n }\n\n // If already disconnected, return immediately\n if (this.#connectionState === WebSocketConnectionState.Disconnected) {\n return;\n }\n\n // Create and store the disconnection promise\n this.#disconnectionPromise = this.#performDisconnection();\n\n try {\n await this.#disconnectionPromise;\n } finally {\n this.#disconnectionPromise = null;\n }\n }\n\n async #performDisconnection(): Promise<void> {\n try {\n this.#updateConnectionState(WebSocketConnectionState.Disconnecting);\n\n this.#deps.debugLogger.log('HyperLiquid: Disconnecting SDK clients', {\n isTestnet: this.#isTestnet,\n timestamp: new Date().toISOString(),\n connectionState: this.#connectionState,\n });\n\n // Clear callbacks\n this.#onReconnectCallback = undefined;\n this.#onTerminateCallback = null;\n\n // Cancel any pending reconnection retry timeout\n if (this.#reconnectionRetryTimeout) {\n clearTimeout(this.#reconnectionRetryTimeout);\n this.#reconnectionRetryTimeout = null;\n }\n\n // Clear connection state listeners to prevent stale callbacks\n this.#connectionStateListeners.clear();\n\n // Reset reconnection flag to allow future manual retries\n // This prevents a race condition where disconnecting during an active\n // reconnection attempt could leave the flag stuck, blocking subsequent retries\n this.#isReconnecting = false;\n\n // Close WebSocket transport only (HTTP is stateless)\n if (this.#wsTransport) {\n try {\n await this.#wsTransport.close();\n this.#deps.debugLogger.log(\n 'HyperLiquid: Closed WebSocket transport',\n {\n timestamp: new Date().toISOString(),\n },\n );\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'HyperLiquidClientService.performDisconnection'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'HyperLiquidClientService.performDisconnection',\n data: { action: 'close_transport' },\n },\n },\n );\n }\n }\n\n // Clear client references\n this.#subscriptionClient = undefined;\n this.#exchangeClient = undefined;\n this.#infoClient = undefined;\n this.#infoClientHttp = undefined;\n this.#wsTransport = undefined;\n this.#httpTransport = undefined;\n\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n\n this.#deps.debugLogger.log(\n 'HyperLiquid: SDK clients fully disconnected',\n {\n timestamp: new Date().toISOString(),\n connectionState: this.#connectionState,\n },\n );\n } catch (error) {\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n this.#deps.logger.error(\n ensureError(error, 'HyperLiquidClientService.performDisconnection'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'HyperLiquidClientService.performDisconnection',\n data: { action: 'outer_catch' },\n },\n },\n );\n throw error;\n }\n }\n\n /**\n * Get current WebSocket connection state\n *\n * @returns The current WebSocket connection state.\n */\n public getConnectionState(): WebSocketConnectionState {\n return this.#connectionState;\n }\n\n /**\n * Check if WebSocket is fully disconnected\n *\n * @returns True if the WebSocket is in disconnected state.\n */\n public isDisconnected(): boolean {\n return this.#connectionState === WebSocketConnectionState.Disconnected;\n }\n\n /**\n * Set callback to be invoked when reconnection is needed\n * This allows the service to notify external components (like PerpsConnectionManager)\n * when a connection drop is detected\n *\n * @param callback - The async callback to invoke when reconnection is needed.\n */\n public setOnReconnectCallback(callback: () => Promise<void>): void {\n this.#onReconnectCallback = callback;\n }\n\n /**\n * Set callback for WebSocket termination events\n * Called when the SDK exhausts all reconnection attempts\n *\n * @param callback - The callback to invoke on termination, or null to clear.\n */\n public setOnTerminateCallback(\n callback: ((error: Error) => void) | null,\n ): void {\n this.#onTerminateCallback = callback;\n }\n\n /**\n * Subscribe to connection state changes.\n * The listener will be called immediately with the current state and whenever the state changes.\n *\n * @param listener - Callback function that receives the new connection state and reconnection attempt\n * @returns Unsubscribe function to remove the listener\n */\n public subscribeToConnectionState(\n listener: (\n state: WebSocketConnectionState,\n reconnectionAttempt: number,\n ) => void,\n ): () => void {\n this.#connectionStateListeners.add(listener);\n\n // Immediately notify with current state\n // Wrap in try-catch to match notifyConnectionStateListeners behavior\n // This ensures the unsubscribe function is always returned even if listener throws\n try {\n listener(this.#connectionState, this.#reconnectionAttempt);\n } catch {\n // Ignore errors in listeners to prevent breaking subscription mechanism\n // If listener throws, it will be removed when unsubscribe is called\n }\n\n // Return unsubscribe function\n return () => {\n this.#connectionStateListeners.delete(listener);\n };\n }\n\n /**\n * Update connection state and notify all listeners\n * Always notifies if state changes OR if we're in CONNECTING state (to update attempt count)\n *\n * @param newState - The new WebSocket connection state.\n */\n #updateConnectionState(newState: WebSocketConnectionState): void {\n const previousState = this.#connectionState;\n const stateChanged = previousState !== newState;\n const isReconnectionAttempt =\n newState === WebSocketConnectionState.Connecting &&\n this.#reconnectionAttempt > 0;\n\n this.#connectionState = newState;\n\n // Reset reconnection attempt counter when successfully connected\n if (newState === WebSocketConnectionState.Connected) {\n this.#reconnectionAttempt = 0;\n }\n\n // Notify if state changed OR if this is a reconnection attempt (to update attempt count)\n if (stateChanged || isReconnectionAttempt) {\n this.#notifyConnectionStateListeners();\n }\n }\n\n /**\n * Notify all connection state listeners of the current state\n */\n #notifyConnectionStateListeners(): void {\n this.#connectionStateListeners.forEach((listener) => {\n try {\n listener(this.#connectionState, this.#reconnectionAttempt);\n } catch {\n // Ignore errors in listeners to prevent breaking other listeners\n }\n });\n }\n\n // Flag to prevent concurrent reconnection attempts\n #isReconnecting = false;\n\n /**\n * Manually trigger a reconnection attempt.\n * This is exposed for UI retry buttons when user wants to force reconnection.\n * Resets the reconnection attempt counter to allow retrying after max attempts.\n */\n public async reconnect(): Promise<void> {\n this.#deps.debugLogger.log(\n '[HyperLiquidClientService] reconnect() called',\n {\n previousAttempt: this.#reconnectionAttempt,\n currentState: this.#connectionState,\n },\n );\n // Reset attempt counter when user manually triggers retry\n this.#reconnectionAttempt = 0;\n await this.#handleConnectionDrop();\n this.#deps.debugLogger.log(\n '[HyperLiquidClientService] reconnect() completed',\n {\n newState: this.#connectionState,\n },\n );\n }\n\n /**\n * Handle detected connection drop\n * Recreates WebSocket transport and notifies callback to restore subscriptions\n * Will give up after maxReconnectionAttempts and mark status as disconnected\n */\n async #handleConnectionDrop(): Promise<void> {\n // Prevent multiple simultaneous reconnection attempts\n if (this.#isReconnecting) {\n return;\n }\n\n this.#isReconnecting = true;\n\n // Increment reconnection attempt counter\n this.#reconnectionAttempt += 1;\n\n // Check if we've exceeded max retry attempts\n if (this.#reconnectionAttempt > maxReconnectionAttempts) {\n this.#isReconnecting = false;\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n return;\n }\n\n try {\n this.#updateConnectionState(WebSocketConnectionState.Connecting);\n\n // Close existing WebSocket transport and clear references\n // so createTransports() will create fresh ones\n if (this.#wsTransport) {\n try {\n await this.#wsTransport.close();\n } catch {\n // Ignore errors during close - transport may already be dead\n }\n }\n this.#wsTransport = undefined;\n this.#httpTransport = undefined;\n\n // Recreate WebSocket transport - returns the new transport for type safety\n const newWsTransport = this.#createTransports();\n\n // Recreate clients that use WebSocket transport\n this.#infoClient = new InfoClient({ transport: newWsTransport });\n this.#subscriptionClient = new SubscriptionClient({\n transport: newWsTransport,\n });\n\n await newWsTransport.ready();\n\n this.#deps.debugLogger.log(\n 'HyperLiquid: Transport ready, restoring subscriptions',\n { timestamp: new Date().toISOString() },\n );\n\n // NOW safe to restore subscriptions\n if (this.#onReconnectCallback) {\n await this.#onReconnectCallback();\n }\n\n // Cancel any pending retry timeout from previous failed attempts\n if (this.#reconnectionRetryTimeout) {\n clearTimeout(this.#reconnectionRetryTimeout);\n this.#reconnectionRetryTimeout = null;\n }\n\n this.#updateConnectionState(WebSocketConnectionState.Connected);\n this.#isReconnecting = false;\n } catch {\n // Reset flag before scheduling retry so the next attempt can proceed\n this.#isReconnecting = false;\n\n // Check if we've exceeded max retry attempts\n if (this.#reconnectionAttempt >= maxReconnectionAttempts) {\n this.#updateConnectionState(WebSocketConnectionState.Disconnected);\n return;\n }\n\n // Reconnection failed - schedule a retry after a delay\n // Store timeout reference so it can be cancelled on intentional disconnect\n this.#reconnectionRetryTimeout = setTimeout(() => {\n this.#reconnectionRetryTimeout = null; // Clear reference after execution\n // Only retry if we haven't been intentionally disconnected\n // and no manual reconnect() is already in progress\n // Note: State may be CONNECTING or DISCONNECTED (if terminate event fired during reconnect)\n if (\n (this.#connectionState === WebSocketConnectionState.Connecting ||\n this.#connectionState === WebSocketConnectionState.Disconnected) &&\n !this.#disconnectionPromise &&\n !this.#isReconnecting\n ) {\n this.#handleConnectionDrop().catch(() => {\n // Error already handled inside #handleConnectionDrop\n });\n }\n }, PERPS_CONSTANTS.ReconnectionRetryDelayMs);\n }\n }\n}\n"]}
@@ -10,9 +10,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _HyperLiquidSubscriptionService_instances, _HyperLiquidSubscriptionService_clientService, _HyperLiquidSubscriptionService_walletService, _HyperLiquidSubscriptionService_hip3Enabled, _HyperLiquidSubscriptionService_enabledDexs, _HyperLiquidSubscriptionService_allowlistMarkets, _HyperLiquidSubscriptionService_blocklistMarkets, _HyperLiquidSubscriptionService_discoveredDexNames, _HyperLiquidSubscriptionService_dexDiscoveryPromise, _HyperLiquidSubscriptionService_dexDiscoveryResolver, _HyperLiquidSubscriptionService_expectedDexs, _HyperLiquidSubscriptionService_initializedDexs, _HyperLiquidSubscriptionService_priceSubscribers, _HyperLiquidSubscriptionService_positionSubscribers, _HyperLiquidSubscriptionService_orderFillSubscribers, _HyperLiquidSubscriptionService_orderSubscribers, _HyperLiquidSubscriptionService_accountSubscribers, _HyperLiquidSubscriptionService_marketDataSubscribers, _HyperLiquidSubscriptionService_orderBookSubscribers, _HyperLiquidSubscriptionService_globalAllMidsSubscription, _HyperLiquidSubscriptionService_globalAllMidsPromise, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, _HyperLiquidSubscriptionService_globalBboSubscriptions, _HyperLiquidSubscriptionService_orderFillSubscriptions, _HyperLiquidSubscriptionService_symbolSubscriberCounts, _HyperLiquidSubscriptionService_dexSubscriberCounts, _HyperLiquidSubscriptionService_webData3Subscriptions, _HyperLiquidSubscriptionService_webData3SubscriptionPromise, _HyperLiquidSubscriptionService_positionSubscriberCount, _HyperLiquidSubscriptionService_orderSubscriberCount, _HyperLiquidSubscriptionService_accountSubscriberCount, _HyperLiquidSubscriptionService_oiCapSubscriberCount, _HyperLiquidSubscriptionService_dexPositionsCache, _HyperLiquidSubscriptionService_dexOrdersCache, _HyperLiquidSubscriptionService_dexAccountCache, _HyperLiquidSubscriptionService_cachedPositions, _HyperLiquidSubscriptionService_cachedOrders, _HyperLiquidSubscriptionService_cachedAccount, _HyperLiquidSubscriptionService_ordersCacheInitialized, _HyperLiquidSubscriptionService_positionsCacheInitialized, _HyperLiquidSubscriptionService_oiCapSubscribers, _HyperLiquidSubscriptionService_cachedOICaps, _HyperLiquidSubscriptionService_cachedOICapsHash, _HyperLiquidSubscriptionService_oiCapsCacheInitialized, _HyperLiquidSubscriptionService_cachedPriceData, _HyperLiquidSubscriptionService_allMidsSnapshots, _HyperLiquidSubscriptionService_cachedFills, _HyperLiquidSubscriptionService_fillsCacheInitialized, _HyperLiquidSubscriptionService_assetCtxsSubscriptions, _HyperLiquidSubscriptionService_dexAssetCtxsCache, _HyperLiquidSubscriptionService_assetCtxsSubscriptionPromises, _HyperLiquidSubscriptionService_dexAllMidsSubscriptions, _HyperLiquidSubscriptionService_dexAllMidsSubscriptionPromises, _HyperLiquidSubscriptionService_clearinghouseStateSubscriptions, _HyperLiquidSubscriptionService_openOrdersSubscriptions, _HyperLiquidSubscriptionService_pendingClearinghouseSubscriptions, _HyperLiquidSubscriptionService_pendingOpenOrdersSubscriptions, _HyperLiquidSubscriptionService_dexMetaCache, _HyperLiquidSubscriptionService_orderBookCache, _HyperLiquidSubscriptionService_marketDataCache, _HyperLiquidSubscriptionService_isClearing, _HyperLiquidSubscriptionService_restoreRetryTimeouts, _HyperLiquidSubscriptionService_deps, _HyperLiquidSubscriptionService_logErrorUnlessClearing, _HyperLiquidSubscriptionService_isTransientAssetCtxsError, _HyperLiquidSubscriptionService_scheduleRestoreRetry, _HyperLiquidSubscriptionService_getErrorContext, _HyperLiquidSubscriptionService_isDexEnabled, _HyperLiquidSubscriptionService_waitForDexDiscovery, _HyperLiquidSubscriptionService_hashPositions, _HyperLiquidSubscriptionService_hashOrders, _HyperLiquidSubscriptionService_hashAccountState, _HyperLiquidSubscriptionService_cachedPositionsHash, _HyperLiquidSubscriptionService_cachedOrdersHash, _HyperLiquidSubscriptionService_cachedAccountHash, _HyperLiquidSubscriptionService_extractTPSLFromOrders, _HyperLiquidSubscriptionService_mergeTPSLIntoPositions, _HyperLiquidSubscriptionService_aggregateAccountStates, _HyperLiquidSubscriptionService_ensureSharedWebData3Subscription, _HyperLiquidSubscriptionService_createUserDataSubscription, _HyperLiquidSubscriptionService_ensureClearinghouseStateSubscription, _HyperLiquidSubscriptionService_createClearinghouseSubscription, _HyperLiquidSubscriptionService_ensureOpenOrdersSubscription, _HyperLiquidSubscriptionService_createOpenOrdersSubscription, _HyperLiquidSubscriptionService_aggregateAndNotifySubscribers, _HyperLiquidSubscriptionService_cleanupSharedWebData3ISubscription, _HyperLiquidSubscriptionService_ensureOrderFillISubscription, _HyperLiquidSubscriptionService_createSubscription, _HyperLiquidSubscriptionService_createPriceUpdate, _HyperLiquidSubscriptionService_ensureGlobalAllMidsSubscription, _HyperLiquidSubscriptionService_ensureActiveAssetSubscription, _HyperLiquidSubscriptionService_cleanupActiveAssetSubscription, _HyperLiquidSubscriptionService_ensureAssetCtxsSubscription, _HyperLiquidSubscriptionService_ensureDexAllMidsSubscription, _HyperLiquidSubscriptionService_createDexAllMidsSubscription, _HyperLiquidSubscriptionService_createAssetCtxsSubscription, _HyperLiquidSubscriptionService_cleanupAssetCtxsSubscription, _HyperLiquidSubscriptionService_ensureBboSubscription, _HyperLiquidSubscriptionService_cleanupBboSubscription, _HyperLiquidSubscriptionService_processOrderBookData, _HyperLiquidSubscriptionService_notifyAllPriceSubscribers;
13
+ var _HyperLiquidSubscriptionService_instances, _HyperLiquidSubscriptionService_clientService, _HyperLiquidSubscriptionService_walletService, _HyperLiquidSubscriptionService_hip3Enabled, _HyperLiquidSubscriptionService_enabledDexs, _HyperLiquidSubscriptionService_allowlistMarkets, _HyperLiquidSubscriptionService_blocklistMarkets, _HyperLiquidSubscriptionService_discoveredDexNames, _HyperLiquidSubscriptionService_dexDiscoveryPromise, _HyperLiquidSubscriptionService_dexDiscoveryResolver, _HyperLiquidSubscriptionService_expectedDexs, _HyperLiquidSubscriptionService_initializedDexs, _HyperLiquidSubscriptionService_priceSubscribers, _HyperLiquidSubscriptionService_positionSubscribers, _HyperLiquidSubscriptionService_orderFillSubscribers, _HyperLiquidSubscriptionService_orderSubscribers, _HyperLiquidSubscriptionService_accountSubscribers, _HyperLiquidSubscriptionService_marketDataSubscribers, _HyperLiquidSubscriptionService_orderBookSubscribers, _HyperLiquidSubscriptionService_globalAllMidsSubscription, _HyperLiquidSubscriptionService_globalAllMidsPromise, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, _HyperLiquidSubscriptionService_globalBboSubscriptions, _HyperLiquidSubscriptionService_pendingBboPromises, _HyperLiquidSubscriptionService_orderFillSubscriptions, _HyperLiquidSubscriptionService_symbolSubscriberCounts, _HyperLiquidSubscriptionService_dexSubscriberCounts, _HyperLiquidSubscriptionService_webData3Subscriptions, _HyperLiquidSubscriptionService_webData3SubscriptionPromise, _HyperLiquidSubscriptionService_positionSubscriberCount, _HyperLiquidSubscriptionService_orderSubscriberCount, _HyperLiquidSubscriptionService_accountSubscriberCount, _HyperLiquidSubscriptionService_oiCapSubscriberCount, _HyperLiquidSubscriptionService_dexPositionsCache, _HyperLiquidSubscriptionService_dexOrdersCache, _HyperLiquidSubscriptionService_dexAccountCache, _HyperLiquidSubscriptionService_cachedPositions, _HyperLiquidSubscriptionService_cachedOrders, _HyperLiquidSubscriptionService_cachedAccount, _HyperLiquidSubscriptionService_ordersCacheInitialized, _HyperLiquidSubscriptionService_positionsCacheInitialized, _HyperLiquidSubscriptionService_oiCapSubscribers, _HyperLiquidSubscriptionService_cachedOICaps, _HyperLiquidSubscriptionService_cachedOICapsHash, _HyperLiquidSubscriptionService_oiCapsCacheInitialized, _HyperLiquidSubscriptionService_cachedPriceData, _HyperLiquidSubscriptionService_allMidsSnapshots, _HyperLiquidSubscriptionService_cachedFills, _HyperLiquidSubscriptionService_fillsCacheInitialized, _HyperLiquidSubscriptionService_assetCtxsSubscriptions, _HyperLiquidSubscriptionService_dexAssetCtxsCache, _HyperLiquidSubscriptionService_assetCtxsSubscriptionPromises, _HyperLiquidSubscriptionService_dexAllMidsSubscriptions, _HyperLiquidSubscriptionService_dexAllMidsSubscriptionPromises, _HyperLiquidSubscriptionService_clearinghouseStateSubscriptions, _HyperLiquidSubscriptionService_openOrdersSubscriptions, _HyperLiquidSubscriptionService_pendingClearinghouseSubscriptions, _HyperLiquidSubscriptionService_pendingOpenOrdersSubscriptions, _HyperLiquidSubscriptionService_dexMetaCache, _HyperLiquidSubscriptionService_orderBookCache, _HyperLiquidSubscriptionService_marketDataCache, _HyperLiquidSubscriptionService_isClearing, _HyperLiquidSubscriptionService_restoreRetryTimeouts, _HyperLiquidSubscriptionService_deps, _HyperLiquidSubscriptionService_logErrorUnlessClearing, _HyperLiquidSubscriptionService_isTransientAssetCtxsError, _HyperLiquidSubscriptionService_scheduleRestoreRetry, _HyperLiquidSubscriptionService_getErrorContext, _HyperLiquidSubscriptionService_isDexEnabled, _HyperLiquidSubscriptionService_waitForDexDiscovery, _HyperLiquidSubscriptionService_hashPositions, _HyperLiquidSubscriptionService_hashOrders, _HyperLiquidSubscriptionService_hashAccountState, _HyperLiquidSubscriptionService_cachedPositionsHash, _HyperLiquidSubscriptionService_cachedOrdersHash, _HyperLiquidSubscriptionService_cachedAccountHash, _HyperLiquidSubscriptionService_extractTPSLFromOrders, _HyperLiquidSubscriptionService_mergeTPSLIntoPositions, _HyperLiquidSubscriptionService_aggregateAccountStates, _HyperLiquidSubscriptionService_ensureSharedWebData3Subscription, _HyperLiquidSubscriptionService_createUserDataSubscription, _HyperLiquidSubscriptionService_ensureClearinghouseStateSubscription, _HyperLiquidSubscriptionService_createClearinghouseSubscription, _HyperLiquidSubscriptionService_ensureOpenOrdersSubscription, _HyperLiquidSubscriptionService_createOpenOrdersSubscription, _HyperLiquidSubscriptionService_aggregateAndNotifySubscribers, _HyperLiquidSubscriptionService_cleanupSharedWebData3ISubscription, _HyperLiquidSubscriptionService_ensureOrderFillISubscription, _HyperLiquidSubscriptionService_createSubscription, _HyperLiquidSubscriptionService_createPriceUpdate, _HyperLiquidSubscriptionService_ensureGlobalAllMidsSubscription, _HyperLiquidSubscriptionService_ensureActiveAssetSubscription, _HyperLiquidSubscriptionService_cleanupActiveAssetSubscription, _HyperLiquidSubscriptionService_ensureAssetCtxsSubscription, _HyperLiquidSubscriptionService_ensureDexAllMidsSubscription, _HyperLiquidSubscriptionService_createDexAllMidsSubscription, _HyperLiquidSubscriptionService_createAssetCtxsSubscription, _HyperLiquidSubscriptionService_cleanupAssetCtxsSubscription, _HyperLiquidSubscriptionService_ensureBboSubscription, _HyperLiquidSubscriptionService_cleanupBboSubscription, _HyperLiquidSubscriptionService_processOrderBookData, _HyperLiquidSubscriptionService_notifyAllPriceSubscribers;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.HyperLiquidSubscriptionService = void 0;
16
+ const utils_1 = require("@metamask/utils");
16
17
  const perpsConfig_1 = require("../constants/perpsConfig.cjs");
17
18
  const types_1 = require("../types/index.cjs");
18
19
  const accountUtils_1 = require("../utils/accountUtils.cjs");
@@ -58,7 +59,12 @@ class HyperLiquidSubscriptionService {
58
59
  _HyperLiquidSubscriptionService_globalAllMidsSubscription.set(this, void 0);
59
60
  _HyperLiquidSubscriptionService_globalAllMidsPromise.set(this, void 0); // Track in-progress subscription
60
61
  _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions.set(this, new Map());
62
+ // Track in-progress activeAssetCtx subscription promises to prevent leaks
63
+ // when cleanup fires before the async subscription resolves (#28141)
64
+ _HyperLiquidSubscriptionService_pendingActiveAssetPromises.set(this, new Map());
61
65
  _HyperLiquidSubscriptionService_globalBboSubscriptions.set(this, new Map());
66
+ // Track in-progress BBO subscription promises to prevent leaks (#28141)
67
+ _HyperLiquidSubscriptionService_pendingBboPromises.set(this, new Map());
62
68
  // Order fill subscriptions keyed by accountId (normalized: undefined -> 'default')
63
69
  _HyperLiquidSubscriptionService_orderFillSubscriptions.set(this, new Map());
64
70
  _HyperLiquidSubscriptionService_symbolSubscriberCounts.set(this, new Map());
@@ -702,6 +708,7 @@ class HyperLiquidSubscriptionService {
702
708
  if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_marketDataSubscribers, "f").size > 0) {
703
709
  // Clear existing subscriptions (they're dead after reconnection)
704
710
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").clear();
711
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").clear();
705
712
  // Clear reference counts to prevent double-counting after reconnection
706
713
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").clear();
707
714
  // Re-establish subscriptions for all symbols with market data subscribers
@@ -714,6 +721,7 @@ class HyperLiquidSubscriptionService {
714
721
  if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_orderBookSubscribers, "f").size > 0) {
715
722
  // Clear existing subscriptions (they're dead after reconnection)
716
723
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").clear();
724
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").clear();
717
725
  // Re-establish subscriptions for all symbols with order book subscribers
718
726
  const symbolsNeedingOrderBook = Array.from(__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_orderBookSubscribers, "f").keys());
719
727
  symbolsNeedingOrderBook.forEach((symbol) => {
@@ -843,7 +851,9 @@ class HyperLiquidSubscriptionService {
843
851
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_globalAllMidsSubscription, undefined, "f");
844
852
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_globalAllMidsPromise, undefined, "f");
845
853
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").clear();
854
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").clear();
846
855
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").clear();
856
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").clear();
847
857
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_webData3Subscriptions, "f").clear();
848
858
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_webData3SubscriptionPromise, undefined, "f");
849
859
  // HIP-3: Clear assetCtxs subscriptions (clearinghouseState no longer needed with webData3)
@@ -883,7 +893,7 @@ class HyperLiquidSubscriptionService {
883
893
  }
884
894
  }
885
895
  exports.HyperLiquidSubscriptionService = HyperLiquidSubscriptionService;
886
- _HyperLiquidSubscriptionService_clientService = new WeakMap(), _HyperLiquidSubscriptionService_walletService = new WeakMap(), _HyperLiquidSubscriptionService_hip3Enabled = new WeakMap(), _HyperLiquidSubscriptionService_enabledDexs = new WeakMap(), _HyperLiquidSubscriptionService_allowlistMarkets = new WeakMap(), _HyperLiquidSubscriptionService_blocklistMarkets = new WeakMap(), _HyperLiquidSubscriptionService_discoveredDexNames = new WeakMap(), _HyperLiquidSubscriptionService_dexDiscoveryPromise = new WeakMap(), _HyperLiquidSubscriptionService_dexDiscoveryResolver = new WeakMap(), _HyperLiquidSubscriptionService_expectedDexs = new WeakMap(), _HyperLiquidSubscriptionService_initializedDexs = new WeakMap(), _HyperLiquidSubscriptionService_priceSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_positionSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_orderFillSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_orderSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_accountSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_marketDataSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_orderBookSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_globalAllMidsSubscription = new WeakMap(), _HyperLiquidSubscriptionService_globalAllMidsPromise = new WeakMap(), _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_globalBboSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_orderFillSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_symbolSubscriberCounts = new WeakMap(), _HyperLiquidSubscriptionService_dexSubscriberCounts = new WeakMap(), _HyperLiquidSubscriptionService_webData3Subscriptions = new WeakMap(), _HyperLiquidSubscriptionService_webData3SubscriptionPromise = new WeakMap(), _HyperLiquidSubscriptionService_positionSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_orderSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_accountSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_oiCapSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_dexPositionsCache = new WeakMap(), _HyperLiquidSubscriptionService_dexOrdersCache = new WeakMap(), _HyperLiquidSubscriptionService_dexAccountCache = new WeakMap(), _HyperLiquidSubscriptionService_cachedPositions = new WeakMap(), _HyperLiquidSubscriptionService_cachedOrders = new WeakMap(), _HyperLiquidSubscriptionService_cachedAccount = new WeakMap(), _HyperLiquidSubscriptionService_ordersCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_positionsCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_oiCapSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_cachedOICaps = new WeakMap(), _HyperLiquidSubscriptionService_cachedOICapsHash = new WeakMap(), _HyperLiquidSubscriptionService_oiCapsCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_cachedPriceData = new WeakMap(), _HyperLiquidSubscriptionService_allMidsSnapshots = new WeakMap(), _HyperLiquidSubscriptionService_cachedFills = new WeakMap(), _HyperLiquidSubscriptionService_fillsCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_assetCtxsSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_dexAssetCtxsCache = new WeakMap(), _HyperLiquidSubscriptionService_assetCtxsSubscriptionPromises = new WeakMap(), _HyperLiquidSubscriptionService_dexAllMidsSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_dexAllMidsSubscriptionPromises = new WeakMap(), _HyperLiquidSubscriptionService_clearinghouseStateSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_openOrdersSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_pendingClearinghouseSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_pendingOpenOrdersSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_dexMetaCache = new WeakMap(), _HyperLiquidSubscriptionService_orderBookCache = new WeakMap(), _HyperLiquidSubscriptionService_marketDataCache = new WeakMap(), _HyperLiquidSubscriptionService_isClearing = new WeakMap(), _HyperLiquidSubscriptionService_restoreRetryTimeouts = new WeakMap(), _HyperLiquidSubscriptionService_deps = new WeakMap(), _HyperLiquidSubscriptionService_cachedPositionsHash = new WeakMap(), _HyperLiquidSubscriptionService_cachedOrdersHash = new WeakMap(), _HyperLiquidSubscriptionService_cachedAccountHash = new WeakMap(), _HyperLiquidSubscriptionService_instances = new WeakSet(), _HyperLiquidSubscriptionService_logErrorUnlessClearing = function _HyperLiquidSubscriptionService_logErrorUnlessClearing(error, context) {
896
+ _HyperLiquidSubscriptionService_clientService = new WeakMap(), _HyperLiquidSubscriptionService_walletService = new WeakMap(), _HyperLiquidSubscriptionService_hip3Enabled = new WeakMap(), _HyperLiquidSubscriptionService_enabledDexs = new WeakMap(), _HyperLiquidSubscriptionService_allowlistMarkets = new WeakMap(), _HyperLiquidSubscriptionService_blocklistMarkets = new WeakMap(), _HyperLiquidSubscriptionService_discoveredDexNames = new WeakMap(), _HyperLiquidSubscriptionService_dexDiscoveryPromise = new WeakMap(), _HyperLiquidSubscriptionService_dexDiscoveryResolver = new WeakMap(), _HyperLiquidSubscriptionService_expectedDexs = new WeakMap(), _HyperLiquidSubscriptionService_initializedDexs = new WeakMap(), _HyperLiquidSubscriptionService_priceSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_positionSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_orderFillSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_orderSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_accountSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_marketDataSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_orderBookSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_globalAllMidsSubscription = new WeakMap(), _HyperLiquidSubscriptionService_globalAllMidsPromise = new WeakMap(), _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_pendingActiveAssetPromises = new WeakMap(), _HyperLiquidSubscriptionService_globalBboSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_pendingBboPromises = new WeakMap(), _HyperLiquidSubscriptionService_orderFillSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_symbolSubscriberCounts = new WeakMap(), _HyperLiquidSubscriptionService_dexSubscriberCounts = new WeakMap(), _HyperLiquidSubscriptionService_webData3Subscriptions = new WeakMap(), _HyperLiquidSubscriptionService_webData3SubscriptionPromise = new WeakMap(), _HyperLiquidSubscriptionService_positionSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_orderSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_accountSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_oiCapSubscriberCount = new WeakMap(), _HyperLiquidSubscriptionService_dexPositionsCache = new WeakMap(), _HyperLiquidSubscriptionService_dexOrdersCache = new WeakMap(), _HyperLiquidSubscriptionService_dexAccountCache = new WeakMap(), _HyperLiquidSubscriptionService_cachedPositions = new WeakMap(), _HyperLiquidSubscriptionService_cachedOrders = new WeakMap(), _HyperLiquidSubscriptionService_cachedAccount = new WeakMap(), _HyperLiquidSubscriptionService_ordersCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_positionsCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_oiCapSubscribers = new WeakMap(), _HyperLiquidSubscriptionService_cachedOICaps = new WeakMap(), _HyperLiquidSubscriptionService_cachedOICapsHash = new WeakMap(), _HyperLiquidSubscriptionService_oiCapsCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_cachedPriceData = new WeakMap(), _HyperLiquidSubscriptionService_allMidsSnapshots = new WeakMap(), _HyperLiquidSubscriptionService_cachedFills = new WeakMap(), _HyperLiquidSubscriptionService_fillsCacheInitialized = new WeakMap(), _HyperLiquidSubscriptionService_assetCtxsSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_dexAssetCtxsCache = new WeakMap(), _HyperLiquidSubscriptionService_assetCtxsSubscriptionPromises = new WeakMap(), _HyperLiquidSubscriptionService_dexAllMidsSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_dexAllMidsSubscriptionPromises = new WeakMap(), _HyperLiquidSubscriptionService_clearinghouseStateSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_openOrdersSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_pendingClearinghouseSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_pendingOpenOrdersSubscriptions = new WeakMap(), _HyperLiquidSubscriptionService_dexMetaCache = new WeakMap(), _HyperLiquidSubscriptionService_orderBookCache = new WeakMap(), _HyperLiquidSubscriptionService_marketDataCache = new WeakMap(), _HyperLiquidSubscriptionService_isClearing = new WeakMap(), _HyperLiquidSubscriptionService_restoreRetryTimeouts = new WeakMap(), _HyperLiquidSubscriptionService_deps = new WeakMap(), _HyperLiquidSubscriptionService_cachedPositionsHash = new WeakMap(), _HyperLiquidSubscriptionService_cachedOrdersHash = new WeakMap(), _HyperLiquidSubscriptionService_cachedAccountHash = new WeakMap(), _HyperLiquidSubscriptionService_instances = new WeakSet(), _HyperLiquidSubscriptionService_logErrorUnlessClearing = function _HyperLiquidSubscriptionService_logErrorUnlessClearing(error, context) {
887
897
  if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_isClearing, "f")) {
888
898
  return;
889
899
  }
@@ -1939,8 +1949,9 @@ async function _HyperLiquidSubscriptionService_ensureOrderFillISubscription(acco
1939
1949
  // Increment subscriber count
1940
1950
  const currentCount = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").get(symbol) ?? 0;
1941
1951
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").set(symbol, currentCount + 1);
1942
- // If subscription already exists, just return
1943
- if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").has(symbol)) {
1952
+ // If subscription already exists or is being created, just return
1953
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").has(symbol) ||
1954
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").has(symbol)) {
1944
1955
  return;
1945
1956
  }
1946
1957
  const subscriptionClient = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_clientService, "f").getSubscriptionClient();
@@ -1952,14 +1963,14 @@ async function _HyperLiquidSubscriptionService_ensureOrderFillISubscription(acco
1952
1963
  messagesReceived: 0,
1953
1964
  startTime: Date.now(),
1954
1965
  };
1955
- subscriptionClient
1966
+ const promise = subscriptionClient
1956
1967
  .activeAssetCtx({ coin: symbol }, (data) => {
1957
1968
  subscriptionMetrics.messagesReceived += 1;
1958
1969
  if (data.coin === symbol && data.ctx) {
1959
1970
  // Type guard using SDK types: check if this is perps (has funding) or spot (no funding)
1960
- const isPerpsContext = (event) => 'funding' in event.ctx &&
1961
- 'openInterest' in event.ctx &&
1962
- 'oraclePx' in event.ctx;
1971
+ const isPerpsContext = (event) => (0, utils_1.hasProperty)(event.ctx, 'funding') &&
1972
+ (0, utils_1.hasProperty)(event.ctx, 'openInterest') &&
1973
+ (0, utils_1.hasProperty)(event.ctx, 'oraclePx');
1963
1974
  const { ctx } = data;
1964
1975
  // Cache market data for consolidation with price updates
1965
1976
  const ctxPrice = ctx.midPx ?? ctx.markPx;
@@ -1998,17 +2009,36 @@ async function _HyperLiquidSubscriptionService_ensureOrderFillISubscription(acco
1998
2009
  }
1999
2010
  })
2000
2011
  .then((sub) => {
2012
+ // Only clear pending ref if this is still the current promise.
2013
+ // A rapid away-and-back can replace the pending promise; blindly
2014
+ // deleting would remove the *newer* reference (#28141).
2015
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").get(symbol) === promise) {
2016
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").delete(symbol);
2017
+ }
2018
+ // Stale subscription: cleanup was called while pending, a newer
2019
+ // subscription already won the race, OR a different pending promise
2020
+ // exists (rapid away-and-back before this one resolved). (#28141)
2021
+ if ((__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").get(symbol) ?? 0) <= 0 ||
2022
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").has(symbol) ||
2023
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").has(symbol)) {
2024
+ return sub.unsubscribe();
2025
+ }
2001
2026
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").set(symbol, sub);
2002
2027
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`HyperLiquid: Market data subscription established for ${symbol}`);
2003
2028
  return undefined;
2004
2029
  })
2005
2030
  .catch((error) => {
2031
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").get(symbol) === promise) {
2032
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").delete(symbol);
2033
+ }
2006
2034
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.ensureActiveAssetSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'ensureActiveAssetSubscription', { symbol }));
2007
2035
  });
2036
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").set(symbol, promise);
2008
2037
  }, _HyperLiquidSubscriptionService_cleanupActiveAssetSubscription = function _HyperLiquidSubscriptionService_cleanupActiveAssetSubscription(symbol) {
2009
2038
  const currentCount = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").get(symbol) ?? 0;
2010
2039
  if (currentCount <= 1) {
2011
2040
  // Last subscriber, cleanup subscription
2041
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").delete(symbol);
2012
2042
  const subscription = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").get(symbol);
2013
2043
  if (subscription && typeof subscription.unsubscribe === 'function') {
2014
2044
  const unsubscribeResult = Promise.resolve(subscription.unsubscribe());
@@ -2016,14 +2046,17 @@ async function _HyperLiquidSubscriptionService_ensureOrderFillISubscription(acco
2016
2046
  // Ignore errors during cleanup
2017
2047
  });
2018
2048
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").delete(symbol);
2019
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").delete(symbol);
2020
2049
  }
2021
2050
  else if (subscription) {
2022
2051
  // Subscription exists but unsubscribe is not a function or doesn't return a Promise
2023
2052
  // Just clean up the reference
2024
2053
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalActiveAssetSubscriptions, "f").delete(symbol);
2025
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_symbolSubscriberCounts, "f").delete(symbol);
2026
2054
  }
2055
+ // If subscription is still pending (async), the .then() handler in
2056
+ // #ensureActiveAssetSubscription will check symbolSubscriberCounts
2057
+ // and unsubscribe immediately when it resolves (#28141)
2058
+ // Clean up the pending promise reference
2059
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingActiveAssetPromises, "f").delete(symbol);
2027
2060
  }
2028
2061
  else {
2029
2062
  // Still has subscribers, just decrement count
@@ -2118,6 +2151,11 @@ async function _HyperLiquidSubscriptionService_createDexAllMidsSubscription(dex)
2118
2151
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_allMidsSnapshots, "f").set(dex, data.mids);
2119
2152
  })
2120
2153
  .then((sub) => {
2154
+ // If a newer subscription already won the race, discard this one (#28141)
2155
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_dexAllMidsSubscriptions, "f").has(dex)) {
2156
+ resolve();
2157
+ return sub.unsubscribe();
2158
+ }
2121
2159
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_dexAllMidsSubscriptions, "f").set(dex, sub);
2122
2160
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`allMids subscription established for DEX: ${dex}`);
2123
2161
  resolve();
@@ -2177,7 +2215,7 @@ async function _HyperLiquidSubscriptionService_createAssetCtxsSubscription(dex)
2177
2215
  // Use cached meta to map ctxs array indices to symbols (no REST API call!)
2178
2216
  validatedMeta.universe.forEach((asset, index) => {
2179
2217
  const ctx = data.ctxs[index];
2180
- if (ctx && 'funding' in ctx) {
2218
+ if (ctx && (0, utils_1.hasProperty)(ctx, 'funding')) {
2181
2219
  // This is a perps context
2182
2220
  const ctxPrice = ctx.midPx ?? ctx.markPx;
2183
2221
  const openInterestUSD = (0, marketDataTransform_1.calculateOpenInterestUSD)(ctx.openInterest, ctxPrice);
@@ -2238,6 +2276,11 @@ async function _HyperLiquidSubscriptionService_createAssetCtxsSubscription(dex)
2238
2276
  };
2239
2277
  subscribeWithRetry()
2240
2278
  .then((sub) => {
2279
+ // If a newer subscription already won the race, discard this one (#28141)
2280
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_assetCtxsSubscriptions, "f").has(dexKey)) {
2281
+ resolve();
2282
+ return sub.unsubscribe();
2283
+ }
2241
2284
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_assetCtxsSubscriptions, "f").set(dexKey, sub);
2242
2285
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`assetCtxs subscription established for ${dex ? `DEX: ${dex}` : 'main DEX'}`);
2243
2286
  resolve();
@@ -2284,14 +2327,16 @@ async function _HyperLiquidSubscriptionService_createAssetCtxsSubscription(dex)
2284
2327
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_dexSubscriberCounts, "f").set(dexKey, currentCount - 1);
2285
2328
  }
2286
2329
  }, _HyperLiquidSubscriptionService_ensureBboSubscription = function _HyperLiquidSubscriptionService_ensureBboSubscription(symbol) {
2287
- if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").has(symbol)) {
2330
+ // Skip if subscription already exists or is being created
2331
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").has(symbol) ||
2332
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").has(symbol)) {
2288
2333
  return;
2289
2334
  }
2290
2335
  const subscriptionClient = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_clientService, "f").getSubscriptionClient();
2291
2336
  if (!subscriptionClient) {
2292
2337
  return;
2293
2338
  }
2294
- subscriptionClient
2339
+ const promise = subscriptionClient
2295
2340
  .bbo({ coin: symbol }, (data) => {
2296
2341
  (0, hyperLiquidOrderBookProcessor_1.processBboData)({
2297
2342
  symbol,
@@ -2303,13 +2348,29 @@ async function _HyperLiquidSubscriptionService_createAssetCtxsSubscription(dex)
2303
2348
  });
2304
2349
  })
2305
2350
  .then((sub) => {
2351
+ // Only clear pending ref if this is still the current promise (#28141).
2352
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").get(symbol) === promise) {
2353
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").delete(symbol);
2354
+ }
2355
+ // Stale subscription: cleanup was called while pending, a newer
2356
+ // subscription already won the race, OR a different pending promise
2357
+ // exists (rapid away-and-back before this one resolved). (#28141)
2358
+ if ((__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_orderBookSubscribers, "f").get(symbol)?.size ?? 0) <= 0 ||
2359
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").has(symbol) ||
2360
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").has(symbol)) {
2361
+ return sub.unsubscribe();
2362
+ }
2306
2363
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").set(symbol, sub);
2307
2364
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`HyperLiquid: BBO subscription established for ${symbol}`);
2308
2365
  return undefined;
2309
2366
  })
2310
2367
  .catch((error) => {
2368
+ if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").get(symbol) === promise) {
2369
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").delete(symbol);
2370
+ }
2311
2371
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.ensureBboSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'ensureBboSubscription', { symbol }));
2312
2372
  });
2373
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").set(symbol, promise);
2313
2374
  }, _HyperLiquidSubscriptionService_cleanupBboSubscription = function _HyperLiquidSubscriptionService_cleanupBboSubscription(symbol) {
2314
2375
  // If anyone still wants order book (top-of-book) data for this symbol, keep the subscription alive.
2315
2376
  if ((__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_orderBookSubscribers, "f").get(symbol)?.size ?? 0) > 0) {
@@ -2330,6 +2391,10 @@ async function _HyperLiquidSubscriptionService_createAssetCtxsSubscription(dex)
2330
2391
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_globalBboSubscriptions, "f").delete(symbol);
2331
2392
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_orderBookCache, "f").delete(symbol);
2332
2393
  }
2394
+ // If subscription is still pending (async), the .then() handler in
2395
+ // #ensureBboSubscription will check orderBookSubscribers and
2396
+ // unsubscribe immediately when it resolves (#28141)
2397
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_pendingBboPromises, "f").delete(symbol);
2333
2398
  }, _HyperLiquidSubscriptionService_processOrderBookData = function _HyperLiquidSubscriptionService_processOrderBookData(data, levels) {
2334
2399
  const bidsRaw = data?.levels?.[0] ?? [];
2335
2400
  const asksRaw = data?.levels?.[1] ?? [];