hypercall/client/wallet_client/
orders.rs1use super::WalletClient;
2use hypercall_types::Side;
3use sonic_rs::{json, Value};
4
5impl WalletClient {
6 pub async fn place_order(
7 &self,
8 base_url: &str,
9 symbol: &str,
10 side: Side,
11 price: f64,
12 size: f64,
13 ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
14 let nonce = self.next_nonce();
16 let side_str = format!("{:?}", side);
17 let price_str = price.to_string();
18 let size_str = size.to_string();
19 let client_id = format!("cli_{}", nonce);
20
21 let signature = self
22 .sign_place_order(
23 symbol, &side_str, &size_str, &price_str, "gtc", &client_id, nonce,
24 )
25 .await?;
26
27 let response = self
28 .http_client
29 .post(format!("{}/order", base_url))
30 .json(&json!({
31 "wallet": self.wallet_address,
32 "symbol": symbol,
33 "side": side_str,
34 "price": price_str,
35 "size": size_str,
36 "tif": "gtc",
37 "client_id": client_id,
38 "nonce": nonce,
39 "signature": signature,
40 }))
41 .send()
42 .await?;
43
44 let status = response.status();
45 let body = response.text().await?;
46
47 if !status.is_success() {
48 return Err(format!("Failed to place order: {} - {}", status, body).into());
49 }
50
51 Ok(sonic_rs::from_str(&body)?)
52 }
53
54 pub async fn cancel_order(
55 &self,
56 base_url: &str,
57 order_id: u64,
58 ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
59 let nonce = self.next_nonce();
61 let order_id_str = order_id.to_string();
62
63 let signature = self.sign_cancel_order(&order_id_str, nonce).await?;
64
65 let response = self
66 .http_client
67 .delete(format!("{}/order", base_url))
68 .json(&json!({
69 "wallet": self.wallet_address,
70 "order_id": order_id, "nonce": nonce,
72 "signature": signature,
73 }))
74 .send()
75 .await?;
76
77 let status = response.status();
78 let body = response.text().await?;
79
80 if !status.is_success() {
81 return Err(format!("Failed to cancel order: {} - {}", status, body).into());
82 }
83
84 Ok(sonic_rs::from_str(&body)?)
85 }
86
87 pub async fn bulk_place_orders(
89 &self,
90 base_url: &str,
91 orders: Vec<(String, Side, f64, f64)>, ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
93 let mut order_requests = Vec::with_capacity(orders.len());
94 for (symbol, side, price, size) in orders {
95 let nonce = self.next_nonce();
96 let side_str = format!("{:?}", side);
97 let price_str = price.to_string();
98 let size_str = size.to_string();
99 let client_id = format!("cli_{}", nonce);
100
101 let signature = self
102 .sign_place_order(
103 &symbol, &side_str, &size_str, &price_str, "gtc", &client_id, nonce,
104 )
105 .await?;
106
107 order_requests.push(json!({
108 "wallet": self.wallet_address,
109 "symbol": symbol,
110 "side": side_str,
111 "price": price_str,
112 "size": size_str,
113 "tif": "gtc",
114 "client_id": client_id,
115 "nonce": nonce,
116 "signature": signature,
117 }));
118 }
119
120 let response = self
121 .http_client
122 .post(format!("{}/bulk_order", base_url))
123 .json(&json!({
124 "orders": order_requests
125 }))
126 .send()
127 .await?;
128
129 let status = response.status();
130 let body = response.text().await?;
131
132 if !status.is_success() {
133 return Err(format!("Failed to place bulk orders: {} - {}", status, body).into());
134 }
135
136 Ok(sonic_rs::from_str(&body)?)
137 }
138
139 pub async fn bulk_place_orders_with_builder(
141 &self,
142 base_url: &str,
143 orders: Vec<(String, Side, f64, f64)>, builder_code_address: Option<&str>,
145 ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
146 let mut order_requests = Vec::with_capacity(orders.len());
147 for (symbol, side, price, size) in orders {
148 let nonce = self.next_nonce();
149 let side_str = format!("{:?}", side);
150 let price_str = price.to_string();
151 let size_str = size.to_string();
152 let client_id = format!("cli_{}", nonce);
153
154 let signature = self
155 .sign_place_order(
156 &symbol, &side_str, &size_str, &price_str, "gtc", &client_id, nonce,
157 )
158 .await?;
159
160 let mut order_json = json!({
161 "wallet": self.wallet_address,
162 "symbol": symbol,
163 "side": side_str,
164 "price": price_str,
165 "size": size_str,
166 "tif": "gtc",
167 "client_id": client_id,
168 "nonce": nonce,
169 "signature": signature,
170 });
171
172 if let Some(builder) = builder_code_address {
174 order_json["builder_code_address"] = json!(builder);
175 }
176
177 order_requests.push(order_json);
178 }
179
180 let response = self
181 .http_client
182 .post(format!("{}/bulk_order", base_url))
183 .json(&json!({
184 "orders": order_requests
185 }))
186 .send()
187 .await?;
188
189 let status = response.status();
190 let body = response.text().await?;
191
192 if !status.is_success() {
193 return Err(format!("Failed to place bulk orders: {} - {}", status, body).into());
194 }
195
196 Ok(sonic_rs::from_str(&body)?)
197 }
198
199 pub async fn bulk_cancel_orders(
201 &self,
202 base_url: &str,
203 order_ids: Vec<u64>,
204 ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
205 let mut cancel_requests = Vec::with_capacity(order_ids.len());
206 for order_id in order_ids {
207 let nonce = self.next_nonce();
208 let order_id_str = order_id.to_string();
209
210 let signature = self.sign_cancel_order(&order_id_str, nonce).await?;
211
212 cancel_requests.push(json!({
213 "wallet": self.wallet_address,
214 "order_id": order_id,
215 "nonce": nonce,
216 "signature": signature,
217 }));
218 }
219
220 let response = self
221 .http_client
222 .delete(format!("{}/bulk_order", base_url))
223 .json(&json!({
224 "cancels": cancel_requests
225 }))
226 .send()
227 .await?;
228
229 let status = response.status();
230 let body = response.text().await?;
231
232 if !status.is_success() {
233 return Err(format!("Failed to cancel bulk orders: {} - {}", status, body).into());
234 }
235
236 Ok(sonic_rs::from_str(&body)?)
237 }
238
239 pub async fn place_order_raw(
242 &self,
243 base_url: &str,
244 symbol: &str,
245 side: Side,
246 price: f64,
247 size: f64,
248 ) -> Result<reqwest::Response, Box<dyn std::error::Error + Send + Sync>> {
249 let nonce = self.next_nonce();
250 let side_str = format!("{:?}", side);
251 let price_str = price.to_string();
252 let size_str = size.to_string();
253 let client_id = format!("cli_{}", nonce);
254
255 let signature = self
256 .sign_place_order(
257 symbol, &side_str, &size_str, &price_str, "gtc", &client_id, nonce,
258 )
259 .await?;
260
261 let response = self
262 .http_client
263 .post(format!("{}/order", base_url))
264 .json(&json!({
265 "wallet": self.wallet_address,
266 "symbol": symbol,
267 "side": side_str,
268 "price": price_str,
269 "size": size_str,
270 "tif": "gtc",
271 "client_id": client_id,
272 "nonce": nonce,
273 "signature": signature,
274 }))
275 .send()
276 .await?;
277
278 Ok(response)
279 }
280
281 pub async fn cancel_order_raw(
284 &self,
285 base_url: &str,
286 order_id: u64,
287 ) -> Result<reqwest::Response, Box<dyn std::error::Error + Send + Sync>> {
288 let nonce = self.next_nonce();
289 let order_id_str = order_id.to_string();
290
291 let signature = self.sign_cancel_order(&order_id_str, nonce).await?;
292
293 let response = self
294 .http_client
295 .delete(format!("{}/order", base_url))
296 .json(&json!({
297 "wallet": self.wallet_address,
298 "order_id": order_id,
299 "nonce": nonce,
300 "signature": signature,
301 }))
302 .send()
303 .await?;
304
305 Ok(response)
306 }
307}