Skip to content

Add stream RPC client#119

Open
alexex10 wants to merge 42 commits into
starknetfrom
task/add-stream-rpc-client
Open

Add stream RPC client#119
alexex10 wants to merge 42 commits into
starknetfrom
task/add-stream-rpc-client

Conversation

@alexex10

@alexex10 alexex10 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Changes

  • Initial RPC stream implementation -- private topics support to be added in the upcoming versions

Demo

[2026-06-29 18:12:41,625 95806 8293851712 DEBUG] Connecting to wss://api.starknet.extended.exchange/stream.extended.exchange/v2/rpc
[2026-06-29 18:12:42,728 95806 8293851712 DEBUG] Connected to wss://api.starknet.extended.exchange/stream.extended.exchange/v2/rpc
[2026-06-29 18:12:43,247 95806 8293851712 INFO] Active subscriptions: []
[2026-06-29 18:12:43,510 95806 8293851712 DEBUG] Subscribed to trades.BTC-USD
[2026-06-29 18:12:43,514 95806 8293851712 INFO] Received message: type='TRADES' data=[PublicTradeModel(id=2071597705951449089, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356180, price=Decimal('59042'), qty=Decimal('0.00020')), PublicTradeModel(id=2071597705968226304, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356184, price=Decimal('59041'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597705968226305, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356184, price=Decimal('59041'), qty=Decimal('0.00033')), PublicTradeModel(id=2071597705968226306, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356184, price=Decimal('59041'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597705968226307, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356184, price=Decimal('59041'), qty=Decimal('0.10000')), PublicTradeModel(id=2071597705968226308, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356184, price=Decimal('59041'), qty=Decimal('0.00028')), PublicTradeModel(id=2071597706001780740, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356192, price=Decimal('59039'), qty=Decimal('0.00037')), PublicTradeModel(id=2071597706001780741, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356192, price=Decimal('59037'), qty=Decimal('0.00057')), PublicTradeModel(id=2071597706001780742, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356192, price=Decimal('59037'), qty=Decimal('0.00031')), PublicTradeModel(id=2071597706001780743, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356192, price=Decimal('59036'), qty=Decimal('0.00020')), PublicTradeModel(id=2071597706026946567, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356198, price=Decimal('59035'), qty=Decimal('0.01058')), PublicTradeModel(id=2071597706026946568, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356198, price=Decimal('59035'), qty=Decimal('0.00073')), PublicTradeModel(id=2071597706043723779, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356202, price=Decimal('59034'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597706043723780, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356202, price=Decimal('59034'), qty=Decimal('0.00020')), PublicTradeModel(id=2071597706043723781, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356202, price=Decimal('59034'), qty=Decimal('0.00040')), PublicTradeModel(id=2071597706043723782, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356202, price=Decimal('59034'), qty=Decimal('0.00031')), PublicTradeModel(id=2071597706043723783, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356202, price=Decimal('59034'), qty=Decimal('0.33865')), PublicTradeModel(id=2071597706043723784, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356202, price=Decimal('59033'), qty=Decimal('0.00067')), PublicTradeModel(id=2071597706085666840, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59032'), qty=Decimal('0.00058')), PublicTradeModel(id=2071597706085666841, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59032'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597706085666842, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59032'), qty=Decimal('0.00043')), PublicTradeModel(id=2071597706085666843, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59031'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597706085666844, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59031'), qty=Decimal('0.00080')), PublicTradeModel(id=2071597706085666845, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59031'), qty=Decimal('0.16932')), PublicTradeModel(id=2071597706085666846, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59030'), qty=Decimal('0.00025')), PublicTradeModel(id=2071597706085666847, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59030'), qty=Decimal('0.00056')), PublicTradeModel(id=2071597706085666848, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356212, price=Decimal('59030'), qty=Decimal('0.00311')), PublicTradeModel(id=2071597706094055428, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356214, price=Decimal('59035'), qty=Decimal('0.04587')), PublicTradeModel(id=2071597706127609861, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356222, price=Decimal('59029'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597706236661762, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356248, price=Decimal('59027'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597706236661763, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356248, price=Decimal('59027'), qty=Decimal('0.00050')), PublicTradeModel(id=2071597706236661764, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356248, price=Decimal('59026'), qty=Decimal('0.00022')), PublicTradeModel(id=2071597706236661765, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356248, price=Decimal('59026'), qty=Decimal('0.00295')), PublicTradeModel(id=2071597706236661766, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356248, price=Decimal('59026'), qty=Decimal('0.00212')), PublicTradeModel(id=2071597706295382019, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356262, price=Decimal('59024'), qty=Decimal('0.16932')), PublicTradeModel(id=2071597706312159240, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356266, price=Decimal('59022'), qty=Decimal('0.16933')), PublicTradeModel(id=2071597706391851013, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356285, price=Decimal('59021'), qty=Decimal('0.00057')), PublicTradeModel(id=2071597706391851014, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356285, price=Decimal('59020'), qty=Decimal('0.00413')), PublicTradeModel(id=2071597706391851015, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742356285, price=Decimal('59020'), qty=Decimal('0.09530')), PublicTradeModel(id=2071597707578839040, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356568, price=Decimal('59021'), qty=Decimal('0.29906')), PublicTradeModel(id=2071597707801137154, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356621, price=Decimal('59021'), qty=Decimal('0.02127')), PublicTradeModel(id=2071597707809525762, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356623, price=Decimal('59021'), qty=Decimal('0.07688')), PublicTradeModel(id=2071597707813720064, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356624, price=Decimal('59021'), qty=Decimal('0.01164')), PublicTradeModel(id=2071597707813720071, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356624, price=Decimal('59021'), qty=Decimal('0.01567')), PublicTradeModel(id=2071597707822108672, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356626, price=Decimal('59021'), qty=Decimal('0.00482')), PublicTradeModel(id=2071597707872440321, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742356638, price=Decimal('59021'), qty=Decimal('0.11460')), PublicTradeModel(id=2071597709864734723, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742357113, price=Decimal('59025'), qty=Decimal('0.20000')), PublicTradeModel(id=2071597734850203653, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742363070, price=Decimal('59021'), qty=Decimal('0.04500')), PublicTradeModel(id=2071597734875369478, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742363076, price=Decimal('59021'), qty=Decimal('0.07024')), PublicTradeModel(id=2071597734879563778, market='BTC-USD', side='BUY', trade_type='TRADE', timestamp=1782742363077, price=Decimal('59021'), qty=Decimal('0.03503'))] error=None ts=1782742364100 seq=0 subscription='trades.BTC-USD'
[2026-06-29 18:12:43,761 95806 8293851712 DEBUG] Subscribed to trades.ETH-USD
[2026-06-29 18:12:43,762 95806 8293851712 INFO] Received message: type='TRADES' data=[PublicTradeModel(id=2071597082669486080, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742207578, price=Decimal('1564.0'), qty=Decimal('0.318')), PublicTradeModel(id=2071597082669486081, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742207578, price=Decimal('1564.0'), qty=Decimal('0.022')), PublicTradeModel(id=2071597093809557504, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742210234, price=Decimal('1563.9'), qty=Decimal('0.160')), PublicTradeModel(id=2071597144548052996, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742222331, price=Decimal('1563.7'), qty=Decimal('0.103')), PublicTradeModel(id=2071597187074101259, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232470, price=Decimal('1563.4'), qty=Decimal('0.052')), PublicTradeModel(id=2071597187279622152, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232519, price=Decimal('1562.9'), qty=Decimal('0.020')), PublicTradeModel(id=2071597187661303813, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232610, price=Decimal('1562.6'), qty=Decimal('0.031')), PublicTradeModel(id=2071597187661303814, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232610, price=Decimal('1562.5'), qty=Decimal('0.062')), PublicTradeModel(id=2071597187661303815, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232610, price=Decimal('1562.4'), qty=Decimal('0.109')), PublicTradeModel(id=2071597187661303816, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232610, price=Decimal('1562.3'), qty=Decimal('5.753')), PublicTradeModel(id=2071597188055568388, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232704, price=Decimal('1562.3'), qty=Decimal('0.642')), PublicTradeModel(id=2071597188055568389, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232704, price=Decimal('1562.3'), qty=Decimal('0.835')), PublicTradeModel(id=2071597188143648779, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742232725, price=Decimal('1562.3'), qty=Decimal('0.569')), PublicTradeModel(id=2071597189829758979, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742233127, price=Decimal('1562.1'), qty=Decimal('0.020')), PublicTradeModel(id=2071597251637022721, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742247863, price=Decimal('1561.6'), qty=Decimal('0.065')), PublicTradeModel(id=2071597251637022722, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742247863, price=Decimal('1561.6'), qty=Decimal('0.318')), PublicTradeModel(id=2071597263217496068, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742250624, price=Decimal('1561.5'), qty=Decimal('0.035')), PublicTradeModel(id=2071597304892100614, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742260560, price=Decimal('1561.4'), qty=Decimal('0.043')), PublicTradeModel(id=2071597304892100615, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742260560, price=Decimal('1561.3'), qty=Decimal('0.031')), PublicTradeModel(id=2071597304892100616, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742260560, price=Decimal('1561.3'), qty=Decimal('0.286')), PublicTradeModel(id=2071597304892100617, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742260560, price=Decimal('1561.3'), qty=Decimal('0.019')), PublicTradeModel(id=2071597304892100618, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742260560, price=Decimal('1561.3'), qty=Decimal('0.023')), PublicTradeModel(id=2071597304892100619, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742260560, price=Decimal('1561.1'), qty=Decimal('0.037')), PublicTradeModel(id=2071597310063677450, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742261793, price=Decimal('1560.9'), qty=Decimal('0.109')), PublicTradeModel(id=2071597325045731328, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742265365, price=Decimal('1560.5'), qty=Decimal('0.190')), PublicTradeModel(id=2071597332993937414, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267260, price=Decimal('1560.2'), qty=Decimal('0.031')), PublicTradeModel(id=2071597332993937415, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267260, price=Decimal('1560.2'), qty=Decimal('0.046')), PublicTradeModel(id=2071597332993937416, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267260, price=Decimal('1560.2'), qty=Decimal('0.112')), PublicTradeModel(id=2071597333065240579, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267277, price=Decimal('1560.2'), qty=Decimal('0.208')), PublicTradeModel(id=2071597333128155138, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267292, price=Decimal('1560.1'), qty=Decimal('0.031')), PublicTradeModel(id=2071597333128155139, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267292, price=Decimal('1560.1'), qty=Decimal('0.010')), PublicTradeModel(id=2071597333128155140, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267292, price=Decimal('1560.1'), qty=Decimal('0.019')), PublicTradeModel(id=2071597333128155141, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742267292, price=Decimal('1560.0'), qty=Decimal('0.129')), PublicTradeModel(id=2071597370948194309, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742276309, price=Decimal('1559.7'), qty=Decimal('0.103')), PublicTradeModel(id=2071597421279842308, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742288309, price=Decimal('1559.6'), qty=Decimal('0.021')), PublicTradeModel(id=2071597421749604357, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742288421, price=Decimal('1559.5'), qty=Decimal('0.019')), PublicTradeModel(id=2071597421749604358, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742288421, price=Decimal('1559.4'), qty=Decimal('0.109')), PublicTradeModel(id=2071597464556670976, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742298627, price=Decimal('1559.7'), qty=Decimal('0.010')), PublicTradeModel(id=2071597464720248854, market='ETH-USD', side='BUY', trade_type='TRADE', timestamp=1782742298666, price=Decimal('1559.8'), qty=Decimal('0.052')), PublicTradeModel(id=2071597505887342596, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742308481, price=Decimal('1560.4'), qty=Decimal('0.103')), PublicTradeModel(id=2071597515777511425, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742310839, price=Decimal('1559.7'), qty=Decimal('0.018')), PublicTradeModel(id=2071597515777511426, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742310839, price=Decimal('1559.7'), qty=Decimal('0.026')), PublicTradeModel(id=2071597683948130321, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742350934, price=Decimal('1559.5'), qty=Decimal('0.052')), PublicTradeModel(id=2071597705901117448, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742356168, price=Decimal('1559.6'), qty=Decimal('0.052')), PublicTradeModel(id=2071597706798698499, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742356382, price=Decimal('1559.2'), qty=Decimal('0.319')), PublicTradeModel(id=2071597706811281411, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742356385, price=Decimal('1559.1'), qty=Decimal('0.022')), PublicTradeModel(id=2071597706928721920, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742356413, price=Decimal('1558.9'), qty=Decimal('0.031')), PublicTradeModel(id=2071597706928721921, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742356413, price=Decimal('1558.9'), qty=Decimal('0.043')), PublicTradeModel(id=2071597706928721922, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742356413, price=Decimal('1558.9'), qty=Decimal('0.010')), PublicTradeModel(id=2071597710581960705, market='ETH-USD', side='SELL', trade_type='TRADE', timestamp=1782742357284, price=Decimal('1558.8'), qty=Decimal('0.010'))] error=None ts=1782742364355 seq=1 subscription='trades.ETH-USD'
[2026-06-29 18:12:44,017 95806 8293851712 DEBUG] Subscribed to prices.index.ETH-USD
[2026-06-29 18:12:44,277 95806 8293851712 DEBUG] Subscribed to candles.index.ETH-USD.PT1M
[2026-06-29 18:12:44,347 95806 8293851712 INFO] Received message: type='TRADES' data=[PublicTradeModel(id=2071597742576111618, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364912, price=Decimal('59019'), qty=Decimal('0.00144')), PublicTradeModel(id=2071597742576111619, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364912, price=Decimal('59019'), qty=Decimal('0.00021')), PublicTradeModel(id=2071597742576111620, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364912, price=Decimal('59019'), qty=Decimal('0.00029'))] error=None ts=1782742364944 seq=2 subscription='trades.BTC-USD'
[2026-06-29 18:12:44,406 95806 8293851712 INFO] Received message: type='TRADES' data=[PublicTradeModel(id=2071597742760660992, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59018'), qty=Decimal('0.00147')), PublicTradeModel(id=2071597742760660993, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59018'), qty=Decimal('0.00022')), PublicTradeModel(id=2071597742760660994, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59018'), qty=Decimal('0.00157')), PublicTradeModel(id=2071597742760660995, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59018'), qty=Decimal('0.00040')), PublicTradeModel(id=2071597742760660996, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59018'), qty=Decimal('0.00046')), PublicTradeModel(id=2071597742760660997, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59018'), qty=Decimal('0.68302')), PublicTradeModel(id=2071597742760660998, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59017'), qty=Decimal('0.00097')), PublicTradeModel(id=2071597742760660999, market='BTC-USD', side='SELL', trade_type='TRADE', timestamp=1782742364956, price=Decimal('59016'), qty=Decimal('0.00028'))] error=None ts=1782742364985 seq=3 subscription='trades.BTC-USD'
[2026-06-29 18:12:44,541 95806 8293851712 INFO] Active subscriptions: ['candles.index.ETH-USD.PT1M', 'prices.index.ETH-USD', 'trades.BTC-USD', 'trades.ETH-USD']
[2026-06-29 18:12:45,219 95806 8293851712 INFO] Received message: type='PRICES.IP' data=StreamRpcPriceModel(market='ETH-USD', price=Decimal('1559.2378438'), ts=1782742365000) error=None ts=1782742365814 seq=4 subscription='prices.index.ETH-USD'
[2026-06-29 18:12:45,229 95806 8293851712 INFO] Received message: type='CANDLES' data=[CandleModel(open=Decimal('1559.973309537499'), low=Decimal('1559.2378438'), high=Decimal('1560.7152834'), close=Decimal('1559.2378438'), volume=None, timestamp=1782742320000)] error=None ts=1782742365823 seq=5 subscription='candles.index.ETH-USD.PT1M'
[2026-06-29 18:12:46,152 95806 8293851712 INFO] Signal received, stopping...
[2026-06-29 18:12:46,302 95806 8293851712 INFO] Received message: type='PRICES.IP' data=StreamRpcPriceModel(market='ETH-USD', price=Decimal('1559.16297355'), ts=1782742366000) error=None ts=1782742366897 seq=6 subscription='prices.index.ETH-USD'
[2026-06-29 18:12:46,304 95806 8293851712 INFO] Received message: type='CANDLES' data=[CandleModel(open=Decimal('1559.973309537499'), low=Decimal('1559.16297355'), high=Decimal('1560.7152834'), close=Decimal('1559.16297355'), volume=None, timestamp=1782742320000)] error=None ts=1782742366901 seq=7 subscription='candles.index.ETH-USD.PT1M'
[2026-06-29 18:12:46,422 95806 8293851712 DEBUG] Connection loop exited

@alexex10 alexex10 marked this pull request as ready for review June 29, 2026 14:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces an initial WebSocket JSON-RPC (“stream RPC”) client to the SDK, along with typed models, subscription parameter helpers, tests, and an example showing how to subscribe to public topics.

Changes:

  • Added StreamRpcClient + dispatcher to manage RPC requests, subscriptions, and reconnections over WebSockets.
  • Added Stream RPC response/account/update models and new deposit/withdrawal status update models.
  • Updated configuration to include a stream_rpc_url, plus tests and an example script for RPC stream subscriptions.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
x10/models/withdrawal.py Adds withdrawal status enum + status update model for stream/RPC updates.
x10/models/stream_rpc.py Introduces Stream RPC envelope + typed models for prices/orderbooks/account updates.
x10/models/deposit.py Adds deposit status enum + status update model for stream/RPC updates.
x10/errors.py Adds Stream RPC-specific error types (server/connection/timeout/parse).
x10/core/client_config.py Extends endpoints config with stream_rpc_url.
x10/config.py Populates stream_rpc_url for sepolia/mainnet configs.
x10/clients/streamrpc/subscription_params.py Adds topic parameter objects (trades/orderbooks/funding/prices/candles/account).
x10/clients/streamrpc/streamrpc_dispatcher.py Adds message dispatching for RPC responses vs stream frames + handler routing.
x10/clients/streamrpc/streamrpc_client.py Implements the WebSocket RPC client, reconnection loop, subscribe/unsubscribe, RPC calls.
x10/clients/streamrpc/init.py Stream RPC client package initializer.
tests/fixtures/market.py Adjusts market fixture booleans (isRfq, isOffHours).
tests/fixtures/candle.py Adds a Stream RPC candle message fixture.
tests/clients/test_streamrpc_client.py Adds an integration-style test using a mock WebSocket server.
tests/clients/test_rest_api_client.py Updates expected market response booleans.
examples/utils.py Adds a helper to create a StreamRpcClient from config.
examples/cases/stream/subscribe_to_rpc_stream.py Adds an example that subscribes to several RPC stream topics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread x10/models/stream_rpc.py
Comment thread x10/models/stream_rpc.py
Comment thread x10/clients/streamrpc/streamrpc_dispatcher.py
Comment thread x10/clients/streamrpc/streamrpc_dispatcher.py Outdated
Comment thread x10/clients/streamrpc/streamrpc_client.py
Comment thread x10/clients/streamrpc/subscription_params.py Outdated
ex10ded
ex10ded previously approved these changes Jun 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 7 comments.

Comment thread x10/models/stream_rpc.py Outdated
Comment thread x10/clients/streamrpc/streamrpc_client.py
Comment thread x10/clients/streamrpc/streamrpc_client.py
Comment thread x10/clients/streamrpc/streamrpc_client.py
Comment thread x10/clients/streamrpc/streamrpc_dispatcher.py Outdated
Comment thread x10/clients/streamrpc/streamrpc_dispatcher.py Outdated
Comment thread x10/clients/streamrpc/subscription_params.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.

Comment thread x10/clients/streamrpc/streamrpc_client.py
Comment thread x10/clients/streamrpc/streamrpc_client.py Outdated
Comment thread tests/fixtures/candle.py
Comment thread tests/clients/test_streamrpc_client.py Outdated
Comment thread x10/clients/streamrpc/streamrpc_client.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants