chore: add ohlcv websocket streaming#29739
Conversation
|
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. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #29739 +/- ##
===========================================
- Coverage 81.54% 55.83% -25.72%
===========================================
Files 5343 5350 +7
Lines 142128 142350 +222
Branches 32411 32463 +52
===========================================
- Hits 115899 79478 -36421
- Misses 18299 56212 +37913
+ Partials 7930 6660 -1270 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| "@metamask/connectivity-controller": "^0.1.0", | ||
| "@metamask/controller-utils": "^11.18.0", | ||
| "@metamask/core-backend": "^6.2.0", | ||
| "@metamask/core-backend": "npm:@metamask-previews/core-backend@6.2.2-preview-094d56fb3", |
There was a problem hiding this comment.
TODO: to be removed after release
| }); | ||
|
|
||
| const wsInterval = WS_INTERVAL_BY_TIME_RANGE[timeRange]; | ||
| // TODO: Check if we want to add a feature flag to gate the WS OHLCV feature |
There was a problem hiding this comment.
Could be a followup
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: The PR introduces a new OHLCVService (real-time OHLCV candlestick WebSocket streaming) integrated into the Engine, along with a new useOHLCVRealtime hook and updates to the Price.advanced.tsx component. Key findings:
No other tags are needed since:
Performance Test Selection: |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d5c404b. Configure here.
| }); | ||
| subscribedRef.current = false; | ||
| }; | ||
| }, [assetId, interval, currency, timePeriod, enabled, buildChannel]); |
There was a problem hiding this comment.
Unnecessary WS teardown when only REST fallback param changes
Medium Severity
timePeriod is in the useEffect dependency array, but it's only consumed by the REST fallback pollLatest function — the WebSocket channel is built solely from assetId, interval, and currency. When switching between time ranges that share the same WS interval (e.g. '1M' → '1Y', both mapped to '1d' in WS_INTERVAL_BY_TIME_RANGE), the effect tears down and re-establishes the identical WS subscription. This causes a ~500ms real-time data gap (debounce) and unnecessary unsubscribe/resubscribe churn on every such switch. Storing timePeriod in a ref that pollLatest reads would avoid triggering the effect on timePeriod-only changes.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d5c404b. Configure here.
|





