mexc_rust_sdk/
account.rs

1use crate::{Mexc, PROD_API_URL};
2use reqwest::{StatusCode, Response};
3use anyhow::{anyhow, bail};
4use serde::Deserialize;
5use crate::utils::get_timestamp;
6
7use crate::utils::parse_string_to_f64;
8
9#[derive(Deserialize, Debug, Clone)]
10pub struct Account {
11    #[serde(rename = "accountType")]
12    pub account_type: String,
13    #[serde(rename = "canDeposit")]
14    pub can_deposit: bool,
15    #[serde(rename = "canTrade")]
16    pub can_trade: bool,
17    #[serde(rename = "canWithdraw")]
18    pub can_withdraw: bool,
19    pub permissions: Vec<String>,
20    pub balances: Vec<AccountBalance>
21}
22
23#[derive(Deserialize, Debug, Clone)]
24pub struct AccountBalance {
25    pub asset: String,
26    #[serde(deserialize_with = "parse_string_to_f64")]
27    pub free: f64,
28    #[serde(deserialize_with = "parse_string_to_f64")]
29    pub locked: f64
30}
31
32#[derive(Deserialize, Debug, Clone)]
33pub struct ListenKeyReponse {
34    #[serde(rename = "listenKey")]
35    pub listen_key: String
36}
37
38impl Mexc {
39
40    pub async fn get_signed(&self, url: &str) -> anyhow::Result<Response> {
41        let api_key = self.api_key.as_ref().ok_or_else(|| anyhow!("Missing api key"))?;
42
43        let resp = self.client
44        .get(url)
45        .header("X-MEXC-APIKEY", api_key)
46        .send().await?;
47        Ok(resp)
48    }
49
50    pub async fn get_account(&self) -> anyhow::Result<Account> {
51
52        let timestamp = get_timestamp();
53
54        let order_request = format!("timestamp={timestamp}");
55        let signed_order = self.sign_request(order_request)?;
56        let url = format!("{PROD_API_URL}/api/v3/account?{signed_order}");
57        let resp: Response = self.get_signed(&url).await?;
58
59        if resp.status() == StatusCode::OK {
60            let account: Account = resp.json().await?;
61            Ok(account)
62        } else {
63            let err = resp.text().await?;
64            bail!(err);
65        }
66    }
67
68    pub async fn get_listen_key(&self) -> anyhow::Result<String> {
69
70        let timestamp = get_timestamp();
71        let order_request = format!("timestamp={timestamp}");
72        let signed_order = self.sign_request(order_request)?;
73
74        let url = format!("{PROD_API_URL}/api/v3/userDataStream?{signed_order}");
75        let resp: Response = self.post_signed(&url).await?;
76
77        let keyresp: ListenKeyReponse = resp.json().await?;
78        Ok(keyresp.listen_key)
79    }
80
81    pub async fn keep_alive_listen_key(&self, listen_key: &str) -> anyhow::Result<String> {
82
83        let timestamp = get_timestamp();
84        let order_request = format!("listenKey={listen_key}&timestamp={timestamp}");
85        let signed_order = self.sign_request(order_request)?;
86
87        let url = format!("{PROD_API_URL}/api/v3/userDataStream?{signed_order}");
88        let resp: Response = self.put_signed(&url).await?;
89
90        let keyresp: ListenKeyReponse = resp.json().await?;
91        Ok(keyresp.listen_key)
92    }
93
94    pub async fn delete_listen_key(&self, listen_key: &str) -> anyhow::Result<String> {
95
96        let timestamp = get_timestamp();
97        let order_request = format!("listenKey={listen_key}&timestamp={timestamp}");
98        let signed_order = self.sign_request(order_request)?;
99
100        let url = format!("{PROD_API_URL}/api/v3/userDataStream?{signed_order}");
101        let resp: Response = self.delete_signed(&url).await?;
102
103        let keyresp: ListenKeyReponse = resp.json().await?;
104        Ok(keyresp.listen_key)
105    }
106}
107
108
109#[cfg(test)]
110mod tests {
111
112    use super::*;
113    use crate::utils::unlock_keys;
114
115    #[tokio::test]
116    pub async fn test_get_account() {
117        let (key, secret) = unlock_keys().unwrap();
118        let client = Mexc::new(Some(key),Some(secret),None).unwrap();
119
120        let acc = client.get_account().await.unwrap();
121        dbg!(acc);
122    }
123
124    #[tokio::test]
125    pub async fn test_get_listenkey() {
126        let (key, secret) = unlock_keys().unwrap();
127        let client = Mexc::new(Some(key),Some(secret),None).unwrap();
128
129        let key = client.get_listen_key().await.unwrap();
130        dbg!(key);
131    }
132
133    #[tokio::test]
134    pub async fn test_keep_alive() {
135        let (key, secret) = unlock_keys().unwrap();
136        let client = Mexc::new(Some(key),Some(secret),None).unwrap();
137
138        let listen_key = "enter key here";
139
140        let key = client.keep_alive_listen_key(&listen_key).await.unwrap();
141        dbg!(key);
142    }
143
144    #[tokio::test]
145    pub async fn test_delete_listen_key() {
146        let (key, secret) = unlock_keys().unwrap();
147        let client = Mexc::new(Some(key),Some(secret),None).unwrap();
148
149        let listen_key = "enter key here";
150
151        let key = client.delete_listen_key(&listen_key).await.unwrap();
152        dbg!(key);
153    }
154}