asterdex_sdk/futures/endpoints/
batch.rs1use crate::futures::models::account::{BatchOrderResult, CancelAllResponse};
4use crate::futures::models::trading::PlaceOrderParams;
5use crate::rest::client::RestClient;
6use crate::rest::error::AsterDexError;
7use crate::rest::response::ApiResponse;
8
9const BATCH_ORDER_MAX: usize = 5;
10
11impl RestClient {
12 pub async fn place_batch_orders(
15 &self,
16 orders: Vec<PlaceOrderParams>,
17 ) -> Result<ApiResponse<Vec<BatchOrderResult>>, AsterDexError> {
18 if orders.len() > BATCH_ORDER_MAX {
19 return Err(AsterDexError::InvalidParams {
20 message: format!("Too many orders: max {BATCH_ORDER_MAX}, got {}", orders.len()),
21 });
22 }
23 self.signed_post_json("/fapi/v3/batchOrders", &[], &orders).await
25 }
26
27 pub async fn cancel_batch_orders(
29 &self,
30 symbol: &str,
31 order_ids: Vec<i64>,
32 ) -> Result<ApiResponse<Vec<BatchOrderResult>>, AsterDexError> {
33 let ids_json = serde_json::to_string(&order_ids).map_err(|e| AsterDexError::SerdeError {
34 message: e.to_string(),
35 })?;
36 self.signed_delete("/fapi/v3/batchOrders", &[
37 ("symbol", symbol),
38 ("orderIdList", &ids_json),
39 ]).await
40 }
41
42 pub async fn cancel_all_open_orders(
44 &self,
45 symbol: &str,
46 ) -> Result<ApiResponse<CancelAllResponse>, AsterDexError> {
47 self.signed_delete("/fapi/v3/allOpenOrders", &[("symbol", symbol)]).await
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::auth::Credentials;
55
56 #[tokio::test]
60 async fn place_batch_orders_too_many_returns_invalid_params() {
61 let client = RestClient::new_public("http://localhost:9999").unwrap();
62 let orders: Vec<PlaceOrderParams> = (0..6).map(|_| PlaceOrderParams::default()).collect();
63 let result = client.place_batch_orders(orders).await;
64 assert!(
65 matches!(result, Err(AsterDexError::InvalidParams { .. })),
66 "expected InvalidParams, got: {:?}",
67 result
68 );
69 }
70
71 #[tokio::test]
73 async fn cancel_all_open_orders_mock() {
74 let mut server = mockito::Server::new_async().await;
75 let _mock = server
76 .mock("DELETE", "/fapi/v3/allOpenOrders")
77 .match_query(mockito::Matcher::Any)
78 .with_status(200)
79 .with_header("content-type", "application/json")
80 .with_body(r#"{"code":200,"msg":"The operation of cancel orders is done."}"#)
81 .create_async()
82 .await;
83
84 let creds = Credentials::new(
85 "0x0000000000000000000000000000000000000001",
86 "0x0000000000000000000000000000000000000002",
87 "0000000000000000000000000000000000000000000000000000000000000001",
88 714,
89 )
90 .unwrap();
91 let client = RestClient::new(&server.url(), creds).unwrap();
92 let resp = client.cancel_all_open_orders("BTCUSDT").await.unwrap();
93 assert_eq!(resp.data.code, 200);
94 }
95}