Description
Related to: https://www.notion.so/metamask-consensys/OHLCV-WebSocket-Integration-UI-Implementation-Guide-346f86d67d6880b6a70fc3be0f0c34b9
Wires
OHLCVServicefrom@metamask/core-backendinto the Engine and creates auseOHLCVRealtimehook that streams live candlestick updates to the advanced chart via the existingrealtimeBarprop onAdvancedChart.Why: The advanced chart currently only renders historical data fetched via the REST OHLCV API. Users see stale candles until they navigate away and back. Real-time streaming via WebSocket keeps the chart live with 5-second heartbeat updates.
How: Follows the exact same Engine wiring pattern as
AccountActivityService— messenger, init function, Engine registration. The newuseOHLCVRealtimehook subscribes toOHLCVService:barUpdatedevents, filters by channel, and converts the WS bar format (timestamp in Unix seconds) to the chart's expected format (time in milliseconds).Manual Test Plan
Prerequisites
backendWebSocketConnectionfeature flag enabledAdding console.log statements to the mobile hook
1. Inside
handleBarUpdated— after the channel guard:2. Inside
handleSubscriptionError— first line of the callback:3. Inside
handleChainStatusChanged— after thechainIds.includesguard:4. Inside
pollLatest— first line of the function:5. Inside the staleness
setInterval— whenisStale || chainDown:6. Inside the debounce
setTimeout— first line:7. In the cleanup
returnfunction — first line:Enabling core logs in the debugger
By default, core
OHLCVServicelogs useprojectLogger(thedebugpackage) and won't appear in the React Native debugger. To make them visible, open:Find this line (near the top, around line 30):
Replace with:
Now all core logs will appear in the debugger with the
[OHLCV-WS]prefix, alongside the mobile hook logs. Revert withyarn installwhen done.Group A — No Code Changes (Just Tap and Observe)
Scenario 1: Basic WebSocket Subscription
Steps:
Expected logs:
Verify: Bars continue arriving every ~5s with updating
closeprices.Scenario 2: Navigate Away (Unsubscribe + Grace Period)
Steps:
Expected logs:
Verify: No more bar updates after grace period expires.
Scenario 3: Rapid Navigation (Grace Period Cancel)
Steps:
Expected logs:
Verify:
Cancelled grace-period unsubscribe, bumped refCountappears — subscription was reused without a server roundtrip.Scenario 4: Switch Between Tokens
Steps:
Expected logs:
Verify: Token A fully unsubscribes (grace period expires). Token B gets its own subscription and bars flow.
Scenario 5: Rapid Time Range Switching
Steps:
Expected logs (showing one switch cycle: 15m → 1h):
This pattern repeats for each switch (1h → 1d → 1h → 15m → 1m). Each time, the old channel is flushed immediately before the new subscribe — no accumulation, no server rejections.
Verify: Every subscribe succeeds (
Subscribe succeeded).Flushing grace-period channelappears before each new subscribe. Bars flow on the final time range.Scenario 6: App Background / Foreground
Steps:
Expected logs:
Verify:
Resubscribing active channels after reconnect {count: 1}appears after foregrounding. Bars resume automatically without user interaction.Scenario 7: Unsupported Token (No OHLCV Data)
Steps:
Expected: No WS subscription, falls back to legacy line chart.
Group B — Requires Changing DEV Constants in
useOHLCVRealtime.tsScenario 8: WebSocket Disconnect → REST Polling Fallback
What this tests: The WebSocket connection drops and stays disconnected. After the staleness threshold (30s) is exceeded, the hook falls back to polling REST.
Code to add
In
useOHLCVRealtime.ts, set the DEV constants:How it works
After 10s, calls
BackendWebSocketService:disconnect(clean shutdown, no auto-reconnect). The WS stays dead. After 30s with no bars, staleness triggers REST polling every 15s.Steps to test
Expected logs:
Verify: After the simulated disconnect, no more
Bar receivedlogs. REST polling kicks in every 15s once staleness threshold (30s) is exceeded.Group C — Requires Editing
.cjsin node_modulesScenario 10: Subscribe Failure / Error Recovery
What this tests:
OHLCVService.subscribe()fails. The service catches the error, publishesOHLCVService:subscriptionError, forces reconnection, and REST fallback keeps the chart alive.Code to add
1. Disable dev simulation constant in
useOHLCVRealtime.ts:2. Simulate subscribe failure — open
node_modules/@metamask/core-backend/dist/ws/ohlcv/OHLCVService.cjs.Find the subscribe call (look for
BackendWebSocketService:subscribe) and comment it out, then add a throw:Steps to test
yarn installto restore the original.cjsExpected — look for these key logs:
Verify: Error is caught, reconnection attempted (
Forcing WebSocket reconnection), and REST fallback keeps chart alive after staleness is detected.Log Reference
All logs use the
OHLCV-WSprefix. Filter byOHLCV-WSin Flipper / debugger.Changelog
CHANGELOG entry: Adds websocket streaming integration for ohlcv data
Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3194?atlOrigin=eyJpIjoiYmQ4N2E3MTlmZTFlNGYyNGFiODUxNzA2YThmM2FkYTkiLCJwIjoiaiJ9
Related: MetaMask/core#8695
Manual testing steps
Screenshots/Recordings
Before
After
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Note
Medium Risk
Adds a new Engine-integrated
OHLCVServiceplus a realtime hook that subscribes to WebSocket events and falls back to REST polling, which can impact chart correctness, network usage, and Engine lifecycle if miswired. Change is gated behind a new remote feature flag but also updates the@metamask/core-backenddependency to a preview build.Overview
Enables real-time candlestick updates on the token details advanced chart by wiring
OHLCVServiceinto the Engine (new init + messenger + type registrations) and feedingAdvancedCharta computedrealtimeBar.Adds
useOHLCVRealtimewith a 500ms subscribe debounce, channel-filteredOHLCVService:barUpdatedhandling, and a staleness/chain-down REST/latestpolling fallback, gated by the new remote flag selectorselectTokenDetailsOhlcvWsEnabled(registry + CI-known constant updates) and covered by new unit tests.Updates
@metamask/core-backendto a preview version to pick up the OHLCV service implementation.Reviewed by Cursor Bugbot for commit d5c404b. Bugbot is set up for automated code reviews on this repo. Configure here.