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::staking::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait SolStakingApi: Send + Sync {
34 async fn claim_boost_rewards(
35 &self,
36 params: ClaimBoostRewardsParams,
37 ) -> anyhow::Result<RestApiResponse<models::ClaimBoostRewardsResponse>>;
38 async fn get_bnsol_rate_history(
39 &self,
40 params: GetBnsolRateHistoryParams,
41 ) -> anyhow::Result<RestApiResponse<models::GetBnsolRateHistoryResponse>>;
42 async fn get_bnsol_rewards_history(
43 &self,
44 params: GetBnsolRewardsHistoryParams,
45 ) -> anyhow::Result<RestApiResponse<models::GetBnsolRewardsHistoryResponse>>;
46 async fn get_boost_rewards_history(
47 &self,
48 params: GetBoostRewardsHistoryParams,
49 ) -> anyhow::Result<RestApiResponse<models::GetBoostRewardsHistoryResponse>>;
50 async fn get_sol_redemption_history(
51 &self,
52 params: GetSolRedemptionHistoryParams,
53 ) -> anyhow::Result<RestApiResponse<models::GetSolRedemptionHistoryResponse>>;
54 async fn get_sol_staking_history(
55 &self,
56 params: GetSolStakingHistoryParams,
57 ) -> anyhow::Result<RestApiResponse<models::GetSolStakingHistoryResponse>>;
58 async fn get_sol_staking_quota_details(
59 &self,
60 params: GetSolStakingQuotaDetailsParams,
61 ) -> anyhow::Result<RestApiResponse<models::GetSolStakingQuotaDetailsResponse>>;
62 async fn get_unclaimed_rewards(
63 &self,
64 params: GetUnclaimedRewardsParams,
65 ) -> anyhow::Result<RestApiResponse<Vec<models::GetUnclaimedRewardsResponseInner>>>;
66 async fn redeem_sol(
67 &self,
68 params: RedeemSolParams,
69 ) -> anyhow::Result<RestApiResponse<models::RedeemSolResponse>>;
70 async fn sol_staking_account(
71 &self,
72 params: SolStakingAccountParams,
73 ) -> anyhow::Result<RestApiResponse<models::SolStakingAccountResponse>>;
74 async fn subscribe_sol_staking(
75 &self,
76 params: SubscribeSolStakingParams,
77 ) -> anyhow::Result<RestApiResponse<models::SubscribeSolStakingResponse>>;
78}
79
80#[derive(Debug, Clone)]
81pub struct SolStakingApiClient {
82 configuration: ConfigurationRestApi,
83}
84
85impl SolStakingApiClient {
86 pub fn new(configuration: ConfigurationRestApi) -> Self {
87 Self { configuration }
88 }
89}
90
91#[derive(Clone, Debug, Builder, Default)]
96#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
97pub struct ClaimBoostRewardsParams {
98 #[builder(setter(into), default)]
103 pub recv_window: Option<i64>,
104}
105
106impl ClaimBoostRewardsParams {
107 #[must_use]
110 pub fn builder() -> ClaimBoostRewardsParamsBuilder {
111 ClaimBoostRewardsParamsBuilder::default()
112 }
113}
114#[derive(Clone, Debug, Builder, Default)]
119#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
120pub struct GetBnsolRateHistoryParams {
121 #[builder(setter(into), default)]
126 pub start_time: Option<i64>,
127 #[builder(setter(into), default)]
132 pub end_time: Option<i64>,
133 #[builder(setter(into), default)]
137 pub current: Option<i64>,
138 #[builder(setter(into), default)]
142 pub size: Option<i64>,
143 #[builder(setter(into), default)]
148 pub recv_window: Option<i64>,
149}
150
151impl GetBnsolRateHistoryParams {
152 #[must_use]
155 pub fn builder() -> GetBnsolRateHistoryParamsBuilder {
156 GetBnsolRateHistoryParamsBuilder::default()
157 }
158}
159#[derive(Clone, Debug, Builder, Default)]
164#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
165pub struct GetBnsolRewardsHistoryParams {
166 #[builder(setter(into), default)]
171 pub start_time: Option<i64>,
172 #[builder(setter(into), default)]
177 pub end_time: Option<i64>,
178 #[builder(setter(into), default)]
182 pub current: Option<i64>,
183 #[builder(setter(into), default)]
187 pub size: Option<i64>,
188 #[builder(setter(into), default)]
193 pub recv_window: Option<i64>,
194}
195
196impl GetBnsolRewardsHistoryParams {
197 #[must_use]
200 pub fn builder() -> GetBnsolRewardsHistoryParamsBuilder {
201 GetBnsolRewardsHistoryParamsBuilder::default()
202 }
203}
204#[derive(Clone, Debug, Builder)]
209#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
210pub struct GetBoostRewardsHistoryParams {
211 #[builder(setter(into))]
215 pub r#type: String,
216 #[builder(setter(into), default)]
221 pub start_time: Option<i64>,
222 #[builder(setter(into), default)]
227 pub end_time: Option<i64>,
228 #[builder(setter(into), default)]
232 pub current: Option<i64>,
233 #[builder(setter(into), default)]
237 pub size: Option<i64>,
238 #[builder(setter(into), default)]
243 pub recv_window: Option<i64>,
244}
245
246impl GetBoostRewardsHistoryParams {
247 #[must_use]
254 pub fn builder(r#type: String) -> GetBoostRewardsHistoryParamsBuilder {
255 GetBoostRewardsHistoryParamsBuilder::default().r#type(r#type)
256 }
257}
258#[derive(Clone, Debug, Builder, Default)]
263#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
264pub struct GetSolRedemptionHistoryParams {
265 #[builder(setter(into), default)]
270 pub redeem_id: Option<i64>,
271 #[builder(setter(into), default)]
276 pub start_time: Option<i64>,
277 #[builder(setter(into), default)]
282 pub end_time: Option<i64>,
283 #[builder(setter(into), default)]
287 pub current: Option<i64>,
288 #[builder(setter(into), default)]
292 pub size: Option<i64>,
293 #[builder(setter(into), default)]
298 pub recv_window: Option<i64>,
299}
300
301impl GetSolRedemptionHistoryParams {
302 #[must_use]
305 pub fn builder() -> GetSolRedemptionHistoryParamsBuilder {
306 GetSolRedemptionHistoryParamsBuilder::default()
307 }
308}
309#[derive(Clone, Debug, Builder, Default)]
314#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
315pub struct GetSolStakingHistoryParams {
316 #[builder(setter(into), default)]
321 pub purchase_id: Option<i64>,
322 #[builder(setter(into), default)]
327 pub start_time: Option<i64>,
328 #[builder(setter(into), default)]
333 pub end_time: Option<i64>,
334 #[builder(setter(into), default)]
338 pub current: Option<i64>,
339 #[builder(setter(into), default)]
343 pub size: Option<i64>,
344 #[builder(setter(into), default)]
349 pub recv_window: Option<i64>,
350}
351
352impl GetSolStakingHistoryParams {
353 #[must_use]
356 pub fn builder() -> GetSolStakingHistoryParamsBuilder {
357 GetSolStakingHistoryParamsBuilder::default()
358 }
359}
360#[derive(Clone, Debug, Builder, Default)]
365#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
366pub struct GetSolStakingQuotaDetailsParams {
367 #[builder(setter(into), default)]
372 pub recv_window: Option<i64>,
373}
374
375impl GetSolStakingQuotaDetailsParams {
376 #[must_use]
379 pub fn builder() -> GetSolStakingQuotaDetailsParamsBuilder {
380 GetSolStakingQuotaDetailsParamsBuilder::default()
381 }
382}
383#[derive(Clone, Debug, Builder, Default)]
388#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
389pub struct GetUnclaimedRewardsParams {
390 #[builder(setter(into), default)]
395 pub recv_window: Option<i64>,
396}
397
398impl GetUnclaimedRewardsParams {
399 #[must_use]
402 pub fn builder() -> GetUnclaimedRewardsParamsBuilder {
403 GetUnclaimedRewardsParamsBuilder::default()
404 }
405}
406#[derive(Clone, Debug, Builder)]
411#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
412pub struct RedeemSolParams {
413 #[builder(setter(into))]
417 pub amount: rust_decimal::Decimal,
418 #[builder(setter(into), default)]
423 pub recv_window: Option<i64>,
424}
425
426impl RedeemSolParams {
427 #[must_use]
434 pub fn builder(amount: rust_decimal::Decimal) -> RedeemSolParamsBuilder {
435 RedeemSolParamsBuilder::default().amount(amount)
436 }
437}
438#[derive(Clone, Debug, Builder, Default)]
443#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
444pub struct SolStakingAccountParams {
445 #[builder(setter(into), default)]
450 pub recv_window: Option<i64>,
451}
452
453impl SolStakingAccountParams {
454 #[must_use]
457 pub fn builder() -> SolStakingAccountParamsBuilder {
458 SolStakingAccountParamsBuilder::default()
459 }
460}
461#[derive(Clone, Debug, Builder)]
466#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
467pub struct SubscribeSolStakingParams {
468 #[builder(setter(into))]
472 pub amount: rust_decimal::Decimal,
473 #[builder(setter(into), default)]
478 pub recv_window: Option<i64>,
479}
480
481impl SubscribeSolStakingParams {
482 #[must_use]
489 pub fn builder(amount: rust_decimal::Decimal) -> SubscribeSolStakingParamsBuilder {
490 SubscribeSolStakingParamsBuilder::default().amount(amount)
491 }
492}
493
494#[async_trait]
495impl SolStakingApi for SolStakingApiClient {
496 async fn claim_boost_rewards(
497 &self,
498 params: ClaimBoostRewardsParams,
499 ) -> anyhow::Result<RestApiResponse<models::ClaimBoostRewardsResponse>> {
500 let ClaimBoostRewardsParams { recv_window } = params;
501
502 let mut query_params = BTreeMap::new();
503 let body_params = BTreeMap::new();
504
505 if let Some(rw) = recv_window {
506 query_params.insert("recvWindow".to_string(), json!(rw));
507 }
508
509 send_request::<models::ClaimBoostRewardsResponse>(
510 &self.configuration,
511 "/sapi/v1/sol-staking/sol/claim",
512 reqwest::Method::POST,
513 query_params,
514 body_params,
515 if HAS_TIME_UNIT {
516 self.configuration.time_unit
517 } else {
518 None
519 },
520 true,
521 )
522 .await
523 }
524
525 async fn get_bnsol_rate_history(
526 &self,
527 params: GetBnsolRateHistoryParams,
528 ) -> anyhow::Result<RestApiResponse<models::GetBnsolRateHistoryResponse>> {
529 let GetBnsolRateHistoryParams {
530 start_time,
531 end_time,
532 current,
533 size,
534 recv_window,
535 } = params;
536
537 let mut query_params = BTreeMap::new();
538 let body_params = BTreeMap::new();
539
540 if let Some(rw) = start_time {
541 query_params.insert("startTime".to_string(), json!(rw));
542 }
543
544 if let Some(rw) = end_time {
545 query_params.insert("endTime".to_string(), json!(rw));
546 }
547
548 if let Some(rw) = current {
549 query_params.insert("current".to_string(), json!(rw));
550 }
551
552 if let Some(rw) = size {
553 query_params.insert("size".to_string(), json!(rw));
554 }
555
556 if let Some(rw) = recv_window {
557 query_params.insert("recvWindow".to_string(), json!(rw));
558 }
559
560 send_request::<models::GetBnsolRateHistoryResponse>(
561 &self.configuration,
562 "/sapi/v1/sol-staking/sol/history/rateHistory",
563 reqwest::Method::GET,
564 query_params,
565 body_params,
566 if HAS_TIME_UNIT {
567 self.configuration.time_unit
568 } else {
569 None
570 },
571 true,
572 )
573 .await
574 }
575
576 async fn get_bnsol_rewards_history(
577 &self,
578 params: GetBnsolRewardsHistoryParams,
579 ) -> anyhow::Result<RestApiResponse<models::GetBnsolRewardsHistoryResponse>> {
580 let GetBnsolRewardsHistoryParams {
581 start_time,
582 end_time,
583 current,
584 size,
585 recv_window,
586 } = params;
587
588 let mut query_params = BTreeMap::new();
589 let body_params = BTreeMap::new();
590
591 if let Some(rw) = start_time {
592 query_params.insert("startTime".to_string(), json!(rw));
593 }
594
595 if let Some(rw) = end_time {
596 query_params.insert("endTime".to_string(), json!(rw));
597 }
598
599 if let Some(rw) = current {
600 query_params.insert("current".to_string(), json!(rw));
601 }
602
603 if let Some(rw) = size {
604 query_params.insert("size".to_string(), json!(rw));
605 }
606
607 if let Some(rw) = recv_window {
608 query_params.insert("recvWindow".to_string(), json!(rw));
609 }
610
611 send_request::<models::GetBnsolRewardsHistoryResponse>(
612 &self.configuration,
613 "/sapi/v1/sol-staking/sol/history/bnsolRewardsHistory",
614 reqwest::Method::GET,
615 query_params,
616 body_params,
617 if HAS_TIME_UNIT {
618 self.configuration.time_unit
619 } else {
620 None
621 },
622 true,
623 )
624 .await
625 }
626
627 async fn get_boost_rewards_history(
628 &self,
629 params: GetBoostRewardsHistoryParams,
630 ) -> anyhow::Result<RestApiResponse<models::GetBoostRewardsHistoryResponse>> {
631 let GetBoostRewardsHistoryParams {
632 r#type,
633 start_time,
634 end_time,
635 current,
636 size,
637 recv_window,
638 } = params;
639
640 let mut query_params = BTreeMap::new();
641 let body_params = BTreeMap::new();
642
643 query_params.insert("type".to_string(), json!(r#type));
644
645 if let Some(rw) = start_time {
646 query_params.insert("startTime".to_string(), json!(rw));
647 }
648
649 if let Some(rw) = end_time {
650 query_params.insert("endTime".to_string(), json!(rw));
651 }
652
653 if let Some(rw) = current {
654 query_params.insert("current".to_string(), json!(rw));
655 }
656
657 if let Some(rw) = size {
658 query_params.insert("size".to_string(), json!(rw));
659 }
660
661 if let Some(rw) = recv_window {
662 query_params.insert("recvWindow".to_string(), json!(rw));
663 }
664
665 send_request::<models::GetBoostRewardsHistoryResponse>(
666 &self.configuration,
667 "/sapi/v1/sol-staking/sol/history/boostRewardsHistory",
668 reqwest::Method::GET,
669 query_params,
670 body_params,
671 if HAS_TIME_UNIT {
672 self.configuration.time_unit
673 } else {
674 None
675 },
676 true,
677 )
678 .await
679 }
680
681 async fn get_sol_redemption_history(
682 &self,
683 params: GetSolRedemptionHistoryParams,
684 ) -> anyhow::Result<RestApiResponse<models::GetSolRedemptionHistoryResponse>> {
685 let GetSolRedemptionHistoryParams {
686 redeem_id,
687 start_time,
688 end_time,
689 current,
690 size,
691 recv_window,
692 } = params;
693
694 let mut query_params = BTreeMap::new();
695 let body_params = BTreeMap::new();
696
697 if let Some(rw) = redeem_id {
698 query_params.insert("redeemId".to_string(), json!(rw));
699 }
700
701 if let Some(rw) = start_time {
702 query_params.insert("startTime".to_string(), json!(rw));
703 }
704
705 if let Some(rw) = end_time {
706 query_params.insert("endTime".to_string(), json!(rw));
707 }
708
709 if let Some(rw) = current {
710 query_params.insert("current".to_string(), json!(rw));
711 }
712
713 if let Some(rw) = size {
714 query_params.insert("size".to_string(), json!(rw));
715 }
716
717 if let Some(rw) = recv_window {
718 query_params.insert("recvWindow".to_string(), json!(rw));
719 }
720
721 send_request::<models::GetSolRedemptionHistoryResponse>(
722 &self.configuration,
723 "/sapi/v1/sol-staking/sol/history/redemptionHistory",
724 reqwest::Method::GET,
725 query_params,
726 body_params,
727 if HAS_TIME_UNIT {
728 self.configuration.time_unit
729 } else {
730 None
731 },
732 true,
733 )
734 .await
735 }
736
737 async fn get_sol_staking_history(
738 &self,
739 params: GetSolStakingHistoryParams,
740 ) -> anyhow::Result<RestApiResponse<models::GetSolStakingHistoryResponse>> {
741 let GetSolStakingHistoryParams {
742 purchase_id,
743 start_time,
744 end_time,
745 current,
746 size,
747 recv_window,
748 } = params;
749
750 let mut query_params = BTreeMap::new();
751 let body_params = BTreeMap::new();
752
753 if let Some(rw) = purchase_id {
754 query_params.insert("purchaseId".to_string(), json!(rw));
755 }
756
757 if let Some(rw) = start_time {
758 query_params.insert("startTime".to_string(), json!(rw));
759 }
760
761 if let Some(rw) = end_time {
762 query_params.insert("endTime".to_string(), json!(rw));
763 }
764
765 if let Some(rw) = current {
766 query_params.insert("current".to_string(), json!(rw));
767 }
768
769 if let Some(rw) = size {
770 query_params.insert("size".to_string(), json!(rw));
771 }
772
773 if let Some(rw) = recv_window {
774 query_params.insert("recvWindow".to_string(), json!(rw));
775 }
776
777 send_request::<models::GetSolStakingHistoryResponse>(
778 &self.configuration,
779 "/sapi/v1/sol-staking/sol/history/stakingHistory",
780 reqwest::Method::GET,
781 query_params,
782 body_params,
783 if HAS_TIME_UNIT {
784 self.configuration.time_unit
785 } else {
786 None
787 },
788 true,
789 )
790 .await
791 }
792
793 async fn get_sol_staking_quota_details(
794 &self,
795 params: GetSolStakingQuotaDetailsParams,
796 ) -> anyhow::Result<RestApiResponse<models::GetSolStakingQuotaDetailsResponse>> {
797 let GetSolStakingQuotaDetailsParams { recv_window } = params;
798
799 let mut query_params = BTreeMap::new();
800 let body_params = BTreeMap::new();
801
802 if let Some(rw) = recv_window {
803 query_params.insert("recvWindow".to_string(), json!(rw));
804 }
805
806 send_request::<models::GetSolStakingQuotaDetailsResponse>(
807 &self.configuration,
808 "/sapi/v1/sol-staking/sol/quota",
809 reqwest::Method::GET,
810 query_params,
811 body_params,
812 if HAS_TIME_UNIT {
813 self.configuration.time_unit
814 } else {
815 None
816 },
817 true,
818 )
819 .await
820 }
821
822 async fn get_unclaimed_rewards(
823 &self,
824 params: GetUnclaimedRewardsParams,
825 ) -> anyhow::Result<RestApiResponse<Vec<models::GetUnclaimedRewardsResponseInner>>> {
826 let GetUnclaimedRewardsParams { recv_window } = params;
827
828 let mut query_params = BTreeMap::new();
829 let body_params = BTreeMap::new();
830
831 if let Some(rw) = recv_window {
832 query_params.insert("recvWindow".to_string(), json!(rw));
833 }
834
835 send_request::<Vec<models::GetUnclaimedRewardsResponseInner>>(
836 &self.configuration,
837 "/sapi/v1/sol-staking/sol/history/unclaimedRewards",
838 reqwest::Method::GET,
839 query_params,
840 body_params,
841 if HAS_TIME_UNIT {
842 self.configuration.time_unit
843 } else {
844 None
845 },
846 true,
847 )
848 .await
849 }
850
851 async fn redeem_sol(
852 &self,
853 params: RedeemSolParams,
854 ) -> anyhow::Result<RestApiResponse<models::RedeemSolResponse>> {
855 let RedeemSolParams {
856 amount,
857 recv_window,
858 } = params;
859
860 let mut query_params = BTreeMap::new();
861 let body_params = BTreeMap::new();
862
863 query_params.insert("amount".to_string(), json!(amount));
864
865 if let Some(rw) = recv_window {
866 query_params.insert("recvWindow".to_string(), json!(rw));
867 }
868
869 send_request::<models::RedeemSolResponse>(
870 &self.configuration,
871 "/sapi/v1/sol-staking/sol/redeem",
872 reqwest::Method::POST,
873 query_params,
874 body_params,
875 if HAS_TIME_UNIT {
876 self.configuration.time_unit
877 } else {
878 None
879 },
880 true,
881 )
882 .await
883 }
884
885 async fn sol_staking_account(
886 &self,
887 params: SolStakingAccountParams,
888 ) -> anyhow::Result<RestApiResponse<models::SolStakingAccountResponse>> {
889 let SolStakingAccountParams { recv_window } = params;
890
891 let mut query_params = BTreeMap::new();
892 let body_params = BTreeMap::new();
893
894 if let Some(rw) = recv_window {
895 query_params.insert("recvWindow".to_string(), json!(rw));
896 }
897
898 send_request::<models::SolStakingAccountResponse>(
899 &self.configuration,
900 "/sapi/v1/sol-staking/account",
901 reqwest::Method::GET,
902 query_params,
903 body_params,
904 if HAS_TIME_UNIT {
905 self.configuration.time_unit
906 } else {
907 None
908 },
909 true,
910 )
911 .await
912 }
913
914 async fn subscribe_sol_staking(
915 &self,
916 params: SubscribeSolStakingParams,
917 ) -> anyhow::Result<RestApiResponse<models::SubscribeSolStakingResponse>> {
918 let SubscribeSolStakingParams {
919 amount,
920 recv_window,
921 } = params;
922
923 let mut query_params = BTreeMap::new();
924 let body_params = BTreeMap::new();
925
926 query_params.insert("amount".to_string(), json!(amount));
927
928 if let Some(rw) = recv_window {
929 query_params.insert("recvWindow".to_string(), json!(rw));
930 }
931
932 send_request::<models::SubscribeSolStakingResponse>(
933 &self.configuration,
934 "/sapi/v1/sol-staking/sol/stake",
935 reqwest::Method::POST,
936 query_params,
937 body_params,
938 if HAS_TIME_UNIT {
939 self.configuration.time_unit
940 } else {
941 None
942 },
943 true,
944 )
945 .await
946 }
947}
948
949#[cfg(all(test, feature = "staking"))]
950mod tests {
951 use super::*;
952 use crate::TOKIO_SHARED_RT;
953 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
954 use async_trait::async_trait;
955 use std::collections::HashMap;
956
957 struct DummyRestApiResponse<T> {
958 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
959 status: u16,
960 headers: HashMap<String, String>,
961 rate_limits: Option<Vec<RestApiRateLimit>>,
962 }
963
964 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
965 fn from(dummy: DummyRestApiResponse<T>) -> Self {
966 Self {
967 data_fn: dummy.inner,
968 status: dummy.status,
969 headers: dummy.headers,
970 rate_limits: dummy.rate_limits,
971 }
972 }
973 }
974
975 struct MockSolStakingApiClient {
976 force_error: bool,
977 }
978
979 #[async_trait]
980 impl SolStakingApi for MockSolStakingApiClient {
981 async fn claim_boost_rewards(
982 &self,
983 _params: ClaimBoostRewardsParams,
984 ) -> anyhow::Result<RestApiResponse<models::ClaimBoostRewardsResponse>> {
985 if self.force_error {
986 return Err(ConnectorError::ConnectorClientError {
987 msg: "ResponseError".to_string(),
988 code: None,
989 }
990 .into());
991 }
992
993 let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
994 let dummy_response: models::ClaimBoostRewardsResponse =
995 serde_json::from_value(resp_json.clone())
996 .expect("should parse into models::ClaimBoostRewardsResponse");
997
998 let dummy = DummyRestApiResponse {
999 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1000 status: 200,
1001 headers: HashMap::new(),
1002 rate_limits: None,
1003 };
1004
1005 Ok(dummy.into())
1006 }
1007
1008 async fn get_bnsol_rate_history(
1009 &self,
1010 _params: GetBnsolRateHistoryParams,
1011 ) -> anyhow::Result<RestApiResponse<models::GetBnsolRateHistoryResponse>> {
1012 if self.force_error {
1013 return Err(ConnectorError::ConnectorClientError {
1014 msg: "ResponseError".to_string(),
1015 code: None,
1016 }
1017 .into());
1018 }
1019
1020 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.001212343432","boostRewards":[{"boostAPR":"0.12000000","rewardsAsset":"SOL"},{"boostAPR":"0.00200000","rewardsAsset":"BNB"}],"time":1577233578000}],"total":"1"}"#).unwrap();
1021 let dummy_response: models::GetBnsolRateHistoryResponse =
1022 serde_json::from_value(resp_json.clone())
1023 .expect("should parse into models::GetBnsolRateHistoryResponse");
1024
1025 let dummy = DummyRestApiResponse {
1026 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1027 status: 200,
1028 headers: HashMap::new(),
1029 rate_limits: None,
1030 };
1031
1032 Ok(dummy.into())
1033 }
1034
1035 async fn get_bnsol_rewards_history(
1036 &self,
1037 _params: GetBnsolRewardsHistoryParams,
1038 ) -> anyhow::Result<RestApiResponse<models::GetBnsolRewardsHistoryResponse>> {
1039 if self.force_error {
1040 return Err(ConnectorError::ConnectorClientError {
1041 msg: "ResponseError".to_string(),
1042 code: None,
1043 }
1044 .into());
1045 }
1046
1047 let resp_json: Value = serde_json::from_str(r#"{"estRewardsInSOL":"1.23230920","rows":[{"time":1575018510000,"amountInSOL":"0.23223","holding":"2.3223","holdingInSOL":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1048 let dummy_response: models::GetBnsolRewardsHistoryResponse =
1049 serde_json::from_value(resp_json.clone())
1050 .expect("should parse into models::GetBnsolRewardsHistoryResponse");
1051
1052 let dummy = DummyRestApiResponse {
1053 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1054 status: 200,
1055 headers: HashMap::new(),
1056 rate_limits: None,
1057 };
1058
1059 Ok(dummy.into())
1060 }
1061
1062 async fn get_boost_rewards_history(
1063 &self,
1064 _params: GetBoostRewardsHistoryParams,
1065 ) -> anyhow::Result<RestApiResponse<models::GetBoostRewardsHistoryResponse>> {
1066 if self.force_error {
1067 return Err(ConnectorError::ConnectorClientError {
1068 msg: "ResponseError".to_string(),
1069 code: None,
1070 }
1071 .into());
1072 }
1073
1074 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1729520680,"token":"SOL","amount":"1.20291028","bnsolHolding":"2.0928798","status":"SUCCESS"}],"total":1}"#).unwrap();
1075 let dummy_response: models::GetBoostRewardsHistoryResponse =
1076 serde_json::from_value(resp_json.clone())
1077 .expect("should parse into models::GetBoostRewardsHistoryResponse");
1078
1079 let dummy = DummyRestApiResponse {
1080 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1081 status: 200,
1082 headers: HashMap::new(),
1083 rate_limits: None,
1084 };
1085
1086 Ok(dummy.into())
1087 }
1088
1089 async fn get_sol_redemption_history(
1090 &self,
1091 _params: GetSolRedemptionHistoryParams,
1092 ) -> anyhow::Result<RestApiResponse<models::GetSolRedemptionHistoryResponse>> {
1093 if self.force_error {
1094 return Err(ConnectorError::ConnectorClientError {
1095 msg: "ResponseError".to_string(),
1096 code: None,
1097 }
1098 .into());
1099 }
1100
1101 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"BNSOL","amount":"21312.23223","distributeAsset":"SOL","distributeAmount":"21338.0699","exchangeRate":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1102 let dummy_response: models::GetSolRedemptionHistoryResponse =
1103 serde_json::from_value(resp_json.clone())
1104 .expect("should parse into models::GetSolRedemptionHistoryResponse");
1105
1106 let dummy = DummyRestApiResponse {
1107 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1108 status: 200,
1109 headers: HashMap::new(),
1110 rate_limits: None,
1111 };
1112
1113 Ok(dummy.into())
1114 }
1115
1116 async fn get_sol_staking_history(
1117 &self,
1118 _params: GetSolStakingHistoryParams,
1119 ) -> anyhow::Result<RestApiResponse<models::GetSolStakingHistoryResponse>> {
1120 if self.force_error {
1121 return Err(ConnectorError::ConnectorClientError {
1122 msg: "ResponseError".to_string(),
1123 code: None,
1124 }
1125 .into());
1126 }
1127
1128 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"SOL","amount":"21312.23223","distributeAsset":"BNSOL","distributeAmount":"21286.42584","exchangeRate":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1129 let dummy_response: models::GetSolStakingHistoryResponse =
1130 serde_json::from_value(resp_json.clone())
1131 .expect("should parse into models::GetSolStakingHistoryResponse");
1132
1133 let dummy = DummyRestApiResponse {
1134 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1135 status: 200,
1136 headers: HashMap::new(),
1137 rate_limits: None,
1138 };
1139
1140 Ok(dummy.into())
1141 }
1142
1143 async fn get_sol_staking_quota_details(
1144 &self,
1145 _params: GetSolStakingQuotaDetailsParams,
1146 ) -> anyhow::Result<RestApiResponse<models::GetSolStakingQuotaDetailsResponse>> {
1147 if self.force_error {
1148 return Err(ConnectorError::ConnectorClientError {
1149 msg: "ResponseError".to_string(),
1150 code: None,
1151 }
1152 .into());
1153 }
1154
1155 let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.01000000","minRedeemAmount":"0.00000001","redeemPeriod":4,"stakeable":true,"redeemable":true,"soldOut":false,"commissionFee":"0.25000000","nextEpochTime":725993969475,"calculating":false}"#).unwrap();
1156 let dummy_response: models::GetSolStakingQuotaDetailsResponse =
1157 serde_json::from_value(resp_json.clone())
1158 .expect("should parse into models::GetSolStakingQuotaDetailsResponse");
1159
1160 let dummy = DummyRestApiResponse {
1161 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1162 status: 200,
1163 headers: HashMap::new(),
1164 rate_limits: None,
1165 };
1166
1167 Ok(dummy.into())
1168 }
1169
1170 async fn get_unclaimed_rewards(
1171 &self,
1172 _params: GetUnclaimedRewardsParams,
1173 ) -> anyhow::Result<RestApiResponse<Vec<models::GetUnclaimedRewardsResponseInner>>>
1174 {
1175 if self.force_error {
1176 return Err(ConnectorError::ConnectorClientError {
1177 msg: "ResponseError".to_string(),
1178 code: None,
1179 }
1180 .into());
1181 }
1182
1183 let resp_json: Value = serde_json::from_str(r#"[{"amount":"1.00000011","rewardsAsset":"SOL"},{"amount":"2.00202321","rewardsAsset":"BNB"}]"#).unwrap();
1184 let dummy_response: Vec<models::GetUnclaimedRewardsResponseInner> =
1185 serde_json::from_value(resp_json.clone())
1186 .expect("should parse into Vec<models::GetUnclaimedRewardsResponseInner>");
1187
1188 let dummy = DummyRestApiResponse {
1189 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1190 status: 200,
1191 headers: HashMap::new(),
1192 rate_limits: None,
1193 };
1194
1195 Ok(dummy.into())
1196 }
1197
1198 async fn redeem_sol(
1199 &self,
1200 _params: RedeemSolParams,
1201 ) -> anyhow::Result<RestApiResponse<models::RedeemSolResponse>> {
1202 if self.force_error {
1203 return Err(ConnectorError::ConnectorClientError {
1204 msg: "ResponseError".to_string(),
1205 code: None,
1206 }
1207 .into());
1208 }
1209
1210 let resp_json: Value = serde_json::from_str(r#"{"success":true,"solAmount":"0.23092091","exchangeRate":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1211 let dummy_response: models::RedeemSolResponse =
1212 serde_json::from_value(resp_json.clone())
1213 .expect("should parse into models::RedeemSolResponse");
1214
1215 let dummy = DummyRestApiResponse {
1216 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1217 status: 200,
1218 headers: HashMap::new(),
1219 rate_limits: None,
1220 };
1221
1222 Ok(dummy.into())
1223 }
1224
1225 async fn sol_staking_account(
1226 &self,
1227 _params: SolStakingAccountParams,
1228 ) -> anyhow::Result<RestApiResponse<models::SolStakingAccountResponse>> {
1229 if self.force_error {
1230 return Err(ConnectorError::ConnectorClientError {
1231 msg: "ResponseError".to_string(),
1232 code: None,
1233 }
1234 .into());
1235 }
1236
1237 let resp_json: Value = serde_json::from_str(r#"{"bnsolAmount":"1.10928781","holdingInSOL":"1.22330928","thirtyDaysProfitInSOL":"0.22330928"}"#).unwrap();
1238 let dummy_response: models::SolStakingAccountResponse =
1239 serde_json::from_value(resp_json.clone())
1240 .expect("should parse into models::SolStakingAccountResponse");
1241
1242 let dummy = DummyRestApiResponse {
1243 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1244 status: 200,
1245 headers: HashMap::new(),
1246 rate_limits: None,
1247 };
1248
1249 Ok(dummy.into())
1250 }
1251
1252 async fn subscribe_sol_staking(
1253 &self,
1254 _params: SubscribeSolStakingParams,
1255 ) -> anyhow::Result<RestApiResponse<models::SubscribeSolStakingResponse>> {
1256 if self.force_error {
1257 return Err(ConnectorError::ConnectorClientError {
1258 msg: "ResponseError".to_string(),
1259 code: None,
1260 }
1261 .into());
1262 }
1263
1264 let resp_json: Value = serde_json::from_str(r#"{"success":true,"bnsolAmount":"0.23092091","exchangeRate":"1.001212342342","purchaseId":1234567}"#).unwrap();
1265 let dummy_response: models::SubscribeSolStakingResponse =
1266 serde_json::from_value(resp_json.clone())
1267 .expect("should parse into models::SubscribeSolStakingResponse");
1268
1269 let dummy = DummyRestApiResponse {
1270 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1271 status: 200,
1272 headers: HashMap::new(),
1273 rate_limits: None,
1274 };
1275
1276 Ok(dummy.into())
1277 }
1278 }
1279
1280 #[test]
1281 fn claim_boost_rewards_required_params_success() {
1282 TOKIO_SHARED_RT.block_on(async {
1283 let client = MockSolStakingApiClient { force_error: false };
1284
1285 let params = ClaimBoostRewardsParams::builder().build().unwrap();
1286
1287 let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
1288 let expected_response: models::ClaimBoostRewardsResponse =
1289 serde_json::from_value(resp_json.clone())
1290 .expect("should parse into models::ClaimBoostRewardsResponse");
1291
1292 let resp = client
1293 .claim_boost_rewards(params)
1294 .await
1295 .expect("Expected a response");
1296 let data_future = resp.data();
1297 let actual_response = data_future.await.unwrap();
1298 assert_eq!(actual_response, expected_response);
1299 });
1300 }
1301
1302 #[test]
1303 fn claim_boost_rewards_optional_params_success() {
1304 TOKIO_SHARED_RT.block_on(async {
1305 let client = MockSolStakingApiClient { force_error: false };
1306
1307 let params = ClaimBoostRewardsParams::builder()
1308 .recv_window(5000)
1309 .build()
1310 .unwrap();
1311
1312 let resp_json: Value = serde_json::from_str(r#"{"success":true}"#).unwrap();
1313 let expected_response: models::ClaimBoostRewardsResponse =
1314 serde_json::from_value(resp_json.clone())
1315 .expect("should parse into models::ClaimBoostRewardsResponse");
1316
1317 let resp = client
1318 .claim_boost_rewards(params)
1319 .await
1320 .expect("Expected a response");
1321 let data_future = resp.data();
1322 let actual_response = data_future.await.unwrap();
1323 assert_eq!(actual_response, expected_response);
1324 });
1325 }
1326
1327 #[test]
1328 fn claim_boost_rewards_response_error() {
1329 TOKIO_SHARED_RT.block_on(async {
1330 let client = MockSolStakingApiClient { force_error: true };
1331
1332 let params = ClaimBoostRewardsParams::builder().build().unwrap();
1333
1334 match client.claim_boost_rewards(params).await {
1335 Ok(_) => panic!("Expected an error"),
1336 Err(err) => {
1337 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1338 }
1339 }
1340 });
1341 }
1342
1343 #[test]
1344 fn get_bnsol_rate_history_required_params_success() {
1345 TOKIO_SHARED_RT.block_on(async {
1346 let client = MockSolStakingApiClient { force_error: false };
1347
1348 let params = GetBnsolRateHistoryParams::builder().build().unwrap();
1349
1350 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.001212343432","boostRewards":[{"boostAPR":"0.12000000","rewardsAsset":"SOL"},{"boostAPR":"0.00200000","rewardsAsset":"BNB"}],"time":1577233578000}],"total":"1"}"#).unwrap();
1351 let expected_response : models::GetBnsolRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBnsolRateHistoryResponse");
1352
1353 let resp = client.get_bnsol_rate_history(params).await.expect("Expected a response");
1354 let data_future = resp.data();
1355 let actual_response = data_future.await.unwrap();
1356 assert_eq!(actual_response, expected_response);
1357 });
1358 }
1359
1360 #[test]
1361 fn get_bnsol_rate_history_optional_params_success() {
1362 TOKIO_SHARED_RT.block_on(async {
1363 let client = MockSolStakingApiClient { force_error: false };
1364
1365 let params = GetBnsolRateHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1366
1367 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.001212343432","boostRewards":[{"boostAPR":"0.12000000","rewardsAsset":"SOL"},{"boostAPR":"0.00200000","rewardsAsset":"BNB"}],"time":1577233578000}],"total":"1"}"#).unwrap();
1368 let expected_response : models::GetBnsolRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBnsolRateHistoryResponse");
1369
1370 let resp = client.get_bnsol_rate_history(params).await.expect("Expected a response");
1371 let data_future = resp.data();
1372 let actual_response = data_future.await.unwrap();
1373 assert_eq!(actual_response, expected_response);
1374 });
1375 }
1376
1377 #[test]
1378 fn get_bnsol_rate_history_response_error() {
1379 TOKIO_SHARED_RT.block_on(async {
1380 let client = MockSolStakingApiClient { force_error: true };
1381
1382 let params = GetBnsolRateHistoryParams::builder().build().unwrap();
1383
1384 match client.get_bnsol_rate_history(params).await {
1385 Ok(_) => panic!("Expected an error"),
1386 Err(err) => {
1387 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1388 }
1389 }
1390 });
1391 }
1392
1393 #[test]
1394 fn get_bnsol_rewards_history_required_params_success() {
1395 TOKIO_SHARED_RT.block_on(async {
1396 let client = MockSolStakingApiClient { force_error: false };
1397
1398 let params = GetBnsolRewardsHistoryParams::builder().build().unwrap();
1399
1400 let resp_json: Value = serde_json::from_str(r#"{"estRewardsInSOL":"1.23230920","rows":[{"time":1575018510000,"amountInSOL":"0.23223","holding":"2.3223","holdingInSOL":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1401 let expected_response : models::GetBnsolRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBnsolRewardsHistoryResponse");
1402
1403 let resp = client.get_bnsol_rewards_history(params).await.expect("Expected a response");
1404 let data_future = resp.data();
1405 let actual_response = data_future.await.unwrap();
1406 assert_eq!(actual_response, expected_response);
1407 });
1408 }
1409
1410 #[test]
1411 fn get_bnsol_rewards_history_optional_params_success() {
1412 TOKIO_SHARED_RT.block_on(async {
1413 let client = MockSolStakingApiClient { force_error: false };
1414
1415 let params = GetBnsolRewardsHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1416
1417 let resp_json: Value = serde_json::from_str(r#"{"estRewardsInSOL":"1.23230920","rows":[{"time":1575018510000,"amountInSOL":"0.23223","holding":"2.3223","holdingInSOL":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1418 let expected_response : models::GetBnsolRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBnsolRewardsHistoryResponse");
1419
1420 let resp = client.get_bnsol_rewards_history(params).await.expect("Expected a response");
1421 let data_future = resp.data();
1422 let actual_response = data_future.await.unwrap();
1423 assert_eq!(actual_response, expected_response);
1424 });
1425 }
1426
1427 #[test]
1428 fn get_bnsol_rewards_history_response_error() {
1429 TOKIO_SHARED_RT.block_on(async {
1430 let client = MockSolStakingApiClient { force_error: true };
1431
1432 let params = GetBnsolRewardsHistoryParams::builder().build().unwrap();
1433
1434 match client.get_bnsol_rewards_history(params).await {
1435 Ok(_) => panic!("Expected an error"),
1436 Err(err) => {
1437 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1438 }
1439 }
1440 });
1441 }
1442
1443 #[test]
1444 fn get_boost_rewards_history_required_params_success() {
1445 TOKIO_SHARED_RT.block_on(async {
1446 let client = MockSolStakingApiClient { force_error: false };
1447
1448 let params = GetBoostRewardsHistoryParams::builder("CLAIM".to_string(),).build().unwrap();
1449
1450 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1729520680,"token":"SOL","amount":"1.20291028","bnsolHolding":"2.0928798","status":"SUCCESS"}],"total":1}"#).unwrap();
1451 let expected_response : models::GetBoostRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBoostRewardsHistoryResponse");
1452
1453 let resp = client.get_boost_rewards_history(params).await.expect("Expected a response");
1454 let data_future = resp.data();
1455 let actual_response = data_future.await.unwrap();
1456 assert_eq!(actual_response, expected_response);
1457 });
1458 }
1459
1460 #[test]
1461 fn get_boost_rewards_history_optional_params_success() {
1462 TOKIO_SHARED_RT.block_on(async {
1463 let client = MockSolStakingApiClient { force_error: false };
1464
1465 let params = GetBoostRewardsHistoryParams::builder("CLAIM".to_string(),).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1466
1467 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1729520680,"token":"SOL","amount":"1.20291028","bnsolHolding":"2.0928798","status":"SUCCESS"}],"total":1}"#).unwrap();
1468 let expected_response : models::GetBoostRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetBoostRewardsHistoryResponse");
1469
1470 let resp = client.get_boost_rewards_history(params).await.expect("Expected a response");
1471 let data_future = resp.data();
1472 let actual_response = data_future.await.unwrap();
1473 assert_eq!(actual_response, expected_response);
1474 });
1475 }
1476
1477 #[test]
1478 fn get_boost_rewards_history_response_error() {
1479 TOKIO_SHARED_RT.block_on(async {
1480 let client = MockSolStakingApiClient { force_error: true };
1481
1482 let params = GetBoostRewardsHistoryParams::builder("CLAIM".to_string())
1483 .build()
1484 .unwrap();
1485
1486 match client.get_boost_rewards_history(params).await {
1487 Ok(_) => panic!("Expected an error"),
1488 Err(err) => {
1489 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1490 }
1491 }
1492 });
1493 }
1494
1495 #[test]
1496 fn get_sol_redemption_history_required_params_success() {
1497 TOKIO_SHARED_RT.block_on(async {
1498 let client = MockSolStakingApiClient { force_error: false };
1499
1500 let params = GetSolRedemptionHistoryParams::builder().build().unwrap();
1501
1502 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"BNSOL","amount":"21312.23223","distributeAsset":"SOL","distributeAmount":"21338.0699","exchangeRate":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1503 let expected_response : models::GetSolRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSolRedemptionHistoryResponse");
1504
1505 let resp = client.get_sol_redemption_history(params).await.expect("Expected a response");
1506 let data_future = resp.data();
1507 let actual_response = data_future.await.unwrap();
1508 assert_eq!(actual_response, expected_response);
1509 });
1510 }
1511
1512 #[test]
1513 fn get_sol_redemption_history_optional_params_success() {
1514 TOKIO_SHARED_RT.block_on(async {
1515 let client = MockSolStakingApiClient { force_error: false };
1516
1517 let params = GetSolRedemptionHistoryParams::builder().redeem_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1518
1519 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"BNSOL","amount":"21312.23223","distributeAsset":"SOL","distributeAmount":"21338.0699","exchangeRate":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1520 let expected_response : models::GetSolRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSolRedemptionHistoryResponse");
1521
1522 let resp = client.get_sol_redemption_history(params).await.expect("Expected a response");
1523 let data_future = resp.data();
1524 let actual_response = data_future.await.unwrap();
1525 assert_eq!(actual_response, expected_response);
1526 });
1527 }
1528
1529 #[test]
1530 fn get_sol_redemption_history_response_error() {
1531 TOKIO_SHARED_RT.block_on(async {
1532 let client = MockSolStakingApiClient { force_error: true };
1533
1534 let params = GetSolRedemptionHistoryParams::builder().build().unwrap();
1535
1536 match client.get_sol_redemption_history(params).await {
1537 Ok(_) => panic!("Expected an error"),
1538 Err(err) => {
1539 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1540 }
1541 }
1542 });
1543 }
1544
1545 #[test]
1546 fn get_sol_staking_history_required_params_success() {
1547 TOKIO_SHARED_RT.block_on(async {
1548 let client = MockSolStakingApiClient { force_error: false };
1549
1550 let params = GetSolStakingHistoryParams::builder().build().unwrap();
1551
1552 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"SOL","amount":"21312.23223","distributeAsset":"BNSOL","distributeAmount":"21286.42584","exchangeRate":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1553 let expected_response : models::GetSolStakingHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSolStakingHistoryResponse");
1554
1555 let resp = client.get_sol_staking_history(params).await.expect("Expected a response");
1556 let data_future = resp.data();
1557 let actual_response = data_future.await.unwrap();
1558 assert_eq!(actual_response, expected_response);
1559 });
1560 }
1561
1562 #[test]
1563 fn get_sol_staking_history_optional_params_success() {
1564 TOKIO_SHARED_RT.block_on(async {
1565 let client = MockSolStakingApiClient { force_error: false };
1566
1567 let params = GetSolStakingHistoryParams::builder().purchase_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1568
1569 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"SOL","amount":"21312.23223","distributeAsset":"BNSOL","distributeAmount":"21286.42584","exchangeRate":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1570 let expected_response : models::GetSolStakingHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSolStakingHistoryResponse");
1571
1572 let resp = client.get_sol_staking_history(params).await.expect("Expected a response");
1573 let data_future = resp.data();
1574 let actual_response = data_future.await.unwrap();
1575 assert_eq!(actual_response, expected_response);
1576 });
1577 }
1578
1579 #[test]
1580 fn get_sol_staking_history_response_error() {
1581 TOKIO_SHARED_RT.block_on(async {
1582 let client = MockSolStakingApiClient { force_error: true };
1583
1584 let params = GetSolStakingHistoryParams::builder().build().unwrap();
1585
1586 match client.get_sol_staking_history(params).await {
1587 Ok(_) => panic!("Expected an error"),
1588 Err(err) => {
1589 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1590 }
1591 }
1592 });
1593 }
1594
1595 #[test]
1596 fn get_sol_staking_quota_details_required_params_success() {
1597 TOKIO_SHARED_RT.block_on(async {
1598 let client = MockSolStakingApiClient { force_error: false };
1599
1600 let params = GetSolStakingQuotaDetailsParams::builder().build().unwrap();
1601
1602 let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.01000000","minRedeemAmount":"0.00000001","redeemPeriod":4,"stakeable":true,"redeemable":true,"soldOut":false,"commissionFee":"0.25000000","nextEpochTime":725993969475,"calculating":false}"#).unwrap();
1603 let expected_response : models::GetSolStakingQuotaDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSolStakingQuotaDetailsResponse");
1604
1605 let resp = client.get_sol_staking_quota_details(params).await.expect("Expected a response");
1606 let data_future = resp.data();
1607 let actual_response = data_future.await.unwrap();
1608 assert_eq!(actual_response, expected_response);
1609 });
1610 }
1611
1612 #[test]
1613 fn get_sol_staking_quota_details_optional_params_success() {
1614 TOKIO_SHARED_RT.block_on(async {
1615 let client = MockSolStakingApiClient { force_error: false };
1616
1617 let params = GetSolStakingQuotaDetailsParams::builder().recv_window(5000).build().unwrap();
1618
1619 let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.01000000","minRedeemAmount":"0.00000001","redeemPeriod":4,"stakeable":true,"redeemable":true,"soldOut":false,"commissionFee":"0.25000000","nextEpochTime":725993969475,"calculating":false}"#).unwrap();
1620 let expected_response : models::GetSolStakingQuotaDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSolStakingQuotaDetailsResponse");
1621
1622 let resp = client.get_sol_staking_quota_details(params).await.expect("Expected a response");
1623 let data_future = resp.data();
1624 let actual_response = data_future.await.unwrap();
1625 assert_eq!(actual_response, expected_response);
1626 });
1627 }
1628
1629 #[test]
1630 fn get_sol_staking_quota_details_response_error() {
1631 TOKIO_SHARED_RT.block_on(async {
1632 let client = MockSolStakingApiClient { force_error: true };
1633
1634 let params = GetSolStakingQuotaDetailsParams::builder().build().unwrap();
1635
1636 match client.get_sol_staking_quota_details(params).await {
1637 Ok(_) => panic!("Expected an error"),
1638 Err(err) => {
1639 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1640 }
1641 }
1642 });
1643 }
1644
1645 #[test]
1646 fn get_unclaimed_rewards_required_params_success() {
1647 TOKIO_SHARED_RT.block_on(async {
1648 let client = MockSolStakingApiClient { force_error: false };
1649
1650 let params = GetUnclaimedRewardsParams::builder().build().unwrap();
1651
1652 let resp_json: Value = serde_json::from_str(r#"[{"amount":"1.00000011","rewardsAsset":"SOL"},{"amount":"2.00202321","rewardsAsset":"BNB"}]"#).unwrap();
1653 let expected_response : Vec<models::GetUnclaimedRewardsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetUnclaimedRewardsResponseInner>");
1654
1655 let resp = client.get_unclaimed_rewards(params).await.expect("Expected a response");
1656 let data_future = resp.data();
1657 let actual_response = data_future.await.unwrap();
1658 assert_eq!(actual_response, expected_response);
1659 });
1660 }
1661
1662 #[test]
1663 fn get_unclaimed_rewards_optional_params_success() {
1664 TOKIO_SHARED_RT.block_on(async {
1665 let client = MockSolStakingApiClient { force_error: false };
1666
1667 let params = GetUnclaimedRewardsParams::builder().recv_window(5000).build().unwrap();
1668
1669 let resp_json: Value = serde_json::from_str(r#"[{"amount":"1.00000011","rewardsAsset":"SOL"},{"amount":"2.00202321","rewardsAsset":"BNB"}]"#).unwrap();
1670 let expected_response : Vec<models::GetUnclaimedRewardsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetUnclaimedRewardsResponseInner>");
1671
1672 let resp = client.get_unclaimed_rewards(params).await.expect("Expected a response");
1673 let data_future = resp.data();
1674 let actual_response = data_future.await.unwrap();
1675 assert_eq!(actual_response, expected_response);
1676 });
1677 }
1678
1679 #[test]
1680 fn get_unclaimed_rewards_response_error() {
1681 TOKIO_SHARED_RT.block_on(async {
1682 let client = MockSolStakingApiClient { force_error: true };
1683
1684 let params = GetUnclaimedRewardsParams::builder().build().unwrap();
1685
1686 match client.get_unclaimed_rewards(params).await {
1687 Ok(_) => panic!("Expected an error"),
1688 Err(err) => {
1689 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1690 }
1691 }
1692 });
1693 }
1694
1695 #[test]
1696 fn redeem_sol_required_params_success() {
1697 TOKIO_SHARED_RT.block_on(async {
1698 let client = MockSolStakingApiClient { force_error: false };
1699
1700 let params = RedeemSolParams::builder(dec!(1.0),).build().unwrap();
1701
1702 let resp_json: Value = serde_json::from_str(r#"{"success":true,"solAmount":"0.23092091","exchangeRate":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1703 let expected_response : models::RedeemSolResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemSolResponse");
1704
1705 let resp = client.redeem_sol(params).await.expect("Expected a response");
1706 let data_future = resp.data();
1707 let actual_response = data_future.await.unwrap();
1708 assert_eq!(actual_response, expected_response);
1709 });
1710 }
1711
1712 #[test]
1713 fn redeem_sol_optional_params_success() {
1714 TOKIO_SHARED_RT.block_on(async {
1715 let client = MockSolStakingApiClient { force_error: false };
1716
1717 let params = RedeemSolParams::builder(dec!(1.0),).recv_window(5000).build().unwrap();
1718
1719 let resp_json: Value = serde_json::from_str(r#"{"success":true,"solAmount":"0.23092091","exchangeRate":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1720 let expected_response : models::RedeemSolResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemSolResponse");
1721
1722 let resp = client.redeem_sol(params).await.expect("Expected a response");
1723 let data_future = resp.data();
1724 let actual_response = data_future.await.unwrap();
1725 assert_eq!(actual_response, expected_response);
1726 });
1727 }
1728
1729 #[test]
1730 fn redeem_sol_response_error() {
1731 TOKIO_SHARED_RT.block_on(async {
1732 let client = MockSolStakingApiClient { force_error: true };
1733
1734 let params = RedeemSolParams::builder(dec!(1.0)).build().unwrap();
1735
1736 match client.redeem_sol(params).await {
1737 Ok(_) => panic!("Expected an error"),
1738 Err(err) => {
1739 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1740 }
1741 }
1742 });
1743 }
1744
1745 #[test]
1746 fn sol_staking_account_required_params_success() {
1747 TOKIO_SHARED_RT.block_on(async {
1748 let client = MockSolStakingApiClient { force_error: false };
1749
1750 let params = SolStakingAccountParams::builder().build().unwrap();
1751
1752 let resp_json: Value = serde_json::from_str(r#"{"bnsolAmount":"1.10928781","holdingInSOL":"1.22330928","thirtyDaysProfitInSOL":"0.22330928"}"#).unwrap();
1753 let expected_response : models::SolStakingAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SolStakingAccountResponse");
1754
1755 let resp = client.sol_staking_account(params).await.expect("Expected a response");
1756 let data_future = resp.data();
1757 let actual_response = data_future.await.unwrap();
1758 assert_eq!(actual_response, expected_response);
1759 });
1760 }
1761
1762 #[test]
1763 fn sol_staking_account_optional_params_success() {
1764 TOKIO_SHARED_RT.block_on(async {
1765 let client = MockSolStakingApiClient { force_error: false };
1766
1767 let params = SolStakingAccountParams::builder().recv_window(5000).build().unwrap();
1768
1769 let resp_json: Value = serde_json::from_str(r#"{"bnsolAmount":"1.10928781","holdingInSOL":"1.22330928","thirtyDaysProfitInSOL":"0.22330928"}"#).unwrap();
1770 let expected_response : models::SolStakingAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SolStakingAccountResponse");
1771
1772 let resp = client.sol_staking_account(params).await.expect("Expected a response");
1773 let data_future = resp.data();
1774 let actual_response = data_future.await.unwrap();
1775 assert_eq!(actual_response, expected_response);
1776 });
1777 }
1778
1779 #[test]
1780 fn sol_staking_account_response_error() {
1781 TOKIO_SHARED_RT.block_on(async {
1782 let client = MockSolStakingApiClient { force_error: true };
1783
1784 let params = SolStakingAccountParams::builder().build().unwrap();
1785
1786 match client.sol_staking_account(params).await {
1787 Ok(_) => panic!("Expected an error"),
1788 Err(err) => {
1789 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1790 }
1791 }
1792 });
1793 }
1794
1795 #[test]
1796 fn subscribe_sol_staking_required_params_success() {
1797 TOKIO_SHARED_RT.block_on(async {
1798 let client = MockSolStakingApiClient { force_error: false };
1799
1800 let params = SubscribeSolStakingParams::builder(dec!(1.0),).build().unwrap();
1801
1802 let resp_json: Value = serde_json::from_str(r#"{"success":true,"bnsolAmount":"0.23092091","exchangeRate":"1.001212342342","purchaseId":1234567}"#).unwrap();
1803 let expected_response : models::SubscribeSolStakingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SubscribeSolStakingResponse");
1804
1805 let resp = client.subscribe_sol_staking(params).await.expect("Expected a response");
1806 let data_future = resp.data();
1807 let actual_response = data_future.await.unwrap();
1808 assert_eq!(actual_response, expected_response);
1809 });
1810 }
1811
1812 #[test]
1813 fn subscribe_sol_staking_optional_params_success() {
1814 TOKIO_SHARED_RT.block_on(async {
1815 let client = MockSolStakingApiClient { force_error: false };
1816
1817 let params = SubscribeSolStakingParams::builder(dec!(1.0),).recv_window(5000).build().unwrap();
1818
1819 let resp_json: Value = serde_json::from_str(r#"{"success":true,"bnsolAmount":"0.23092091","exchangeRate":"1.001212342342","purchaseId":1234567}"#).unwrap();
1820 let expected_response : models::SubscribeSolStakingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SubscribeSolStakingResponse");
1821
1822 let resp = client.subscribe_sol_staking(params).await.expect("Expected a response");
1823 let data_future = resp.data();
1824 let actual_response = data_future.await.unwrap();
1825 assert_eq!(actual_response, expected_response);
1826 });
1827 }
1828
1829 #[test]
1830 fn subscribe_sol_staking_response_error() {
1831 TOKIO_SHARED_RT.block_on(async {
1832 let client = MockSolStakingApiClient { force_error: true };
1833
1834 let params = SubscribeSolStakingParams::builder(dec!(1.0))
1835 .build()
1836 .unwrap();
1837
1838 match client.subscribe_sol_staking(params).await {
1839 Ok(_) => panic!("Expected an error"),
1840 Err(err) => {
1841 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1842 }
1843 }
1844 });
1845 }
1846}