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::mining::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait Api: Send + Sync {
34 async fn account_list(
35 &self,
36 params: AccountListParams,
37 ) -> anyhow::Result<RestApiResponse<models::AccountListResponse>>;
38 async fn acquiring_algorithm(
39 &self,
40 ) -> anyhow::Result<RestApiResponse<models::AcquiringAlgorithmResponse>>;
41 async fn acquiring_coinname(
42 &self,
43 ) -> anyhow::Result<RestApiResponse<models::AcquiringCoinnameResponse>>;
44 async fn cancel_hashrate_resale_configuration(
45 &self,
46 params: CancelHashrateResaleConfigurationParams,
47 ) -> anyhow::Result<RestApiResponse<models::CancelHashrateResaleConfigurationResponse>>;
48 async fn earnings_list(
49 &self,
50 params: EarningsListParams,
51 ) -> anyhow::Result<RestApiResponse<models::EarningsListResponse>>;
52 async fn extra_bonus_list(
53 &self,
54 params: ExtraBonusListParams,
55 ) -> anyhow::Result<RestApiResponse<models::ExtraBonusListResponse>>;
56 async fn hashrate_resale_detail(
57 &self,
58 params: HashrateResaleDetailParams,
59 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleDetailResponse>>;
60 async fn hashrate_resale_list(
61 &self,
62 params: HashrateResaleListParams,
63 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleListResponse>>;
64 async fn hashrate_resale_request(
65 &self,
66 params: HashrateResaleRequestParams,
67 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleRequestResponse>>;
68 async fn mining_account_earning(
69 &self,
70 params: MiningAccountEarningParams,
71 ) -> anyhow::Result<RestApiResponse<models::MiningAccountEarningResponse>>;
72 async fn request_for_detail_miner_list(
73 &self,
74 params: RequestForDetailMinerListParams,
75 ) -> anyhow::Result<RestApiResponse<models::RequestForDetailMinerListResponse>>;
76 async fn request_for_miner_list(
77 &self,
78 params: RequestForMinerListParams,
79 ) -> anyhow::Result<RestApiResponse<models::RequestForMinerListResponse>>;
80 async fn statistic_list(
81 &self,
82 params: StatisticListParams,
83 ) -> anyhow::Result<RestApiResponse<models::StatisticListResponse>>;
84}
85
86#[derive(Debug, Clone)]
87pub struct ApiClient {
88 configuration: ConfigurationRestApi,
89}
90
91impl ApiClient {
92 pub fn new(configuration: ConfigurationRestApi) -> Self {
93 Self { configuration }
94 }
95}
96
97#[derive(Clone, Debug, Builder, Deserialize)]
102#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
103pub struct AccountListParams {
104 #[builder(setter(into))]
108 #[serde(rename = "algo")]
109 pub algo: String,
110 #[builder(setter(into))]
114 #[serde(rename = "userName")]
115 pub user_name: String,
116 #[builder(setter(into), default)]
120 #[serde(rename = "recvWindow", default)]
121 pub recv_window: Option<i64>,
122}
123
124impl AccountListParams {
125 #[must_use]
133 pub fn builder(algo: String, user_name: String) -> AccountListParamsBuilder {
134 AccountListParamsBuilder::default()
135 .algo(algo)
136 .user_name(user_name)
137 }
138}
139#[derive(Clone, Debug, Builder, Deserialize)]
144#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
145pub struct CancelHashrateResaleConfigurationParams {
146 #[builder(setter(into))]
150 #[serde(rename = "configId")]
151 pub config_id: i64,
152 #[builder(setter(into))]
156 #[serde(rename = "userName")]
157 pub user_name: String,
158 #[builder(setter(into), default)]
162 #[serde(rename = "recvWindow", default)]
163 pub recv_window: Option<i64>,
164}
165
166impl CancelHashrateResaleConfigurationParams {
167 #[must_use]
175 pub fn builder(
176 config_id: i64,
177 user_name: String,
178 ) -> CancelHashrateResaleConfigurationParamsBuilder {
179 CancelHashrateResaleConfigurationParamsBuilder::default()
180 .config_id(config_id)
181 .user_name(user_name)
182 }
183}
184#[derive(Clone, Debug, Builder, Deserialize)]
189#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
190pub struct EarningsListParams {
191 #[builder(setter(into))]
195 #[serde(rename = "algo")]
196 pub algo: String,
197 #[builder(setter(into))]
201 #[serde(rename = "userName")]
202 pub user_name: String,
203 #[builder(setter(into), default)]
207 #[serde(rename = "coin", default)]
208 pub coin: Option<String>,
209 #[builder(setter(into), default)]
213 #[serde(rename = "startDate", default)]
214 pub start_date: Option<i64>,
215 #[builder(setter(into), default)]
219 #[serde(rename = "endDate", default)]
220 pub end_date: Option<i64>,
221 #[builder(setter(into), default)]
225 #[serde(rename = "pageIndex", default)]
226 pub page_index: Option<i64>,
227 #[builder(setter(into), default)]
231 #[serde(rename = "pageSize", default)]
232 pub page_size: Option<i64>,
233 #[builder(setter(into), default)]
237 #[serde(rename = "recvWindow", default)]
238 pub recv_window: Option<i64>,
239}
240
241impl EarningsListParams {
242 #[must_use]
250 pub fn builder(algo: String, user_name: String) -> EarningsListParamsBuilder {
251 EarningsListParamsBuilder::default()
252 .algo(algo)
253 .user_name(user_name)
254 }
255}
256#[derive(Clone, Debug, Builder, Deserialize)]
261#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
262pub struct ExtraBonusListParams {
263 #[builder(setter(into))]
267 #[serde(rename = "algo")]
268 pub algo: String,
269 #[builder(setter(into))]
273 #[serde(rename = "userName")]
274 pub user_name: String,
275 #[builder(setter(into), default)]
279 #[serde(rename = "coin", default)]
280 pub coin: Option<String>,
281 #[builder(setter(into), default)]
285 #[serde(rename = "startDate", default)]
286 pub start_date: Option<i64>,
287 #[builder(setter(into), default)]
291 #[serde(rename = "endDate", default)]
292 pub end_date: Option<i64>,
293 #[builder(setter(into), default)]
297 #[serde(rename = "pageIndex", default)]
298 pub page_index: Option<i64>,
299 #[builder(setter(into), default)]
303 #[serde(rename = "pageSize", default)]
304 pub page_size: Option<i64>,
305 #[builder(setter(into), default)]
309 #[serde(rename = "recvWindow", default)]
310 pub recv_window: Option<i64>,
311}
312
313impl ExtraBonusListParams {
314 #[must_use]
322 pub fn builder(algo: String, user_name: String) -> ExtraBonusListParamsBuilder {
323 ExtraBonusListParamsBuilder::default()
324 .algo(algo)
325 .user_name(user_name)
326 }
327}
328#[derive(Clone, Debug, Builder, Deserialize)]
333#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
334pub struct HashrateResaleDetailParams {
335 #[builder(setter(into))]
339 #[serde(rename = "configId")]
340 pub config_id: i64,
341 #[builder(setter(into), default)]
345 #[serde(rename = "pageIndex", default)]
346 pub page_index: Option<i64>,
347 #[builder(setter(into), default)]
351 #[serde(rename = "pageSize", default)]
352 pub page_size: Option<i64>,
353 #[builder(setter(into), default)]
357 #[serde(rename = "recvWindow", default)]
358 pub recv_window: Option<i64>,
359}
360
361impl HashrateResaleDetailParams {
362 #[must_use]
369 pub fn builder(config_id: i64) -> HashrateResaleDetailParamsBuilder {
370 HashrateResaleDetailParamsBuilder::default().config_id(config_id)
371 }
372}
373#[derive(Clone, Debug, Builder, Deserialize, Default)]
378#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
379pub struct HashrateResaleListParams {
380 #[builder(setter(into), default)]
384 #[serde(rename = "pageIndex", default)]
385 pub page_index: Option<i64>,
386 #[builder(setter(into), default)]
390 #[serde(rename = "pageSize", default)]
391 pub page_size: Option<i64>,
392 #[builder(setter(into), default)]
396 #[serde(rename = "recvWindow", default)]
397 pub recv_window: Option<i64>,
398}
399
400impl HashrateResaleListParams {
401 #[must_use]
404 pub fn builder() -> HashrateResaleListParamsBuilder {
405 HashrateResaleListParamsBuilder::default()
406 }
407}
408#[derive(Clone, Debug, Builder, Deserialize)]
413#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
414pub struct HashrateResaleRequestParams {
415 #[builder(setter(into))]
419 #[serde(rename = "userName")]
420 pub user_name: String,
421 #[builder(setter(into))]
425 #[serde(rename = "algo")]
426 pub algo: String,
427 #[builder(setter(into))]
431 #[serde(rename = "endDate")]
432 pub end_date: i64,
433 #[builder(setter(into))]
437 #[serde(rename = "startDate")]
438 pub start_date: i64,
439 #[builder(setter(into))]
443 #[serde(rename = "toPoolUser")]
444 pub to_pool_user: String,
445 #[builder(setter(into))]
450 #[serde(rename = "hashRate")]
451 pub hash_rate: i64,
452 #[builder(setter(into), default)]
456 #[serde(rename = "recvWindow", default)]
457 pub recv_window: Option<i64>,
458}
459
460impl HashrateResaleRequestParams {
461 #[must_use]
473 pub fn builder(
474 user_name: String,
475 algo: String,
476 end_date: i64,
477 start_date: i64,
478 to_pool_user: String,
479 hash_rate: i64,
480 ) -> HashrateResaleRequestParamsBuilder {
481 HashrateResaleRequestParamsBuilder::default()
482 .user_name(user_name)
483 .algo(algo)
484 .end_date(end_date)
485 .start_date(start_date)
486 .to_pool_user(to_pool_user)
487 .hash_rate(hash_rate)
488 }
489}
490#[derive(Clone, Debug, Builder, Deserialize)]
495#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
496pub struct MiningAccountEarningParams {
497 #[builder(setter(into))]
501 #[serde(rename = "algo")]
502 pub algo: String,
503 #[builder(setter(into), default)]
507 #[serde(rename = "startDate", default)]
508 pub start_date: Option<i64>,
509 #[builder(setter(into), default)]
513 #[serde(rename = "endDate", default)]
514 pub end_date: Option<i64>,
515 #[builder(setter(into), default)]
519 #[serde(rename = "pageIndex", default)]
520 pub page_index: Option<i64>,
521 #[builder(setter(into), default)]
525 #[serde(rename = "pageSize", default)]
526 pub page_size: Option<i64>,
527 #[builder(setter(into), default)]
531 #[serde(rename = "recvWindow", default)]
532 pub recv_window: Option<i64>,
533}
534
535impl MiningAccountEarningParams {
536 #[must_use]
543 pub fn builder(algo: String) -> MiningAccountEarningParamsBuilder {
544 MiningAccountEarningParamsBuilder::default().algo(algo)
545 }
546}
547#[derive(Clone, Debug, Builder, Deserialize)]
552#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
553pub struct RequestForDetailMinerListParams {
554 #[builder(setter(into))]
558 #[serde(rename = "algo")]
559 pub algo: String,
560 #[builder(setter(into))]
564 #[serde(rename = "userName")]
565 pub user_name: String,
566 #[builder(setter(into))]
570 #[serde(rename = "workerName")]
571 pub worker_name: String,
572 #[builder(setter(into), default)]
576 #[serde(rename = "recvWindow", default)]
577 pub recv_window: Option<i64>,
578}
579
580impl RequestForDetailMinerListParams {
581 #[must_use]
590 pub fn builder(
591 algo: String,
592 user_name: String,
593 worker_name: String,
594 ) -> RequestForDetailMinerListParamsBuilder {
595 RequestForDetailMinerListParamsBuilder::default()
596 .algo(algo)
597 .user_name(user_name)
598 .worker_name(worker_name)
599 }
600}
601#[derive(Clone, Debug, Builder, Deserialize)]
606#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
607pub struct RequestForMinerListParams {
608 #[builder(setter(into))]
612 #[serde(rename = "algo")]
613 pub algo: String,
614 #[builder(setter(into))]
618 #[serde(rename = "userName")]
619 pub user_name: String,
620 #[builder(setter(into), default)]
624 #[serde(rename = "pageIndex", default)]
625 pub page_index: Option<i64>,
626 #[builder(setter(into), default)]
630 #[serde(rename = "sort", default)]
631 pub sort: Option<i64>,
632 #[builder(setter(into), default)]
637 #[serde(rename = "sortColumn", default)]
638 pub sort_column: Option<i64>,
639 #[builder(setter(into), default)]
643 #[serde(rename = "workerStatus", default)]
644 pub worker_status: Option<i64>,
645 #[builder(setter(into), default)]
649 #[serde(rename = "recvWindow", default)]
650 pub recv_window: Option<i64>,
651}
652
653impl RequestForMinerListParams {
654 #[must_use]
662 pub fn builder(algo: String, user_name: String) -> RequestForMinerListParamsBuilder {
663 RequestForMinerListParamsBuilder::default()
664 .algo(algo)
665 .user_name(user_name)
666 }
667}
668#[derive(Clone, Debug, Builder, Deserialize)]
673#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
674pub struct StatisticListParams {
675 #[builder(setter(into))]
679 #[serde(rename = "algo")]
680 pub algo: String,
681 #[builder(setter(into))]
685 #[serde(rename = "userName")]
686 pub user_name: String,
687 #[builder(setter(into), default)]
691 #[serde(rename = "recvWindow", default)]
692 pub recv_window: Option<i64>,
693}
694
695impl StatisticListParams {
696 #[must_use]
704 pub fn builder(algo: String, user_name: String) -> StatisticListParamsBuilder {
705 StatisticListParamsBuilder::default()
706 .algo(algo)
707 .user_name(user_name)
708 }
709}
710
711#[async_trait]
712impl Api for ApiClient {
713 async fn account_list(
714 &self,
715 params: AccountListParams,
716 ) -> anyhow::Result<RestApiResponse<models::AccountListResponse>> {
717 let AccountListParams {
718 algo,
719 user_name,
720 recv_window,
721 } = params;
722
723 let mut query_params = BTreeMap::new();
724 let body_params = BTreeMap::new();
725
726 query_params.insert("algo".to_string(), json!(algo));
727
728 query_params.insert("userName".to_string(), json!(user_name));
729
730 if let Some(rw) = recv_window {
731 query_params.insert("recvWindow".to_string(), json!(rw));
732 }
733
734 send_request::<models::AccountListResponse>(
735 &self.configuration,
736 "/sapi/v1/mining/statistics/user/list",
737 reqwest::Method::GET,
738 query_params,
739 body_params,
740 if HAS_TIME_UNIT {
741 self.configuration.time_unit
742 } else {
743 None
744 },
745 true,
746 )
747 .await
748 }
749
750 async fn acquiring_algorithm(
751 &self,
752 ) -> anyhow::Result<RestApiResponse<models::AcquiringAlgorithmResponse>> {
753 let query_params = BTreeMap::new();
754 let body_params = BTreeMap::new();
755
756 send_request::<models::AcquiringAlgorithmResponse>(
757 &self.configuration,
758 "/sapi/v1/mining/pub/algoList",
759 reqwest::Method::GET,
760 query_params,
761 body_params,
762 if HAS_TIME_UNIT {
763 self.configuration.time_unit
764 } else {
765 None
766 },
767 false,
768 )
769 .await
770 }
771
772 async fn acquiring_coinname(
773 &self,
774 ) -> anyhow::Result<RestApiResponse<models::AcquiringCoinnameResponse>> {
775 let query_params = BTreeMap::new();
776 let body_params = BTreeMap::new();
777
778 send_request::<models::AcquiringCoinnameResponse>(
779 &self.configuration,
780 "/sapi/v1/mining/pub/coinList",
781 reqwest::Method::GET,
782 query_params,
783 body_params,
784 if HAS_TIME_UNIT {
785 self.configuration.time_unit
786 } else {
787 None
788 },
789 false,
790 )
791 .await
792 }
793
794 async fn cancel_hashrate_resale_configuration(
795 &self,
796 params: CancelHashrateResaleConfigurationParams,
797 ) -> anyhow::Result<RestApiResponse<models::CancelHashrateResaleConfigurationResponse>> {
798 let CancelHashrateResaleConfigurationParams {
799 config_id,
800 user_name,
801 recv_window,
802 } = params;
803
804 let mut query_params = BTreeMap::new();
805 let body_params = BTreeMap::new();
806
807 query_params.insert("configId".to_string(), json!(config_id));
808
809 query_params.insert("userName".to_string(), json!(user_name));
810
811 if let Some(rw) = recv_window {
812 query_params.insert("recvWindow".to_string(), json!(rw));
813 }
814
815 send_request::<models::CancelHashrateResaleConfigurationResponse>(
816 &self.configuration,
817 "/sapi/v1/mining/hash-transfer/config/cancel",
818 reqwest::Method::POST,
819 query_params,
820 body_params,
821 if HAS_TIME_UNIT {
822 self.configuration.time_unit
823 } else {
824 None
825 },
826 true,
827 )
828 .await
829 }
830
831 async fn earnings_list(
832 &self,
833 params: EarningsListParams,
834 ) -> anyhow::Result<RestApiResponse<models::EarningsListResponse>> {
835 let EarningsListParams {
836 algo,
837 user_name,
838 coin,
839 start_date,
840 end_date,
841 page_index,
842 page_size,
843 recv_window,
844 } = params;
845
846 let mut query_params = BTreeMap::new();
847 let body_params = BTreeMap::new();
848
849 query_params.insert("algo".to_string(), json!(algo));
850
851 query_params.insert("userName".to_string(), json!(user_name));
852
853 if let Some(rw) = coin {
854 query_params.insert("coin".to_string(), json!(rw));
855 }
856
857 if let Some(rw) = start_date {
858 query_params.insert("startDate".to_string(), json!(rw));
859 }
860
861 if let Some(rw) = end_date {
862 query_params.insert("endDate".to_string(), json!(rw));
863 }
864
865 if let Some(rw) = page_index {
866 query_params.insert("pageIndex".to_string(), json!(rw));
867 }
868
869 if let Some(rw) = page_size {
870 query_params.insert("pageSize".to_string(), json!(rw));
871 }
872
873 if let Some(rw) = recv_window {
874 query_params.insert("recvWindow".to_string(), json!(rw));
875 }
876
877 send_request::<models::EarningsListResponse>(
878 &self.configuration,
879 "/sapi/v1/mining/payment/list",
880 reqwest::Method::GET,
881 query_params,
882 body_params,
883 if HAS_TIME_UNIT {
884 self.configuration.time_unit
885 } else {
886 None
887 },
888 true,
889 )
890 .await
891 }
892
893 async fn extra_bonus_list(
894 &self,
895 params: ExtraBonusListParams,
896 ) -> anyhow::Result<RestApiResponse<models::ExtraBonusListResponse>> {
897 let ExtraBonusListParams {
898 algo,
899 user_name,
900 coin,
901 start_date,
902 end_date,
903 page_index,
904 page_size,
905 recv_window,
906 } = params;
907
908 let mut query_params = BTreeMap::new();
909 let body_params = BTreeMap::new();
910
911 query_params.insert("algo".to_string(), json!(algo));
912
913 query_params.insert("userName".to_string(), json!(user_name));
914
915 if let Some(rw) = coin {
916 query_params.insert("coin".to_string(), json!(rw));
917 }
918
919 if let Some(rw) = start_date {
920 query_params.insert("startDate".to_string(), json!(rw));
921 }
922
923 if let Some(rw) = end_date {
924 query_params.insert("endDate".to_string(), json!(rw));
925 }
926
927 if let Some(rw) = page_index {
928 query_params.insert("pageIndex".to_string(), json!(rw));
929 }
930
931 if let Some(rw) = page_size {
932 query_params.insert("pageSize".to_string(), json!(rw));
933 }
934
935 if let Some(rw) = recv_window {
936 query_params.insert("recvWindow".to_string(), json!(rw));
937 }
938
939 send_request::<models::ExtraBonusListResponse>(
940 &self.configuration,
941 "/sapi/v1/mining/payment/other",
942 reqwest::Method::GET,
943 query_params,
944 body_params,
945 if HAS_TIME_UNIT {
946 self.configuration.time_unit
947 } else {
948 None
949 },
950 true,
951 )
952 .await
953 }
954
955 async fn hashrate_resale_detail(
956 &self,
957 params: HashrateResaleDetailParams,
958 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleDetailResponse>> {
959 let HashrateResaleDetailParams {
960 config_id,
961 page_index,
962 page_size,
963 recv_window,
964 } = params;
965
966 let mut query_params = BTreeMap::new();
967 let body_params = BTreeMap::new();
968
969 query_params.insert("configId".to_string(), json!(config_id));
970
971 if let Some(rw) = page_index {
972 query_params.insert("pageIndex".to_string(), json!(rw));
973 }
974
975 if let Some(rw) = page_size {
976 query_params.insert("pageSize".to_string(), json!(rw));
977 }
978
979 if let Some(rw) = recv_window {
980 query_params.insert("recvWindow".to_string(), json!(rw));
981 }
982
983 send_request::<models::HashrateResaleDetailResponse>(
984 &self.configuration,
985 "/sapi/v1/mining/hash-transfer/profit/details",
986 reqwest::Method::GET,
987 query_params,
988 body_params,
989 if HAS_TIME_UNIT {
990 self.configuration.time_unit
991 } else {
992 None
993 },
994 true,
995 )
996 .await
997 }
998
999 async fn hashrate_resale_list(
1000 &self,
1001 params: HashrateResaleListParams,
1002 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleListResponse>> {
1003 let HashrateResaleListParams {
1004 page_index,
1005 page_size,
1006 recv_window,
1007 } = params;
1008
1009 let mut query_params = BTreeMap::new();
1010 let body_params = BTreeMap::new();
1011
1012 if let Some(rw) = page_index {
1013 query_params.insert("pageIndex".to_string(), json!(rw));
1014 }
1015
1016 if let Some(rw) = page_size {
1017 query_params.insert("pageSize".to_string(), json!(rw));
1018 }
1019
1020 if let Some(rw) = recv_window {
1021 query_params.insert("recvWindow".to_string(), json!(rw));
1022 }
1023
1024 send_request::<models::HashrateResaleListResponse>(
1025 &self.configuration,
1026 "/sapi/v1/mining/hash-transfer/config/details/list",
1027 reqwest::Method::GET,
1028 query_params,
1029 body_params,
1030 if HAS_TIME_UNIT {
1031 self.configuration.time_unit
1032 } else {
1033 None
1034 },
1035 true,
1036 )
1037 .await
1038 }
1039
1040 async fn hashrate_resale_request(
1041 &self,
1042 params: HashrateResaleRequestParams,
1043 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleRequestResponse>> {
1044 let HashrateResaleRequestParams {
1045 user_name,
1046 algo,
1047 end_date,
1048 start_date,
1049 to_pool_user,
1050 hash_rate,
1051 recv_window,
1052 } = params;
1053
1054 let mut query_params = BTreeMap::new();
1055 let body_params = BTreeMap::new();
1056
1057 query_params.insert("userName".to_string(), json!(user_name));
1058
1059 query_params.insert("algo".to_string(), json!(algo));
1060
1061 query_params.insert("endDate".to_string(), json!(end_date));
1062
1063 query_params.insert("startDate".to_string(), json!(start_date));
1064
1065 query_params.insert("toPoolUser".to_string(), json!(to_pool_user));
1066
1067 query_params.insert("hashRate".to_string(), json!(hash_rate));
1068
1069 if let Some(rw) = recv_window {
1070 query_params.insert("recvWindow".to_string(), json!(rw));
1071 }
1072
1073 send_request::<models::HashrateResaleRequestResponse>(
1074 &self.configuration,
1075 "/sapi/v1/mining/hash-transfer/config",
1076 reqwest::Method::POST,
1077 query_params,
1078 body_params,
1079 if HAS_TIME_UNIT {
1080 self.configuration.time_unit
1081 } else {
1082 None
1083 },
1084 true,
1085 )
1086 .await
1087 }
1088
1089 async fn mining_account_earning(
1090 &self,
1091 params: MiningAccountEarningParams,
1092 ) -> anyhow::Result<RestApiResponse<models::MiningAccountEarningResponse>> {
1093 let MiningAccountEarningParams {
1094 algo,
1095 start_date,
1096 end_date,
1097 page_index,
1098 page_size,
1099 recv_window,
1100 } = params;
1101
1102 let mut query_params = BTreeMap::new();
1103 let body_params = BTreeMap::new();
1104
1105 query_params.insert("algo".to_string(), json!(algo));
1106
1107 if let Some(rw) = start_date {
1108 query_params.insert("startDate".to_string(), json!(rw));
1109 }
1110
1111 if let Some(rw) = end_date {
1112 query_params.insert("endDate".to_string(), json!(rw));
1113 }
1114
1115 if let Some(rw) = page_index {
1116 query_params.insert("pageIndex".to_string(), json!(rw));
1117 }
1118
1119 if let Some(rw) = page_size {
1120 query_params.insert("pageSize".to_string(), json!(rw));
1121 }
1122
1123 if let Some(rw) = recv_window {
1124 query_params.insert("recvWindow".to_string(), json!(rw));
1125 }
1126
1127 send_request::<models::MiningAccountEarningResponse>(
1128 &self.configuration,
1129 "/sapi/v1/mining/payment/uid",
1130 reqwest::Method::GET,
1131 query_params,
1132 body_params,
1133 if HAS_TIME_UNIT {
1134 self.configuration.time_unit
1135 } else {
1136 None
1137 },
1138 true,
1139 )
1140 .await
1141 }
1142
1143 async fn request_for_detail_miner_list(
1144 &self,
1145 params: RequestForDetailMinerListParams,
1146 ) -> anyhow::Result<RestApiResponse<models::RequestForDetailMinerListResponse>> {
1147 let RequestForDetailMinerListParams {
1148 algo,
1149 user_name,
1150 worker_name,
1151 recv_window,
1152 } = params;
1153
1154 let mut query_params = BTreeMap::new();
1155 let body_params = BTreeMap::new();
1156
1157 query_params.insert("algo".to_string(), json!(algo));
1158
1159 query_params.insert("userName".to_string(), json!(user_name));
1160
1161 query_params.insert("workerName".to_string(), json!(worker_name));
1162
1163 if let Some(rw) = recv_window {
1164 query_params.insert("recvWindow".to_string(), json!(rw));
1165 }
1166
1167 send_request::<models::RequestForDetailMinerListResponse>(
1168 &self.configuration,
1169 "/sapi/v1/mining/worker/detail",
1170 reqwest::Method::GET,
1171 query_params,
1172 body_params,
1173 if HAS_TIME_UNIT {
1174 self.configuration.time_unit
1175 } else {
1176 None
1177 },
1178 true,
1179 )
1180 .await
1181 }
1182
1183 async fn request_for_miner_list(
1184 &self,
1185 params: RequestForMinerListParams,
1186 ) -> anyhow::Result<RestApiResponse<models::RequestForMinerListResponse>> {
1187 let RequestForMinerListParams {
1188 algo,
1189 user_name,
1190 page_index,
1191 sort,
1192 sort_column,
1193 worker_status,
1194 recv_window,
1195 } = params;
1196
1197 let mut query_params = BTreeMap::new();
1198 let body_params = BTreeMap::new();
1199
1200 query_params.insert("algo".to_string(), json!(algo));
1201
1202 query_params.insert("userName".to_string(), json!(user_name));
1203
1204 if let Some(rw) = page_index {
1205 query_params.insert("pageIndex".to_string(), json!(rw));
1206 }
1207
1208 if let Some(rw) = sort {
1209 query_params.insert("sort".to_string(), json!(rw));
1210 }
1211
1212 if let Some(rw) = sort_column {
1213 query_params.insert("sortColumn".to_string(), json!(rw));
1214 }
1215
1216 if let Some(rw) = worker_status {
1217 query_params.insert("workerStatus".to_string(), json!(rw));
1218 }
1219
1220 if let Some(rw) = recv_window {
1221 query_params.insert("recvWindow".to_string(), json!(rw));
1222 }
1223
1224 send_request::<models::RequestForMinerListResponse>(
1225 &self.configuration,
1226 "/sapi/v1/mining/worker/list",
1227 reqwest::Method::GET,
1228 query_params,
1229 body_params,
1230 if HAS_TIME_UNIT {
1231 self.configuration.time_unit
1232 } else {
1233 None
1234 },
1235 true,
1236 )
1237 .await
1238 }
1239
1240 async fn statistic_list(
1241 &self,
1242 params: StatisticListParams,
1243 ) -> anyhow::Result<RestApiResponse<models::StatisticListResponse>> {
1244 let StatisticListParams {
1245 algo,
1246 user_name,
1247 recv_window,
1248 } = params;
1249
1250 let mut query_params = BTreeMap::new();
1251 let body_params = BTreeMap::new();
1252
1253 query_params.insert("algo".to_string(), json!(algo));
1254
1255 query_params.insert("userName".to_string(), json!(user_name));
1256
1257 if let Some(rw) = recv_window {
1258 query_params.insert("recvWindow".to_string(), json!(rw));
1259 }
1260
1261 send_request::<models::StatisticListResponse>(
1262 &self.configuration,
1263 "/sapi/v1/mining/statistics/user/status",
1264 reqwest::Method::GET,
1265 query_params,
1266 body_params,
1267 if HAS_TIME_UNIT {
1268 self.configuration.time_unit
1269 } else {
1270 None
1271 },
1272 true,
1273 )
1274 .await
1275 }
1276}
1277
1278#[cfg(all(test, feature = "mining"))]
1279mod tests {
1280 use super::*;
1281 use crate::TOKIO_SHARED_RT;
1282 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
1283 use async_trait::async_trait;
1284 use std::collections::HashMap;
1285
1286 struct DummyRestApiResponse<T> {
1287 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
1288 status: u16,
1289 headers: HashMap<String, String>,
1290 rate_limits: Option<Vec<RestApiRateLimit>>,
1291 }
1292
1293 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
1294 fn from(dummy: DummyRestApiResponse<T>) -> Self {
1295 Self {
1296 data_fn: dummy.inner,
1297 status: dummy.status,
1298 headers: dummy.headers,
1299 rate_limits: dummy.rate_limits,
1300 }
1301 }
1302 }
1303
1304 struct MockApiClient {
1305 force_error: bool,
1306 }
1307
1308 #[async_trait]
1309 impl Api for MockApiClient {
1310 async fn account_list(
1311 &self,
1312 _params: AccountListParams,
1313 ) -> anyhow::Result<RestApiResponse<models::AccountListResponse>> {
1314 if self.force_error {
1315 return Err(ConnectorError::ConnectorClientError {
1316 msg: "ResponseError".to_string(),
1317 code: None,
1318 }
1319 .into());
1320 }
1321
1322 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"type":"H_hashrate","userName":"test","list":[{"time":1585267200000,"hashrate":"0.00000000","reject":"0.00000000"}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1323 let dummy_response: models::AccountListResponse =
1324 serde_json::from_value(resp_json.clone())
1325 .expect("should parse into models::AccountListResponse");
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 async fn acquiring_algorithm(
1338 &self,
1339 ) -> anyhow::Result<RestApiResponse<models::AcquiringAlgorithmResponse>> {
1340 if self.force_error {
1341 return Err(ConnectorError::ConnectorClientError {
1342 msg: "ResponseError".to_string(),
1343 code: None,
1344 }
1345 .into());
1346 }
1347
1348 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"algoName":"SHA256-BTC","algoId":1,"poolIndex":100,"unit":"h/s"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1349 let dummy_response: models::AcquiringAlgorithmResponse =
1350 serde_json::from_value(resp_json.clone())
1351 .expect("should parse into models::AcquiringAlgorithmResponse");
1352
1353 let dummy = DummyRestApiResponse {
1354 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1355 status: 200,
1356 headers: HashMap::new(),
1357 rate_limits: None,
1358 };
1359
1360 Ok(dummy.into())
1361 }
1362
1363 async fn acquiring_coinname(
1364 &self,
1365 ) -> anyhow::Result<RestApiResponse<models::AcquiringCoinnameResponse>> {
1366 if self.force_error {
1367 return Err(ConnectorError::ConnectorClientError {
1368 msg: "ResponseError".to_string(),
1369 code: None,
1370 }
1371 .into());
1372 }
1373
1374 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"coinName":"BTC","coinId":1,"poolIndex":0,"algoId":1,"algoName":"SHA256-BTC"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1375 let dummy_response: models::AcquiringCoinnameResponse =
1376 serde_json::from_value(resp_json.clone())
1377 .expect("should parse into models::AcquiringCoinnameResponse");
1378
1379 let dummy = DummyRestApiResponse {
1380 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1381 status: 200,
1382 headers: HashMap::new(),
1383 rate_limits: None,
1384 };
1385
1386 Ok(dummy.into())
1387 }
1388
1389 async fn cancel_hashrate_resale_configuration(
1390 &self,
1391 _params: CancelHashrateResaleConfigurationParams,
1392 ) -> anyhow::Result<RestApiResponse<models::CancelHashrateResaleConfigurationResponse>>
1393 {
1394 if self.force_error {
1395 return Err(ConnectorError::ConnectorClientError {
1396 msg: "ResponseError".to_string(),
1397 code: None,
1398 }
1399 .into());
1400 }
1401
1402 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":true}"#)
1403 .unwrap_or_else(|_| serde_json::json!({}));
1404 let dummy_response: models::CancelHashrateResaleConfigurationResponse =
1405 serde_json::from_value(resp_json.clone())
1406 .expect("should parse into models::CancelHashrateResaleConfigurationResponse");
1407
1408 let dummy = DummyRestApiResponse {
1409 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1410 status: 200,
1411 headers: HashMap::new(),
1412 rate_limits: None,
1413 };
1414
1415 Ok(dummy.into())
1416 }
1417
1418 async fn earnings_list(
1419 &self,
1420 _params: EarningsListParams,
1421 ) -> anyhow::Result<RestApiResponse<models::EarningsListResponse>> {
1422 if self.force_error {
1423 return Err(ConnectorError::ConnectorClientError {
1424 msg: "ResponseError".to_string(),
1425 code: None,
1426 }
1427 .into());
1428 }
1429
1430 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"accountProfits":[{"time":1586188800000,"type":31,"hashTransfer":200000000000,"transferAmount":0.02180958,"dayHashRate":129129903378244,"profitAmount":8.6083060304,"coinName":"BTC","status":2}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1431 let dummy_response: models::EarningsListResponse =
1432 serde_json::from_value(resp_json.clone())
1433 .expect("should parse into models::EarningsListResponse");
1434
1435 let dummy = DummyRestApiResponse {
1436 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1437 status: 200,
1438 headers: HashMap::new(),
1439 rate_limits: None,
1440 };
1441
1442 Ok(dummy.into())
1443 }
1444
1445 async fn extra_bonus_list(
1446 &self,
1447 _params: ExtraBonusListParams,
1448 ) -> anyhow::Result<RestApiResponse<models::ExtraBonusListResponse>> {
1449 if self.force_error {
1450 return Err(ConnectorError::ConnectorClientError {
1451 msg: "ResponseError".to_string(),
1452 code: None,
1453 }
1454 .into());
1455 }
1456
1457 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"otherProfits":[{"time":1607443200000,"coinName":"BTC","type":4,"profitAmount":0.0011859,"status":2}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1458 let dummy_response: models::ExtraBonusListResponse =
1459 serde_json::from_value(resp_json.clone())
1460 .expect("should parse into models::ExtraBonusListResponse");
1461
1462 let dummy = DummyRestApiResponse {
1463 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1464 status: 200,
1465 headers: HashMap::new(),
1466 rate_limits: None,
1467 };
1468
1469 Ok(dummy.into())
1470 }
1471
1472 async fn hashrate_resale_detail(
1473 &self,
1474 _params: HashrateResaleDetailParams,
1475 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleDetailResponse>> {
1476 if self.force_error {
1477 return Err(ConnectorError::ConnectorClientError {
1478 msg: "ResponseError".to_string(),
1479 code: None,
1480 }
1481 .into());
1482 }
1483
1484 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"profitTransferDetails":[{"poolUsername":"test4001","toPoolUsername":"pop","algoName":"sha256","hashRate":200000000000,"day":20201213,"amount":0.2256872,"coinName":"BTC"}],"totalNum":8,"pageSize":200}}"#).unwrap_or_else(|_| serde_json::json!({}));
1485 let dummy_response: models::HashrateResaleDetailResponse =
1486 serde_json::from_value(resp_json.clone())
1487 .expect("should parse into models::HashrateResaleDetailResponse");
1488
1489 let dummy = DummyRestApiResponse {
1490 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1491 status: 200,
1492 headers: HashMap::new(),
1493 rate_limits: None,
1494 };
1495
1496 Ok(dummy.into())
1497 }
1498
1499 async fn hashrate_resale_list(
1500 &self,
1501 _params: HashrateResaleListParams,
1502 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleListResponse>> {
1503 if self.force_error {
1504 return Err(ConnectorError::ConnectorClientError {
1505 msg: "ResponseError".to_string(),
1506 code: None,
1507 }
1508 .into());
1509 }
1510
1511 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"configDetails":[{"configId":168,"poolUsername":"123","toPoolUsername":"user1","algoName":"Ethash","hashRate":5000000,"startDay":20201210,"endDay":20210405,"status":1,"type":0}],"totalNum":21,"pageSize":200}}"#).unwrap_or_else(|_| serde_json::json!({}));
1512 let dummy_response: models::HashrateResaleListResponse =
1513 serde_json::from_value(resp_json.clone())
1514 .expect("should parse into models::HashrateResaleListResponse");
1515
1516 let dummy = DummyRestApiResponse {
1517 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1518 status: 200,
1519 headers: HashMap::new(),
1520 rate_limits: None,
1521 };
1522
1523 Ok(dummy.into())
1524 }
1525
1526 async fn hashrate_resale_request(
1527 &self,
1528 _params: HashrateResaleRequestParams,
1529 ) -> anyhow::Result<RestApiResponse<models::HashrateResaleRequestResponse>> {
1530 if self.force_error {
1531 return Err(ConnectorError::ConnectorClientError {
1532 msg: "ResponseError".to_string(),
1533 code: None,
1534 }
1535 .into());
1536 }
1537
1538 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":171}"#)
1539 .unwrap_or_else(|_| serde_json::json!({}));
1540 let dummy_response: models::HashrateResaleRequestResponse =
1541 serde_json::from_value(resp_json.clone())
1542 .expect("should parse into models::HashrateResaleRequestResponse");
1543
1544 let dummy = DummyRestApiResponse {
1545 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1546 status: 200,
1547 headers: HashMap::new(),
1548 rate_limits: None,
1549 };
1550
1551 Ok(dummy.into())
1552 }
1553
1554 async fn mining_account_earning(
1555 &self,
1556 _params: MiningAccountEarningParams,
1557 ) -> anyhow::Result<RestApiResponse<models::MiningAccountEarningResponse>> {
1558 if self.force_error {
1559 return Err(ConnectorError::ConnectorClientError {
1560 msg: "ResponseError".to_string(),
1561 code: None,
1562 }
1563 .into());
1564 }
1565
1566 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"accountProfits":[{"time":1607443200000,"coinName":"BTC","type":2,"puid":59985472,"subName":"vdvaghani","amount":0.09186957}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1567 let dummy_response: models::MiningAccountEarningResponse =
1568 serde_json::from_value(resp_json.clone())
1569 .expect("should parse into models::MiningAccountEarningResponse");
1570
1571 let dummy = DummyRestApiResponse {
1572 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1573 status: 200,
1574 headers: HashMap::new(),
1575 rate_limits: None,
1576 };
1577
1578 Ok(dummy.into())
1579 }
1580
1581 async fn request_for_detail_miner_list(
1582 &self,
1583 _params: RequestForDetailMinerListParams,
1584 ) -> anyhow::Result<RestApiResponse<models::RequestForDetailMinerListResponse>> {
1585 if self.force_error {
1586 return Err(ConnectorError::ConnectorClientError {
1587 msg: "ResponseError".to_string(),
1588 code: None,
1589 }
1590 .into());
1591 }
1592
1593 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"workerName":"bhdc1.16A10404B","type":"H_hashrate","hashrateDatas":[{"time":1587902400000,"hashrate":"0","reject":0}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1594 let dummy_response: models::RequestForDetailMinerListResponse =
1595 serde_json::from_value(resp_json.clone())
1596 .expect("should parse into models::RequestForDetailMinerListResponse");
1597
1598 let dummy = DummyRestApiResponse {
1599 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1600 status: 200,
1601 headers: HashMap::new(),
1602 rate_limits: None,
1603 };
1604
1605 Ok(dummy.into())
1606 }
1607
1608 async fn request_for_miner_list(
1609 &self,
1610 _params: RequestForMinerListParams,
1611 ) -> anyhow::Result<RestApiResponse<models::RequestForMinerListResponse>> {
1612 if self.force_error {
1613 return Err(ConnectorError::ConnectorClientError {
1614 msg: "ResponseError".to_string(),
1615 code: None,
1616 }
1617 .into());
1618 }
1619
1620 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"workerDatas":[{"workerId":"1420554439452400131","workerName":"2X73","status":3,"hashRate":0,"dayHashRate":1.269778129801366E13,"rejectRate":0,"lastShareTime":1587712919000}],"totalNum":18530,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1621 let dummy_response: models::RequestForMinerListResponse =
1622 serde_json::from_value(resp_json.clone())
1623 .expect("should parse into models::RequestForMinerListResponse");
1624
1625 let dummy = DummyRestApiResponse {
1626 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1627 status: 200,
1628 headers: HashMap::new(),
1629 rate_limits: None,
1630 };
1631
1632 Ok(dummy.into())
1633 }
1634
1635 async fn statistic_list(
1636 &self,
1637 _params: StatisticListParams,
1638 ) -> anyhow::Result<RestApiResponse<models::StatisticListResponse>> {
1639 if self.force_error {
1640 return Err(ConnectorError::ConnectorClientError {
1641 msg: "ResponseError".to_string(),
1642 code: None,
1643 }
1644 .into());
1645 }
1646
1647 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"fifteenMinHashRate":"457835490067496409.00000000","dayHashRate":"214289268068874127.65000000","validNum":0,"invalidNum":17562,"profitToday":{"BTC":"0.00314332","BSV":"56.17055953","BCH":"106.61586001"},"profitYesterday":{"BTC":"0.00314332","BSV":"56.17055953","BCH":"106.61586001"},"userName":"test","unit":"h/s","algo":"sha256"}}"#).unwrap_or_else(|_| serde_json::json!({}));
1648 let dummy_response: models::StatisticListResponse =
1649 serde_json::from_value(resp_json.clone())
1650 .expect("should parse into models::StatisticListResponse");
1651
1652 let dummy = DummyRestApiResponse {
1653 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1654 status: 200,
1655 headers: HashMap::new(),
1656 rate_limits: None,
1657 };
1658
1659 Ok(dummy.into())
1660 }
1661 }
1662
1663 #[test]
1664 fn account_list_required_params_success() {
1665 TOKIO_SHARED_RT.block_on(async {
1666 let client = MockApiClient { force_error: false };
1667
1668 let params = AccountListParams::builder("sha256".to_string(),"test".to_string(),).build().unwrap();
1669
1670 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"type":"H_hashrate","userName":"test","list":[{"time":1585267200000,"hashrate":"0.00000000","reject":"0.00000000"}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1671 let expected_response : models::AccountListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountListResponse");
1672
1673 let resp = client.account_list(params).await.expect("Expected a response");
1674 let data_future = resp.data();
1675 let actual_response = data_future.await.unwrap();
1676 assert_eq!(actual_response, expected_response);
1677 });
1678 }
1679
1680 #[test]
1681 fn account_list_optional_params_success() {
1682 TOKIO_SHARED_RT.block_on(async {
1683 let client = MockApiClient { force_error: false };
1684
1685 let params = AccountListParams::builder("sha256".to_string(),"test".to_string(),).recv_window(5000).build().unwrap();
1686
1687 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"type":"H_hashrate","userName":"test","list":[{"time":1585267200000,"hashrate":"0.00000000","reject":"0.00000000"}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1688 let expected_response : models::AccountListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AccountListResponse");
1689
1690 let resp = client.account_list(params).await.expect("Expected a response");
1691 let data_future = resp.data();
1692 let actual_response = data_future.await.unwrap();
1693 assert_eq!(actual_response, expected_response);
1694 });
1695 }
1696
1697 #[test]
1698 fn account_list_response_error() {
1699 TOKIO_SHARED_RT.block_on(async {
1700 let client = MockApiClient { force_error: true };
1701
1702 let params = AccountListParams::builder("sha256".to_string(), "test".to_string())
1703 .build()
1704 .unwrap();
1705
1706 match client.account_list(params).await {
1707 Ok(_) => panic!("Expected an error"),
1708 Err(err) => {
1709 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1710 }
1711 }
1712 });
1713 }
1714
1715 #[test]
1716 fn acquiring_algorithm_required_params_success() {
1717 TOKIO_SHARED_RT.block_on(async {
1718 let client = MockApiClient { force_error: false };
1719
1720
1721 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"algoName":"SHA256-BTC","algoId":1,"poolIndex":100,"unit":"h/s"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1722 let expected_response : models::AcquiringAlgorithmResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AcquiringAlgorithmResponse");
1723
1724 let resp = client.acquiring_algorithm().await.expect("Expected a response");
1725 let data_future = resp.data();
1726 let actual_response = data_future.await.unwrap();
1727 assert_eq!(actual_response, expected_response);
1728 });
1729 }
1730
1731 #[test]
1732 fn acquiring_algorithm_optional_params_success() {
1733 TOKIO_SHARED_RT.block_on(async {
1734 let client = MockApiClient { force_error: false };
1735
1736
1737 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"algoName":"SHA256-BTC","algoId":1,"poolIndex":100,"unit":"h/s"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1738 let expected_response : models::AcquiringAlgorithmResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AcquiringAlgorithmResponse");
1739
1740 let resp = client.acquiring_algorithm().await.expect("Expected a response");
1741 let data_future = resp.data();
1742 let actual_response = data_future.await.unwrap();
1743 assert_eq!(actual_response, expected_response);
1744 });
1745 }
1746
1747 #[test]
1748 fn acquiring_algorithm_response_error() {
1749 TOKIO_SHARED_RT.block_on(async {
1750 let client = MockApiClient { force_error: true };
1751
1752 match client.acquiring_algorithm().await {
1753 Ok(_) => panic!("Expected an error"),
1754 Err(err) => {
1755 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1756 }
1757 }
1758 });
1759 }
1760
1761 #[test]
1762 fn acquiring_coinname_required_params_success() {
1763 TOKIO_SHARED_RT.block_on(async {
1764 let client = MockApiClient { force_error: false };
1765
1766
1767 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"coinName":"BTC","coinId":1,"poolIndex":0,"algoId":1,"algoName":"SHA256-BTC"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1768 let expected_response : models::AcquiringCoinnameResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AcquiringCoinnameResponse");
1769
1770 let resp = client.acquiring_coinname().await.expect("Expected a response");
1771 let data_future = resp.data();
1772 let actual_response = data_future.await.unwrap();
1773 assert_eq!(actual_response, expected_response);
1774 });
1775 }
1776
1777 #[test]
1778 fn acquiring_coinname_optional_params_success() {
1779 TOKIO_SHARED_RT.block_on(async {
1780 let client = MockApiClient { force_error: false };
1781
1782
1783 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"coinName":"BTC","coinId":1,"poolIndex":0,"algoId":1,"algoName":"SHA256-BTC"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1784 let expected_response : models::AcquiringCoinnameResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AcquiringCoinnameResponse");
1785
1786 let resp = client.acquiring_coinname().await.expect("Expected a response");
1787 let data_future = resp.data();
1788 let actual_response = data_future.await.unwrap();
1789 assert_eq!(actual_response, expected_response);
1790 });
1791 }
1792
1793 #[test]
1794 fn acquiring_coinname_response_error() {
1795 TOKIO_SHARED_RT.block_on(async {
1796 let client = MockApiClient { force_error: true };
1797
1798 match client.acquiring_coinname().await {
1799 Ok(_) => panic!("Expected an error"),
1800 Err(err) => {
1801 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1802 }
1803 }
1804 });
1805 }
1806
1807 #[test]
1808 fn cancel_hashrate_resale_configuration_required_params_success() {
1809 TOKIO_SHARED_RT.block_on(async {
1810 let client = MockApiClient { force_error: false };
1811
1812 let params = CancelHashrateResaleConfigurationParams::builder(168, "test".to_string())
1813 .build()
1814 .unwrap();
1815
1816 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":true}"#)
1817 .unwrap_or_else(|_| serde_json::json!({}));
1818 let expected_response: models::CancelHashrateResaleConfigurationResponse =
1819 serde_json::from_value(resp_json.clone())
1820 .expect("should parse into models::CancelHashrateResaleConfigurationResponse");
1821
1822 let resp = client
1823 .cancel_hashrate_resale_configuration(params)
1824 .await
1825 .expect("Expected a response");
1826 let data_future = resp.data();
1827 let actual_response = data_future.await.unwrap();
1828 assert_eq!(actual_response, expected_response);
1829 });
1830 }
1831
1832 #[test]
1833 fn cancel_hashrate_resale_configuration_optional_params_success() {
1834 TOKIO_SHARED_RT.block_on(async {
1835 let client = MockApiClient { force_error: false };
1836
1837 let params = CancelHashrateResaleConfigurationParams::builder(168, "test".to_string())
1838 .recv_window(5000)
1839 .build()
1840 .unwrap();
1841
1842 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":true}"#)
1843 .unwrap_or_else(|_| serde_json::json!({}));
1844 let expected_response: models::CancelHashrateResaleConfigurationResponse =
1845 serde_json::from_value(resp_json.clone())
1846 .expect("should parse into models::CancelHashrateResaleConfigurationResponse");
1847
1848 let resp = client
1849 .cancel_hashrate_resale_configuration(params)
1850 .await
1851 .expect("Expected a response");
1852 let data_future = resp.data();
1853 let actual_response = data_future.await.unwrap();
1854 assert_eq!(actual_response, expected_response);
1855 });
1856 }
1857
1858 #[test]
1859 fn cancel_hashrate_resale_configuration_response_error() {
1860 TOKIO_SHARED_RT.block_on(async {
1861 let client = MockApiClient { force_error: true };
1862
1863 let params = CancelHashrateResaleConfigurationParams::builder(168, "test".to_string())
1864 .build()
1865 .unwrap();
1866
1867 match client.cancel_hashrate_resale_configuration(params).await {
1868 Ok(_) => panic!("Expected an error"),
1869 Err(err) => {
1870 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1871 }
1872 }
1873 });
1874 }
1875
1876 #[test]
1877 fn earnings_list_required_params_success() {
1878 TOKIO_SHARED_RT.block_on(async {
1879 let client = MockApiClient { force_error: false };
1880
1881 let params = EarningsListParams::builder("sha256".to_string(),"test".to_string(),).build().unwrap();
1882
1883 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"accountProfits":[{"time":1586188800000,"type":31,"hashTransfer":200000000000,"transferAmount":0.02180958,"dayHashRate":129129903378244,"profitAmount":8.6083060304,"coinName":"BTC","status":2}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1884 let expected_response : models::EarningsListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::EarningsListResponse");
1885
1886 let resp = client.earnings_list(params).await.expect("Expected a response");
1887 let data_future = resp.data();
1888 let actual_response = data_future.await.unwrap();
1889 assert_eq!(actual_response, expected_response);
1890 });
1891 }
1892
1893 #[test]
1894 fn earnings_list_optional_params_success() {
1895 TOKIO_SHARED_RT.block_on(async {
1896 let client = MockApiClient { force_error: false };
1897
1898 let params = EarningsListParams::builder("sha256".to_string(),"test".to_string(),).coin("BTC".to_string()).start_date(1770736694138).end_date(1770736694138).page_index(1).page_size(10).recv_window(5000).build().unwrap();
1899
1900 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"accountProfits":[{"time":1586188800000,"type":31,"hashTransfer":200000000000,"transferAmount":0.02180958,"dayHashRate":129129903378244,"profitAmount":8.6083060304,"coinName":"BTC","status":2}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1901 let expected_response : models::EarningsListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::EarningsListResponse");
1902
1903 let resp = client.earnings_list(params).await.expect("Expected a response");
1904 let data_future = resp.data();
1905 let actual_response = data_future.await.unwrap();
1906 assert_eq!(actual_response, expected_response);
1907 });
1908 }
1909
1910 #[test]
1911 fn earnings_list_response_error() {
1912 TOKIO_SHARED_RT.block_on(async {
1913 let client = MockApiClient { force_error: true };
1914
1915 let params = EarningsListParams::builder("sha256".to_string(), "test".to_string())
1916 .build()
1917 .unwrap();
1918
1919 match client.earnings_list(params).await {
1920 Ok(_) => panic!("Expected an error"),
1921 Err(err) => {
1922 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1923 }
1924 }
1925 });
1926 }
1927
1928 #[test]
1929 fn extra_bonus_list_required_params_success() {
1930 TOKIO_SHARED_RT.block_on(async {
1931 let client = MockApiClient { force_error: false };
1932
1933 let params = ExtraBonusListParams::builder("sha256".to_string(),"test".to_string(),).build().unwrap();
1934
1935 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"otherProfits":[{"time":1607443200000,"coinName":"BTC","type":4,"profitAmount":0.0011859,"status":2}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1936 let expected_response : models::ExtraBonusListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ExtraBonusListResponse");
1937
1938 let resp = client.extra_bonus_list(params).await.expect("Expected a response");
1939 let data_future = resp.data();
1940 let actual_response = data_future.await.unwrap();
1941 assert_eq!(actual_response, expected_response);
1942 });
1943 }
1944
1945 #[test]
1946 fn extra_bonus_list_optional_params_success() {
1947 TOKIO_SHARED_RT.block_on(async {
1948 let client = MockApiClient { force_error: false };
1949
1950 let params = ExtraBonusListParams::builder("sha256".to_string(),"test".to_string(),).coin("BTC".to_string()).start_date(1770736694138).end_date(1770736694138).page_index(1).page_size(10).recv_window(5000).build().unwrap();
1951
1952 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"otherProfits":[{"time":1607443200000,"coinName":"BTC","type":4,"profitAmount":0.0011859,"status":2}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
1953 let expected_response : models::ExtraBonusListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ExtraBonusListResponse");
1954
1955 let resp = client.extra_bonus_list(params).await.expect("Expected a response");
1956 let data_future = resp.data();
1957 let actual_response = data_future.await.unwrap();
1958 assert_eq!(actual_response, expected_response);
1959 });
1960 }
1961
1962 #[test]
1963 fn extra_bonus_list_response_error() {
1964 TOKIO_SHARED_RT.block_on(async {
1965 let client = MockApiClient { force_error: true };
1966
1967 let params = ExtraBonusListParams::builder("sha256".to_string(), "test".to_string())
1968 .build()
1969 .unwrap();
1970
1971 match client.extra_bonus_list(params).await {
1972 Ok(_) => panic!("Expected an error"),
1973 Err(err) => {
1974 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1975 }
1976 }
1977 });
1978 }
1979
1980 #[test]
1981 fn hashrate_resale_detail_required_params_success() {
1982 TOKIO_SHARED_RT.block_on(async {
1983 let client = MockApiClient { force_error: false };
1984
1985 let params = HashrateResaleDetailParams::builder(168,).build().unwrap();
1986
1987 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"profitTransferDetails":[{"poolUsername":"test4001","toPoolUsername":"pop","algoName":"sha256","hashRate":200000000000,"day":20201213,"amount":0.2256872,"coinName":"BTC"}],"totalNum":8,"pageSize":200}}"#).unwrap_or_else(|_| serde_json::json!({}));
1988 let expected_response : models::HashrateResaleDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::HashrateResaleDetailResponse");
1989
1990 let resp = client.hashrate_resale_detail(params).await.expect("Expected a response");
1991 let data_future = resp.data();
1992 let actual_response = data_future.await.unwrap();
1993 assert_eq!(actual_response, expected_response);
1994 });
1995 }
1996
1997 #[test]
1998 fn hashrate_resale_detail_optional_params_success() {
1999 TOKIO_SHARED_RT.block_on(async {
2000 let client = MockApiClient { force_error: false };
2001
2002 let params = HashrateResaleDetailParams::builder(168,).page_index(1).page_size(10).recv_window(5000).build().unwrap();
2003
2004 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"profitTransferDetails":[{"poolUsername":"test4001","toPoolUsername":"pop","algoName":"sha256","hashRate":200000000000,"day":20201213,"amount":0.2256872,"coinName":"BTC"}],"totalNum":8,"pageSize":200}}"#).unwrap_or_else(|_| serde_json::json!({}));
2005 let expected_response : models::HashrateResaleDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::HashrateResaleDetailResponse");
2006
2007 let resp = client.hashrate_resale_detail(params).await.expect("Expected a response");
2008 let data_future = resp.data();
2009 let actual_response = data_future.await.unwrap();
2010 assert_eq!(actual_response, expected_response);
2011 });
2012 }
2013
2014 #[test]
2015 fn hashrate_resale_detail_response_error() {
2016 TOKIO_SHARED_RT.block_on(async {
2017 let client = MockApiClient { force_error: true };
2018
2019 let params = HashrateResaleDetailParams::builder(168).build().unwrap();
2020
2021 match client.hashrate_resale_detail(params).await {
2022 Ok(_) => panic!("Expected an error"),
2023 Err(err) => {
2024 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2025 }
2026 }
2027 });
2028 }
2029
2030 #[test]
2031 fn hashrate_resale_list_required_params_success() {
2032 TOKIO_SHARED_RT.block_on(async {
2033 let client = MockApiClient { force_error: false };
2034
2035 let params = HashrateResaleListParams::builder().build().unwrap();
2036
2037 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"configDetails":[{"configId":168,"poolUsername":"123","toPoolUsername":"user1","algoName":"Ethash","hashRate":5000000,"startDay":20201210,"endDay":20210405,"status":1,"type":0}],"totalNum":21,"pageSize":200}}"#).unwrap_or_else(|_| serde_json::json!({}));
2038 let expected_response : models::HashrateResaleListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::HashrateResaleListResponse");
2039
2040 let resp = client.hashrate_resale_list(params).await.expect("Expected a response");
2041 let data_future = resp.data();
2042 let actual_response = data_future.await.unwrap();
2043 assert_eq!(actual_response, expected_response);
2044 });
2045 }
2046
2047 #[test]
2048 fn hashrate_resale_list_optional_params_success() {
2049 TOKIO_SHARED_RT.block_on(async {
2050 let client = MockApiClient { force_error: false };
2051
2052 let params = HashrateResaleListParams::builder().page_index(1).page_size(10).recv_window(5000).build().unwrap();
2053
2054 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"configDetails":[{"configId":168,"poolUsername":"123","toPoolUsername":"user1","algoName":"Ethash","hashRate":5000000,"startDay":20201210,"endDay":20210405,"status":1,"type":0}],"totalNum":21,"pageSize":200}}"#).unwrap_or_else(|_| serde_json::json!({}));
2055 let expected_response : models::HashrateResaleListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::HashrateResaleListResponse");
2056
2057 let resp = client.hashrate_resale_list(params).await.expect("Expected a response");
2058 let data_future = resp.data();
2059 let actual_response = data_future.await.unwrap();
2060 assert_eq!(actual_response, expected_response);
2061 });
2062 }
2063
2064 #[test]
2065 fn hashrate_resale_list_response_error() {
2066 TOKIO_SHARED_RT.block_on(async {
2067 let client = MockApiClient { force_error: true };
2068
2069 let params = HashrateResaleListParams::builder().build().unwrap();
2070
2071 match client.hashrate_resale_list(params).await {
2072 Ok(_) => panic!("Expected an error"),
2073 Err(err) => {
2074 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2075 }
2076 }
2077 });
2078 }
2079
2080 #[test]
2081 fn hashrate_resale_request_required_params_success() {
2082 TOKIO_SHARED_RT.block_on(async {
2083 let client = MockApiClient { force_error: false };
2084
2085 let params = HashrateResaleRequestParams::builder(
2086 "test".to_string(),
2087 "sha256".to_string(),
2088 1770736694138,
2089 1770736694138,
2090 "S19pro".to_string(),
2091 100000000,
2092 )
2093 .build()
2094 .unwrap();
2095
2096 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":171}"#)
2097 .unwrap_or_else(|_| serde_json::json!({}));
2098 let expected_response: models::HashrateResaleRequestResponse =
2099 serde_json::from_value(resp_json.clone())
2100 .expect("should parse into models::HashrateResaleRequestResponse");
2101
2102 let resp = client
2103 .hashrate_resale_request(params)
2104 .await
2105 .expect("Expected a response");
2106 let data_future = resp.data();
2107 let actual_response = data_future.await.unwrap();
2108 assert_eq!(actual_response, expected_response);
2109 });
2110 }
2111
2112 #[test]
2113 fn hashrate_resale_request_optional_params_success() {
2114 TOKIO_SHARED_RT.block_on(async {
2115 let client = MockApiClient { force_error: false };
2116
2117 let params = HashrateResaleRequestParams::builder(
2118 "test".to_string(),
2119 "sha256".to_string(),
2120 1770736694138,
2121 1770736694138,
2122 "S19pro".to_string(),
2123 100000000,
2124 )
2125 .recv_window(5000)
2126 .build()
2127 .unwrap();
2128
2129 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":171}"#)
2130 .unwrap_or_else(|_| serde_json::json!({}));
2131 let expected_response: models::HashrateResaleRequestResponse =
2132 serde_json::from_value(resp_json.clone())
2133 .expect("should parse into models::HashrateResaleRequestResponse");
2134
2135 let resp = client
2136 .hashrate_resale_request(params)
2137 .await
2138 .expect("Expected a response");
2139 let data_future = resp.data();
2140 let actual_response = data_future.await.unwrap();
2141 assert_eq!(actual_response, expected_response);
2142 });
2143 }
2144
2145 #[test]
2146 fn hashrate_resale_request_response_error() {
2147 TOKIO_SHARED_RT.block_on(async {
2148 let client = MockApiClient { force_error: true };
2149
2150 let params = HashrateResaleRequestParams::builder(
2151 "test".to_string(),
2152 "sha256".to_string(),
2153 1770736694138,
2154 1770736694138,
2155 "S19pro".to_string(),
2156 100000000,
2157 )
2158 .build()
2159 .unwrap();
2160
2161 match client.hashrate_resale_request(params).await {
2162 Ok(_) => panic!("Expected an error"),
2163 Err(err) => {
2164 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2165 }
2166 }
2167 });
2168 }
2169
2170 #[test]
2171 fn mining_account_earning_required_params_success() {
2172 TOKIO_SHARED_RT.block_on(async {
2173 let client = MockApiClient { force_error: false };
2174
2175 let params = MiningAccountEarningParams::builder("sha256".to_string(),).build().unwrap();
2176
2177 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"accountProfits":[{"time":1607443200000,"coinName":"BTC","type":2,"puid":59985472,"subName":"vdvaghani","amount":0.09186957}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
2178 let expected_response : models::MiningAccountEarningResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MiningAccountEarningResponse");
2179
2180 let resp = client.mining_account_earning(params).await.expect("Expected a response");
2181 let data_future = resp.data();
2182 let actual_response = data_future.await.unwrap();
2183 assert_eq!(actual_response, expected_response);
2184 });
2185 }
2186
2187 #[test]
2188 fn mining_account_earning_optional_params_success() {
2189 TOKIO_SHARED_RT.block_on(async {
2190 let client = MockApiClient { force_error: false };
2191
2192 let params = MiningAccountEarningParams::builder("sha256".to_string(),).start_date(1770736694138).end_date(1770736694138).page_index(1).page_size(10).recv_window(5000).build().unwrap();
2193
2194 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"accountProfits":[{"time":1607443200000,"coinName":"BTC","type":2,"puid":59985472,"subName":"vdvaghani","amount":0.09186957}],"totalNum":3,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
2195 let expected_response : models::MiningAccountEarningResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MiningAccountEarningResponse");
2196
2197 let resp = client.mining_account_earning(params).await.expect("Expected a response");
2198 let data_future = resp.data();
2199 let actual_response = data_future.await.unwrap();
2200 assert_eq!(actual_response, expected_response);
2201 });
2202 }
2203
2204 #[test]
2205 fn mining_account_earning_response_error() {
2206 TOKIO_SHARED_RT.block_on(async {
2207 let client = MockApiClient { force_error: true };
2208
2209 let params = MiningAccountEarningParams::builder("sha256".to_string())
2210 .build()
2211 .unwrap();
2212
2213 match client.mining_account_earning(params).await {
2214 Ok(_) => panic!("Expected an error"),
2215 Err(err) => {
2216 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2217 }
2218 }
2219 });
2220 }
2221
2222 #[test]
2223 fn request_for_detail_miner_list_required_params_success() {
2224 TOKIO_SHARED_RT.block_on(async {
2225 let client = MockApiClient { force_error: false };
2226
2227 let params = RequestForDetailMinerListParams::builder("sha256".to_string(),"test".to_string(),"bhdc1.16A10404B".to_string(),).build().unwrap();
2228
2229 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"workerName":"bhdc1.16A10404B","type":"H_hashrate","hashrateDatas":[{"time":1587902400000,"hashrate":"0","reject":0}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2230 let expected_response : models::RequestForDetailMinerListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RequestForDetailMinerListResponse");
2231
2232 let resp = client.request_for_detail_miner_list(params).await.expect("Expected a response");
2233 let data_future = resp.data();
2234 let actual_response = data_future.await.unwrap();
2235 assert_eq!(actual_response, expected_response);
2236 });
2237 }
2238
2239 #[test]
2240 fn request_for_detail_miner_list_optional_params_success() {
2241 TOKIO_SHARED_RT.block_on(async {
2242 let client = MockApiClient { force_error: false };
2243
2244 let params = RequestForDetailMinerListParams::builder("sha256".to_string(),"test".to_string(),"bhdc1.16A10404B".to_string(),).recv_window(5000).build().unwrap();
2245
2246 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":[{"workerName":"bhdc1.16A10404B","type":"H_hashrate","hashrateDatas":[{"time":1587902400000,"hashrate":"0","reject":0}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2247 let expected_response : models::RequestForDetailMinerListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RequestForDetailMinerListResponse");
2248
2249 let resp = client.request_for_detail_miner_list(params).await.expect("Expected a response");
2250 let data_future = resp.data();
2251 let actual_response = data_future.await.unwrap();
2252 assert_eq!(actual_response, expected_response);
2253 });
2254 }
2255
2256 #[test]
2257 fn request_for_detail_miner_list_response_error() {
2258 TOKIO_SHARED_RT.block_on(async {
2259 let client = MockApiClient { force_error: true };
2260
2261 let params = RequestForDetailMinerListParams::builder(
2262 "sha256".to_string(),
2263 "test".to_string(),
2264 "bhdc1.16A10404B".to_string(),
2265 )
2266 .build()
2267 .unwrap();
2268
2269 match client.request_for_detail_miner_list(params).await {
2270 Ok(_) => panic!("Expected an error"),
2271 Err(err) => {
2272 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2273 }
2274 }
2275 });
2276 }
2277
2278 #[test]
2279 fn request_for_miner_list_required_params_success() {
2280 TOKIO_SHARED_RT.block_on(async {
2281 let client = MockApiClient { force_error: false };
2282
2283 let params = RequestForMinerListParams::builder("sha256".to_string(),"test".to_string(),).build().unwrap();
2284
2285 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"workerDatas":[{"workerId":"1420554439452400131","workerName":"2X73","status":3,"hashRate":0,"dayHashRate":1.269778129801366E13,"rejectRate":0,"lastShareTime":1587712919000}],"totalNum":18530,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
2286 let expected_response : models::RequestForMinerListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RequestForMinerListResponse");
2287
2288 let resp = client.request_for_miner_list(params).await.expect("Expected a response");
2289 let data_future = resp.data();
2290 let actual_response = data_future.await.unwrap();
2291 assert_eq!(actual_response, expected_response);
2292 });
2293 }
2294
2295 #[test]
2296 fn request_for_miner_list_optional_params_success() {
2297 TOKIO_SHARED_RT.block_on(async {
2298 let client = MockApiClient { force_error: false };
2299
2300 let params = RequestForMinerListParams::builder("sha256".to_string(),"test".to_string(),).page_index(1).sort(0).sort_column(1).worker_status(0).recv_window(5000).build().unwrap();
2301
2302 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"workerDatas":[{"workerId":"1420554439452400131","workerName":"2X73","status":3,"hashRate":0,"dayHashRate":1.269778129801366E13,"rejectRate":0,"lastShareTime":1587712919000}],"totalNum":18530,"pageSize":20}}"#).unwrap_or_else(|_| serde_json::json!({}));
2303 let expected_response : models::RequestForMinerListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RequestForMinerListResponse");
2304
2305 let resp = client.request_for_miner_list(params).await.expect("Expected a response");
2306 let data_future = resp.data();
2307 let actual_response = data_future.await.unwrap();
2308 assert_eq!(actual_response, expected_response);
2309 });
2310 }
2311
2312 #[test]
2313 fn request_for_miner_list_response_error() {
2314 TOKIO_SHARED_RT.block_on(async {
2315 let client = MockApiClient { force_error: true };
2316
2317 let params =
2318 RequestForMinerListParams::builder("sha256".to_string(), "test".to_string())
2319 .build()
2320 .unwrap();
2321
2322 match client.request_for_miner_list(params).await {
2323 Ok(_) => panic!("Expected an error"),
2324 Err(err) => {
2325 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2326 }
2327 }
2328 });
2329 }
2330
2331 #[test]
2332 fn statistic_list_required_params_success() {
2333 TOKIO_SHARED_RT.block_on(async {
2334 let client = MockApiClient { force_error: false };
2335
2336 let params = StatisticListParams::builder("sha256".to_string(),"test".to_string(),).build().unwrap();
2337
2338 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"fifteenMinHashRate":"457835490067496409.00000000","dayHashRate":"214289268068874127.65000000","validNum":0,"invalidNum":17562,"profitToday":{"BTC":"0.00314332","BSV":"56.17055953","BCH":"106.61586001"},"profitYesterday":{"BTC":"0.00314332","BSV":"56.17055953","BCH":"106.61586001"},"userName":"test","unit":"h/s","algo":"sha256"}}"#).unwrap_or_else(|_| serde_json::json!({}));
2339 let expected_response : models::StatisticListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::StatisticListResponse");
2340
2341 let resp = client.statistic_list(params).await.expect("Expected a response");
2342 let data_future = resp.data();
2343 let actual_response = data_future.await.unwrap();
2344 assert_eq!(actual_response, expected_response);
2345 });
2346 }
2347
2348 #[test]
2349 fn statistic_list_optional_params_success() {
2350 TOKIO_SHARED_RT.block_on(async {
2351 let client = MockApiClient { force_error: false };
2352
2353 let params = StatisticListParams::builder("sha256".to_string(),"test".to_string(),).recv_window(5000).build().unwrap();
2354
2355 let resp_json: Value = serde_json::from_str(r#"{"code":0,"msg":"","data":{"fifteenMinHashRate":"457835490067496409.00000000","dayHashRate":"214289268068874127.65000000","validNum":0,"invalidNum":17562,"profitToday":{"BTC":"0.00314332","BSV":"56.17055953","BCH":"106.61586001"},"profitYesterday":{"BTC":"0.00314332","BSV":"56.17055953","BCH":"106.61586001"},"userName":"test","unit":"h/s","algo":"sha256"}}"#).unwrap_or_else(|_| serde_json::json!({}));
2356 let expected_response : models::StatisticListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::StatisticListResponse");
2357
2358 let resp = client.statistic_list(params).await.expect("Expected a response");
2359 let data_future = resp.data();
2360 let actual_response = data_future.await.unwrap();
2361 assert_eq!(actual_response, expected_response);
2362 });
2363 }
2364
2365 #[test]
2366 fn statistic_list_response_error() {
2367 TOKIO_SHARED_RT.block_on(async {
2368 let client = MockApiClient { force_error: true };
2369
2370 let params = StatisticListParams::builder("sha256".to_string(), "test".to_string())
2371 .build()
2372 .unwrap();
2373
2374 match client.statistic_list(params).await {
2375 Ok(_) => panic!("Expected an error"),
2376 Err(err) => {
2377 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2378 }
2379 }
2380 });
2381 }
2382}