nautilus_hyperliquid/http/
query.rs1use serde::Serialize;
17use serde_json::Value;
18
19#[derive(Debug, Clone, Serialize)]
21pub struct InfoRequest {
22 #[serde(rename = "type")]
23 pub request_type: String,
24 #[serde(flatten)]
25 pub params: Value,
26}
27
28impl InfoRequest {
29 pub fn meta() -> Self {
31 Self {
32 request_type: "meta".to_string(),
33 params: Value::Null,
34 }
35 }
36
37 pub fn spot_meta() -> Self {
39 Self {
40 request_type: "spotMeta".to_string(),
41 params: Value::Null,
42 }
43 }
44
45 pub fn meta_and_asset_ctxs() -> Self {
47 Self {
48 request_type: "metaAndAssetCtxs".to_string(),
49 params: Value::Null,
50 }
51 }
52
53 pub fn spot_meta_and_asset_ctxs() -> Self {
55 Self {
56 request_type: "spotMetaAndAssetCtxs".to_string(),
57 params: Value::Null,
58 }
59 }
60
61 pub fn l2_book(coin: &str) -> Self {
63 Self {
64 request_type: "l2Book".to_string(),
65 params: serde_json::json!({ "coin": coin }),
66 }
67 }
68
69 pub fn user_fills(user: &str) -> Self {
71 Self {
72 request_type: "userFills".to_string(),
73 params: serde_json::json!({ "user": user }),
74 }
75 }
76
77 pub fn order_status(user: &str, oid: u64) -> Self {
79 Self {
80 request_type: "orderStatus".to_string(),
81 params: serde_json::json!({ "user": user, "oid": oid }),
82 }
83 }
84
85 pub fn open_orders(user: &str) -> Self {
87 Self {
88 request_type: "openOrders".to_string(),
89 params: serde_json::json!({ "user": user }),
90 }
91 }
92
93 pub fn frontend_open_orders(user: &str) -> Self {
95 Self {
96 request_type: "frontendOpenOrders".to_string(),
97 params: serde_json::json!({ "user": user }),
98 }
99 }
100
101 pub fn clearinghouse_state(user: &str) -> Self {
103 Self {
104 request_type: "clearinghouseState".to_string(),
105 params: serde_json::json!({ "user": user }),
106 }
107 }
108
109 pub fn candle_snapshot(coin: &str, interval: &str, start_time: u64, end_time: u64) -> Self {
117 Self {
118 request_type: "candleSnapshot".to_string(),
119 params: serde_json::json!({
120 "req": {
121 "coin": coin,
122 "interval": interval,
123 "startTime": start_time,
124 "endTime": end_time
125 }
126 }),
127 }
128 }
129}
130
131#[derive(Debug, Clone, Serialize)]
133pub struct ExchangeAction {
134 #[serde(rename = "type")]
135 pub action_type: String,
136 #[serde(flatten)]
137 pub params: Value,
138}
139
140impl ExchangeAction {
141 pub fn order(orders: Value) -> Self {
143 Self {
144 action_type: "order".to_string(),
145 params: serde_json::json!({ "orders": orders }),
146 }
147 }
148
149 pub fn cancel(cancels: Value) -> Self {
151 Self {
152 action_type: "cancel".to_string(),
153 params: serde_json::json!({ "cancels": cancels }),
154 }
155 }
156
157 pub fn cancel_by_cloid(cancels: Value) -> Self {
159 Self {
160 action_type: "cancelByCloid".to_string(),
161 params: serde_json::json!({ "cancels": cancels }),
162 }
163 }
164
165 pub fn modify(oid: u64, order: Value) -> Self {
167 Self {
168 action_type: "modify".to_string(),
169 params: serde_json::json!({ "oid": oid, "order": order }),
170 }
171 }
172
173 pub fn update_leverage(asset: u32, is_cross: bool, leverage: u32) -> Self {
175 Self {
176 action_type: "updateLeverage".to_string(),
177 params: serde_json::json!({
178 "asset": asset,
179 "isCross": is_cross,
180 "leverage": leverage
181 }),
182 }
183 }
184
185 pub fn update_isolated_margin(asset: u32, is_buy: bool, ntli: i64) -> Self {
187 Self {
188 action_type: "updateIsolatedMargin".to_string(),
189 params: serde_json::json!({
190 "asset": asset,
191 "isBuy": is_buy,
192 "ntli": ntli
193 }),
194 }
195 }
196}
197
198#[cfg(test)]
203mod tests {
204 use rstest::rstest;
205
206 use super::*;
207
208 #[rstest]
209 fn test_info_request_meta() {
210 let req = InfoRequest::meta();
211
212 assert_eq!(req.request_type, "meta");
213 assert_eq!(req.params, Value::Null);
214 }
215
216 #[rstest]
217 fn test_info_request_l2_book() {
218 let req = InfoRequest::l2_book("BTC");
219
220 assert_eq!(req.request_type, "l2Book");
221 let json = serde_json::to_string(&req).unwrap();
222 assert!(json.contains("\"coin\":\"BTC\""));
223 }
224
225 #[rstest]
226 fn test_exchange_action_order() {
227 let orders =
228 serde_json::json!([{"asset": 0, "isBuy": true, "sz": "1.0", "limitPx": "50000"}]);
229
230 let action = ExchangeAction::order(orders);
231
232 assert_eq!(action.action_type, "order");
233 let json = serde_json::to_string(&action).unwrap();
234 assert!(json.contains("\"orders\""));
235 }
236
237 #[rstest]
238 fn test_exchange_action_cancel() {
239 let cancels = serde_json::json!([{"asset": 0, "oid": 123}]);
240
241 let action = ExchangeAction::cancel(cancels);
242
243 assert_eq!(action.action_type, "cancel");
244 }
245}