rust_okx/api/finance/api.rs
1use crate::client::OkxClient;
2use crate::error::Error;
3use crate::model::EmptyRequest;
4use crate::transport::Transport;
5
6use super::endpoints::*;
7use super::requests::*;
8use super::responses::*;
9/// Accessor for OKX finance endpoint groups.
10///
11/// Obtain one via [`OkxClient::finance`](crate::OkxClient::finance).
12pub struct Finance<'a, T> {
13 client: &'a OkxClient<T>,
14}
15
16impl<'a, T: Transport> Finance<'a, T> {
17 pub(crate) fn new(client: &'a OkxClient<T>) -> Self {
18 Self { client }
19 }
20
21 /// Access Savings endpoints.
22 pub fn savings(&self) -> Savings<'_, T> {
23 Savings {
24 client: self.client,
25 }
26 }
27
28 /// Access Staking/DeFi endpoints.
29 pub fn staking_defi(&self) -> StakingDefi<'_, T> {
30 StakingDefi {
31 client: self.client,
32 }
33 }
34
35 /// Access ETH staking endpoints.
36 pub fn eth_staking(&self) -> EthStaking<'_, T> {
37 EthStaking {
38 client: self.client,
39 }
40 }
41
42 /// Access SOL staking endpoints.
43 pub fn sol_staking(&self) -> SolStaking<'_, T> {
44 SolStaking {
45 client: self.client,
46 }
47 }
48
49 /// Access Flexible Loan endpoints.
50 pub fn flexible_loan(&self) -> FlexibleLoan<'_, T> {
51 FlexibleLoan {
52 client: self.client,
53 }
54 }
55}
56
57/// Accessor for Savings endpoints.
58pub struct Savings<'a, T> {
59 client: &'a OkxClient<T>,
60}
61
62impl<T: Transport> Savings<'_, T> {
63 /// Retrieve savings balances.
64 ///
65 /// `GET /api/v5/finance/savings/balance`. Authenticated.
66 ///
67 /// # Errors
68 ///
69 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero
70 /// OKX code, or transport/decode errors.
71 pub async fn get_saving_balance(
72 &self,
73 request: &CurrencyRequest<'_>,
74 ) -> Result<Vec<SavingBalance>, Error> {
75 self.client.get(SAVINGS_BALANCE, request, true).await
76 }
77
78 /// Purchase or redeem savings.
79 ///
80 /// `POST /api/v5/finance/savings/purchase-redempt`. Authenticated.
81 ///
82 /// # Errors
83 ///
84 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero
85 /// OKX code, or transport/decode errors.
86 pub async fn purchase_redemption(
87 &self,
88 request: &SavingsPurchaseRedemptionRequest,
89 ) -> Result<Vec<SavingsPurchaseRedemptionResult>, Error> {
90 self.client
91 .post(SAVINGS_PURCHASE_REDEMPT, request, true)
92 .await
93 }
94
95 /// Set the savings lending rate.
96 ///
97 /// `POST /api/v5/finance/savings/set-lending-rate`. Authenticated.
98 ///
99 /// # Errors
100 ///
101 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero
102 /// OKX code, or transport/decode errors.
103 pub async fn set_lending_rate(
104 &self,
105 request: &SetLendingRateRequest<'_>,
106 ) -> Result<Vec<SetLendingRateResult>, Error> {
107 self.client
108 .post(SAVINGS_SET_LENDING_RATE, request, true)
109 .await
110 }
111
112 /// Retrieve lending history.
113 ///
114 /// `GET /api/v5/finance/savings/lending-history`. Authenticated.
115 ///
116 /// # Errors
117 ///
118 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero
119 /// OKX code, or transport/decode errors.
120 pub async fn get_lending_history(
121 &self,
122 request: &FinanceHistoryRequest,
123 ) -> Result<Vec<LendingHistory>, Error> {
124 self.client
125 .get(SAVINGS_LENDING_HISTORY, request, true)
126 .await
127 }
128
129 /// Retrieve public borrow history.
130 ///
131 /// `GET /api/v5/finance/savings/lending-rate-history`. Public.
132 ///
133 /// # Errors
134 ///
135 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
136 pub async fn get_public_borrow_history(
137 &self,
138 request: &FinanceHistoryRequest,
139 ) -> Result<Vec<PublicBorrowHistory>, Error> {
140 self.client
141 .get(SAVINGS_PUBLIC_BORROW_HISTORY, request, false)
142 .await
143 }
144
145 /// Retrieve public borrow info.
146 ///
147 /// `GET /api/v5/finance/savings/lending-rate-summary`. Public.
148 ///
149 /// # Errors
150 ///
151 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
152 pub async fn get_public_borrow_info(
153 &self,
154 request: &CurrencyRequest<'_>,
155 ) -> Result<Vec<PublicBorrowInfo>, Error> {
156 self.client
157 .get(SAVINGS_PUBLIC_BORROW_INFO, request, false)
158 .await
159 }
160}
161
162/// Accessor for Staking/DeFi endpoints.
163pub struct StakingDefi<'a, T> {
164 client: &'a OkxClient<T>,
165}
166
167impl<T: Transport> StakingDefi<'_, T> {
168 /// Retrieve Staking/DeFi offers.
169 ///
170 /// `GET /api/v5/finance/staking-defi/offers`. Authenticated.
171 ///
172 /// # Errors
173 ///
174 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
175 pub async fn get_offers(
176 &self,
177 request: &StakingDefiOffersRequest,
178 ) -> Result<Vec<StakingDefiOffer>, Error> {
179 self.client.get(STAKING_DEFI_OFFERS, request, true).await
180 }
181
182 /// Purchase a Staking/DeFi product.
183 ///
184 /// `POST /api/v5/finance/staking-defi/purchase`. Authenticated.
185 ///
186 /// # Errors
187 ///
188 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
189 pub async fn purchase(
190 &self,
191 request: &StakingDefiPurchaseRequest,
192 ) -> Result<Vec<StakingDefiOrder>, Error> {
193 self.client.post(STAKING_DEFI_PURCHASE, request, true).await
194 }
195
196 /// Redeem a Staking/DeFi order.
197 ///
198 /// `POST /api/v5/finance/staking-defi/redeem`. Authenticated.
199 ///
200 /// # Errors
201 ///
202 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
203 pub async fn redeem(
204 &self,
205 request: &StakingDefiRedeemRequest,
206 ) -> Result<Vec<StakingDefiOrder>, Error> {
207 self.client.post(STAKING_DEFI_REDEEM, request, true).await
208 }
209
210 /// Cancel a Staking/DeFi order.
211 ///
212 /// `POST /api/v5/finance/staking-defi/cancel`. Authenticated.
213 ///
214 /// # Errors
215 ///
216 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
217 pub async fn cancel(
218 &self,
219 request: &StakingDefiCancelRequest,
220 ) -> Result<Vec<StakingDefiOrder>, Error> {
221 self.client.post(STAKING_DEFI_CANCEL, request, true).await
222 }
223
224 /// Retrieve active Staking/DeFi orders.
225 ///
226 /// `GET /api/v5/finance/staking-defi/orders-active`. Authenticated.
227 ///
228 /// # Errors
229 ///
230 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
231 pub async fn get_active_orders(
232 &self,
233 request: &StakingDefiActiveOrdersRequest,
234 ) -> Result<Vec<StakingDefiOrder>, Error> {
235 self.client
236 .get(STAKING_DEFI_ACTIVE_ORDERS, request, true)
237 .await
238 }
239
240 /// Retrieve Staking/DeFi order history.
241 ///
242 /// `GET /api/v5/finance/staking-defi/orders-history`. Authenticated.
243 ///
244 /// # Errors
245 ///
246 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
247 pub async fn get_orders_history(
248 &self,
249 request: &StakingDefiOrderHistoryRequest,
250 ) -> Result<Vec<StakingDefiOrder>, Error> {
251 self.client
252 .get(STAKING_DEFI_ORDERS_HISTORY, request, true)
253 .await
254 }
255}
256
257/// Accessor for ETH staking endpoints.
258pub struct EthStaking<'a, T> {
259 client: &'a OkxClient<T>,
260}
261
262impl<T: Transport> EthStaking<'_, T> {
263 /// Retrieve ETH staking product info.
264 ///
265 /// `GET /api/v5/finance/staking-defi/eth/product-info`. Authenticated.
266 ///
267 /// # Errors
268 ///
269 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
270 pub async fn product_info(&self) -> Result<Vec<StakingProductInfo>, Error> {
271 self.client
272 .get(ETH_PRODUCT_INFO, &EmptyRequest {}, true)
273 .await
274 }
275
276 /// Purchase ETH staking.
277 ///
278 /// `POST /api/v5/finance/staking-defi/eth/purchase`. Authenticated.
279 ///
280 /// # Errors
281 ///
282 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
283 pub async fn purchase(&self, request: &AmountRequest<'_>) -> Result<Vec<StakingOrder>, Error> {
284 self.client.post(ETH_PURCHASE, request, true).await
285 }
286
287 /// Redeem ETH staking.
288 ///
289 /// `POST /api/v5/finance/staking-defi/eth/redeem`. Authenticated.
290 ///
291 /// # Errors
292 ///
293 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
294 pub async fn redeem(&self, request: &AmountRequest<'_>) -> Result<Vec<StakingOrder>, Error> {
295 self.client.post(ETH_REDEEM, request, true).await
296 }
297
298 /// Cancel redeem ETH staking.
299 ///
300 /// `POST /api/v5/finance/staking-defi/eth/cancel-redeem`. Authenticated.
301 ///
302 /// # Errors
303 ///
304 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
305 pub async fn cancel_redeem(
306 &self,
307 request: &CancelRedeemRequest<'_>,
308 ) -> Result<Vec<CancelRedeem>, Error> {
309 self.client.post(ETH_CANCEL_REDEEM, request, true).await
310 }
311
312 /// Retrieve ETH staking balance.
313 ///
314 /// `GET /api/v5/finance/staking-defi/eth/balance`. Authenticated.
315 ///
316 /// # Errors
317 ///
318 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
319 pub async fn balance(&self) -> Result<Vec<StakingBalance>, Error> {
320 self.client.get(ETH_BALANCE, &EmptyRequest {}, true).await
321 }
322
323 /// Retrieve ETH staking purchase/redeem history.
324 ///
325 /// `GET /api/v5/finance/staking-defi/eth/purchase-redeem-history`. Authenticated.
326 ///
327 /// # Errors
328 ///
329 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
330 pub async fn purchase_redeem_history(
331 &self,
332 request: &FinanceHistoryRequest,
333 ) -> Result<Vec<StakingHistory>, Error> {
334 self.client.get(ETH_HISTORY, request, true).await
335 }
336
337 /// Retrieve ETH staking APY history.
338 ///
339 /// `GET /api/v5/finance/staking-defi/eth/apy-history`. Public.
340 ///
341 /// # Errors
342 ///
343 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
344 pub async fn apy_history(
345 &self,
346 request: &ApyHistoryRequest<'_>,
347 ) -> Result<Vec<StakingApyHistory>, Error> {
348 self.client.get(ETH_APY_HISTORY, request, false).await
349 }
350}
351
352/// Accessor for SOL staking endpoints.
353pub struct SolStaking<'a, T> {
354 client: &'a OkxClient<T>,
355}
356
357impl<T: Transport> SolStaking<'_, T> {
358 /// Retrieve SOL staking product info.
359 ///
360 /// `GET /api/v5/finance/staking-defi/sol/product-info`. Authenticated.
361 ///
362 /// # Errors
363 ///
364 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
365 pub async fn product_info(&self) -> Result<StakingProductInfo, Error> {
366 self.client
367 .get(SOL_PRODUCT_INFO, &EmptyRequest {}, true)
368 .await
369 }
370
371 /// Purchase SOL staking.
372 ///
373 /// `POST /api/v5/finance/staking-defi/sol/purchase`. Authenticated.
374 ///
375 /// # Errors
376 ///
377 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
378 pub async fn purchase(&self, request: &AmountRequest<'_>) -> Result<Vec<StakingOrder>, Error> {
379 self.client.post(SOL_PURCHASE, request, true).await
380 }
381
382 /// Redeem SOL staking.
383 ///
384 /// `POST /api/v5/finance/staking-defi/sol/redeem`. Authenticated.
385 ///
386 /// # Errors
387 ///
388 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
389 pub async fn redeem(&self, request: &AmountRequest<'_>) -> Result<Vec<StakingOrder>, Error> {
390 self.client.post(SOL_REDEEM, request, true).await
391 }
392
393 /// Retrieve SOL staking balance.
394 ///
395 /// `GET /api/v5/finance/staking-defi/sol/balance`. Authenticated.
396 ///
397 /// # Errors
398 ///
399 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
400 pub async fn balance(&self) -> Result<Vec<StakingBalance>, Error> {
401 self.client.get(SOL_BALANCE, &EmptyRequest {}, true).await
402 }
403
404 /// Retrieve SOL staking purchase/redeem history.
405 ///
406 /// `GET /api/v5/finance/staking-defi/sol/purchase-redeem-history`. Authenticated.
407 ///
408 /// # Errors
409 ///
410 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
411 pub async fn purchase_redeem_history(
412 &self,
413 request: &FinanceHistoryRequest,
414 ) -> Result<Vec<StakingHistory>, Error> {
415 self.client.get(SOL_HISTORY, request, true).await
416 }
417
418 /// Retrieve SOL staking APY history.
419 ///
420 /// `GET /api/v5/finance/staking-defi/sol/apy-history`. Public.
421 ///
422 /// # Errors
423 ///
424 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
425 pub async fn apy_history(
426 &self,
427 request: &ApyHistoryRequest<'_>,
428 ) -> Result<Vec<StakingApyHistory>, Error> {
429 self.client.get(SOL_APY_HISTORY, request, false).await
430 }
431}
432
433/// Accessor for Flexible Loan endpoints.
434pub struct FlexibleLoan<'a, T> {
435 client: &'a OkxClient<T>,
436}
437
438impl<T: Transport> FlexibleLoan<'_, T> {
439 /// Retrieve borrowable currencies.
440 ///
441 /// `GET /api/v5/finance/flexible-loan/borrow-currencies`. Authenticated.
442 ///
443 /// # Errors
444 ///
445 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
446 pub async fn borrow_currencies(&self) -> Result<Vec<FlexibleLoanCurrency>, Error> {
447 self.client
448 .get(FLEX_BORROW_CURRENCIES, &EmptyRequest {}, true)
449 .await
450 }
451
452 /// Retrieve collateral assets.
453 ///
454 /// `GET /api/v5/finance/flexible-loan/collateral-assets`. Public.
455 ///
456 /// # Errors
457 ///
458 /// Returns [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
459 pub async fn collateral_assets(
460 &self,
461 request: &FlexibleLoanCollateralAssetsRequest,
462 ) -> Result<Vec<FlexibleLoanCollateralAsset>, Error> {
463 self.client
464 .get(FLEX_COLLATERAL_ASSETS, request, false)
465 .await
466 }
467
468 /// Estimate maximum flexible-loan amount.
469 ///
470 /// `POST /api/v5/finance/flexible-loan/max-loan`. Authenticated.
471 ///
472 /// # Errors
473 ///
474 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
475 pub async fn max_loan(
476 &self,
477 request: &FlexibleLoanMaxLoanRequest,
478 ) -> Result<Vec<FlexibleLoanMaxLoan>, Error> {
479 self.client.post(FLEX_MAX_LOAN, request, true).await
480 }
481
482 /// Retrieve maximum collateral redeem amount.
483 ///
484 /// `GET /api/v5/finance/flexible-loan/max-collateral-redeem-amount`. Authenticated.
485 ///
486 /// # Errors
487 ///
488 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
489 pub async fn max_collateral_redeem_amount(
490 &self,
491 request: &FlexibleLoanMaxRedeemRequest,
492 ) -> Result<Vec<FlexibleLoanMaxRedeem>, Error> {
493 self.client.get(FLEX_MAX_REDEEM, request, true).await
494 }
495
496 /// Adjust flexible-loan collateral.
497 ///
498 /// `POST /api/v5/finance/flexible-loan/adjust-collateral`. Authenticated.
499 ///
500 /// # Errors
501 ///
502 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
503 pub async fn adjust_collateral(
504 &self,
505 request: &FlexibleLoanAdjustCollateralRequest,
506 ) -> Result<Vec<FlexibleLoanOrder>, Error> {
507 self.client
508 .post(FLEX_ADJUST_COLLATERAL, request, true)
509 .await
510 }
511
512 /// Retrieve flexible-loan info.
513 ///
514 /// `GET /api/v5/finance/flexible-loan/loan-info`. Authenticated.
515 ///
516 /// # Errors
517 ///
518 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
519 pub async fn loan_info(
520 &self,
521 request: &FlexibleLoanInfoRequest,
522 ) -> Result<Vec<FlexibleLoanInfo>, Error> {
523 self.client.get(FLEX_LOAN_INFO, request, true).await
524 }
525
526 /// Retrieve flexible-loan history.
527 ///
528 /// `GET /api/v5/finance/flexible-loan/loan-history`. Authenticated.
529 ///
530 /// # Errors
531 ///
532 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
533 pub async fn loan_history(
534 &self,
535 request: &FlexibleLoanHistoryRequest,
536 ) -> Result<Vec<FlexibleLoanHistory>, Error> {
537 self.client.get(FLEX_LOAN_HISTORY, request, true).await
538 }
539
540 /// Retrieve flexible-loan accrued interest.
541 ///
542 /// `GET /api/v5/finance/flexible-loan/interest-accrued`. Authenticated.
543 ///
544 /// # Errors
545 ///
546 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
547 pub async fn interest_accrued(
548 &self,
549 request: &FlexibleLoanInterestAccruedRequest,
550 ) -> Result<Vec<FlexibleLoanInterest>, Error> {
551 self.client.get(FLEX_INTEREST_ACCRUED, request, true).await
552 }
553}