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