bybit_rust_api/rest/spot_leverage_token/
spot_leverage_token_client.rs

1use crate::rest::client::{RestClient, SecType, ServerResponse};
2use crate::rest::BybitResult as Result;
3use serde_json::json;
4
5#[derive(Clone)]
6pub struct SpotLeverageTokenClient {
7    client: RestClient,
8}
9
10impl SpotLeverageTokenClient {
11    pub fn new(client: RestClient) -> Self {
12        SpotLeverageTokenClient { client }
13    }
14
15    /// Get leverage token info
16    /// https://bybit-exchange.github.io/docs/v5/lt/leverage-token-info
17    pub async fn get_leverage_token_info(
18        &self,
19        lt_coin: Option<&str>,
20    ) -> Result<ServerResponse<serde_json::Value>> {
21        let endpoint = "v5/spot-lever-token/info";
22        let mut params = json!({});
23
24        if let Some(lt_coin) = lt_coin {
25            params["ltCoin"] = json!(lt_coin);
26        }
27
28        let response = self.client.get(endpoint, params, SecType::None).await?;
29        Ok(response)
30    }
31
32    /// Get leverage token market
33    /// https://bybit-exchange.github.io/docs/v5/lt/leverage-token-reference
34    pub async fn get_leverage_token_reference(
35        &self,
36        lt_coin: &str,
37    ) -> Result<ServerResponse<serde_json::Value>> {
38        let endpoint = "v5/spot-lever-token/reference";
39        let params = json!({
40            "ltCoin": lt_coin,
41        });
42
43        let response = self.client.get(endpoint, params, SecType::None).await?;
44        Ok(response)
45    }
46
47    /// Purchase leverage token
48    /// https://bybit-exchange.github.io/docs/v5/lt/purchase
49    pub async fn purchase(
50        &self,
51        lt_coin: &str,
52        lt_amount: &str,
53        serial_no: Option<&str>,
54    ) -> Result<ServerResponse<serde_json::Value>> {
55        let endpoint = "v5/spot-lever-token/purchase";
56        let mut body = json!({
57            "ltCoin": lt_coin,
58            "ltAmount": lt_amount,
59        });
60
61        if let Some(serial_no) = serial_no {
62            body["serialNo"] = json!(serial_no);
63        }
64
65        let response = self.client.post(endpoint, body, SecType::Signed).await?;
66        Ok(response)
67    }
68
69    /// Redeem leverage token
70    /// https://bybit-exchange.github.io/docs/v5/lt/redeem
71    pub async fn redeem(
72        &self,
73        lt_coin: &str,
74        lt_amount: &str,
75        serial_no: Option<&str>,
76    ) -> Result<ServerResponse<serde_json::Value>> {
77        let endpoint = "v5/spot-lever-token/redeem";
78        let mut body = json!({
79            "ltCoin": lt_coin,
80            "ltAmount": lt_amount,
81        });
82
83        if let Some(serial_no) = serial_no {
84            body["serialNo"] = json!(serial_no);
85        }
86
87        let response = self.client.post(endpoint, body, SecType::Signed).await?;
88        Ok(response)
89    }
90
91    /// Get purchase/redemption records
92    /// https://bybit-exchange.github.io/docs/v5/lt/order-record
93    pub async fn get_order_record(
94        &self,
95        lt_coin: Option<&str>,
96        order_id: Option<&str>,
97        start_time: Option<i64>,
98        end_time: Option<i64>,
99        limit: Option<i32>,
100        lt_order_type: Option<i32>, // 1: purchase, 2: redemption
101        serial_no: Option<&str>,
102    ) -> Result<ServerResponse<serde_json::Value>> {
103        let endpoint = "v5/spot-lever-token/order-record";
104        let mut params = json!({});
105
106        if let Some(lt_coin) = lt_coin {
107            params["ltCoin"] = json!(lt_coin);
108        }
109        if let Some(order_id) = order_id {
110            params["orderId"] = json!(order_id);
111        }
112        if let Some(start_time) = start_time {
113            params["startTime"] = json!(start_time);
114        }
115        if let Some(end_time) = end_time {
116            params["endTime"] = json!(end_time);
117        }
118        if let Some(limit) = limit {
119            params["limit"] = json!(limit);
120        }
121        if let Some(lt_order_type) = lt_order_type {
122            params["ltOrderType"] = json!(lt_order_type);
123        }
124        if let Some(serial_no) = serial_no {
125            params["serialNo"] = json!(serial_no);
126        }
127
128        let response = self.client.get(endpoint, params, SecType::Signed).await?;
129        Ok(response)
130    }
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136    use crate::rest::ApiKeyPair;
137
138    fn create_test_client() -> SpotLeverageTokenClient {
139        let api_key_pair = ApiKeyPair::new(
140            "test_key".to_string(),
141            "test_secret".to_string(),
142            "".to_string(),
143        );
144        let rest_client =
145            RestClient::new(api_key_pair, "https://api-testnet.bybit.com".to_string());
146        SpotLeverageTokenClient::new(rest_client)
147    }
148
149    #[test]
150    fn test_client_creation() {
151        let client = create_test_client();
152        // Test that client was created successfully
153        assert_eq!(
154            std::mem::size_of_val(&client),
155            std::mem::size_of::<SpotLeverageTokenClient>()
156        );
157    }
158
159    #[tokio::test]
160    async fn test_purchase_required_params() {
161        let client = create_test_client();
162        let result = client.purchase("BTC3LUSDT", "100.0", None).await;
163        // Should not panic with valid required parameters
164        assert!(result.is_err() || result.is_ok());
165    }
166
167    #[tokio::test]
168    async fn test_redeem_required_params() {
169        let client = create_test_client();
170        let result = client
171            .redeem("BTC3LUSDT", "50.0", Some("test_serial_123"))
172            .await;
173        // Should not panic with valid required parameters
174        assert!(result.is_err() || result.is_ok());
175    }
176
177    #[tokio::test]
178    async fn test_get_leverage_token_reference_required_params() {
179        let client = create_test_client();
180        let result = client.get_leverage_token_reference("BTC3LUSDT").await;
181        // Should not panic with valid required lt_coin parameter
182        assert!(result.is_err() || result.is_ok());
183    }
184}