1#![allow(unused_imports)]
15use async_trait::async_trait;
16use derive_builder::Builder;
17use reqwest;
18use rust_decimal::prelude::*;
19use serde::{Deserialize, Serialize};
20use serde_json::{Value, json};
21use std::collections::BTreeMap;
22
23use crate::common::{
24 config::ConfigurationRestApi,
25 models::{ParamBuildError, RestApiResponse},
26 utils::send_request,
27};
28use crate::simple_earn::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait RwusdApi: Send + Sync {
34 async fn get_rwusd_account(
35 &self,
36 params: GetRwusdAccountParams,
37 ) -> anyhow::Result<RestApiResponse<models::GetRwusdAccountResponse>>;
38 async fn get_rwusd_quota_details(
39 &self,
40 params: GetRwusdQuotaDetailsParams,
41 ) -> anyhow::Result<RestApiResponse<models::GetRwusdQuotaDetailsResponse>>;
42 async fn get_rwusd_rate_history(
43 &self,
44 params: GetRwusdRateHistoryParams,
45 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRateHistoryResponse>>;
46 async fn get_rwusd_redemption_history(
47 &self,
48 params: GetRwusdRedemptionHistoryParams,
49 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRedemptionHistoryResponse>>;
50 async fn get_rwusd_rewards_history(
51 &self,
52 params: GetRwusdRewardsHistoryParams,
53 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRewardsHistoryResponse>>;
54 async fn get_rwusd_subscription_history(
55 &self,
56 params: GetRwusdSubscriptionHistoryParams,
57 ) -> anyhow::Result<RestApiResponse<models::GetRwusdSubscriptionHistoryResponse>>;
58 async fn redeem_rwusd(
59 &self,
60 params: RedeemRwusdParams,
61 ) -> anyhow::Result<RestApiResponse<models::RedeemRwusdResponse>>;
62 async fn subscribe_rwusd(
63 &self,
64 params: SubscribeRwusdParams,
65 ) -> anyhow::Result<RestApiResponse<models::SubscribeRwusdResponse>>;
66}
67
68#[derive(Debug, Clone)]
69pub struct RwusdApiClient {
70 configuration: ConfigurationRestApi,
71}
72
73impl RwusdApiClient {
74 pub fn new(configuration: ConfigurationRestApi) -> Self {
75 Self { configuration }
76 }
77}
78
79#[derive(Clone, Debug, Builder, Default)]
84#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
85pub struct GetRwusdAccountParams {
86 #[builder(setter(into), default)]
90 pub recv_window: Option<i64>,
91}
92
93impl GetRwusdAccountParams {
94 #[must_use]
97 pub fn builder() -> GetRwusdAccountParamsBuilder {
98 GetRwusdAccountParamsBuilder::default()
99 }
100}
101#[derive(Clone, Debug, Builder, Default)]
106#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
107pub struct GetRwusdQuotaDetailsParams {
108 #[builder(setter(into), default)]
112 pub recv_window: Option<i64>,
113}
114
115impl GetRwusdQuotaDetailsParams {
116 #[must_use]
119 pub fn builder() -> GetRwusdQuotaDetailsParamsBuilder {
120 GetRwusdQuotaDetailsParamsBuilder::default()
121 }
122}
123#[derive(Clone, Debug, Builder, Default)]
128#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
129pub struct GetRwusdRateHistoryParams {
130 #[builder(setter(into), default)]
135 pub start_time: Option<i64>,
136 #[builder(setter(into), default)]
141 pub end_time: Option<i64>,
142 #[builder(setter(into), default)]
146 pub current: Option<i64>,
147 #[builder(setter(into), default)]
151 pub size: Option<i64>,
152 #[builder(setter(into), default)]
156 pub recv_window: Option<i64>,
157}
158
159impl GetRwusdRateHistoryParams {
160 #[must_use]
163 pub fn builder() -> GetRwusdRateHistoryParamsBuilder {
164 GetRwusdRateHistoryParamsBuilder::default()
165 }
166}
167#[derive(Clone, Debug, Builder, Default)]
172#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
173pub struct GetRwusdRedemptionHistoryParams {
174 #[builder(setter(into), default)]
179 pub start_time: Option<i64>,
180 #[builder(setter(into), default)]
185 pub end_time: Option<i64>,
186 #[builder(setter(into), default)]
190 pub current: Option<i64>,
191 #[builder(setter(into), default)]
195 pub size: Option<i64>,
196 #[builder(setter(into), default)]
200 pub recv_window: Option<i64>,
201}
202
203impl GetRwusdRedemptionHistoryParams {
204 #[must_use]
207 pub fn builder() -> GetRwusdRedemptionHistoryParamsBuilder {
208 GetRwusdRedemptionHistoryParamsBuilder::default()
209 }
210}
211#[derive(Clone, Debug, Builder, Default)]
216#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
217pub struct GetRwusdRewardsHistoryParams {
218 #[builder(setter(into), default)]
223 pub start_time: Option<i64>,
224 #[builder(setter(into), default)]
229 pub end_time: Option<i64>,
230 #[builder(setter(into), default)]
234 pub current: Option<i64>,
235 #[builder(setter(into), default)]
239 pub size: Option<i64>,
240 #[builder(setter(into), default)]
244 pub recv_window: Option<i64>,
245}
246
247impl GetRwusdRewardsHistoryParams {
248 #[must_use]
251 pub fn builder() -> GetRwusdRewardsHistoryParamsBuilder {
252 GetRwusdRewardsHistoryParamsBuilder::default()
253 }
254}
255#[derive(Clone, Debug, Builder, Default)]
260#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
261pub struct GetRwusdSubscriptionHistoryParams {
262 #[builder(setter(into), default)]
266 pub asset: Option<String>,
267 #[builder(setter(into), default)]
272 pub start_time: Option<i64>,
273 #[builder(setter(into), default)]
278 pub end_time: Option<i64>,
279 #[builder(setter(into), default)]
283 pub current: Option<i64>,
284 #[builder(setter(into), default)]
288 pub size: Option<i64>,
289 #[builder(setter(into), default)]
293 pub recv_window: Option<i64>,
294}
295
296impl GetRwusdSubscriptionHistoryParams {
297 #[must_use]
300 pub fn builder() -> GetRwusdSubscriptionHistoryParamsBuilder {
301 GetRwusdSubscriptionHistoryParamsBuilder::default()
302 }
303}
304#[derive(Clone, Debug, Builder)]
309#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
310pub struct RedeemRwusdParams {
311 #[builder(setter(into))]
315 pub amount: rust_decimal::Decimal,
316 #[builder(setter(into))]
320 pub r#type: String,
321 #[builder(setter(into), default)]
325 pub recv_window: Option<i64>,
326}
327
328impl RedeemRwusdParams {
329 #[must_use]
337 pub fn builder(amount: rust_decimal::Decimal, r#type: String) -> RedeemRwusdParamsBuilder {
338 RedeemRwusdParamsBuilder::default()
339 .amount(amount)
340 .r#type(r#type)
341 }
342}
343#[derive(Clone, Debug, Builder)]
348#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
349pub struct SubscribeRwusdParams {
350 #[builder(setter(into))]
354 pub asset: String,
355 #[builder(setter(into))]
359 pub amount: rust_decimal::Decimal,
360 #[builder(setter(into), default)]
364 pub recv_window: Option<i64>,
365}
366
367impl SubscribeRwusdParams {
368 #[must_use]
376 pub fn builder(asset: String, amount: rust_decimal::Decimal) -> SubscribeRwusdParamsBuilder {
377 SubscribeRwusdParamsBuilder::default()
378 .asset(asset)
379 .amount(amount)
380 }
381}
382
383#[async_trait]
384impl RwusdApi for RwusdApiClient {
385 async fn get_rwusd_account(
386 &self,
387 params: GetRwusdAccountParams,
388 ) -> anyhow::Result<RestApiResponse<models::GetRwusdAccountResponse>> {
389 let GetRwusdAccountParams { recv_window } = params;
390
391 let mut query_params = BTreeMap::new();
392 let body_params = BTreeMap::new();
393
394 if let Some(rw) = recv_window {
395 query_params.insert("recvWindow".to_string(), json!(rw));
396 }
397
398 send_request::<models::GetRwusdAccountResponse>(
399 &self.configuration,
400 "/sapi/v1/rwusd/account",
401 reqwest::Method::GET,
402 query_params,
403 body_params,
404 if HAS_TIME_UNIT {
405 self.configuration.time_unit
406 } else {
407 None
408 },
409 true,
410 )
411 .await
412 }
413
414 async fn get_rwusd_quota_details(
415 &self,
416 params: GetRwusdQuotaDetailsParams,
417 ) -> anyhow::Result<RestApiResponse<models::GetRwusdQuotaDetailsResponse>> {
418 let GetRwusdQuotaDetailsParams { recv_window } = params;
419
420 let mut query_params = BTreeMap::new();
421 let body_params = BTreeMap::new();
422
423 if let Some(rw) = recv_window {
424 query_params.insert("recvWindow".to_string(), json!(rw));
425 }
426
427 send_request::<models::GetRwusdQuotaDetailsResponse>(
428 &self.configuration,
429 "/sapi/v1/rwusd/quota",
430 reqwest::Method::GET,
431 query_params,
432 body_params,
433 if HAS_TIME_UNIT {
434 self.configuration.time_unit
435 } else {
436 None
437 },
438 true,
439 )
440 .await
441 }
442
443 async fn get_rwusd_rate_history(
444 &self,
445 params: GetRwusdRateHistoryParams,
446 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRateHistoryResponse>> {
447 let GetRwusdRateHistoryParams {
448 start_time,
449 end_time,
450 current,
451 size,
452 recv_window,
453 } = params;
454
455 let mut query_params = BTreeMap::new();
456 let body_params = BTreeMap::new();
457
458 if let Some(rw) = start_time {
459 query_params.insert("startTime".to_string(), json!(rw));
460 }
461
462 if let Some(rw) = end_time {
463 query_params.insert("endTime".to_string(), json!(rw));
464 }
465
466 if let Some(rw) = current {
467 query_params.insert("current".to_string(), json!(rw));
468 }
469
470 if let Some(rw) = size {
471 query_params.insert("size".to_string(), json!(rw));
472 }
473
474 if let Some(rw) = recv_window {
475 query_params.insert("recvWindow".to_string(), json!(rw));
476 }
477
478 send_request::<models::GetRwusdRateHistoryResponse>(
479 &self.configuration,
480 "/sapi/v1/rwusd/history/rateHistory",
481 reqwest::Method::GET,
482 query_params,
483 body_params,
484 if HAS_TIME_UNIT {
485 self.configuration.time_unit
486 } else {
487 None
488 },
489 true,
490 )
491 .await
492 }
493
494 async fn get_rwusd_redemption_history(
495 &self,
496 params: GetRwusdRedemptionHistoryParams,
497 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRedemptionHistoryResponse>> {
498 let GetRwusdRedemptionHistoryParams {
499 start_time,
500 end_time,
501 current,
502 size,
503 recv_window,
504 } = params;
505
506 let mut query_params = BTreeMap::new();
507 let body_params = BTreeMap::new();
508
509 if let Some(rw) = start_time {
510 query_params.insert("startTime".to_string(), json!(rw));
511 }
512
513 if let Some(rw) = end_time {
514 query_params.insert("endTime".to_string(), json!(rw));
515 }
516
517 if let Some(rw) = current {
518 query_params.insert("current".to_string(), json!(rw));
519 }
520
521 if let Some(rw) = size {
522 query_params.insert("size".to_string(), json!(rw));
523 }
524
525 if let Some(rw) = recv_window {
526 query_params.insert("recvWindow".to_string(), json!(rw));
527 }
528
529 send_request::<models::GetRwusdRedemptionHistoryResponse>(
530 &self.configuration,
531 "/sapi/v1/rwusd/history/redemptionHistory",
532 reqwest::Method::GET,
533 query_params,
534 body_params,
535 if HAS_TIME_UNIT {
536 self.configuration.time_unit
537 } else {
538 None
539 },
540 true,
541 )
542 .await
543 }
544
545 async fn get_rwusd_rewards_history(
546 &self,
547 params: GetRwusdRewardsHistoryParams,
548 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRewardsHistoryResponse>> {
549 let GetRwusdRewardsHistoryParams {
550 start_time,
551 end_time,
552 current,
553 size,
554 recv_window,
555 } = params;
556
557 let mut query_params = BTreeMap::new();
558 let body_params = BTreeMap::new();
559
560 if let Some(rw) = start_time {
561 query_params.insert("startTime".to_string(), json!(rw));
562 }
563
564 if let Some(rw) = end_time {
565 query_params.insert("endTime".to_string(), json!(rw));
566 }
567
568 if let Some(rw) = current {
569 query_params.insert("current".to_string(), json!(rw));
570 }
571
572 if let Some(rw) = size {
573 query_params.insert("size".to_string(), json!(rw));
574 }
575
576 if let Some(rw) = recv_window {
577 query_params.insert("recvWindow".to_string(), json!(rw));
578 }
579
580 send_request::<models::GetRwusdRewardsHistoryResponse>(
581 &self.configuration,
582 "/sapi/v1/rwusd/history/rewardsHistory",
583 reqwest::Method::GET,
584 query_params,
585 body_params,
586 if HAS_TIME_UNIT {
587 self.configuration.time_unit
588 } else {
589 None
590 },
591 true,
592 )
593 .await
594 }
595
596 async fn get_rwusd_subscription_history(
597 &self,
598 params: GetRwusdSubscriptionHistoryParams,
599 ) -> anyhow::Result<RestApiResponse<models::GetRwusdSubscriptionHistoryResponse>> {
600 let GetRwusdSubscriptionHistoryParams {
601 asset,
602 start_time,
603 end_time,
604 current,
605 size,
606 recv_window,
607 } = params;
608
609 let mut query_params = BTreeMap::new();
610 let body_params = BTreeMap::new();
611
612 if let Some(rw) = asset {
613 query_params.insert("asset".to_string(), json!(rw));
614 }
615
616 if let Some(rw) = start_time {
617 query_params.insert("startTime".to_string(), json!(rw));
618 }
619
620 if let Some(rw) = end_time {
621 query_params.insert("endTime".to_string(), json!(rw));
622 }
623
624 if let Some(rw) = current {
625 query_params.insert("current".to_string(), json!(rw));
626 }
627
628 if let Some(rw) = size {
629 query_params.insert("size".to_string(), json!(rw));
630 }
631
632 if let Some(rw) = recv_window {
633 query_params.insert("recvWindow".to_string(), json!(rw));
634 }
635
636 send_request::<models::GetRwusdSubscriptionHistoryResponse>(
637 &self.configuration,
638 "/sapi/v1/rwusd/history/subscriptionHistory",
639 reqwest::Method::GET,
640 query_params,
641 body_params,
642 if HAS_TIME_UNIT {
643 self.configuration.time_unit
644 } else {
645 None
646 },
647 true,
648 )
649 .await
650 }
651
652 async fn redeem_rwusd(
653 &self,
654 params: RedeemRwusdParams,
655 ) -> anyhow::Result<RestApiResponse<models::RedeemRwusdResponse>> {
656 let RedeemRwusdParams {
657 amount,
658 r#type,
659 recv_window,
660 } = params;
661
662 let mut query_params = BTreeMap::new();
663 let body_params = BTreeMap::new();
664
665 query_params.insert("amount".to_string(), json!(amount));
666
667 query_params.insert("type".to_string(), json!(r#type));
668
669 if let Some(rw) = recv_window {
670 query_params.insert("recvWindow".to_string(), json!(rw));
671 }
672
673 send_request::<models::RedeemRwusdResponse>(
674 &self.configuration,
675 "/sapi/v1/rwusd/redeem",
676 reqwest::Method::POST,
677 query_params,
678 body_params,
679 if HAS_TIME_UNIT {
680 self.configuration.time_unit
681 } else {
682 None
683 },
684 true,
685 )
686 .await
687 }
688
689 async fn subscribe_rwusd(
690 &self,
691 params: SubscribeRwusdParams,
692 ) -> anyhow::Result<RestApiResponse<models::SubscribeRwusdResponse>> {
693 let SubscribeRwusdParams {
694 asset,
695 amount,
696 recv_window,
697 } = params;
698
699 let mut query_params = BTreeMap::new();
700 let body_params = BTreeMap::new();
701
702 query_params.insert("asset".to_string(), json!(asset));
703
704 query_params.insert("amount".to_string(), json!(amount));
705
706 if let Some(rw) = recv_window {
707 query_params.insert("recvWindow".to_string(), json!(rw));
708 }
709
710 send_request::<models::SubscribeRwusdResponse>(
711 &self.configuration,
712 "/sapi/v1/rwusd/subscribe",
713 reqwest::Method::POST,
714 query_params,
715 body_params,
716 if HAS_TIME_UNIT {
717 self.configuration.time_unit
718 } else {
719 None
720 },
721 true,
722 )
723 .await
724 }
725}
726
727#[cfg(all(test, feature = "simple_earn"))]
728mod tests {
729 use super::*;
730 use crate::TOKIO_SHARED_RT;
731 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
732 use async_trait::async_trait;
733 use std::collections::HashMap;
734
735 struct DummyRestApiResponse<T> {
736 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
737 status: u16,
738 headers: HashMap<String, String>,
739 rate_limits: Option<Vec<RestApiRateLimit>>,
740 }
741
742 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
743 fn from(dummy: DummyRestApiResponse<T>) -> Self {
744 Self {
745 data_fn: dummy.inner,
746 status: dummy.status,
747 headers: dummy.headers,
748 rate_limits: dummy.rate_limits,
749 }
750 }
751 }
752
753 struct MockRwusdApiClient {
754 force_error: bool,
755 }
756
757 #[async_trait]
758 impl RwusdApi for MockRwusdApiClient {
759 async fn get_rwusd_account(
760 &self,
761 _params: GetRwusdAccountParams,
762 ) -> anyhow::Result<RestApiResponse<models::GetRwusdAccountResponse>> {
763 if self.force_error {
764 return Err(ConnectorError::ConnectorClientError {
765 msg: "ResponseError".to_string(),
766 code: None,
767 }
768 .into());
769 }
770
771 let resp_json: Value =
772 serde_json::from_str(r#"{"rwusdAmount":"100","totalProfit":"12.81"}"#).unwrap();
773 let dummy_response: models::GetRwusdAccountResponse =
774 serde_json::from_value(resp_json.clone())
775 .expect("should parse into models::GetRwusdAccountResponse");
776
777 let dummy = DummyRestApiResponse {
778 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
779 status: 200,
780 headers: HashMap::new(),
781 rate_limits: None,
782 };
783
784 Ok(dummy.into())
785 }
786
787 async fn get_rwusd_quota_details(
788 &self,
789 _params: GetRwusdQuotaDetailsParams,
790 ) -> anyhow::Result<RestApiResponse<models::GetRwusdQuotaDetailsResponse>> {
791 if self.force_error {
792 return Err(ConnectorError::ConnectorClientError {
793 msg: "ResponseError".to_string(),
794 code: None,
795 }
796 .into());
797 }
798
799 let resp_json: Value = serde_json::from_str(r#"{"subscriptionQuota":{"assets":["USDT","USDC"],"leftQuota":"1000","minimum":"0.10000000"},"fastRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.0005","freeQuota":"100"},"standardRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.001","redeemPeriod":3},"subscribeEnable":true,"redeemEnable":true}"#).unwrap();
800 let dummy_response: models::GetRwusdQuotaDetailsResponse =
801 serde_json::from_value(resp_json.clone())
802 .expect("should parse into models::GetRwusdQuotaDetailsResponse");
803
804 let dummy = DummyRestApiResponse {
805 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
806 status: 200,
807 headers: HashMap::new(),
808 rate_limits: None,
809 };
810
811 Ok(dummy.into())
812 }
813
814 async fn get_rwusd_rate_history(
815 &self,
816 _params: GetRwusdRateHistoryParams,
817 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRateHistoryResponse>> {
818 if self.force_error {
819 return Err(ConnectorError::ConnectorClientError {
820 msg: "ResponseError".to_string(),
821 code: None,
822 }
823 .into());
824 }
825
826 let resp_json: Value = serde_json::from_str(
827 r#"{"rows":[{"annualPercentageRate":"0.0418","time":1577233578000}],"total":"1"}"#,
828 )
829 .unwrap();
830 let dummy_response: models::GetRwusdRateHistoryResponse =
831 serde_json::from_value(resp_json.clone())
832 .expect("should parse into models::GetRwusdRateHistoryResponse");
833
834 let dummy = DummyRestApiResponse {
835 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
836 status: 200,
837 headers: HashMap::new(),
838 rate_limits: None,
839 };
840
841 Ok(dummy.into())
842 }
843
844 async fn get_rwusd_redemption_history(
845 &self,
846 _params: GetRwusdRedemptionHistoryParams,
847 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRedemptionHistoryResponse>> {
848 if self.force_error {
849 return Err(ConnectorError::ConnectorClientError {
850 msg: "ResponseError".to_string(),
851 code: None,
852 }
853 .into());
854 }
855
856 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"RWUSD","amount":"51","receiveAsset":"USDC","receiveAmount":"50","fee":"1","arrivalTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap();
857 let dummy_response: models::GetRwusdRedemptionHistoryResponse =
858 serde_json::from_value(resp_json.clone())
859 .expect("should parse into models::GetRwusdRedemptionHistoryResponse");
860
861 let dummy = DummyRestApiResponse {
862 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
863 status: 200,
864 headers: HashMap::new(),
865 rate_limits: None,
866 };
867
868 Ok(dummy.into())
869 }
870
871 async fn get_rwusd_rewards_history(
872 &self,
873 _params: GetRwusdRewardsHistoryParams,
874 ) -> anyhow::Result<RestApiResponse<models::GetRwusdRewardsHistoryResponse>> {
875 if self.force_error {
876 return Err(ConnectorError::ConnectorClientError {
877 msg: "ResponseError".to_string(),
878 code: None,
879 }
880 .into());
881 }
882
883 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"rewardsAmount":"1","rwusdPosition":"100","annualPercentageRate":"0.0418"}],"total":1}"#).unwrap();
884 let dummy_response: models::GetRwusdRewardsHistoryResponse =
885 serde_json::from_value(resp_json.clone())
886 .expect("should parse into models::GetRwusdRewardsHistoryResponse");
887
888 let dummy = DummyRestApiResponse {
889 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
890 status: 200,
891 headers: HashMap::new(),
892 rate_limits: None,
893 };
894
895 Ok(dummy.into())
896 }
897
898 async fn get_rwusd_subscription_history(
899 &self,
900 _params: GetRwusdSubscriptionHistoryParams,
901 ) -> anyhow::Result<RestApiResponse<models::GetRwusdSubscriptionHistoryResponse>> {
902 if self.force_error {
903 return Err(ConnectorError::ConnectorClientError {
904 msg: "ResponseError".to_string(),
905 code: None,
906 }
907 .into());
908 }
909
910 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"USDC","amount":"100","receiveAsset":"RWUSD","receiveAmount":"100","status":"SUCCESS"}],"total":1}"#).unwrap();
911 let dummy_response: models::GetRwusdSubscriptionHistoryResponse =
912 serde_json::from_value(resp_json.clone())
913 .expect("should parse into models::GetRwusdSubscriptionHistoryResponse");
914
915 let dummy = DummyRestApiResponse {
916 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
917 status: 200,
918 headers: HashMap::new(),
919 rate_limits: None,
920 };
921
922 Ok(dummy.into())
923 }
924
925 async fn redeem_rwusd(
926 &self,
927 _params: RedeemRwusdParams,
928 ) -> anyhow::Result<RestApiResponse<models::RedeemRwusdResponse>> {
929 if self.force_error {
930 return Err(ConnectorError::ConnectorClientError {
931 msg: "ResponseError".to_string(),
932 code: None,
933 }
934 .into());
935 }
936
937 let resp_json: Value = serde_json::from_str(r#"{"success":true,"receiveAmount":"0.23092091","fee":"0.00000012","arrivalTime":1575018510000}"#).unwrap();
938 let dummy_response: models::RedeemRwusdResponse =
939 serde_json::from_value(resp_json.clone())
940 .expect("should parse into models::RedeemRwusdResponse");
941
942 let dummy = DummyRestApiResponse {
943 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
944 status: 200,
945 headers: HashMap::new(),
946 rate_limits: None,
947 };
948
949 Ok(dummy.into())
950 }
951
952 async fn subscribe_rwusd(
953 &self,
954 _params: SubscribeRwusdParams,
955 ) -> anyhow::Result<RestApiResponse<models::SubscribeRwusdResponse>> {
956 if self.force_error {
957 return Err(ConnectorError::ConnectorClientError {
958 msg: "ResponseError".to_string(),
959 code: None,
960 }
961 .into());
962 }
963
964 let resp_json: Value =
965 serde_json::from_str(r#"{"success":true,"rwusdAmount":"0.22091092"}"#).unwrap();
966 let dummy_response: models::SubscribeRwusdResponse =
967 serde_json::from_value(resp_json.clone())
968 .expect("should parse into models::SubscribeRwusdResponse");
969
970 let dummy = DummyRestApiResponse {
971 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
972 status: 200,
973 headers: HashMap::new(),
974 rate_limits: None,
975 };
976
977 Ok(dummy.into())
978 }
979 }
980
981 #[test]
982 fn get_rwusd_account_required_params_success() {
983 TOKIO_SHARED_RT.block_on(async {
984 let client = MockRwusdApiClient { force_error: false };
985
986 let params = GetRwusdAccountParams::builder().build().unwrap();
987
988 let resp_json: Value =
989 serde_json::from_str(r#"{"rwusdAmount":"100","totalProfit":"12.81"}"#).unwrap();
990 let expected_response: models::GetRwusdAccountResponse =
991 serde_json::from_value(resp_json.clone())
992 .expect("should parse into models::GetRwusdAccountResponse");
993
994 let resp = client
995 .get_rwusd_account(params)
996 .await
997 .expect("Expected a response");
998 let data_future = resp.data();
999 let actual_response = data_future.await.unwrap();
1000 assert_eq!(actual_response, expected_response);
1001 });
1002 }
1003
1004 #[test]
1005 fn get_rwusd_account_optional_params_success() {
1006 TOKIO_SHARED_RT.block_on(async {
1007 let client = MockRwusdApiClient { force_error: false };
1008
1009 let params = GetRwusdAccountParams::builder()
1010 .recv_window(5000)
1011 .build()
1012 .unwrap();
1013
1014 let resp_json: Value =
1015 serde_json::from_str(r#"{"rwusdAmount":"100","totalProfit":"12.81"}"#).unwrap();
1016 let expected_response: models::GetRwusdAccountResponse =
1017 serde_json::from_value(resp_json.clone())
1018 .expect("should parse into models::GetRwusdAccountResponse");
1019
1020 let resp = client
1021 .get_rwusd_account(params)
1022 .await
1023 .expect("Expected a response");
1024 let data_future = resp.data();
1025 let actual_response = data_future.await.unwrap();
1026 assert_eq!(actual_response, expected_response);
1027 });
1028 }
1029
1030 #[test]
1031 fn get_rwusd_account_response_error() {
1032 TOKIO_SHARED_RT.block_on(async {
1033 let client = MockRwusdApiClient { force_error: true };
1034
1035 let params = GetRwusdAccountParams::builder().build().unwrap();
1036
1037 match client.get_rwusd_account(params).await {
1038 Ok(_) => panic!("Expected an error"),
1039 Err(err) => {
1040 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1041 }
1042 }
1043 });
1044 }
1045
1046 #[test]
1047 fn get_rwusd_quota_details_required_params_success() {
1048 TOKIO_SHARED_RT.block_on(async {
1049 let client = MockRwusdApiClient { force_error: false };
1050
1051 let params = GetRwusdQuotaDetailsParams::builder().build().unwrap();
1052
1053 let resp_json: Value = serde_json::from_str(r#"{"subscriptionQuota":{"assets":["USDT","USDC"],"leftQuota":"1000","minimum":"0.10000000"},"fastRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.0005","freeQuota":"100"},"standardRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.001","redeemPeriod":3},"subscribeEnable":true,"redeemEnable":true}"#).unwrap();
1054 let expected_response : models::GetRwusdQuotaDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdQuotaDetailsResponse");
1055
1056 let resp = client.get_rwusd_quota_details(params).await.expect("Expected a response");
1057 let data_future = resp.data();
1058 let actual_response = data_future.await.unwrap();
1059 assert_eq!(actual_response, expected_response);
1060 });
1061 }
1062
1063 #[test]
1064 fn get_rwusd_quota_details_optional_params_success() {
1065 TOKIO_SHARED_RT.block_on(async {
1066 let client = MockRwusdApiClient { force_error: false };
1067
1068 let params = GetRwusdQuotaDetailsParams::builder().recv_window(5000).build().unwrap();
1069
1070 let resp_json: Value = serde_json::from_str(r#"{"subscriptionQuota":{"assets":["USDT","USDC"],"leftQuota":"1000","minimum":"0.10000000"},"fastRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.0005","freeQuota":"100"},"standardRedemptionQuota":{"leftQuota":"2","minimum":"0.1","fee":"0.001","redeemPeriod":3},"subscribeEnable":true,"redeemEnable":true}"#).unwrap();
1071 let expected_response : models::GetRwusdQuotaDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdQuotaDetailsResponse");
1072
1073 let resp = client.get_rwusd_quota_details(params).await.expect("Expected a response");
1074 let data_future = resp.data();
1075 let actual_response = data_future.await.unwrap();
1076 assert_eq!(actual_response, expected_response);
1077 });
1078 }
1079
1080 #[test]
1081 fn get_rwusd_quota_details_response_error() {
1082 TOKIO_SHARED_RT.block_on(async {
1083 let client = MockRwusdApiClient { force_error: true };
1084
1085 let params = GetRwusdQuotaDetailsParams::builder().build().unwrap();
1086
1087 match client.get_rwusd_quota_details(params).await {
1088 Ok(_) => panic!("Expected an error"),
1089 Err(err) => {
1090 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1091 }
1092 }
1093 });
1094 }
1095
1096 #[test]
1097 fn get_rwusd_rate_history_required_params_success() {
1098 TOKIO_SHARED_RT.block_on(async {
1099 let client = MockRwusdApiClient { force_error: false };
1100
1101 let params = GetRwusdRateHistoryParams::builder().build().unwrap();
1102
1103 let resp_json: Value = serde_json::from_str(
1104 r#"{"rows":[{"annualPercentageRate":"0.0418","time":1577233578000}],"total":"1"}"#,
1105 )
1106 .unwrap();
1107 let expected_response: models::GetRwusdRateHistoryResponse =
1108 serde_json::from_value(resp_json.clone())
1109 .expect("should parse into models::GetRwusdRateHistoryResponse");
1110
1111 let resp = client
1112 .get_rwusd_rate_history(params)
1113 .await
1114 .expect("Expected a response");
1115 let data_future = resp.data();
1116 let actual_response = data_future.await.unwrap();
1117 assert_eq!(actual_response, expected_response);
1118 });
1119 }
1120
1121 #[test]
1122 fn get_rwusd_rate_history_optional_params_success() {
1123 TOKIO_SHARED_RT.block_on(async {
1124 let client = MockRwusdApiClient { force_error: false };
1125
1126 let params = GetRwusdRateHistoryParams::builder()
1127 .start_time(1623319461670)
1128 .end_time(1641782889000)
1129 .current(1)
1130 .size(10)
1131 .recv_window(5000)
1132 .build()
1133 .unwrap();
1134
1135 let resp_json: Value = serde_json::from_str(
1136 r#"{"rows":[{"annualPercentageRate":"0.0418","time":1577233578000}],"total":"1"}"#,
1137 )
1138 .unwrap();
1139 let expected_response: models::GetRwusdRateHistoryResponse =
1140 serde_json::from_value(resp_json.clone())
1141 .expect("should parse into models::GetRwusdRateHistoryResponse");
1142
1143 let resp = client
1144 .get_rwusd_rate_history(params)
1145 .await
1146 .expect("Expected a response");
1147 let data_future = resp.data();
1148 let actual_response = data_future.await.unwrap();
1149 assert_eq!(actual_response, expected_response);
1150 });
1151 }
1152
1153 #[test]
1154 fn get_rwusd_rate_history_response_error() {
1155 TOKIO_SHARED_RT.block_on(async {
1156 let client = MockRwusdApiClient { force_error: true };
1157
1158 let params = GetRwusdRateHistoryParams::builder().build().unwrap();
1159
1160 match client.get_rwusd_rate_history(params).await {
1161 Ok(_) => panic!("Expected an error"),
1162 Err(err) => {
1163 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1164 }
1165 }
1166 });
1167 }
1168
1169 #[test]
1170 fn get_rwusd_redemption_history_required_params_success() {
1171 TOKIO_SHARED_RT.block_on(async {
1172 let client = MockRwusdApiClient { force_error: false };
1173
1174 let params = GetRwusdRedemptionHistoryParams::builder().build().unwrap();
1175
1176 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"RWUSD","amount":"51","receiveAsset":"USDC","receiveAmount":"50","fee":"1","arrivalTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap();
1177 let expected_response : models::GetRwusdRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdRedemptionHistoryResponse");
1178
1179 let resp = client.get_rwusd_redemption_history(params).await.expect("Expected a response");
1180 let data_future = resp.data();
1181 let actual_response = data_future.await.unwrap();
1182 assert_eq!(actual_response, expected_response);
1183 });
1184 }
1185
1186 #[test]
1187 fn get_rwusd_redemption_history_optional_params_success() {
1188 TOKIO_SHARED_RT.block_on(async {
1189 let client = MockRwusdApiClient { force_error: false };
1190
1191 let params = GetRwusdRedemptionHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1192
1193 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"RWUSD","amount":"51","receiveAsset":"USDC","receiveAmount":"50","fee":"1","arrivalTime":1575018510000,"status":"SUCCESS"}],"total":1}"#).unwrap();
1194 let expected_response : models::GetRwusdRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdRedemptionHistoryResponse");
1195
1196 let resp = client.get_rwusd_redemption_history(params).await.expect("Expected a response");
1197 let data_future = resp.data();
1198 let actual_response = data_future.await.unwrap();
1199 assert_eq!(actual_response, expected_response);
1200 });
1201 }
1202
1203 #[test]
1204 fn get_rwusd_redemption_history_response_error() {
1205 TOKIO_SHARED_RT.block_on(async {
1206 let client = MockRwusdApiClient { force_error: true };
1207
1208 let params = GetRwusdRedemptionHistoryParams::builder().build().unwrap();
1209
1210 match client.get_rwusd_redemption_history(params).await {
1211 Ok(_) => panic!("Expected an error"),
1212 Err(err) => {
1213 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1214 }
1215 }
1216 });
1217 }
1218
1219 #[test]
1220 fn get_rwusd_rewards_history_required_params_success() {
1221 TOKIO_SHARED_RT.block_on(async {
1222 let client = MockRwusdApiClient { force_error: false };
1223
1224 let params = GetRwusdRewardsHistoryParams::builder().build().unwrap();
1225
1226 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"rewardsAmount":"1","rwusdPosition":"100","annualPercentageRate":"0.0418"}],"total":1}"#).unwrap();
1227 let expected_response : models::GetRwusdRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdRewardsHistoryResponse");
1228
1229 let resp = client.get_rwusd_rewards_history(params).await.expect("Expected a response");
1230 let data_future = resp.data();
1231 let actual_response = data_future.await.unwrap();
1232 assert_eq!(actual_response, expected_response);
1233 });
1234 }
1235
1236 #[test]
1237 fn get_rwusd_rewards_history_optional_params_success() {
1238 TOKIO_SHARED_RT.block_on(async {
1239 let client = MockRwusdApiClient { force_error: false };
1240
1241 let params = GetRwusdRewardsHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1242
1243 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"rewardsAmount":"1","rwusdPosition":"100","annualPercentageRate":"0.0418"}],"total":1}"#).unwrap();
1244 let expected_response : models::GetRwusdRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdRewardsHistoryResponse");
1245
1246 let resp = client.get_rwusd_rewards_history(params).await.expect("Expected a response");
1247 let data_future = resp.data();
1248 let actual_response = data_future.await.unwrap();
1249 assert_eq!(actual_response, expected_response);
1250 });
1251 }
1252
1253 #[test]
1254 fn get_rwusd_rewards_history_response_error() {
1255 TOKIO_SHARED_RT.block_on(async {
1256 let client = MockRwusdApiClient { force_error: true };
1257
1258 let params = GetRwusdRewardsHistoryParams::builder().build().unwrap();
1259
1260 match client.get_rwusd_rewards_history(params).await {
1261 Ok(_) => panic!("Expected an error"),
1262 Err(err) => {
1263 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1264 }
1265 }
1266 });
1267 }
1268
1269 #[test]
1270 fn get_rwusd_subscription_history_required_params_success() {
1271 TOKIO_SHARED_RT.block_on(async {
1272 let client = MockRwusdApiClient { force_error: false };
1273
1274 let params = GetRwusdSubscriptionHistoryParams::builder().build().unwrap();
1275
1276 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"USDC","amount":"100","receiveAsset":"RWUSD","receiveAmount":"100","status":"SUCCESS"}],"total":1}"#).unwrap();
1277 let expected_response : models::GetRwusdSubscriptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdSubscriptionHistoryResponse");
1278
1279 let resp = client.get_rwusd_subscription_history(params).await.expect("Expected a response");
1280 let data_future = resp.data();
1281 let actual_response = data_future.await.unwrap();
1282 assert_eq!(actual_response, expected_response);
1283 });
1284 }
1285
1286 #[test]
1287 fn get_rwusd_subscription_history_optional_params_success() {
1288 TOKIO_SHARED_RT.block_on(async {
1289 let client = MockRwusdApiClient { force_error: false };
1290
1291 let params = GetRwusdSubscriptionHistoryParams::builder().asset("asset_example".to_string()).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1292
1293 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"USDC","amount":"100","receiveAsset":"RWUSD","receiveAmount":"100","status":"SUCCESS"}],"total":1}"#).unwrap();
1294 let expected_response : models::GetRwusdSubscriptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetRwusdSubscriptionHistoryResponse");
1295
1296 let resp = client.get_rwusd_subscription_history(params).await.expect("Expected a response");
1297 let data_future = resp.data();
1298 let actual_response = data_future.await.unwrap();
1299 assert_eq!(actual_response, expected_response);
1300 });
1301 }
1302
1303 #[test]
1304 fn get_rwusd_subscription_history_response_error() {
1305 TOKIO_SHARED_RT.block_on(async {
1306 let client = MockRwusdApiClient { force_error: true };
1307
1308 let params = GetRwusdSubscriptionHistoryParams::builder()
1309 .build()
1310 .unwrap();
1311
1312 match client.get_rwusd_subscription_history(params).await {
1313 Ok(_) => panic!("Expected an error"),
1314 Err(err) => {
1315 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1316 }
1317 }
1318 });
1319 }
1320
1321 #[test]
1322 fn redeem_rwusd_required_params_success() {
1323 TOKIO_SHARED_RT.block_on(async {
1324 let client = MockRwusdApiClient { force_error: false };
1325
1326 let params = RedeemRwusdParams::builder(dec!(1.0),"s".to_string(),).build().unwrap();
1327
1328 let resp_json: Value = serde_json::from_str(r#"{"success":true,"receiveAmount":"0.23092091","fee":"0.00000012","arrivalTime":1575018510000}"#).unwrap();
1329 let expected_response : models::RedeemRwusdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemRwusdResponse");
1330
1331 let resp = client.redeem_rwusd(params).await.expect("Expected a response");
1332 let data_future = resp.data();
1333 let actual_response = data_future.await.unwrap();
1334 assert_eq!(actual_response, expected_response);
1335 });
1336 }
1337
1338 #[test]
1339 fn redeem_rwusd_optional_params_success() {
1340 TOKIO_SHARED_RT.block_on(async {
1341 let client = MockRwusdApiClient { force_error: false };
1342
1343 let params = RedeemRwusdParams::builder(dec!(1.0),"s".to_string(),).recv_window(5000).build().unwrap();
1344
1345 let resp_json: Value = serde_json::from_str(r#"{"success":true,"receiveAmount":"0.23092091","fee":"0.00000012","arrivalTime":1575018510000}"#).unwrap();
1346 let expected_response : models::RedeemRwusdResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemRwusdResponse");
1347
1348 let resp = client.redeem_rwusd(params).await.expect("Expected a response");
1349 let data_future = resp.data();
1350 let actual_response = data_future.await.unwrap();
1351 assert_eq!(actual_response, expected_response);
1352 });
1353 }
1354
1355 #[test]
1356 fn redeem_rwusd_response_error() {
1357 TOKIO_SHARED_RT.block_on(async {
1358 let client = MockRwusdApiClient { force_error: true };
1359
1360 let params = RedeemRwusdParams::builder(dec!(1.0), "s".to_string())
1361 .build()
1362 .unwrap();
1363
1364 match client.redeem_rwusd(params).await {
1365 Ok(_) => panic!("Expected an error"),
1366 Err(err) => {
1367 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1368 }
1369 }
1370 });
1371 }
1372
1373 #[test]
1374 fn subscribe_rwusd_required_params_success() {
1375 TOKIO_SHARED_RT.block_on(async {
1376 let client = MockRwusdApiClient { force_error: false };
1377
1378 let params = SubscribeRwusdParams::builder("asset_example".to_string(), dec!(1.0))
1379 .build()
1380 .unwrap();
1381
1382 let resp_json: Value =
1383 serde_json::from_str(r#"{"success":true,"rwusdAmount":"0.22091092"}"#).unwrap();
1384 let expected_response: models::SubscribeRwusdResponse =
1385 serde_json::from_value(resp_json.clone())
1386 .expect("should parse into models::SubscribeRwusdResponse");
1387
1388 let resp = client
1389 .subscribe_rwusd(params)
1390 .await
1391 .expect("Expected a response");
1392 let data_future = resp.data();
1393 let actual_response = data_future.await.unwrap();
1394 assert_eq!(actual_response, expected_response);
1395 });
1396 }
1397
1398 #[test]
1399 fn subscribe_rwusd_optional_params_success() {
1400 TOKIO_SHARED_RT.block_on(async {
1401 let client = MockRwusdApiClient { force_error: false };
1402
1403 let params = SubscribeRwusdParams::builder("asset_example".to_string(), dec!(1.0))
1404 .recv_window(5000)
1405 .build()
1406 .unwrap();
1407
1408 let resp_json: Value =
1409 serde_json::from_str(r#"{"success":true,"rwusdAmount":"0.22091092"}"#).unwrap();
1410 let expected_response: models::SubscribeRwusdResponse =
1411 serde_json::from_value(resp_json.clone())
1412 .expect("should parse into models::SubscribeRwusdResponse");
1413
1414 let resp = client
1415 .subscribe_rwusd(params)
1416 .await
1417 .expect("Expected a response");
1418 let data_future = resp.data();
1419 let actual_response = data_future.await.unwrap();
1420 assert_eq!(actual_response, expected_response);
1421 });
1422 }
1423
1424 #[test]
1425 fn subscribe_rwusd_response_error() {
1426 TOKIO_SHARED_RT.block_on(async {
1427 let client = MockRwusdApiClient { force_error: true };
1428
1429 let params = SubscribeRwusdParams::builder("asset_example".to_string(), dec!(1.0))
1430 .build()
1431 .unwrap();
1432
1433 match client.subscribe_rwusd(params).await {
1434 Ok(_) => panic!("Expected an error"),
1435 Err(err) => {
1436 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1437 }
1438 }
1439 });
1440 }
1441}