Skip to content

Commit d822d01

Browse files
authored
Add WsBbo (#142)
1 parent f3e6e92 commit d822d01

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

examples/basic_ws.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def main():
1717
info.subscribe({"type": "userFundings", "user": address}, print)
1818
info.subscribe({"type": "userNonFundingLedgerUpdates", "user": address}, print)
1919
info.subscribe({"type": "webData2", "user": address}, print)
20+
info.subscribe({"type": "bbo", "coin": "ETH"}, print)
2021

2122

2223
if __name__ == "__main__":

hyperliquid/info.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,17 +598,24 @@ def query_sub_accounts(self, user: str) -> Any:
598598
def query_user_to_multi_sig_signers(self, multi_sig_user: str) -> Any:
599599
return self.post("/info", {"type": "userToMultiSigSigners", "user": multi_sig_user})
600600

601-
def subscribe(self, subscription: Subscription, callback: Callable[[Any], None]) -> int:
602-
if subscription["type"] == "l2Book" or subscription["type"] == "trades" or subscription["type"] == "candle":
601+
def _validate_subscription(self, subscription: Subscription) -> None:
602+
if (
603+
subscription["type"] == "l2Book"
604+
or subscription["type"] == "trades"
605+
or subscription["type"] == "candle"
606+
or subscription["type"] == "bbo"
607+
):
603608
subscription["coin"] = self.name_to_coin[subscription["coin"]]
609+
610+
def subscribe(self, subscription: Subscription, callback: Callable[[Any], None]) -> int:
611+
self._validate_subscription(subscription)
604612
if self.ws_manager is None:
605613
raise RuntimeError("Cannot call subscribe since skip_ws was used")
606614
else:
607615
return self.ws_manager.subscribe(subscription, callback)
608616

609617
def unsubscribe(self, subscription: Subscription, subscription_id: int) -> bool:
610-
if subscription["type"] == "l2Book" or subscription["type"] == "trades" or subscription["type"] == "candle":
611-
subscription["coin"] = self.name_to_coin[subscription["coin"]]
618+
self._validate_subscription(subscription)
612619
if self.ws_manager is None:
613620
raise RuntimeError("Cannot call unsubscribe since skip_ws was used")
614621
else:

hyperliquid/utils/types.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
SpotMetaAndAssetCtxs = Tuple[SpotMeta, List[SpotAssetCtx]]
3838

3939
AllMidsSubscription = TypedDict("AllMidsSubscription", {"type": Literal["allMids"]})
40+
BboSubscription = TypedDict("BboSubscription", {"type": Literal["bbo"], "coin": str})
4041
L2BookSubscription = TypedDict("L2BookSubscription", {"type": Literal["l2Book"], "coin": str})
4142
TradesSubscription = TypedDict("TradesSubscription", {"type": Literal["trades"], "coin": str})
4243
UserEventsSubscription = TypedDict("UserEventsSubscription", {"type": Literal["userEvents"], "user": str})
@@ -51,6 +52,7 @@
5152
# If adding new subscription types that contain coin's don't forget to handle automatically rewrite name to coin in info.subscribe
5253
Subscription = Union[
5354
AllMidsSubscription,
55+
BboSubscription,
5456
L2BookSubscription,
5557
TradesSubscription,
5658
UserEventsSubscription,
@@ -65,6 +67,8 @@
6567
AllMidsData = TypedDict("AllMidsData", {"mids": Dict[str, str]})
6668
AllMidsMsg = TypedDict("AllMidsMsg", {"channel": Literal["allMids"], "data": AllMidsData})
6769
L2Level = TypedDict("L2Level", {"px": str, "sz": str, "n": int})
70+
BboData = TypedDict("BboData", {"coin": str, "time": int, "bbo": Tuple[Optional[L2Level], Optional[L2Level]]})
71+
BboMsg = TypedDict("BboMsg", {"channel": Literal["bbo"], "data": BboData})
6872
L2BookData = TypedDict("L2BookData", {"coin": str, "levels": Tuple[List[L2Level], List[L2Level]], "time": int})
6973
L2BookMsg = TypedDict("L2BookMsg", {"channel": Literal["l2Book"], "data": L2BookData})
7074
PongMsg = TypedDict("PongMsg", {"channel": Literal["pong"]})
@@ -108,7 +112,7 @@
108112
},
109113
total=False,
110114
)
111-
WsMsg = Union[AllMidsMsg, L2BookMsg, TradesMsg, UserEventsMsg, PongMsg, UserFillsMsg, OtherWsMsg]
115+
WsMsg = Union[AllMidsMsg, BboMsg, L2BookMsg, TradesMsg, UserEventsMsg, PongMsg, UserFillsMsg, OtherWsMsg]
112116

113117
# b is the public address of the builder, f is the amount of the fee in tenths of basis points. e.g. 10 means 1 basis point
114118
BuilderInfo = TypedDict("BuilderInfo", {"b": str, "f": int})

hyperliquid/websocket_manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def subscription_to_identifier(subscription: Subscription) -> str:
3131
return f'userNonFundingLedgerUpdates:{subscription["user"].lower()}'
3232
elif subscription["type"] == "webData2":
3333
return f'webData2:{subscription["user"].lower()}'
34+
elif subscription["type"] == "bbo":
35+
return f'bbo:{subscription["coin"].lower()}'
3436

3537

3638
def ws_msg_to_identifier(ws_msg: WsMsg) -> Optional[str]:
@@ -60,6 +62,8 @@ def ws_msg_to_identifier(ws_msg: WsMsg) -> Optional[str]:
6062
return f'userNonFundingLedgerUpdates:{ws_msg["data"]["user"].lower()}'
6163
elif ws_msg["channel"] == "webData2":
6264
return f'webData2:{ws_msg["data"]["user"].lower()}'
65+
elif ws_msg["channel"] == "bbo":
66+
return f'bbo:{ws_msg["data"]["coin"].lower()}'
6367

6468

6569
class WebsocketManager(threading.Thread):

0 commit comments

Comments
 (0)