bybit_rust_api/rest/crypto_loan/
crypto_loan_client.rs1use crate::rest::client::{RestClient, SecType, ServerResponse};
2use anyhow::Result;
3use serde_json::json;
4
5pub struct CryptoLoanClient {
6 client: RestClient,
7}
8
9impl CryptoLoanClient {
10 pub fn new(client: RestClient) -> Self {
11 CryptoLoanClient { client }
12 }
13
14 pub async fn get_collateral_data(
17 &self,
18 ltv_type: Option<&str>,
19 ) -> Result<ServerResponse<serde_json::Value>> {
20 let endpoint = "v5/crypto-loan/collateral-data";
21 let mut params = json!({});
22
23 if let Some(ltv_type) = ltv_type {
24 params["ltvType"] = json!(ltv_type);
25 }
26
27 let response = self.client.get(endpoint, params, SecType::Signed).await?;
28 Ok(response)
29 }
30
31 pub async fn borrow(
34 &self,
35 ltv_type: &str,
36 loan_currency: &str,
37 loan_amount: &str,
38 collateral_currency: &str,
39 max_rate: Option<&str>,
40 ) -> Result<ServerResponse<serde_json::Value>> {
41 let endpoint = "v5/crypto-loan/borrow";
42 let mut body = json!({
43 "ltvType": ltv_type,
44 "loanCurrency": loan_currency,
45 "loanAmount": loan_amount,
46 "collateralCurrency": collateral_currency,
47 });
48
49 if let Some(max_rate) = max_rate {
50 body["maxRate"] = json!(max_rate);
51 }
52
53 let response = self.client.post(endpoint, body, SecType::Signed).await?;
54 Ok(response)
55 }
56
57 pub async fn repay(
60 &self,
61 order_id: &str,
62 repay_amount: Option<&str>,
63 ) -> Result<ServerResponse<serde_json::Value>> {
64 let endpoint = "v5/crypto-loan/repay";
65 let mut body = json!({
66 "orderId": order_id,
67 });
68
69 if let Some(repay_amount) = repay_amount {
70 body["repayAmount"] = json!(repay_amount);
71 }
72
73 let response = self.client.post(endpoint, body, SecType::Signed).await?;
74 Ok(response)
75 }
76
77 pub async fn get_ongoing_orders(
80 &self,
81 order_id: Option<&str>,
82 loan_currency: Option<&str>,
83 collateral_currency: Option<&str>,
84 limit: Option<i32>,
85 cursor: Option<&str>,
86 ) -> Result<ServerResponse<serde_json::Value>> {
87 let endpoint = "v5/crypto-loan/ongoing-orders";
88 let mut params = json!({});
89
90 if let Some(order_id) = order_id {
91 params["orderId"] = json!(order_id);
92 }
93 if let Some(loan_currency) = loan_currency {
94 params["loanCurrency"] = json!(loan_currency);
95 }
96 if let Some(collateral_currency) = collateral_currency {
97 params["collateralCurrency"] = json!(collateral_currency);
98 }
99 if let Some(limit) = limit {
100 params["limit"] = json!(limit);
101 }
102 if let Some(cursor) = cursor {
103 params["cursor"] = json!(cursor);
104 }
105
106 let response = self.client.get(endpoint, params, SecType::Signed).await?;
107 Ok(response)
108 }
109
110 pub async fn get_borrow_history(
113 &self,
114 order_id: Option<&str>,
115 loan_currency: Option<&str>,
116 collateral_currency: Option<&str>,
117 start_time: Option<i64>,
118 end_time: Option<i64>,
119 limit: Option<i32>,
120 cursor: Option<&str>,
121 ) -> Result<ServerResponse<serde_json::Value>> {
122 let endpoint = "v5/crypto-loan/borrow-history";
123 let mut params = json!({});
124
125 if let Some(order_id) = order_id {
126 params["orderId"] = json!(order_id);
127 }
128 if let Some(loan_currency) = loan_currency {
129 params["loanCurrency"] = json!(loan_currency);
130 }
131 if let Some(collateral_currency) = collateral_currency {
132 params["collateralCurrency"] = json!(collateral_currency);
133 }
134 if let Some(start_time) = start_time {
135 params["startTime"] = json!(start_time);
136 }
137 if let Some(end_time) = end_time {
138 params["endTime"] = json!(end_time);
139 }
140 if let Some(limit) = limit {
141 params["limit"] = json!(limit);
142 }
143 if let Some(cursor) = cursor {
144 params["cursor"] = json!(cursor);
145 }
146
147 let response = self.client.get(endpoint, params, SecType::Signed).await?;
148 Ok(response)
149 }
150
151 pub async fn get_max_collateral_amount(
154 &self,
155 ltv_type: &str,
156 loan_currency: &str,
157 loan_amount: &str,
158 collateral_currency: &str,
159 ) -> Result<ServerResponse<serde_json::Value>> {
160 let endpoint = "v5/crypto-loan/max-collateral-amount";
161 let params = json!({
162 "ltvType": ltv_type,
163 "loanCurrency": loan_currency,
164 "loanAmount": loan_amount,
165 "collateralCurrency": collateral_currency,
166 });
167
168 let response = self.client.get(endpoint, params, SecType::Signed).await?;
169 Ok(response)
170 }
171
172 pub async fn adjust_ltv(
175 &self,
176 order_id: &str,
177 amount: &str,
178 direction: i32, ) -> Result<ServerResponse<serde_json::Value>> {
180 let endpoint = "v5/crypto-loan/adjust-ltv";
181 let body = json!({
182 "orderId": order_id,
183 "amount": amount,
184 "direction": direction,
185 });
186
187 let response = self.client.post(endpoint, body, SecType::Signed).await?;
188 Ok(response)
189 }
190
191 pub async fn get_adjustment_history(
194 &self,
195 order_id: Option<&str>,
196 adjustment_id: Option<&str>,
197 start_time: Option<i64>,
198 end_time: Option<i64>,
199 limit: Option<i32>,
200 cursor: Option<&str>,
201 ) -> Result<ServerResponse<serde_json::Value>> {
202 let endpoint = "v5/crypto-loan/adjustment-history";
203 let mut params = json!({});
204
205 if let Some(order_id) = order_id {
206 params["orderId"] = json!(order_id);
207 }
208 if let Some(adjustment_id) = adjustment_id {
209 params["adjustmentId"] = json!(adjustment_id);
210 }
211 if let Some(start_time) = start_time {
212 params["startTime"] = json!(start_time);
213 }
214 if let Some(end_time) = end_time {
215 params["endTime"] = json!(end_time);
216 }
217 if let Some(limit) = limit {
218 params["limit"] = json!(limit);
219 }
220 if let Some(cursor) = cursor {
221 params["cursor"] = json!(cursor);
222 }
223
224 let response = self.client.get(endpoint, params, SecType::Signed).await?;
225 Ok(response)
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::*;
232 use crate::rest::ApiKeyPair;
233
234 fn create_test_client() -> CryptoLoanClient {
235 let api_key_pair = ApiKeyPair::new(
236 "test_key".to_string(),
237 "test_secret".to_string(),
238 "".to_string(),
239 );
240 let rest_client = RestClient::new(
241 api_key_pair,
242 "https://api-testnet.bybit.com".to_string(),
243 false,
244 );
245 CryptoLoanClient::new(rest_client)
246 }
247
248 #[test]
249 fn test_client_creation() {
250 let client = create_test_client();
251 assert_eq!(
253 std::mem::size_of_val(&client),
254 std::mem::size_of::<CryptoLoanClient>()
255 );
256 }
257
258 #[tokio::test]
259 async fn test_borrow_required_params() {
260 let client = create_test_client();
261 let result = client
262 .borrow("1", "USDT", "1000.0", "BTC", Some("0.05"))
263 .await;
264 assert!(result.is_err() || result.is_ok());
266 }
267
268 #[tokio::test]
269 async fn test_repay_required_params() {
270 let client = create_test_client();
271 let result = client.repay("order_123", Some("500.0")).await;
272 assert!(result.is_err() || result.is_ok());
274 }
275
276 #[tokio::test]
277 async fn test_adjust_ltv_required_params() {
278 let client = create_test_client();
279 let result = client
280 .adjust_ltv(
281 "order_123",
282 "100.0",
283 1, )
285 .await;
286 assert!(result.is_err() || result.is_ok());
288 }
289}