feat(perps): sdk reconnect on native socket event#25022
Conversation
- Create PerpsWebSocketHealthToast component with slide-from-top animation - Show connection states: disconnected (error), connecting (warning), connected (success) - Position toast at top of screen (74px from top) with solid background and shadow - Update useWebSocketHealthToast hook to return state for custom toast rendering - Remove websocketHealth options from usePerpsToasts (no longer needed) - Update PerpsStreamBridge to render the custom toast component
- Add reconnect() method to HyperLiquidClientService, Provider, and Controller - Show Retry button on toast when connection is disconnected - Update toast positioning to 12px from left/right edges - Update copy: title, description, and button text per design specs
- Limit auto-reconnection to 10 attempts before marking as disconnected - Reset attempt counter when user manually clicks Retry button - Allows user to always retry even after max attempts reached
…sitioning - Create WebSocketHealthToastContext for managing toast state globally - Render PerpsWebSocketHealthToast at App level next to existing Toast - Update useWebSocketHealthToast hook to use context instead of local state - Remove toast rendering from PerpsStreamBridge (now uses context) - Ensures toast appears on top of all content regardless of where useWebSocketHealthToast is called
…ached - Update condition to show disconnected toast when transitioning from CONNECTING to DISCONNECTED (max attempts reached case) - Previously only showed toast for direct CONNECTED to DISCONNECTED transition
- Update CandleStreamChannel.reconnect() to call disconnect() instead of disconnectAll() directly so the spy in tests can detect the call - Update reconnect test to verify reconnection happened without relying on exact call count (more resilient to implementation changes)
- Use advanceTimersByTimeAsync for proper async promise handling - Add await to initialize() calls since it's an async method - Add mock cleanup in afterEach to prevent leakage between tests - Use rejects.toThrow() for async error assertions
…ptionClient - Add await before initialize() in toggleTestnet to ensure SDK clients are ready before returning - Change ensureSubscriptionClient from sync to async and await initialize() call - Update all callers in HyperLiquidSubscriptionService to await ensureSubscriptionClient - Fix Jest open handles by using fake timers globally and proper cleanup in afterEach - Update test mocks to use mockResolvedValue for async ensureSubscriptionClient
…nnect
The reconnect() method was using split('-') which incorrectly parsed cache
keys when coin symbols contained hyphens (e.g., 'ETH-USD'). This would
cause 'ETH-USD-1h' to be parsed as coin='ETH' and interval='USD' instead
of coin='ETH-USD' and interval='1h'.
Fixed by using lastIndexOf('-') to split from the right, ensuring the
interval (always the last segment) is correctly identified while preserving
the full coin symbol including any hyphens.
Added tests to verify the fix works for coins with and without hyphens.
Wrap initial listener call in try-catch to match notifyConnectionStateListeners behavior. This ensures the unsubscribe function is always returned even if the listener throws during the initial call, preventing zombie listeners from remaining in the Set.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
Resolve merge conflicts preserving WebSocket terminate event detection: - HyperLiquidProvider: Combined initialization promise caching from main with terminate callback from HEAD for robust connection handling - HyperLiquidClientService: Used HEAD's simpler transport.ready() approach, terminate events handle connection failures - Tests: Updated to use main's naming convention while keeping all terminate event tests from HEAD
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsThis PR introduces WebSocket connection health monitoring and toast notifications for the Perps (perpetuals trading) feature. The changes include:
All changes except the App.tsx wrapper are isolated to the Perps module ( The risk is medium because:
|
|
|
No release label on PR. Adding release label release-7.64.0 on PR, as PR was added to branch 7.64.0 when release was cut. |
|
No release label on PR. Adding release label release-7.63.1 on PR, as PR was cherry-picked in branch 7.63.1. |
|
Missing release label release-7.63.1 on PR. Adding release label release-7.63.1 on PR and removing other release labels(release-7.64.0), as PR was cherry-picked in branch 7.63.1. |



Description
This PR implements an event-based WebSocket connection health monitoring system for Perps with visual toast notifications.
What is the reason for the change?
The previous WebSocket connection monitoring used polling (5-second intervals) to check connection state, which caused:
What is the improvement/solution?
This PR implements a layered architecture with event-driven connection monitoring:
UI Layer: Custom
PerpsWebSocketHealthToastcomponent with animated slide-in/out notifications showing connection states (connected/connecting/disconnected) with retry functionalityBridge Layer:
useWebSocketHealthToasthook that subscribes to connection state changes and translates them into toast notificationsController Layer:
PerpsControllerfacade exposingsubscribeToConnectionState()andreconnect()methodsService Layer:
HyperLiquidClientServicenow listens to the SDK'sterminateevent (fired when all reconnection attempts are exhausted) for instant detectionKey improvements:
terminateevent instead of polling for instant feedbackChangelog
CHANGELOG entry: Added WebSocket connection health toast notification for Perps trading to show real-time connection status with manual retry option
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
No visual feedback when WebSocket connection fails - users only notice when data stops updating.
After
auto-reconnect.mp4
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Implements event-driven WebSocket health monitoring for Perps with user-visible status and retry.
PerpsWebSocketHealthToast+ context/provider rendered at App level; slide-in states forDISCONNECTED/CONNECTING/CONNECTED, auto-hide on success, manual Retry, and test IDsuseWebSocketHealthToasthook bridges stream context to global toast; auto-retry after 10s, cleans up on unmountgetWebSocketConnectionState(),subscribeToConnectionState(), andreconnect(); propagate toHyperLiquidProviderterminateevent listening; connection state listeners, manual/auto reconnection with capped attempts and retry delay; cleanup on disconnect; ensure transports/clients recreated safelyPerpsStreamManager.clearAllChannels()now reconnects active channels;CandleStreamChannel.reconnect()fixes hyphenated symbols parsingRECONNECTION_RETRY_DELAY_MSand i18n copy for toastWritten by Cursor Bugbot for commit f8c2166. This will update automatically on new commits. Configure here.