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 l2_book(coin: &str) -> Self {
39 Self {
40 request_type: "l2Book".to_string(),
41 params: serde_json::json!({ "coin": coin }),
42 }
43 }
44
45 pub fn user_fills(user: &str) -> Self {
47 Self {
48 request_type: "userFills".to_string(),
49 params: serde_json::json!({ "user": user }),
50 }
51 }
52
53 pub fn order_status(user: &str, oid: u64) -> Self {
55 Self {
56 request_type: "orderStatus".to_string(),
57 params: serde_json::json!({ "user": user, "oid": oid }),
58 }
59 }
60}
61
62#[derive(Debug, Clone, Serialize)]
64pub struct ExchangeAction {
65 #[serde(rename = "type")]
66 pub action_type: String,
67 #[serde(flatten)]
68 pub params: Value,
69}
70
71impl ExchangeAction {
72 pub fn order(orders: Value) -> Self {
74 Self {
75 action_type: "order".to_string(),
76 params: serde_json::json!({ "orders": orders }),
77 }
78 }
79
80 pub fn cancel(cancels: Value) -> Self {
82 Self {
83 action_type: "cancel".to_string(),
84 params: serde_json::json!({ "cancels": cancels }),
85 }
86 }
87
88 pub fn cancel_by_cloid(cancels: Value) -> Self {
90 Self {
91 action_type: "cancelByCloid".to_string(),
92 params: serde_json::json!({ "cancels": cancels }),
93 }
94 }
95
96 pub fn modify(oid: u64, order: Value) -> Self {
98 Self {
99 action_type: "modify".to_string(),
100 params: serde_json::json!({ "oid": oid, "order": order }),
101 }
102 }
103
104 pub fn update_leverage(asset: u32, is_cross: bool, leverage: u32) -> Self {
106 Self {
107 action_type: "updateLeverage".to_string(),
108 params: serde_json::json!({
109 "asset": asset,
110 "isCross": is_cross,
111 "leverage": leverage
112 }),
113 }
114 }
115
116 pub fn update_isolated_margin(asset: u32, is_buy: bool, ntli: i64) -> Self {
118 Self {
119 action_type: "updateIsolatedMargin".to_string(),
120 params: serde_json::json!({
121 "asset": asset,
122 "isBuy": is_buy,
123 "ntli": ntli
124 }),
125 }
126 }
127}
128
129#[cfg(test)]
134mod tests {
135 use rstest::rstest;
136
137 use super::*;
138
139 #[rstest]
140 fn test_info_request_meta() {
141 let req = InfoRequest::meta();
142
143 assert_eq!(req.request_type, "meta");
144 assert_eq!(req.params, Value::Null);
145 }
146
147 #[rstest]
148 fn test_info_request_l2_book() {
149 let req = InfoRequest::l2_book("BTC");
150
151 assert_eq!(req.request_type, "l2Book");
152 let json = serde_json::to_string(&req).unwrap();
153 assert!(json.contains("\"coin\":\"BTC\""));
154 }
155
156 #[rstest]
157 fn test_exchange_action_order() {
158 let orders =
159 serde_json::json!([{"asset": 0, "isBuy": true, "sz": "1.0", "limitPx": "50000"}]);
160
161 let action = ExchangeAction::order(orders);
162
163 assert_eq!(action.action_type, "order");
164 let json = serde_json::to_string(&action).unwrap();
165 assert!(json.contains("\"orders\""));
166 }
167
168 #[rstest]
169 fn test_exchange_action_cancel() {
170 let cancels = serde_json::json!([{"asset": 0, "oid": 123}]);
171
172 let action = ExchangeAction::cancel(cancels);
173
174 assert_eq!(action.action_type, "cancel");
175 }
176}