Skip to content

Commit 697910d

Browse files
authored
Add WsBbo (#111)
# Description Add Bbo subscription type. This is done in #100 but it looks like the commit started adding other changes. Keeping this PR simple # Test Plan ``` $ RUST_LOG=info cargo run --bin ws_bbo [2025-06-24T00:57:23Z INFO ws_bbo] Received bbo: Bbo { data: BboData { coin: "BTC", time: 1750726643319, bbo: [Some(BookLevel { px: "105206.0", sz: "0.52263", n: 3 }), Some(BookLevel { px: "105250.0", sz: "0.27132", n: 2 })] } } [2025-06-24T00:57:25Z INFO ws_bbo] Received bbo: Bbo { data: BboData { coin: "BTC", time: 1750726644739, bbo: [Some(BookLevel { px: "105206.0", sz: "0.52263", n: 3 }), Some(BookLevel { px: "105242.0", sz: "0.13319", n: 1 })] } } [2025-06-24T00:57:25Z INFO ws_bbo] Received bbo: Bbo { data: BboData { coin: "BTC", time: 1750726644944, bbo: [Some(BookLevel { px: "105206.0", sz: "0.25431", n: 2 }), Some(BookLevel { px: "105242.0", sz: "0.13319", n: 1 })] } } [2025-06-24T00:57:25Z INFO ws_bbo] Received bbo: Bbo { data: BboData { coin: "BTC", time: 1750726645146, bbo: [Some(BookLevel { px: "105206.0", sz: "0.0006", n: 1 }), Some(BookLevel { px: "105234.0", sz: "0.14562", n: 1 })] } } [2025-06-24T00:57:25Z INFO ws_bbo] Received bbo: Bbo { data: BboData { coin: "BTC", time: 1750726645348, bbo: [Some(BookLevel { px: "105206.0", sz: "0.0006", n: 1 }), Some(BookLevel { px: "105230.0", sz: "0.12148", n: 1 })] } } ```
1 parent 67ee7fc commit 697910d

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

src/bin/ws_bbo.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use hyperliquid_rust_sdk::{BaseUrl, InfoClient, Message, Subscription};
2+
use log::info;
3+
use tokio::{
4+
spawn,
5+
sync::mpsc::unbounded_channel,
6+
time::{sleep, Duration},
7+
};
8+
9+
#[tokio::main]
10+
async fn main() {
11+
env_logger::init();
12+
let mut info_client = InfoClient::new(None, Some(BaseUrl::Testnet)).await.unwrap();
13+
let coin = "BTC".to_string();
14+
15+
let (sender, mut receiver) = unbounded_channel();
16+
let subscription_id = info_client
17+
.subscribe(Subscription::Bbo { coin }, sender)
18+
.await
19+
.unwrap();
20+
21+
spawn(async move {
22+
sleep(Duration::from_secs(30)).await;
23+
info!("Unsubscribing from bbo");
24+
info_client.unsubscribe(subscription_id).await.unwrap()
25+
});
26+
27+
while let Some(Message::Bbo(bbo)) = receiver.recv().await {
28+
info!("Received bbo: {bbo:?}");
29+
}
30+
}

src/ws/message_types.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,8 @@ pub struct WebData2 {
6060
pub struct ActiveAssetCtx {
6161
pub data: ActiveAssetCtxData,
6262
}
63+
64+
#[derive(Deserialize, Clone, Debug)]
65+
pub struct Bbo {
66+
pub data: BboData,
67+
}

src/ws/sub_structs.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,11 @@ pub struct SpotAssetCtx {
322322
pub shared: SharedAssetCtx,
323323
pub circulating_supply: String,
324324
}
325+
326+
#[derive(Deserialize, Clone, Debug)]
327+
#[serde(rename_all = "camelCase")]
328+
pub struct BboData {
329+
pub coin: String,
330+
pub time: u64,
331+
pub bbo: Vec<Option<BookLevel>>,
332+
}

src/ws/ws_manager.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
prelude::*,
3-
ws::message_types::{AllMids, Candle, L2Book, OrderUpdates, Trades, User},
3+
ws::message_types::{AllMids, Bbo, Candle, L2Book, OrderUpdates, Trades, User},
44
ActiveAssetCtx, Error, Notification, UserFills, UserFundings, UserNonFundingLedgerUpdates,
55
WebData2,
66
};
@@ -62,6 +62,7 @@ pub enum Subscription {
6262
UserFundings { user: H160 },
6363
UserNonFundingLedgerUpdates { user: H160 },
6464
ActiveAssetCtx { coin: String },
65+
Bbo { coin: String },
6566
}
6667

6768
#[derive(Deserialize, Clone, Debug)]
@@ -83,6 +84,7 @@ pub enum Message {
8384
Notification(Notification),
8485
WebData2(WebData2),
8586
ActiveAssetCtx(ActiveAssetCtx),
87+
Bbo(Bbo),
8688
Pong,
8789
}
8890

@@ -267,6 +269,10 @@ impl WsManager {
267269
})
268270
.map_err(|e| Error::JsonParse(e.to_string()))
269271
}
272+
Message::Bbo(bbo) => serde_json::to_string(&Subscription::Bbo {
273+
coin: bbo.data.coin.clone(),
274+
})
275+
.map_err(|e| Error::JsonParse(e.to_string())),
270276
Message::SubscriptionResponse | Message::Pong => Ok(String::default()),
271277
Message::NoData => Ok("".to_string()),
272278
Message::HyperliquidError(err) => Ok(format!("hyperliquid error: {err:?}")),

0 commit comments

Comments
 (0)