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 EthStakingApi: Send + Sync {
34 async fn eth_staking_account(
35 &self,
36 params: EthStakingAccountParams,
37 ) -> anyhow::Result<RestApiResponse<models::EthStakingAccountResponse>>;
38 async fn get_current_eth_staking_quota(
39 &self,
40 params: GetCurrentEthStakingQuotaParams,
41 ) -> anyhow::Result<RestApiResponse<models::GetCurrentEthStakingQuotaResponse>>;
42 async fn get_eth_redemption_history(
43 &self,
44 params: GetEthRedemptionHistoryParams,
45 ) -> anyhow::Result<RestApiResponse<models::GetEthRedemptionHistoryResponse>>;
46 async fn get_eth_staking_history(
47 &self,
48 params: GetEthStakingHistoryParams,
49 ) -> anyhow::Result<RestApiResponse<models::GetEthStakingHistoryResponse>>;
50 async fn get_wbeth_rate_history(
51 &self,
52 params: GetWbethRateHistoryParams,
53 ) -> anyhow::Result<RestApiResponse<models::GetWbethRateHistoryResponse>>;
54 async fn get_wbeth_rewards_history(
55 &self,
56 params: GetWbethRewardsHistoryParams,
57 ) -> anyhow::Result<RestApiResponse<models::GetWbethRewardsHistoryResponse>>;
58 async fn get_wbeth_unwrap_history(
59 &self,
60 params: GetWbethUnwrapHistoryParams,
61 ) -> anyhow::Result<RestApiResponse<models::GetWbethUnwrapHistoryResponse>>;
62 async fn get_wbeth_wrap_history(
63 &self,
64 params: GetWbethWrapHistoryParams,
65 ) -> anyhow::Result<RestApiResponse<models::GetWbethWrapHistoryResponse>>;
66 async fn redeem_eth(
67 &self,
68 params: RedeemEthParams,
69 ) -> anyhow::Result<RestApiResponse<models::RedeemEthResponse>>;
70 async fn subscribe_eth_staking(
71 &self,
72 params: SubscribeEthStakingParams,
73 ) -> anyhow::Result<RestApiResponse<models::SubscribeEthStakingResponse>>;
74 async fn wrap_beth(
75 &self,
76 params: WrapBethParams,
77 ) -> anyhow::Result<RestApiResponse<models::WrapBethResponse>>;
78}
79
80#[derive(Debug, Clone)]
81pub struct EthStakingApiClient {
82 configuration: ConfigurationRestApi,
83}
84
85impl EthStakingApiClient {
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 EthStakingAccountParams {
98 #[builder(setter(into), default)]
103 pub recv_window: Option<i64>,
104}
105
106impl EthStakingAccountParams {
107 #[must_use]
110 pub fn builder() -> EthStakingAccountParamsBuilder {
111 EthStakingAccountParamsBuilder::default()
112 }
113}
114#[derive(Clone, Debug, Builder, Default)]
119#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
120pub struct GetCurrentEthStakingQuotaParams {
121 #[builder(setter(into), default)]
126 pub recv_window: Option<i64>,
127}
128
129impl GetCurrentEthStakingQuotaParams {
130 #[must_use]
133 pub fn builder() -> GetCurrentEthStakingQuotaParamsBuilder {
134 GetCurrentEthStakingQuotaParamsBuilder::default()
135 }
136}
137#[derive(Clone, Debug, Builder, Default)]
142#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
143pub struct GetEthRedemptionHistoryParams {
144 #[builder(setter(into), default)]
149 pub redeem_id: Option<i64>,
150 #[builder(setter(into), default)]
155 pub start_time: Option<i64>,
156 #[builder(setter(into), default)]
161 pub end_time: Option<i64>,
162 #[builder(setter(into), default)]
166 pub current: Option<i64>,
167 #[builder(setter(into), default)]
171 pub size: Option<i64>,
172 #[builder(setter(into), default)]
177 pub recv_window: Option<i64>,
178}
179
180impl GetEthRedemptionHistoryParams {
181 #[must_use]
184 pub fn builder() -> GetEthRedemptionHistoryParamsBuilder {
185 GetEthRedemptionHistoryParamsBuilder::default()
186 }
187}
188#[derive(Clone, Debug, Builder, Default)]
193#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
194pub struct GetEthStakingHistoryParams {
195 #[builder(setter(into), default)]
200 pub purchase_id: Option<i64>,
201 #[builder(setter(into), default)]
206 pub start_time: Option<i64>,
207 #[builder(setter(into), default)]
212 pub end_time: Option<i64>,
213 #[builder(setter(into), default)]
217 pub current: Option<i64>,
218 #[builder(setter(into), default)]
222 pub size: Option<i64>,
223 #[builder(setter(into), default)]
228 pub recv_window: Option<i64>,
229}
230
231impl GetEthStakingHistoryParams {
232 #[must_use]
235 pub fn builder() -> GetEthStakingHistoryParamsBuilder {
236 GetEthStakingHistoryParamsBuilder::default()
237 }
238}
239#[derive(Clone, Debug, Builder, Default)]
244#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
245pub struct GetWbethRateHistoryParams {
246 #[builder(setter(into), default)]
251 pub start_time: Option<i64>,
252 #[builder(setter(into), default)]
257 pub end_time: Option<i64>,
258 #[builder(setter(into), default)]
262 pub current: Option<i64>,
263 #[builder(setter(into), default)]
267 pub size: Option<i64>,
268 #[builder(setter(into), default)]
273 pub recv_window: Option<i64>,
274}
275
276impl GetWbethRateHistoryParams {
277 #[must_use]
280 pub fn builder() -> GetWbethRateHistoryParamsBuilder {
281 GetWbethRateHistoryParamsBuilder::default()
282 }
283}
284#[derive(Clone, Debug, Builder, Default)]
289#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
290pub struct GetWbethRewardsHistoryParams {
291 #[builder(setter(into), default)]
296 pub start_time: Option<i64>,
297 #[builder(setter(into), default)]
302 pub end_time: Option<i64>,
303 #[builder(setter(into), default)]
307 pub current: Option<i64>,
308 #[builder(setter(into), default)]
312 pub size: Option<i64>,
313 #[builder(setter(into), default)]
318 pub recv_window: Option<i64>,
319}
320
321impl GetWbethRewardsHistoryParams {
322 #[must_use]
325 pub fn builder() -> GetWbethRewardsHistoryParamsBuilder {
326 GetWbethRewardsHistoryParamsBuilder::default()
327 }
328}
329#[derive(Clone, Debug, Builder, Default)]
334#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
335pub struct GetWbethUnwrapHistoryParams {
336 #[builder(setter(into), default)]
341 pub start_time: Option<i64>,
342 #[builder(setter(into), default)]
347 pub end_time: Option<i64>,
348 #[builder(setter(into), default)]
352 pub current: Option<i64>,
353 #[builder(setter(into), default)]
357 pub size: Option<i64>,
358 #[builder(setter(into), default)]
363 pub recv_window: Option<i64>,
364}
365
366impl GetWbethUnwrapHistoryParams {
367 #[must_use]
370 pub fn builder() -> GetWbethUnwrapHistoryParamsBuilder {
371 GetWbethUnwrapHistoryParamsBuilder::default()
372 }
373}
374#[derive(Clone, Debug, Builder, Default)]
379#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
380pub struct GetWbethWrapHistoryParams {
381 #[builder(setter(into), default)]
386 pub start_time: Option<i64>,
387 #[builder(setter(into), default)]
392 pub end_time: Option<i64>,
393 #[builder(setter(into), default)]
397 pub current: Option<i64>,
398 #[builder(setter(into), default)]
402 pub size: Option<i64>,
403 #[builder(setter(into), default)]
408 pub recv_window: Option<i64>,
409}
410
411impl GetWbethWrapHistoryParams {
412 #[must_use]
415 pub fn builder() -> GetWbethWrapHistoryParamsBuilder {
416 GetWbethWrapHistoryParamsBuilder::default()
417 }
418}
419#[derive(Clone, Debug, Builder)]
424#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
425pub struct RedeemEthParams {
426 #[builder(setter(into))]
430 pub amount: rust_decimal::Decimal,
431 #[builder(setter(into), default)]
435 pub asset: Option<String>,
436 #[builder(setter(into), default)]
441 pub recv_window: Option<i64>,
442}
443
444impl RedeemEthParams {
445 #[must_use]
452 pub fn builder(amount: rust_decimal::Decimal) -> RedeemEthParamsBuilder {
453 RedeemEthParamsBuilder::default().amount(amount)
454 }
455}
456#[derive(Clone, Debug, Builder)]
461#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
462pub struct SubscribeEthStakingParams {
463 #[builder(setter(into))]
467 pub amount: rust_decimal::Decimal,
468 #[builder(setter(into), default)]
473 pub recv_window: Option<i64>,
474}
475
476impl SubscribeEthStakingParams {
477 #[must_use]
484 pub fn builder(amount: rust_decimal::Decimal) -> SubscribeEthStakingParamsBuilder {
485 SubscribeEthStakingParamsBuilder::default().amount(amount)
486 }
487}
488#[derive(Clone, Debug, Builder)]
493#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
494pub struct WrapBethParams {
495 #[builder(setter(into))]
499 pub amount: rust_decimal::Decimal,
500 #[builder(setter(into), default)]
505 pub recv_window: Option<i64>,
506}
507
508impl WrapBethParams {
509 #[must_use]
516 pub fn builder(amount: rust_decimal::Decimal) -> WrapBethParamsBuilder {
517 WrapBethParamsBuilder::default().amount(amount)
518 }
519}
520
521#[async_trait]
522impl EthStakingApi for EthStakingApiClient {
523 async fn eth_staking_account(
524 &self,
525 params: EthStakingAccountParams,
526 ) -> anyhow::Result<RestApiResponse<models::EthStakingAccountResponse>> {
527 let EthStakingAccountParams { recv_window } = params;
528
529 let mut query_params = BTreeMap::new();
530 let body_params = BTreeMap::new();
531
532 if let Some(rw) = recv_window {
533 query_params.insert("recvWindow".to_string(), json!(rw));
534 }
535
536 send_request::<models::EthStakingAccountResponse>(
537 &self.configuration,
538 "/sapi/v2/eth-staking/account",
539 reqwest::Method::GET,
540 query_params,
541 body_params,
542 if HAS_TIME_UNIT {
543 self.configuration.time_unit
544 } else {
545 None
546 },
547 true,
548 )
549 .await
550 }
551
552 async fn get_current_eth_staking_quota(
553 &self,
554 params: GetCurrentEthStakingQuotaParams,
555 ) -> anyhow::Result<RestApiResponse<models::GetCurrentEthStakingQuotaResponse>> {
556 let GetCurrentEthStakingQuotaParams { recv_window } = params;
557
558 let mut query_params = BTreeMap::new();
559 let body_params = BTreeMap::new();
560
561 if let Some(rw) = recv_window {
562 query_params.insert("recvWindow".to_string(), json!(rw));
563 }
564
565 send_request::<models::GetCurrentEthStakingQuotaResponse>(
566 &self.configuration,
567 "/sapi/v1/eth-staking/eth/quota",
568 reqwest::Method::GET,
569 query_params,
570 body_params,
571 if HAS_TIME_UNIT {
572 self.configuration.time_unit
573 } else {
574 None
575 },
576 true,
577 )
578 .await
579 }
580
581 async fn get_eth_redemption_history(
582 &self,
583 params: GetEthRedemptionHistoryParams,
584 ) -> anyhow::Result<RestApiResponse<models::GetEthRedemptionHistoryResponse>> {
585 let GetEthRedemptionHistoryParams {
586 redeem_id,
587 start_time,
588 end_time,
589 current,
590 size,
591 recv_window,
592 } = params;
593
594 let mut query_params = BTreeMap::new();
595 let body_params = BTreeMap::new();
596
597 if let Some(rw) = redeem_id {
598 query_params.insert("redeemId".to_string(), json!(rw));
599 }
600
601 if let Some(rw) = start_time {
602 query_params.insert("startTime".to_string(), json!(rw));
603 }
604
605 if let Some(rw) = end_time {
606 query_params.insert("endTime".to_string(), json!(rw));
607 }
608
609 if let Some(rw) = current {
610 query_params.insert("current".to_string(), json!(rw));
611 }
612
613 if let Some(rw) = size {
614 query_params.insert("size".to_string(), json!(rw));
615 }
616
617 if let Some(rw) = recv_window {
618 query_params.insert("recvWindow".to_string(), json!(rw));
619 }
620
621 send_request::<models::GetEthRedemptionHistoryResponse>(
622 &self.configuration,
623 "/sapi/v1/eth-staking/eth/history/redemptionHistory",
624 reqwest::Method::GET,
625 query_params,
626 body_params,
627 if HAS_TIME_UNIT {
628 self.configuration.time_unit
629 } else {
630 None
631 },
632 true,
633 )
634 .await
635 }
636
637 async fn get_eth_staking_history(
638 &self,
639 params: GetEthStakingHistoryParams,
640 ) -> anyhow::Result<RestApiResponse<models::GetEthStakingHistoryResponse>> {
641 let GetEthStakingHistoryParams {
642 purchase_id,
643 start_time,
644 end_time,
645 current,
646 size,
647 recv_window,
648 } = params;
649
650 let mut query_params = BTreeMap::new();
651 let body_params = BTreeMap::new();
652
653 if let Some(rw) = purchase_id {
654 query_params.insert("purchaseId".to_string(), json!(rw));
655 }
656
657 if let Some(rw) = start_time {
658 query_params.insert("startTime".to_string(), json!(rw));
659 }
660
661 if let Some(rw) = end_time {
662 query_params.insert("endTime".to_string(), json!(rw));
663 }
664
665 if let Some(rw) = current {
666 query_params.insert("current".to_string(), json!(rw));
667 }
668
669 if let Some(rw) = size {
670 query_params.insert("size".to_string(), json!(rw));
671 }
672
673 if let Some(rw) = recv_window {
674 query_params.insert("recvWindow".to_string(), json!(rw));
675 }
676
677 send_request::<models::GetEthStakingHistoryResponse>(
678 &self.configuration,
679 "/sapi/v1/eth-staking/eth/history/stakingHistory",
680 reqwest::Method::GET,
681 query_params,
682 body_params,
683 if HAS_TIME_UNIT {
684 self.configuration.time_unit
685 } else {
686 None
687 },
688 true,
689 )
690 .await
691 }
692
693 async fn get_wbeth_rate_history(
694 &self,
695 params: GetWbethRateHistoryParams,
696 ) -> anyhow::Result<RestApiResponse<models::GetWbethRateHistoryResponse>> {
697 let GetWbethRateHistoryParams {
698 start_time,
699 end_time,
700 current,
701 size,
702 recv_window,
703 } = params;
704
705 let mut query_params = BTreeMap::new();
706 let body_params = BTreeMap::new();
707
708 if let Some(rw) = start_time {
709 query_params.insert("startTime".to_string(), json!(rw));
710 }
711
712 if let Some(rw) = end_time {
713 query_params.insert("endTime".to_string(), json!(rw));
714 }
715
716 if let Some(rw) = current {
717 query_params.insert("current".to_string(), json!(rw));
718 }
719
720 if let Some(rw) = size {
721 query_params.insert("size".to_string(), json!(rw));
722 }
723
724 if let Some(rw) = recv_window {
725 query_params.insert("recvWindow".to_string(), json!(rw));
726 }
727
728 send_request::<models::GetWbethRateHistoryResponse>(
729 &self.configuration,
730 "/sapi/v1/eth-staking/eth/history/rateHistory",
731 reqwest::Method::GET,
732 query_params,
733 body_params,
734 if HAS_TIME_UNIT {
735 self.configuration.time_unit
736 } else {
737 None
738 },
739 true,
740 )
741 .await
742 }
743
744 async fn get_wbeth_rewards_history(
745 &self,
746 params: GetWbethRewardsHistoryParams,
747 ) -> anyhow::Result<RestApiResponse<models::GetWbethRewardsHistoryResponse>> {
748 let GetWbethRewardsHistoryParams {
749 start_time,
750 end_time,
751 current,
752 size,
753 recv_window,
754 } = params;
755
756 let mut query_params = BTreeMap::new();
757 let body_params = BTreeMap::new();
758
759 if let Some(rw) = start_time {
760 query_params.insert("startTime".to_string(), json!(rw));
761 }
762
763 if let Some(rw) = end_time {
764 query_params.insert("endTime".to_string(), json!(rw));
765 }
766
767 if let Some(rw) = current {
768 query_params.insert("current".to_string(), json!(rw));
769 }
770
771 if let Some(rw) = size {
772 query_params.insert("size".to_string(), json!(rw));
773 }
774
775 if let Some(rw) = recv_window {
776 query_params.insert("recvWindow".to_string(), json!(rw));
777 }
778
779 send_request::<models::GetWbethRewardsHistoryResponse>(
780 &self.configuration,
781 "/sapi/v1/eth-staking/eth/history/wbethRewardsHistory",
782 reqwest::Method::GET,
783 query_params,
784 body_params,
785 if HAS_TIME_UNIT {
786 self.configuration.time_unit
787 } else {
788 None
789 },
790 true,
791 )
792 .await
793 }
794
795 async fn get_wbeth_unwrap_history(
796 &self,
797 params: GetWbethUnwrapHistoryParams,
798 ) -> anyhow::Result<RestApiResponse<models::GetWbethUnwrapHistoryResponse>> {
799 let GetWbethUnwrapHistoryParams {
800 start_time,
801 end_time,
802 current,
803 size,
804 recv_window,
805 } = params;
806
807 let mut query_params = BTreeMap::new();
808 let body_params = BTreeMap::new();
809
810 if let Some(rw) = start_time {
811 query_params.insert("startTime".to_string(), json!(rw));
812 }
813
814 if let Some(rw) = end_time {
815 query_params.insert("endTime".to_string(), json!(rw));
816 }
817
818 if let Some(rw) = current {
819 query_params.insert("current".to_string(), json!(rw));
820 }
821
822 if let Some(rw) = size {
823 query_params.insert("size".to_string(), json!(rw));
824 }
825
826 if let Some(rw) = recv_window {
827 query_params.insert("recvWindow".to_string(), json!(rw));
828 }
829
830 send_request::<models::GetWbethUnwrapHistoryResponse>(
831 &self.configuration,
832 "/sapi/v1/eth-staking/wbeth/history/unwrapHistory",
833 reqwest::Method::GET,
834 query_params,
835 body_params,
836 if HAS_TIME_UNIT {
837 self.configuration.time_unit
838 } else {
839 None
840 },
841 true,
842 )
843 .await
844 }
845
846 async fn get_wbeth_wrap_history(
847 &self,
848 params: GetWbethWrapHistoryParams,
849 ) -> anyhow::Result<RestApiResponse<models::GetWbethWrapHistoryResponse>> {
850 let GetWbethWrapHistoryParams {
851 start_time,
852 end_time,
853 current,
854 size,
855 recv_window,
856 } = params;
857
858 let mut query_params = BTreeMap::new();
859 let body_params = BTreeMap::new();
860
861 if let Some(rw) = start_time {
862 query_params.insert("startTime".to_string(), json!(rw));
863 }
864
865 if let Some(rw) = end_time {
866 query_params.insert("endTime".to_string(), json!(rw));
867 }
868
869 if let Some(rw) = current {
870 query_params.insert("current".to_string(), json!(rw));
871 }
872
873 if let Some(rw) = size {
874 query_params.insert("size".to_string(), json!(rw));
875 }
876
877 if let Some(rw) = recv_window {
878 query_params.insert("recvWindow".to_string(), json!(rw));
879 }
880
881 send_request::<models::GetWbethWrapHistoryResponse>(
882 &self.configuration,
883 "/sapi/v1/eth-staking/wbeth/history/wrapHistory",
884 reqwest::Method::GET,
885 query_params,
886 body_params,
887 if HAS_TIME_UNIT {
888 self.configuration.time_unit
889 } else {
890 None
891 },
892 true,
893 )
894 .await
895 }
896
897 async fn redeem_eth(
898 &self,
899 params: RedeemEthParams,
900 ) -> anyhow::Result<RestApiResponse<models::RedeemEthResponse>> {
901 let RedeemEthParams {
902 amount,
903 asset,
904 recv_window,
905 } = params;
906
907 let mut query_params = BTreeMap::new();
908 let body_params = BTreeMap::new();
909
910 query_params.insert("amount".to_string(), json!(amount));
911
912 if let Some(rw) = asset {
913 query_params.insert("asset".to_string(), json!(rw));
914 }
915
916 if let Some(rw) = recv_window {
917 query_params.insert("recvWindow".to_string(), json!(rw));
918 }
919
920 send_request::<models::RedeemEthResponse>(
921 &self.configuration,
922 "/sapi/v1/eth-staking/eth/redeem",
923 reqwest::Method::POST,
924 query_params,
925 body_params,
926 if HAS_TIME_UNIT {
927 self.configuration.time_unit
928 } else {
929 None
930 },
931 true,
932 )
933 .await
934 }
935
936 async fn subscribe_eth_staking(
937 &self,
938 params: SubscribeEthStakingParams,
939 ) -> anyhow::Result<RestApiResponse<models::SubscribeEthStakingResponse>> {
940 let SubscribeEthStakingParams {
941 amount,
942 recv_window,
943 } = params;
944
945 let mut query_params = BTreeMap::new();
946 let body_params = BTreeMap::new();
947
948 query_params.insert("amount".to_string(), json!(amount));
949
950 if let Some(rw) = recv_window {
951 query_params.insert("recvWindow".to_string(), json!(rw));
952 }
953
954 send_request::<models::SubscribeEthStakingResponse>(
955 &self.configuration,
956 "/sapi/v2/eth-staking/eth/stake",
957 reqwest::Method::POST,
958 query_params,
959 body_params,
960 if HAS_TIME_UNIT {
961 self.configuration.time_unit
962 } else {
963 None
964 },
965 true,
966 )
967 .await
968 }
969
970 async fn wrap_beth(
971 &self,
972 params: WrapBethParams,
973 ) -> anyhow::Result<RestApiResponse<models::WrapBethResponse>> {
974 let WrapBethParams {
975 amount,
976 recv_window,
977 } = params;
978
979 let mut query_params = BTreeMap::new();
980 let body_params = BTreeMap::new();
981
982 query_params.insert("amount".to_string(), json!(amount));
983
984 if let Some(rw) = recv_window {
985 query_params.insert("recvWindow".to_string(), json!(rw));
986 }
987
988 send_request::<models::WrapBethResponse>(
989 &self.configuration,
990 "/sapi/v1/eth-staking/wbeth/wrap",
991 reqwest::Method::POST,
992 query_params,
993 body_params,
994 if HAS_TIME_UNIT {
995 self.configuration.time_unit
996 } else {
997 None
998 },
999 true,
1000 )
1001 .await
1002 }
1003}
1004
1005#[cfg(all(test, feature = "staking"))]
1006mod tests {
1007 use super::*;
1008 use crate::TOKIO_SHARED_RT;
1009 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
1010 use async_trait::async_trait;
1011 use std::collections::HashMap;
1012
1013 struct DummyRestApiResponse<T> {
1014 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
1015 status: u16,
1016 headers: HashMap<String, String>,
1017 rate_limits: Option<Vec<RestApiRateLimit>>,
1018 }
1019
1020 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
1021 fn from(dummy: DummyRestApiResponse<T>) -> Self {
1022 Self {
1023 data_fn: dummy.inner,
1024 status: dummy.status,
1025 headers: dummy.headers,
1026 rate_limits: dummy.rate_limits,
1027 }
1028 }
1029 }
1030
1031 struct MockEthStakingApiClient {
1032 force_error: bool,
1033 }
1034
1035 #[async_trait]
1036 impl EthStakingApi for MockEthStakingApiClient {
1037 async fn eth_staking_account(
1038 &self,
1039 _params: EthStakingAccountParams,
1040 ) -> anyhow::Result<RestApiResponse<models::EthStakingAccountResponse>> {
1041 if self.force_error {
1042 return Err(ConnectorError::ConnectorClientError {
1043 msg: "ResponseError".to_string(),
1044 code: None,
1045 }
1046 .into());
1047 }
1048
1049 let resp_json: Value = serde_json::from_str(r#"{"holdingInETH":"1.22330928","holdings":{"wbethAmount":"1.10928781","bethAmount":"1.90002112"},"thirtyDaysProfitInETH":"0.22330928","profit":{"amountFromWBETH":"0.12330928","amountFromBETH":"0.1"}}"#).unwrap();
1050 let dummy_response: models::EthStakingAccountResponse =
1051 serde_json::from_value(resp_json.clone())
1052 .expect("should parse into models::EthStakingAccountResponse");
1053
1054 let dummy = DummyRestApiResponse {
1055 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1056 status: 200,
1057 headers: HashMap::new(),
1058 rate_limits: None,
1059 };
1060
1061 Ok(dummy.into())
1062 }
1063
1064 async fn get_current_eth_staking_quota(
1065 &self,
1066 _params: GetCurrentEthStakingQuotaParams,
1067 ) -> anyhow::Result<RestApiResponse<models::GetCurrentEthStakingQuotaResponse>> {
1068 if self.force_error {
1069 return Err(ConnectorError::ConnectorClientError {
1070 msg: "ResponseError".to_string(),
1071 code: None,
1072 }
1073 .into());
1074 }
1075
1076 let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.00010000","minRedeemAmount":"0.00000001","redeemPeriod":20,"stakeable":true,"redeemable":true,"commissionFee":"0.05000000","calculating":false}"#).unwrap();
1077 let dummy_response: models::GetCurrentEthStakingQuotaResponse =
1078 serde_json::from_value(resp_json.clone())
1079 .expect("should parse into models::GetCurrentEthStakingQuotaResponse");
1080
1081 let dummy = DummyRestApiResponse {
1082 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1083 status: 200,
1084 headers: HashMap::new(),
1085 rate_limits: None,
1086 };
1087
1088 Ok(dummy.into())
1089 }
1090
1091 async fn get_eth_redemption_history(
1092 &self,
1093 _params: GetEthRedemptionHistoryParams,
1094 ) -> anyhow::Result<RestApiResponse<models::GetEthRedemptionHistoryResponse>> {
1095 if self.force_error {
1096 return Err(ConnectorError::ConnectorClientError {
1097 msg: "ResponseError".to_string(),
1098 code: None,
1099 }
1100 .into());
1101 }
1102
1103 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"WBETH","amount":"21312.23223","distributeAsset":"ETH","distributeAmount":"21338.0699","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1104 let dummy_response: models::GetEthRedemptionHistoryResponse =
1105 serde_json::from_value(resp_json.clone())
1106 .expect("should parse into models::GetEthRedemptionHistoryResponse");
1107
1108 let dummy = DummyRestApiResponse {
1109 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1110 status: 200,
1111 headers: HashMap::new(),
1112 rate_limits: None,
1113 };
1114
1115 Ok(dummy.into())
1116 }
1117
1118 async fn get_eth_staking_history(
1119 &self,
1120 _params: GetEthStakingHistoryParams,
1121 ) -> anyhow::Result<RestApiResponse<models::GetEthStakingHistoryResponse>> {
1122 if self.force_error {
1123 return Err(ConnectorError::ConnectorClientError {
1124 msg: "ResponseError".to_string(),
1125 code: None,
1126 }
1127 .into());
1128 }
1129
1130 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"ETH","amount":"21312.23223","distributeAsset":"WBETH","distributeAmount":"21286.42584","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1131 let dummy_response: models::GetEthStakingHistoryResponse =
1132 serde_json::from_value(resp_json.clone())
1133 .expect("should parse into models::GetEthStakingHistoryResponse");
1134
1135 let dummy = DummyRestApiResponse {
1136 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1137 status: 200,
1138 headers: HashMap::new(),
1139 rate_limits: None,
1140 };
1141
1142 Ok(dummy.into())
1143 }
1144
1145 async fn get_wbeth_rate_history(
1146 &self,
1147 _params: GetWbethRateHistoryParams,
1148 ) -> anyhow::Result<RestApiResponse<models::GetWbethRateHistoryResponse>> {
1149 if self.force_error {
1150 return Err(ConnectorError::ConnectorClientError {
1151 msg: "ResponseError".to_string(),
1152 code: None,
1153 }
1154 .into());
1155 }
1156
1157 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.00121234","time":1577233578000}],"total":"1"}"#).unwrap();
1158 let dummy_response: models::GetWbethRateHistoryResponse =
1159 serde_json::from_value(resp_json.clone())
1160 .expect("should parse into models::GetWbethRateHistoryResponse");
1161
1162 let dummy = DummyRestApiResponse {
1163 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1164 status: 200,
1165 headers: HashMap::new(),
1166 rate_limits: None,
1167 };
1168
1169 Ok(dummy.into())
1170 }
1171
1172 async fn get_wbeth_rewards_history(
1173 &self,
1174 _params: GetWbethRewardsHistoryParams,
1175 ) -> anyhow::Result<RestApiResponse<models::GetWbethRewardsHistoryResponse>> {
1176 if self.force_error {
1177 return Err(ConnectorError::ConnectorClientError {
1178 msg: "ResponseError".to_string(),
1179 code: None,
1180 }
1181 .into());
1182 }
1183
1184 let resp_json: Value = serde_json::from_str(r#"{"estRewardsInETH":"1.23230920","rows":[{"time":1575018510000,"amountInETH":"0.23223","holding":"2.3223","holdingInETH":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1185 let dummy_response: models::GetWbethRewardsHistoryResponse =
1186 serde_json::from_value(resp_json.clone())
1187 .expect("should parse into models::GetWbethRewardsHistoryResponse");
1188
1189 let dummy = DummyRestApiResponse {
1190 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1191 status: 200,
1192 headers: HashMap::new(),
1193 rate_limits: None,
1194 };
1195
1196 Ok(dummy.into())
1197 }
1198
1199 async fn get_wbeth_unwrap_history(
1200 &self,
1201 _params: GetWbethUnwrapHistoryParams,
1202 ) -> anyhow::Result<RestApiResponse<models::GetWbethUnwrapHistoryResponse>> {
1203 if self.force_error {
1204 return Err(ConnectorError::ConnectorClientError {
1205 msg: "ResponseError".to_string(),
1206 code: None,
1207 }
1208 .into());
1209 }
1210
1211 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"WBETH","fromAmount":"21312.23223","toAsset":"BETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1212 let dummy_response: models::GetWbethUnwrapHistoryResponse =
1213 serde_json::from_value(resp_json.clone())
1214 .expect("should parse into models::GetWbethUnwrapHistoryResponse");
1215
1216 let dummy = DummyRestApiResponse {
1217 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1218 status: 200,
1219 headers: HashMap::new(),
1220 rate_limits: None,
1221 };
1222
1223 Ok(dummy.into())
1224 }
1225
1226 async fn get_wbeth_wrap_history(
1227 &self,
1228 _params: GetWbethWrapHistoryParams,
1229 ) -> anyhow::Result<RestApiResponse<models::GetWbethWrapHistoryResponse>> {
1230 if self.force_error {
1231 return Err(ConnectorError::ConnectorClientError {
1232 msg: "ResponseError".to_string(),
1233 code: None,
1234 }
1235 .into());
1236 }
1237
1238 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"BETH","fromAmount":"21312.23223","toAsset":"WBETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1239 let dummy_response: models::GetWbethWrapHistoryResponse =
1240 serde_json::from_value(resp_json.clone())
1241 .expect("should parse into models::GetWbethWrapHistoryResponse");
1242
1243 let dummy = DummyRestApiResponse {
1244 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1245 status: 200,
1246 headers: HashMap::new(),
1247 rate_limits: None,
1248 };
1249
1250 Ok(dummy.into())
1251 }
1252
1253 async fn redeem_eth(
1254 &self,
1255 _params: RedeemEthParams,
1256 ) -> anyhow::Result<RestApiResponse<models::RedeemEthResponse>> {
1257 if self.force_error {
1258 return Err(ConnectorError::ConnectorClientError {
1259 msg: "ResponseError".to_string(),
1260 code: None,
1261 }
1262 .into());
1263 }
1264
1265 let resp_json: Value = serde_json::from_str(r#"{"success":true,"ethAmount":"0.23092091","conversionRatio":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1266 let dummy_response: models::RedeemEthResponse =
1267 serde_json::from_value(resp_json.clone())
1268 .expect("should parse into models::RedeemEthResponse");
1269
1270 let dummy = DummyRestApiResponse {
1271 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1272 status: 200,
1273 headers: HashMap::new(),
1274 rate_limits: None,
1275 };
1276
1277 Ok(dummy.into())
1278 }
1279
1280 async fn subscribe_eth_staking(
1281 &self,
1282 _params: SubscribeEthStakingParams,
1283 ) -> anyhow::Result<RestApiResponse<models::SubscribeEthStakingResponse>> {
1284 if self.force_error {
1285 return Err(ConnectorError::ConnectorClientError {
1286 msg: "ResponseError".to_string(),
1287 code: None,
1288 }
1289 .into());
1290 }
1291
1292 let resp_json: Value = serde_json::from_str(r#"{"success":true,"wbethAmount":"0.23092091","conversionRatio":"1.001212342342","purchaseId":1234567}"#).unwrap();
1293 let dummy_response: models::SubscribeEthStakingResponse =
1294 serde_json::from_value(resp_json.clone())
1295 .expect("should parse into models::SubscribeEthStakingResponse");
1296
1297 let dummy = DummyRestApiResponse {
1298 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1299 status: 200,
1300 headers: HashMap::new(),
1301 rate_limits: None,
1302 };
1303
1304 Ok(dummy.into())
1305 }
1306
1307 async fn wrap_beth(
1308 &self,
1309 _params: WrapBethParams,
1310 ) -> anyhow::Result<RestApiResponse<models::WrapBethResponse>> {
1311 if self.force_error {
1312 return Err(ConnectorError::ConnectorClientError {
1313 msg: "ResponseError".to_string(),
1314 code: None,
1315 }
1316 .into());
1317 }
1318
1319 let resp_json: Value = serde_json::from_str(
1320 r#"{"success":true,"wbethAmount":"0.23092091","exchangeRate":"1.001212343432"}"#,
1321 )
1322 .unwrap();
1323 let dummy_response: models::WrapBethResponse =
1324 serde_json::from_value(resp_json.clone())
1325 .expect("should parse into models::WrapBethResponse");
1326
1327 let dummy = DummyRestApiResponse {
1328 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1329 status: 200,
1330 headers: HashMap::new(),
1331 rate_limits: None,
1332 };
1333
1334 Ok(dummy.into())
1335 }
1336 }
1337
1338 #[test]
1339 fn eth_staking_account_required_params_success() {
1340 TOKIO_SHARED_RT.block_on(async {
1341 let client = MockEthStakingApiClient { force_error: false };
1342
1343 let params = EthStakingAccountParams::builder().build().unwrap();
1344
1345 let resp_json: Value = serde_json::from_str(r#"{"holdingInETH":"1.22330928","holdings":{"wbethAmount":"1.10928781","bethAmount":"1.90002112"},"thirtyDaysProfitInETH":"0.22330928","profit":{"amountFromWBETH":"0.12330928","amountFromBETH":"0.1"}}"#).unwrap();
1346 let expected_response : models::EthStakingAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::EthStakingAccountResponse");
1347
1348 let resp = client.eth_staking_account(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 eth_staking_account_optional_params_success() {
1357 TOKIO_SHARED_RT.block_on(async {
1358 let client = MockEthStakingApiClient { force_error: false };
1359
1360 let params = EthStakingAccountParams::builder().recv_window(5000).build().unwrap();
1361
1362 let resp_json: Value = serde_json::from_str(r#"{"holdingInETH":"1.22330928","holdings":{"wbethAmount":"1.10928781","bethAmount":"1.90002112"},"thirtyDaysProfitInETH":"0.22330928","profit":{"amountFromWBETH":"0.12330928","amountFromBETH":"0.1"}}"#).unwrap();
1363 let expected_response : models::EthStakingAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::EthStakingAccountResponse");
1364
1365 let resp = client.eth_staking_account(params).await.expect("Expected a response");
1366 let data_future = resp.data();
1367 let actual_response = data_future.await.unwrap();
1368 assert_eq!(actual_response, expected_response);
1369 });
1370 }
1371
1372 #[test]
1373 fn eth_staking_account_response_error() {
1374 TOKIO_SHARED_RT.block_on(async {
1375 let client = MockEthStakingApiClient { force_error: true };
1376
1377 let params = EthStakingAccountParams::builder().build().unwrap();
1378
1379 match client.eth_staking_account(params).await {
1380 Ok(_) => panic!("Expected an error"),
1381 Err(err) => {
1382 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1383 }
1384 }
1385 });
1386 }
1387
1388 #[test]
1389 fn get_current_eth_staking_quota_required_params_success() {
1390 TOKIO_SHARED_RT.block_on(async {
1391 let client = MockEthStakingApiClient { force_error: false };
1392
1393 let params = GetCurrentEthStakingQuotaParams::builder().build().unwrap();
1394
1395 let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.00010000","minRedeemAmount":"0.00000001","redeemPeriod":20,"stakeable":true,"redeemable":true,"commissionFee":"0.05000000","calculating":false}"#).unwrap();
1396 let expected_response : models::GetCurrentEthStakingQuotaResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCurrentEthStakingQuotaResponse");
1397
1398 let resp = client.get_current_eth_staking_quota(params).await.expect("Expected a response");
1399 let data_future = resp.data();
1400 let actual_response = data_future.await.unwrap();
1401 assert_eq!(actual_response, expected_response);
1402 });
1403 }
1404
1405 #[test]
1406 fn get_current_eth_staking_quota_optional_params_success() {
1407 TOKIO_SHARED_RT.block_on(async {
1408 let client = MockEthStakingApiClient { force_error: false };
1409
1410 let params = GetCurrentEthStakingQuotaParams::builder().recv_window(5000).build().unwrap();
1411
1412 let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.00010000","minRedeemAmount":"0.00000001","redeemPeriod":20,"stakeable":true,"redeemable":true,"commissionFee":"0.05000000","calculating":false}"#).unwrap();
1413 let expected_response : models::GetCurrentEthStakingQuotaResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCurrentEthStakingQuotaResponse");
1414
1415 let resp = client.get_current_eth_staking_quota(params).await.expect("Expected a response");
1416 let data_future = resp.data();
1417 let actual_response = data_future.await.unwrap();
1418 assert_eq!(actual_response, expected_response);
1419 });
1420 }
1421
1422 #[test]
1423 fn get_current_eth_staking_quota_response_error() {
1424 TOKIO_SHARED_RT.block_on(async {
1425 let client = MockEthStakingApiClient { force_error: true };
1426
1427 let params = GetCurrentEthStakingQuotaParams::builder().build().unwrap();
1428
1429 match client.get_current_eth_staking_quota(params).await {
1430 Ok(_) => panic!("Expected an error"),
1431 Err(err) => {
1432 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1433 }
1434 }
1435 });
1436 }
1437
1438 #[test]
1439 fn get_eth_redemption_history_required_params_success() {
1440 TOKIO_SHARED_RT.block_on(async {
1441 let client = MockEthStakingApiClient { force_error: false };
1442
1443 let params = GetEthRedemptionHistoryParams::builder().build().unwrap();
1444
1445 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"WBETH","amount":"21312.23223","distributeAsset":"ETH","distributeAmount":"21338.0699","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1446 let expected_response : models::GetEthRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthRedemptionHistoryResponse");
1447
1448 let resp = client.get_eth_redemption_history(params).await.expect("Expected a response");
1449 let data_future = resp.data();
1450 let actual_response = data_future.await.unwrap();
1451 assert_eq!(actual_response, expected_response);
1452 });
1453 }
1454
1455 #[test]
1456 fn get_eth_redemption_history_optional_params_success() {
1457 TOKIO_SHARED_RT.block_on(async {
1458 let client = MockEthStakingApiClient { force_error: false };
1459
1460 let params = GetEthRedemptionHistoryParams::builder().redeem_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1461
1462 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"WBETH","amount":"21312.23223","distributeAsset":"ETH","distributeAmount":"21338.0699","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1463 let expected_response : models::GetEthRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthRedemptionHistoryResponse");
1464
1465 let resp = client.get_eth_redemption_history(params).await.expect("Expected a response");
1466 let data_future = resp.data();
1467 let actual_response = data_future.await.unwrap();
1468 assert_eq!(actual_response, expected_response);
1469 });
1470 }
1471
1472 #[test]
1473 fn get_eth_redemption_history_response_error() {
1474 TOKIO_SHARED_RT.block_on(async {
1475 let client = MockEthStakingApiClient { force_error: true };
1476
1477 let params = GetEthRedemptionHistoryParams::builder().build().unwrap();
1478
1479 match client.get_eth_redemption_history(params).await {
1480 Ok(_) => panic!("Expected an error"),
1481 Err(err) => {
1482 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1483 }
1484 }
1485 });
1486 }
1487
1488 #[test]
1489 fn get_eth_staking_history_required_params_success() {
1490 TOKIO_SHARED_RT.block_on(async {
1491 let client = MockEthStakingApiClient { force_error: false };
1492
1493 let params = GetEthStakingHistoryParams::builder().build().unwrap();
1494
1495 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"ETH","amount":"21312.23223","distributeAsset":"WBETH","distributeAmount":"21286.42584","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1496 let expected_response : models::GetEthStakingHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthStakingHistoryResponse");
1497
1498 let resp = client.get_eth_staking_history(params).await.expect("Expected a response");
1499 let data_future = resp.data();
1500 let actual_response = data_future.await.unwrap();
1501 assert_eq!(actual_response, expected_response);
1502 });
1503 }
1504
1505 #[test]
1506 fn get_eth_staking_history_optional_params_success() {
1507 TOKIO_SHARED_RT.block_on(async {
1508 let client = MockEthStakingApiClient { force_error: false };
1509
1510 let params = GetEthStakingHistoryParams::builder().purchase_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1511
1512 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"ETH","amount":"21312.23223","distributeAsset":"WBETH","distributeAmount":"21286.42584","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1513 let expected_response : models::GetEthStakingHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthStakingHistoryResponse");
1514
1515 let resp = client.get_eth_staking_history(params).await.expect("Expected a response");
1516 let data_future = resp.data();
1517 let actual_response = data_future.await.unwrap();
1518 assert_eq!(actual_response, expected_response);
1519 });
1520 }
1521
1522 #[test]
1523 fn get_eth_staking_history_response_error() {
1524 TOKIO_SHARED_RT.block_on(async {
1525 let client = MockEthStakingApiClient { force_error: true };
1526
1527 let params = GetEthStakingHistoryParams::builder().build().unwrap();
1528
1529 match client.get_eth_staking_history(params).await {
1530 Ok(_) => panic!("Expected an error"),
1531 Err(err) => {
1532 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1533 }
1534 }
1535 });
1536 }
1537
1538 #[test]
1539 fn get_wbeth_rate_history_required_params_success() {
1540 TOKIO_SHARED_RT.block_on(async {
1541 let client = MockEthStakingApiClient { force_error: false };
1542
1543 let params = GetWbethRateHistoryParams::builder().build().unwrap();
1544
1545 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.00121234","time":1577233578000}],"total":"1"}"#).unwrap();
1546 let expected_response : models::GetWbethRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRateHistoryResponse");
1547
1548 let resp = client.get_wbeth_rate_history(params).await.expect("Expected a response");
1549 let data_future = resp.data();
1550 let actual_response = data_future.await.unwrap();
1551 assert_eq!(actual_response, expected_response);
1552 });
1553 }
1554
1555 #[test]
1556 fn get_wbeth_rate_history_optional_params_success() {
1557 TOKIO_SHARED_RT.block_on(async {
1558 let client = MockEthStakingApiClient { force_error: false };
1559
1560 let params = GetWbethRateHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1561
1562 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.00121234","time":1577233578000}],"total":"1"}"#).unwrap();
1563 let expected_response : models::GetWbethRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRateHistoryResponse");
1564
1565 let resp = client.get_wbeth_rate_history(params).await.expect("Expected a response");
1566 let data_future = resp.data();
1567 let actual_response = data_future.await.unwrap();
1568 assert_eq!(actual_response, expected_response);
1569 });
1570 }
1571
1572 #[test]
1573 fn get_wbeth_rate_history_response_error() {
1574 TOKIO_SHARED_RT.block_on(async {
1575 let client = MockEthStakingApiClient { force_error: true };
1576
1577 let params = GetWbethRateHistoryParams::builder().build().unwrap();
1578
1579 match client.get_wbeth_rate_history(params).await {
1580 Ok(_) => panic!("Expected an error"),
1581 Err(err) => {
1582 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1583 }
1584 }
1585 });
1586 }
1587
1588 #[test]
1589 fn get_wbeth_rewards_history_required_params_success() {
1590 TOKIO_SHARED_RT.block_on(async {
1591 let client = MockEthStakingApiClient { force_error: false };
1592
1593 let params = GetWbethRewardsHistoryParams::builder().build().unwrap();
1594
1595 let resp_json: Value = serde_json::from_str(r#"{"estRewardsInETH":"1.23230920","rows":[{"time":1575018510000,"amountInETH":"0.23223","holding":"2.3223","holdingInETH":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1596 let expected_response : models::GetWbethRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRewardsHistoryResponse");
1597
1598 let resp = client.get_wbeth_rewards_history(params).await.expect("Expected a response");
1599 let data_future = resp.data();
1600 let actual_response = data_future.await.unwrap();
1601 assert_eq!(actual_response, expected_response);
1602 });
1603 }
1604
1605 #[test]
1606 fn get_wbeth_rewards_history_optional_params_success() {
1607 TOKIO_SHARED_RT.block_on(async {
1608 let client = MockEthStakingApiClient { force_error: false };
1609
1610 let params = GetWbethRewardsHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1611
1612 let resp_json: Value = serde_json::from_str(r#"{"estRewardsInETH":"1.23230920","rows":[{"time":1575018510000,"amountInETH":"0.23223","holding":"2.3223","holdingInETH":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1613 let expected_response : models::GetWbethRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRewardsHistoryResponse");
1614
1615 let resp = client.get_wbeth_rewards_history(params).await.expect("Expected a response");
1616 let data_future = resp.data();
1617 let actual_response = data_future.await.unwrap();
1618 assert_eq!(actual_response, expected_response);
1619 });
1620 }
1621
1622 #[test]
1623 fn get_wbeth_rewards_history_response_error() {
1624 TOKIO_SHARED_RT.block_on(async {
1625 let client = MockEthStakingApiClient { force_error: true };
1626
1627 let params = GetWbethRewardsHistoryParams::builder().build().unwrap();
1628
1629 match client.get_wbeth_rewards_history(params).await {
1630 Ok(_) => panic!("Expected an error"),
1631 Err(err) => {
1632 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1633 }
1634 }
1635 });
1636 }
1637
1638 #[test]
1639 fn get_wbeth_unwrap_history_required_params_success() {
1640 TOKIO_SHARED_RT.block_on(async {
1641 let client = MockEthStakingApiClient { force_error: false };
1642
1643 let params = GetWbethUnwrapHistoryParams::builder().build().unwrap();
1644
1645 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"WBETH","fromAmount":"21312.23223","toAsset":"BETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1646 let expected_response : models::GetWbethUnwrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethUnwrapHistoryResponse");
1647
1648 let resp = client.get_wbeth_unwrap_history(params).await.expect("Expected a response");
1649 let data_future = resp.data();
1650 let actual_response = data_future.await.unwrap();
1651 assert_eq!(actual_response, expected_response);
1652 });
1653 }
1654
1655 #[test]
1656 fn get_wbeth_unwrap_history_optional_params_success() {
1657 TOKIO_SHARED_RT.block_on(async {
1658 let client = MockEthStakingApiClient { force_error: false };
1659
1660 let params = GetWbethUnwrapHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1661
1662 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"WBETH","fromAmount":"21312.23223","toAsset":"BETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1663 let expected_response : models::GetWbethUnwrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethUnwrapHistoryResponse");
1664
1665 let resp = client.get_wbeth_unwrap_history(params).await.expect("Expected a response");
1666 let data_future = resp.data();
1667 let actual_response = data_future.await.unwrap();
1668 assert_eq!(actual_response, expected_response);
1669 });
1670 }
1671
1672 #[test]
1673 fn get_wbeth_unwrap_history_response_error() {
1674 TOKIO_SHARED_RT.block_on(async {
1675 let client = MockEthStakingApiClient { force_error: true };
1676
1677 let params = GetWbethUnwrapHistoryParams::builder().build().unwrap();
1678
1679 match client.get_wbeth_unwrap_history(params).await {
1680 Ok(_) => panic!("Expected an error"),
1681 Err(err) => {
1682 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1683 }
1684 }
1685 });
1686 }
1687
1688 #[test]
1689 fn get_wbeth_wrap_history_required_params_success() {
1690 TOKIO_SHARED_RT.block_on(async {
1691 let client = MockEthStakingApiClient { force_error: false };
1692
1693 let params = GetWbethWrapHistoryParams::builder().build().unwrap();
1694
1695 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"BETH","fromAmount":"21312.23223","toAsset":"WBETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1696 let expected_response : models::GetWbethWrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethWrapHistoryResponse");
1697
1698 let resp = client.get_wbeth_wrap_history(params).await.expect("Expected a response");
1699 let data_future = resp.data();
1700 let actual_response = data_future.await.unwrap();
1701 assert_eq!(actual_response, expected_response);
1702 });
1703 }
1704
1705 #[test]
1706 fn get_wbeth_wrap_history_optional_params_success() {
1707 TOKIO_SHARED_RT.block_on(async {
1708 let client = MockEthStakingApiClient { force_error: false };
1709
1710 let params = GetWbethWrapHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1711
1712 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"BETH","fromAmount":"21312.23223","toAsset":"WBETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1713 let expected_response : models::GetWbethWrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethWrapHistoryResponse");
1714
1715 let resp = client.get_wbeth_wrap_history(params).await.expect("Expected a response");
1716 let data_future = resp.data();
1717 let actual_response = data_future.await.unwrap();
1718 assert_eq!(actual_response, expected_response);
1719 });
1720 }
1721
1722 #[test]
1723 fn get_wbeth_wrap_history_response_error() {
1724 TOKIO_SHARED_RT.block_on(async {
1725 let client = MockEthStakingApiClient { force_error: true };
1726
1727 let params = GetWbethWrapHistoryParams::builder().build().unwrap();
1728
1729 match client.get_wbeth_wrap_history(params).await {
1730 Ok(_) => panic!("Expected an error"),
1731 Err(err) => {
1732 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1733 }
1734 }
1735 });
1736 }
1737
1738 #[test]
1739 fn redeem_eth_required_params_success() {
1740 TOKIO_SHARED_RT.block_on(async {
1741 let client = MockEthStakingApiClient { force_error: false };
1742
1743 let params = RedeemEthParams::builder(dec!(1.0),).build().unwrap();
1744
1745 let resp_json: Value = serde_json::from_str(r#"{"success":true,"ethAmount":"0.23092091","conversionRatio":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1746 let expected_response : models::RedeemEthResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemEthResponse");
1747
1748 let resp = client.redeem_eth(params).await.expect("Expected a response");
1749 let data_future = resp.data();
1750 let actual_response = data_future.await.unwrap();
1751 assert_eq!(actual_response, expected_response);
1752 });
1753 }
1754
1755 #[test]
1756 fn redeem_eth_optional_params_success() {
1757 TOKIO_SHARED_RT.block_on(async {
1758 let client = MockEthStakingApiClient { force_error: false };
1759
1760 let params = RedeemEthParams::builder(dec!(1.0),).asset("BETH".to_string()).recv_window(5000).build().unwrap();
1761
1762 let resp_json: Value = serde_json::from_str(r#"{"success":true,"ethAmount":"0.23092091","conversionRatio":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1763 let expected_response : models::RedeemEthResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemEthResponse");
1764
1765 let resp = client.redeem_eth(params).await.expect("Expected a response");
1766 let data_future = resp.data();
1767 let actual_response = data_future.await.unwrap();
1768 assert_eq!(actual_response, expected_response);
1769 });
1770 }
1771
1772 #[test]
1773 fn redeem_eth_response_error() {
1774 TOKIO_SHARED_RT.block_on(async {
1775 let client = MockEthStakingApiClient { force_error: true };
1776
1777 let params = RedeemEthParams::builder(dec!(1.0)).build().unwrap();
1778
1779 match client.redeem_eth(params).await {
1780 Ok(_) => panic!("Expected an error"),
1781 Err(err) => {
1782 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1783 }
1784 }
1785 });
1786 }
1787
1788 #[test]
1789 fn subscribe_eth_staking_required_params_success() {
1790 TOKIO_SHARED_RT.block_on(async {
1791 let client = MockEthStakingApiClient { force_error: false };
1792
1793 let params = SubscribeEthStakingParams::builder(dec!(1.0),).build().unwrap();
1794
1795 let resp_json: Value = serde_json::from_str(r#"{"success":true,"wbethAmount":"0.23092091","conversionRatio":"1.001212342342","purchaseId":1234567}"#).unwrap();
1796 let expected_response : models::SubscribeEthStakingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SubscribeEthStakingResponse");
1797
1798 let resp = client.subscribe_eth_staking(params).await.expect("Expected a response");
1799 let data_future = resp.data();
1800 let actual_response = data_future.await.unwrap();
1801 assert_eq!(actual_response, expected_response);
1802 });
1803 }
1804
1805 #[test]
1806 fn subscribe_eth_staking_optional_params_success() {
1807 TOKIO_SHARED_RT.block_on(async {
1808 let client = MockEthStakingApiClient { force_error: false };
1809
1810 let params = SubscribeEthStakingParams::builder(dec!(1.0),).recv_window(5000).build().unwrap();
1811
1812 let resp_json: Value = serde_json::from_str(r#"{"success":true,"wbethAmount":"0.23092091","conversionRatio":"1.001212342342","purchaseId":1234567}"#).unwrap();
1813 let expected_response : models::SubscribeEthStakingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SubscribeEthStakingResponse");
1814
1815 let resp = client.subscribe_eth_staking(params).await.expect("Expected a response");
1816 let data_future = resp.data();
1817 let actual_response = data_future.await.unwrap();
1818 assert_eq!(actual_response, expected_response);
1819 });
1820 }
1821
1822 #[test]
1823 fn subscribe_eth_staking_response_error() {
1824 TOKIO_SHARED_RT.block_on(async {
1825 let client = MockEthStakingApiClient { force_error: true };
1826
1827 let params = SubscribeEthStakingParams::builder(dec!(1.0))
1828 .build()
1829 .unwrap();
1830
1831 match client.subscribe_eth_staking(params).await {
1832 Ok(_) => panic!("Expected an error"),
1833 Err(err) => {
1834 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1835 }
1836 }
1837 });
1838 }
1839
1840 #[test]
1841 fn wrap_beth_required_params_success() {
1842 TOKIO_SHARED_RT.block_on(async {
1843 let client = MockEthStakingApiClient { force_error: false };
1844
1845 let params = WrapBethParams::builder(dec!(1.0)).build().unwrap();
1846
1847 let resp_json: Value = serde_json::from_str(
1848 r#"{"success":true,"wbethAmount":"0.23092091","exchangeRate":"1.001212343432"}"#,
1849 )
1850 .unwrap();
1851 let expected_response: models::WrapBethResponse =
1852 serde_json::from_value(resp_json.clone())
1853 .expect("should parse into models::WrapBethResponse");
1854
1855 let resp = client.wrap_beth(params).await.expect("Expected a response");
1856 let data_future = resp.data();
1857 let actual_response = data_future.await.unwrap();
1858 assert_eq!(actual_response, expected_response);
1859 });
1860 }
1861
1862 #[test]
1863 fn wrap_beth_optional_params_success() {
1864 TOKIO_SHARED_RT.block_on(async {
1865 let client = MockEthStakingApiClient { force_error: false };
1866
1867 let params = WrapBethParams::builder(dec!(1.0))
1868 .recv_window(5000)
1869 .build()
1870 .unwrap();
1871
1872 let resp_json: Value = serde_json::from_str(
1873 r#"{"success":true,"wbethAmount":"0.23092091","exchangeRate":"1.001212343432"}"#,
1874 )
1875 .unwrap();
1876 let expected_response: models::WrapBethResponse =
1877 serde_json::from_value(resp_json.clone())
1878 .expect("should parse into models::WrapBethResponse");
1879
1880 let resp = client.wrap_beth(params).await.expect("Expected a response");
1881 let data_future = resp.data();
1882 let actual_response = data_future.await.unwrap();
1883 assert_eq!(actual_response, expected_response);
1884 });
1885 }
1886
1887 #[test]
1888 fn wrap_beth_response_error() {
1889 TOKIO_SHARED_RT.block_on(async {
1890 let client = MockEthStakingApiClient { force_error: true };
1891
1892 let params = WrapBethParams::builder(dec!(1.0)).build().unwrap();
1893
1894 match client.wrap_beth(params).await {
1895 Ok(_) => panic!("Expected an error"),
1896 Err(err) => {
1897 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1898 }
1899 }
1900 });
1901 }
1902}