asterdex_sdk/futures/endpoints/
mmp.rs1use crate::futures::models::account::{MmpResponse, MmpUpdateParams};
4use crate::rest::client::RestClient;
5use crate::rest::error::AsterDexError;
6use crate::rest::response::ApiResponse;
7
8impl RestClient {
9 pub async fn get_mmp(
18 &self,
19 symbol: Option<&str>,
20 ) -> Result<ApiResponse<Vec<MmpResponse>>, AsterDexError> {
21 let mut params = vec![];
22 if let Some(s) = symbol {
23 params.push(("symbol", s));
24 }
25 self.signed_get("/fapi/v3/mmp", ¶ms).await
26 }
27
28 pub async fn update_mmp(
35 &self,
36 params: MmpUpdateParams,
37 ) -> Result<ApiResponse<bool>, AsterDexError> {
38 let window_str = params.window_time_ms.to_string();
39 let frozen_str = params.frozen_time_ms.to_string();
40 let mut pairs: Vec<(&str, &str)> = vec![
41 ("symbol", params.symbol.as_str()),
42 ("windowTimeInMilliseconds", &window_str),
43 ("frozenTimeInMilliseconds", &frozen_str),
44 ];
45 let qty_str;
47 let value_str;
48 let delta_str;
49 if let Some(q) = params.qty_limit {
50 qty_str = q.to_string();
51 pairs.push(("qtyLimit", &qty_str));
52 }
53 if let Some(v) = params.value_limit {
54 value_str = v.to_string();
55 pairs.push(("valueLimit", &value_str));
56 }
57 if let Some(d) = params.delta_limit {
58 delta_str = d.to_string();
59 pairs.push(("deltaLimit", &delta_str));
60 }
61 self.signed_post("/fapi/v3/mmp", &pairs).await
62 }
63
64 pub async fn delete_mmp(
71 &self,
72 symbol: &str,
73 ) -> Result<ApiResponse<bool>, AsterDexError> {
74 self.signed_delete("/fapi/v3/mmp", &[("symbol", symbol)])
75 .await
76 }
77
78 pub async fn reset_mmp(
85 &self,
86 symbol: &str,
87 ) -> Result<ApiResponse<bool>, AsterDexError> {
88 self.signed_post("/fapi/v3/mmpReset", &[("symbol", symbol)])
89 .await
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[tokio::test]
99 async fn get_mmp_without_credentials_returns_config_error() {
100 let server = mockito::Server::new_async().await;
101 let client = RestClient::new_public(&server.url()).unwrap();
102 let result = client.get_mmp(Some("BTCUSDT")).await;
103 assert!(
104 matches!(result, Err(AsterDexError::ConfigError { .. })),
105 "expected ConfigError, got: {:?}",
106 result
107 );
108 drop(server);
109 }
110
111 #[tokio::test]
113 async fn get_mmp_mock() {
114 let mut server = mockito::Server::new_async().await;
115 let _mock = server
116 .mock("GET", "/fapi/v3/mmp")
117 .match_query(mockito::Matcher::Any)
118 .with_status(200)
119 .with_header("content-type", "application/json")
120 .with_body(r#"[{"symbol":"BTCUSDT","windowTimeInMilliseconds":5000,"frozenTimeInMilliseconds":10000,"qtyLimit":10,"valueLimit":200000000,"deltaLimit":100000000}]"#)
121 .create_async()
122 .await;
123 let creds = crate::auth::Credentials::new(
124 "0x0000000000000000000000000000000000000001",
125 "0x0000000000000000000000000000000000000002",
126 "0000000000000000000000000000000000000000000000000000000000000001",
127 714,
128 ).unwrap();
129 let client = RestClient::new(&server.url(), creds).unwrap();
130 let resp = client.get_mmp(Some("BTCUSDT")).await.unwrap();
131 assert_eq!(resp.data[0].symbol, "BTCUSDT");
132 assert_eq!(resp.data[0].window_time_ms, 5000);
133 assert_eq!(resp.data[0].qty_limit, Some(10));
134 }
135
136 #[tokio::test]
138 async fn update_mmp_without_credentials_returns_config_error() {
139 let server = mockito::Server::new_async().await;
140 let client = RestClient::new_public(&server.url()).unwrap();
141 let params = MmpUpdateParams {
142 symbol: "BTCUSDT".to_string(),
143 window_time_ms: 5000,
144 frozen_time_ms: 3000,
145 qty_limit: Some(100),
146 value_limit: None,
147 delta_limit: Some(50),
148 };
149 let result = client.update_mmp(params).await;
150 assert!(
151 matches!(result, Err(AsterDexError::ConfigError { .. })),
152 "expected ConfigError, got: {:?}",
153 result
154 );
155 drop(server);
156 }
157}