bybit_rust_api/rest/spot_leverage_token/
spot_leverage_token_client.rs

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