Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
aeed743
chore: add ohlcv websocket streaming
sahar-fehri May 5, 2026
6b18707
chore: integrate OHLCVService WebSocket streaming into advanced charts
sahar-fehri May 6, 2026
8748a32
fix: add ohlcv latest fallback on disconnect or down
sahar-fehri May 11, 2026
5e5c781
Merge branch 'main' into chore/ohlcv-ws-streaming-integration
sahar-fehri May 11, 2026
6182bb7
fix: todo comment
sahar-fehri May 11, 2026
5786c6c
Merge branch 'main' into chore/ohlcv-ws-streaming-integration
sahar-fehri May 11, 2026
ad5be51
fix: test log
sahar-fehri May 11, 2026
edda0db
fix: cleanup
sahar-fehri May 11, 2026
837b876
fix: lint
sahar-fehri May 11, 2026
caefeb6
fix: ut
sahar-fehri May 12, 2026
88c63a7
fix: fix ut
sahar-fehri May 12, 2026
89f5283
fix: add feature flag to gate WS logic
sahar-fehri May 12, 2026
7664973
Merge branch 'main' into chore/ohlcv-ws-streaming-integration
sahar-fehri May 12, 2026
38cf74e
fix: merge conflict
sahar-fehri May 12, 2026
6754036
fix: fix handling subscription error
sahar-fehri May 12, 2026
d5c404b
fix: FF registration
sahar-fehri May 12, 2026
c49a444
fix: new preview
sahar-fehri May 13, 2026
d6be82e
fix: plug realtime update to price
sahar-fehri May 13, 2026
a24239b
fix: dedupe
sahar-fehri May 13, 2026
1d8190f
fix: fix
sahar-fehri May 13, 2026
f7d859f
fix: immediate poll on error
sahar-fehri May 14, 2026
2ea0f35
Merge branch 'main' into chore/ohlcv-ws-streaming-integration
sahar-fehri May 14, 2026
fd4200d
fix: ut
sahar-fehri May 14, 2026
0e1c567
bump core-backend
bergarces May 14, 2026
88ec55d
Merge branch 'main' into chore/ohlcv-ws-streaming-integration
bergarces May 14, 2026
fe6f560
Merge branch 'main' into chore/ohlcv-ws-streaming-integration
Prithpal-Sooriya May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ jest.mock('../../Charts/AdvancedChart/useOHLCVChart', () => ({
useOHLCVChart: (...args: unknown[]) => mockUseOHLCVChart(...args),
}));

jest.mock('../../Charts/AdvancedChart/useOHLCVRealtime', () => ({
useOHLCVRealtime: () => ({ latestBar: null }),
}));

jest.mock('../../Charts/AdvancedChart/TimeRangeSelector', () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const { View, Pressable, Text } = require('react-native');
Expand Down
46 changes: 46 additions & 0 deletions app/components/UI/AssetOverview/Price/Price.advanced.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
type TimeRange,
} from '../../Charts/AdvancedChart/TimeRangeSelector';
import { useOHLCVChart } from '../../Charts/AdvancedChart/useOHLCVChart';
import { useOHLCVRealtime } from '../../Charts/AdvancedChart/useOHLCVRealtime';
import { OHLCVBar } from '../../Charts/AdvancedChart/OHLCVBar/OHLCVBar';
import {
Box,
Expand Down Expand Up @@ -65,6 +66,19 @@

const EMPTY_INDICATORS: IndicatorType[] = [];

/**
* Maps UI time-range selections to the WebSocket candle interval used by
* OHLCVService. These match the default intervals the REST OHLCV API returns
* for each timePeriod.
*/
const WS_INTERVAL_BY_TIME_RANGE: Record<TimeRange, string> = {
'1H': '1m',
'1D': '15m',
'1W': '1h',
'1M': '1d',
'1Y': '1d',
};

const TIME_RANGE_LABELS: Record<TimeRange, string> = {
'1H': 'asset_overview.chart_time_period.1h',
'1D': 'asset_overview.chart_time_period.1d',
Expand Down Expand Up @@ -129,7 +143,7 @@
timePeriod = '1d',
chartNavigationButtons = [],
setTimePeriod,
}: PriceAdvancedProps) => {

Check failure on line 146 in app/components/UI/AssetOverview/Price/Price.advanced.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 31 to the 30 allowed.

See more on https://sonarcloud.io/project/issues?id=metamask-mobile&issues=AZ4Wbyc1-DQLXMz_mHED&open=AZ4Wbyc1-DQLXMz_mHED&pullRequest=29739
const dispatch = useDispatch();
const { trackEvent, createEventBuilder } = useAnalytics();
const [timeRange, setTimeRange] = useState<TimeRange>('1D');
Expand Down Expand Up @@ -293,6 +307,37 @@
vsCurrency: currentCurrency,
});

const wsInterval = WS_INTERVAL_BY_TIME_RANGE[timeRange];
// TODO: Check if we want to add a feature flag to gate the WS OHLCV feature

Check warning on line 311 in app/components/UI/AssetOverview/Price/Price.advanced.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=metamask-mobile&issues=AZ4WmsRpwAOQT67rNcME&open=AZ4WmsRpwAOQT67rNcME&pullRequest=29739
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a followup

const wsEnabled =
!chartLoading &&
ohlcvData.length >= CHART_DATA_THRESHOLD &&
!hasEmptyData &&
!chartError;

const { latestBar } = useOHLCVRealtime({
assetId,
interval: wsInterval,
currency: currentCurrency,
timePeriod: timeRange.toLowerCase(),
enabled: wsEnabled,
});

// TradingView Advanced Charts Bar.time expects milliseconds
// https://www.tradingview.com/charting-library-docs/latest/api/interfaces/Datafeed.Bar/
// OHLCVService delivers bars with `timestamp` in Unix seconds — multiply by 1000
const realtimeBar = useMemo(() => {
if (!latestBar) return undefined;
return {
time: latestBar.timestamp * 1000,
open: latestBar.open,
high: latestBar.high,
low: latestBar.low,
close: latestBar.close,
volume: latestBar.volume,
};
}, [latestBar]);
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated

const ohlcvPagination = useMemo(
() => ({
nextCursor,
Expand Down Expand Up @@ -554,6 +599,7 @@
<AdvancedChart
ohlcvData={ohlcvData}
ohlcvSeriesKey={ohlcvSeriesKey}
realtimeBar={realtimeBar}
height={CHART_HEIGHT}
showVolume={chartType === ChartType.Candles}
volumeOverlay
Expand Down
4 changes: 4 additions & 0 deletions app/components/UI/AssetOverview/Price/Price.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ jest.mock('../../Charts/AdvancedChart/useOHLCVChart', () => ({
useOHLCVChart: (...args: unknown[]) => mockUseOHLCVChart(...args),
}));

jest.mock('../../Charts/AdvancedChart/useOHLCVRealtime', () => ({
useOHLCVRealtime: () => ({ latestBar: null }),
}));

jest.mock('../PriceChart/PriceChart', () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const { View } = require('react-native');
Expand Down
Loading
Loading