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::sub_account::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait ManagedSubAccountApi: Send + Sync {
34 async fn deposit_assets_into_the_managed_sub_account(
35 &self,
36 params: DepositAssetsIntoTheManagedSubAccountParams,
37 ) -> anyhow::Result<RestApiResponse<models::DepositAssetsIntoTheManagedSubAccountResponse>>;
38 async fn get_managed_sub_account_deposit_address(
39 &self,
40 params: GetManagedSubAccountDepositAddressParams,
41 ) -> anyhow::Result<RestApiResponse<models::GetManagedSubAccountDepositAddressResponse>>;
42 async fn query_managed_sub_account_asset_details(
43 &self,
44 params: QueryManagedSubAccountAssetDetailsParams,
45 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>>>;
46 async fn query_managed_sub_account_futures_asset_details(
47 &self,
48 params: QueryManagedSubAccountFuturesAssetDetailsParams,
49 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountFuturesAssetDetailsResponse>>;
50 async fn query_managed_sub_account_list(
51 &self,
52 params: QueryManagedSubAccountListParams,
53 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountListResponse>>;
54 async fn query_managed_sub_account_margin_asset_details(
55 &self,
56 params: QueryManagedSubAccountMarginAssetDetailsParams,
57 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountMarginAssetDetailsResponse>>;
58 async fn query_managed_sub_account_snapshot(
59 &self,
60 params: QueryManagedSubAccountSnapshotParams,
61 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountSnapshotResponse>>;
62 async fn query_managed_sub_account_transfer_log_master_account_investor(
63 &self,
64 params: QueryManagedSubAccountTransferLogMasterAccountInvestorParams,
65 ) -> anyhow::Result<
66 RestApiResponse<models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse>,
67 >;
68 async fn query_managed_sub_account_transfer_log_master_account_trading(
69 &self,
70 params: QueryManagedSubAccountTransferLogMasterAccountTradingParams,
71 ) -> anyhow::Result<
72 RestApiResponse<models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse>,
73 >;
74 async fn query_managed_sub_account_transfer_log_sub_account_trading(
75 &self,
76 params: QueryManagedSubAccountTransferLogSubAccountTradingParams,
77 ) -> anyhow::Result<
78 RestApiResponse<models::QueryManagedSubAccountTransferLogSubAccountTradingResponse>,
79 >;
80 async fn withdrawl_assets_from_the_managed_sub_account(
81 &self,
82 params: WithdrawlAssetsFromTheManagedSubAccountParams,
83 ) -> anyhow::Result<RestApiResponse<models::WithdrawlAssetsFromTheManagedSubAccountResponse>>;
84}
85
86#[derive(Debug, Clone)]
87pub struct ManagedSubAccountApiClient {
88 configuration: ConfigurationRestApi,
89}
90
91impl ManagedSubAccountApiClient {
92 pub fn new(configuration: ConfigurationRestApi) -> Self {
93 Self { configuration }
94 }
95}
96
97#[allow(non_camel_case_types)]
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub enum QueryManagedSubAccountSnapshotTypeEnum {
100 #[serde(rename = "SPOT")]
101 Spot,
102 #[serde(rename = "MARGIN")]
103 Margin,
104 #[serde(rename = "FUTURES")]
105 Futures,
106}
107
108impl QueryManagedSubAccountSnapshotTypeEnum {
109 #[must_use]
110 pub fn as_str(&self) -> &'static str {
111 match self {
112 Self::Spot => "SPOT",
113 Self::Margin => "MARGIN",
114 Self::Futures => "FUTURES",
115 }
116 }
117}
118
119impl std::str::FromStr for QueryManagedSubAccountSnapshotTypeEnum {
120 type Err = Box<dyn std::error::Error + Send + Sync>;
121
122 fn from_str(s: &str) -> Result<Self, Self::Err> {
123 match s {
124 "SPOT" => Ok(Self::Spot),
125 "MARGIN" => Ok(Self::Margin),
126 "FUTURES" => Ok(Self::Futures),
127 other => {
128 Err(format!("invalid QueryManagedSubAccountSnapshotTypeEnum: {}", other).into())
129 }
130 }
131 }
132}
133
134#[allow(non_camel_case_types)]
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub enum QueryManagedSubAccountTransferLogMasterAccountInvestorTransferFunctionAccountTypeEnum {
137 #[serde(rename = "SPOT")]
138 Spot,
139 #[serde(rename = "MARGIN")]
140 Margin,
141 #[serde(rename = "ISOLATED_MARGIN")]
142 IsolatedMargin,
143 #[serde(rename = "USDT_FUTURE")]
144 UsdtFuture,
145 #[serde(rename = "COIN_FUTURE")]
146 CoinFuture,
147}
148
149impl QueryManagedSubAccountTransferLogMasterAccountInvestorTransferFunctionAccountTypeEnum {
150 #[must_use]
151 pub fn as_str(&self) -> &'static str {
152 match self {
153 Self::Spot => "SPOT",
154 Self::Margin => "MARGIN",
155 Self::IsolatedMargin => "ISOLATED_MARGIN",
156 Self::UsdtFuture => "USDT_FUTURE",
157 Self::CoinFuture => "COIN_FUTURE",
158 }
159 }
160}
161
162impl std::str::FromStr
163 for QueryManagedSubAccountTransferLogMasterAccountInvestorTransferFunctionAccountTypeEnum
164{
165 type Err = Box<dyn std::error::Error + Send + Sync>;
166
167 fn from_str(s: &str) -> Result<Self, Self::Err> {
168 match s {
169 "SPOT" => Ok(Self::Spot),
170 "MARGIN" => Ok(Self::Margin),
171 "ISOLATED_MARGIN" => Ok(Self::IsolatedMargin),
172 "USDT_FUTURE" => Ok(Self::UsdtFuture),
173 "COIN_FUTURE" => Ok(Self::CoinFuture),
174 other => Err(format!("invalid QueryManagedSubAccountTransferLogMasterAccountInvestorTransferFunctionAccountTypeEnum: {}", other).into()),
175 }
176 }
177}
178
179#[allow(non_camel_case_types)]
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub enum QueryManagedSubAccountTransferLogMasterAccountTradingTransferFunctionAccountTypeEnum {
182 #[serde(rename = "SPOT")]
183 Spot,
184 #[serde(rename = "MARGIN")]
185 Margin,
186 #[serde(rename = "ISOLATED_MARGIN")]
187 IsolatedMargin,
188 #[serde(rename = "USDT_FUTURE")]
189 UsdtFuture,
190 #[serde(rename = "COIN_FUTURE")]
191 CoinFuture,
192}
193
194impl QueryManagedSubAccountTransferLogMasterAccountTradingTransferFunctionAccountTypeEnum {
195 #[must_use]
196 pub fn as_str(&self) -> &'static str {
197 match self {
198 Self::Spot => "SPOT",
199 Self::Margin => "MARGIN",
200 Self::IsolatedMargin => "ISOLATED_MARGIN",
201 Self::UsdtFuture => "USDT_FUTURE",
202 Self::CoinFuture => "COIN_FUTURE",
203 }
204 }
205}
206
207impl std::str::FromStr
208 for QueryManagedSubAccountTransferLogMasterAccountTradingTransferFunctionAccountTypeEnum
209{
210 type Err = Box<dyn std::error::Error + Send + Sync>;
211
212 fn from_str(s: &str) -> Result<Self, Self::Err> {
213 match s {
214 "SPOT" => Ok(Self::Spot),
215 "MARGIN" => Ok(Self::Margin),
216 "ISOLATED_MARGIN" => Ok(Self::IsolatedMargin),
217 "USDT_FUTURE" => Ok(Self::UsdtFuture),
218 "COIN_FUTURE" => Ok(Self::CoinFuture),
219 other => Err(format!("invalid QueryManagedSubAccountTransferLogMasterAccountTradingTransferFunctionAccountTypeEnum: {}", other).into()),
220 }
221 }
222}
223
224#[allow(non_camel_case_types)]
225#[derive(Debug, Clone, Serialize, Deserialize)]
226pub enum QueryManagedSubAccountTransferLogSubAccountTradingTransferFunctionAccountTypeEnum {
227 #[serde(rename = "SPOT")]
228 Spot,
229 #[serde(rename = "MARGIN")]
230 Margin,
231 #[serde(rename = "ISOLATED_MARGIN")]
232 IsolatedMargin,
233 #[serde(rename = "USDT_FUTURE")]
234 UsdtFuture,
235 #[serde(rename = "COIN_FUTURE")]
236 CoinFuture,
237}
238
239impl QueryManagedSubAccountTransferLogSubAccountTradingTransferFunctionAccountTypeEnum {
240 #[must_use]
241 pub fn as_str(&self) -> &'static str {
242 match self {
243 Self::Spot => "SPOT",
244 Self::Margin => "MARGIN",
245 Self::IsolatedMargin => "ISOLATED_MARGIN",
246 Self::UsdtFuture => "USDT_FUTURE",
247 Self::CoinFuture => "COIN_FUTURE",
248 }
249 }
250}
251
252impl std::str::FromStr
253 for QueryManagedSubAccountTransferLogSubAccountTradingTransferFunctionAccountTypeEnum
254{
255 type Err = Box<dyn std::error::Error + Send + Sync>;
256
257 fn from_str(s: &str) -> Result<Self, Self::Err> {
258 match s {
259 "SPOT" => Ok(Self::Spot),
260 "MARGIN" => Ok(Self::Margin),
261 "ISOLATED_MARGIN" => Ok(Self::IsolatedMargin),
262 "USDT_FUTURE" => Ok(Self::UsdtFuture),
263 "COIN_FUTURE" => Ok(Self::CoinFuture),
264 other => Err(format!("invalid QueryManagedSubAccountTransferLogSubAccountTradingTransferFunctionAccountTypeEnum: {}", other).into()),
265 }
266 }
267}
268
269#[derive(Clone, Debug, Builder, Deserialize)]
274#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
275pub struct DepositAssetsIntoTheManagedSubAccountParams {
276 #[builder(setter(into))]
281 #[serde(rename = "toEmail")]
282 pub to_email: String,
283 #[builder(setter(into))]
288 #[serde(rename = "asset")]
289 pub asset: String,
290 #[builder(setter(into))]
295 #[serde(rename = "amount")]
296 pub amount: rust_decimal::Decimal,
297 #[builder(setter(into), default)]
302 #[serde(rename = "recvWindow", default)]
303 pub recv_window: Option<i64>,
304}
305
306impl DepositAssetsIntoTheManagedSubAccountParams {
307 #[must_use]
316 pub fn builder(
317 to_email: String,
318 asset: String,
319 amount: rust_decimal::Decimal,
320 ) -> DepositAssetsIntoTheManagedSubAccountParamsBuilder {
321 DepositAssetsIntoTheManagedSubAccountParamsBuilder::default()
322 .to_email(to_email)
323 .asset(asset)
324 .amount(amount)
325 }
326}
327#[derive(Clone, Debug, Builder, Deserialize)]
332#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
333pub struct GetManagedSubAccountDepositAddressParams {
334 #[builder(setter(into))]
339 #[serde(rename = "email")]
340 pub email: String,
341 #[builder(setter(into))]
346 #[serde(rename = "coin")]
347 pub coin: String,
348 #[builder(setter(into), default)]
352 #[serde(rename = "network", default)]
353 pub network: Option<String>,
354 #[builder(setter(into), default)]
359 #[serde(rename = "amount", default)]
360 pub amount: Option<rust_decimal::Decimal>,
361 #[builder(setter(into), default)]
366 #[serde(rename = "recvWindow", default)]
367 pub recv_window: Option<i64>,
368}
369
370impl GetManagedSubAccountDepositAddressParams {
371 #[must_use]
379 pub fn builder(email: String, coin: String) -> GetManagedSubAccountDepositAddressParamsBuilder {
380 GetManagedSubAccountDepositAddressParamsBuilder::default()
381 .email(email)
382 .coin(coin)
383 }
384}
385#[derive(Clone, Debug, Builder, Deserialize)]
390#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
391pub struct QueryManagedSubAccountAssetDetailsParams {
392 #[builder(setter(into))]
397 #[serde(rename = "email")]
398 pub email: String,
399 #[builder(setter(into), default)]
404 #[serde(rename = "recvWindow", default)]
405 pub recv_window: Option<i64>,
406}
407
408impl QueryManagedSubAccountAssetDetailsParams {
409 #[must_use]
416 pub fn builder(email: String) -> QueryManagedSubAccountAssetDetailsParamsBuilder {
417 QueryManagedSubAccountAssetDetailsParamsBuilder::default().email(email)
418 }
419}
420#[derive(Clone, Debug, Builder, Deserialize)]
425#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
426pub struct QueryManagedSubAccountFuturesAssetDetailsParams {
427 #[builder(setter(into))]
432 #[serde(rename = "email")]
433 pub email: String,
434 #[builder(setter(into), default)]
438 #[serde(rename = "accountType", default)]
439 pub account_type: Option<String>,
440}
441
442impl QueryManagedSubAccountFuturesAssetDetailsParams {
443 #[must_use]
450 pub fn builder(email: String) -> QueryManagedSubAccountFuturesAssetDetailsParamsBuilder {
451 QueryManagedSubAccountFuturesAssetDetailsParamsBuilder::default().email(email)
452 }
453}
454#[derive(Clone, Debug, Builder, Deserialize, Default)]
459#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
460pub struct QueryManagedSubAccountListParams {
461 #[builder(setter(into), default)]
466 #[serde(rename = "email", default)]
467 pub email: Option<String>,
468 #[builder(setter(into), default)]
473 #[serde(rename = "page", default)]
474 pub page: Option<i64>,
475 #[builder(setter(into), default)]
480 #[serde(rename = "limit", default)]
481 pub limit: Option<i64>,
482 #[builder(setter(into), default)]
487 #[serde(rename = "recvWindow", default)]
488 pub recv_window: Option<i64>,
489}
490
491impl QueryManagedSubAccountListParams {
492 #[must_use]
495 pub fn builder() -> QueryManagedSubAccountListParamsBuilder {
496 QueryManagedSubAccountListParamsBuilder::default()
497 }
498}
499#[derive(Clone, Debug, Builder, Deserialize)]
504#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
505pub struct QueryManagedSubAccountMarginAssetDetailsParams {
506 #[builder(setter(into))]
511 #[serde(rename = "email")]
512 pub email: String,
513 #[builder(setter(into), default)]
518 #[serde(rename = "accountType", default)]
519 pub account_type: Option<String>,
520}
521
522impl QueryManagedSubAccountMarginAssetDetailsParams {
523 #[must_use]
530 pub fn builder(email: String) -> QueryManagedSubAccountMarginAssetDetailsParamsBuilder {
531 QueryManagedSubAccountMarginAssetDetailsParamsBuilder::default().email(email)
532 }
533}
534#[derive(Clone, Debug, Builder, Deserialize)]
539#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
540pub struct QueryManagedSubAccountSnapshotParams {
541 #[builder(setter(into))]
546 #[serde(rename = "email")]
547 pub email: String,
548 #[builder(setter(into))]
553 #[serde(rename = "type")]
554 pub r#type: QueryManagedSubAccountSnapshotTypeEnum,
555 #[builder(setter(into), default)]
559 #[serde(rename = "startTime", default)]
560 pub start_time: Option<i64>,
561 #[builder(setter(into), default)]
565 #[serde(rename = "endTime", default)]
566 pub end_time: Option<i64>,
567 #[builder(setter(into), default)]
572 #[serde(rename = "limit", default)]
573 pub limit: Option<i64>,
574 #[builder(setter(into), default)]
579 #[serde(rename = "recvWindow", default)]
580 pub recv_window: Option<i64>,
581}
582
583impl QueryManagedSubAccountSnapshotParams {
584 #[must_use]
592 pub fn builder(
593 email: String,
594 r#type: QueryManagedSubAccountSnapshotTypeEnum,
595 ) -> QueryManagedSubAccountSnapshotParamsBuilder {
596 QueryManagedSubAccountSnapshotParamsBuilder::default()
597 .email(email)
598 .r#type(r#type)
599 }
600}
601#[derive(Clone, Debug, Builder, Deserialize)]
606#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
607pub struct QueryManagedSubAccountTransferLogMasterAccountInvestorParams {
608 #[builder(setter(into))]
613 #[serde(rename = "email")]
614 pub email: String,
615 #[builder(setter(into))]
619 #[serde(rename = "startTime")]
620 pub start_time: i64,
621 #[builder(setter(into))]
625 #[serde(rename = "endTime")]
626 pub end_time: i64,
627 #[builder(setter(into))]
631 #[serde(rename = "page")]
632 pub page: i64,
633 #[builder(setter(into))]
638 #[serde(rename = "limit")]
639 pub limit: i64,
640 #[builder(setter(into), default)]
644 #[serde(rename = "transfers", default)]
645 pub transfers: Option<String>,
646 #[builder(setter(into), default)]
651 #[serde(rename = "transferFunctionAccountType", default)]
652 pub transfer_function_account_type: Option<
653 QueryManagedSubAccountTransferLogMasterAccountInvestorTransferFunctionAccountTypeEnum,
654 >,
655}
656
657impl QueryManagedSubAccountTransferLogMasterAccountInvestorParams {
658 #[must_use]
669 pub fn builder(
670 email: String,
671 start_time: i64,
672 end_time: i64,
673 page: i64,
674 limit: i64,
675 ) -> QueryManagedSubAccountTransferLogMasterAccountInvestorParamsBuilder {
676 QueryManagedSubAccountTransferLogMasterAccountInvestorParamsBuilder::default()
677 .email(email)
678 .start_time(start_time)
679 .end_time(end_time)
680 .page(page)
681 .limit(limit)
682 }
683}
684#[derive(Clone, Debug, Builder, Deserialize)]
689#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
690pub struct QueryManagedSubAccountTransferLogMasterAccountTradingParams {
691 #[builder(setter(into))]
696 #[serde(rename = "email")]
697 pub email: String,
698 #[builder(setter(into))]
702 #[serde(rename = "startTime")]
703 pub start_time: i64,
704 #[builder(setter(into))]
708 #[serde(rename = "endTime")]
709 pub end_time: i64,
710 #[builder(setter(into))]
715 #[serde(rename = "page")]
716 pub page: i64,
717 #[builder(setter(into))]
722 #[serde(rename = "limit")]
723 pub limit: i64,
724 #[builder(setter(into), default)]
728 #[serde(rename = "transfers", default)]
729 pub transfers: Option<String>,
730 #[builder(setter(into), default)]
735 #[serde(rename = "transferFunctionAccountType", default)]
736 pub transfer_function_account_type: Option<
737 QueryManagedSubAccountTransferLogMasterAccountTradingTransferFunctionAccountTypeEnum,
738 >,
739}
740
741impl QueryManagedSubAccountTransferLogMasterAccountTradingParams {
742 #[must_use]
753 pub fn builder(
754 email: String,
755 start_time: i64,
756 end_time: i64,
757 page: i64,
758 limit: i64,
759 ) -> QueryManagedSubAccountTransferLogMasterAccountTradingParamsBuilder {
760 QueryManagedSubAccountTransferLogMasterAccountTradingParamsBuilder::default()
761 .email(email)
762 .start_time(start_time)
763 .end_time(end_time)
764 .page(page)
765 .limit(limit)
766 }
767}
768#[derive(Clone, Debug, Builder, Deserialize)]
773#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
774pub struct QueryManagedSubAccountTransferLogSubAccountTradingParams {
775 #[builder(setter(into))]
779 #[serde(rename = "startTime")]
780 pub start_time: i64,
781 #[builder(setter(into))]
785 #[serde(rename = "endTime")]
786 pub end_time: i64,
787 #[builder(setter(into))]
792 #[serde(rename = "page")]
793 pub page: i64,
794 #[builder(setter(into))]
799 #[serde(rename = "limit")]
800 pub limit: i64,
801 #[builder(setter(into), default)]
805 #[serde(rename = "transfers", default)]
806 pub transfers: Option<String>,
807 #[builder(setter(into), default)]
812 #[serde(rename = "transferFunctionAccountType", default)]
813 pub transfer_function_account_type:
814 Option<QueryManagedSubAccountTransferLogSubAccountTradingTransferFunctionAccountTypeEnum>,
815 #[builder(setter(into), default)]
820 #[serde(rename = "recvWindow", default)]
821 pub recv_window: Option<i64>,
822}
823
824impl QueryManagedSubAccountTransferLogSubAccountTradingParams {
825 #[must_use]
835 pub fn builder(
836 start_time: i64,
837 end_time: i64,
838 page: i64,
839 limit: i64,
840 ) -> QueryManagedSubAccountTransferLogSubAccountTradingParamsBuilder {
841 QueryManagedSubAccountTransferLogSubAccountTradingParamsBuilder::default()
842 .start_time(start_time)
843 .end_time(end_time)
844 .page(page)
845 .limit(limit)
846 }
847}
848#[derive(Clone, Debug, Builder, Deserialize)]
853#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
854pub struct WithdrawlAssetsFromTheManagedSubAccountParams {
855 #[builder(setter(into))]
860 #[serde(rename = "fromEmail")]
861 pub from_email: String,
862 #[builder(setter(into))]
867 #[serde(rename = "asset")]
868 pub asset: String,
869 #[builder(setter(into))]
874 #[serde(rename = "amount")]
875 pub amount: rust_decimal::Decimal,
876 #[builder(setter(into), default)]
881 #[serde(rename = "transferDate", default)]
882 pub transfer_date: Option<i64>,
883 #[builder(setter(into), default)]
888 #[serde(rename = "recvWindow", default)]
889 pub recv_window: Option<i64>,
890}
891
892impl WithdrawlAssetsFromTheManagedSubAccountParams {
893 #[must_use]
902 pub fn builder(
903 from_email: String,
904 asset: String,
905 amount: rust_decimal::Decimal,
906 ) -> WithdrawlAssetsFromTheManagedSubAccountParamsBuilder {
907 WithdrawlAssetsFromTheManagedSubAccountParamsBuilder::default()
908 .from_email(from_email)
909 .asset(asset)
910 .amount(amount)
911 }
912}
913
914#[async_trait]
915impl ManagedSubAccountApi for ManagedSubAccountApiClient {
916 async fn deposit_assets_into_the_managed_sub_account(
917 &self,
918 params: DepositAssetsIntoTheManagedSubAccountParams,
919 ) -> anyhow::Result<RestApiResponse<models::DepositAssetsIntoTheManagedSubAccountResponse>>
920 {
921 let DepositAssetsIntoTheManagedSubAccountParams {
922 to_email,
923 asset,
924 amount,
925 recv_window,
926 } = params;
927
928 let mut query_params = BTreeMap::new();
929 let body_params = BTreeMap::new();
930
931 query_params.insert("toEmail".to_string(), json!(to_email));
932
933 query_params.insert("asset".to_string(), json!(asset));
934
935 query_params.insert("amount".to_string(), json!(amount));
936
937 if let Some(rw) = recv_window {
938 query_params.insert("recvWindow".to_string(), json!(rw));
939 }
940
941 send_request::<models::DepositAssetsIntoTheManagedSubAccountResponse>(
942 &self.configuration,
943 "/sapi/v1/managed-subaccount/deposit",
944 reqwest::Method::POST,
945 query_params,
946 body_params,
947 if HAS_TIME_UNIT {
948 self.configuration.time_unit
949 } else {
950 None
951 },
952 true,
953 )
954 .await
955 }
956
957 async fn get_managed_sub_account_deposit_address(
958 &self,
959 params: GetManagedSubAccountDepositAddressParams,
960 ) -> anyhow::Result<RestApiResponse<models::GetManagedSubAccountDepositAddressResponse>> {
961 let GetManagedSubAccountDepositAddressParams {
962 email,
963 coin,
964 network,
965 amount,
966 recv_window,
967 } = params;
968
969 let mut query_params = BTreeMap::new();
970 let body_params = BTreeMap::new();
971
972 query_params.insert("email".to_string(), json!(email));
973
974 query_params.insert("coin".to_string(), json!(coin));
975
976 if let Some(rw) = network {
977 query_params.insert("network".to_string(), json!(rw));
978 }
979
980 if let Some(rw) = amount {
981 query_params.insert("amount".to_string(), json!(rw));
982 }
983
984 if let Some(rw) = recv_window {
985 query_params.insert("recvWindow".to_string(), json!(rw));
986 }
987
988 send_request::<models::GetManagedSubAccountDepositAddressResponse>(
989 &self.configuration,
990 "/sapi/v1/managed-subaccount/deposit/address",
991 reqwest::Method::GET,
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 async fn query_managed_sub_account_asset_details(
1005 &self,
1006 params: QueryManagedSubAccountAssetDetailsParams,
1007 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>>>
1008 {
1009 let QueryManagedSubAccountAssetDetailsParams { email, recv_window } = params;
1010
1011 let mut query_params = BTreeMap::new();
1012 let body_params = BTreeMap::new();
1013
1014 query_params.insert("email".to_string(), json!(email));
1015
1016 if let Some(rw) = recv_window {
1017 query_params.insert("recvWindow".to_string(), json!(rw));
1018 }
1019
1020 send_request::<Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>>(
1021 &self.configuration,
1022 "/sapi/v1/managed-subaccount/asset",
1023 reqwest::Method::GET,
1024 query_params,
1025 body_params,
1026 if HAS_TIME_UNIT {
1027 self.configuration.time_unit
1028 } else {
1029 None
1030 },
1031 true,
1032 )
1033 .await
1034 }
1035
1036 async fn query_managed_sub_account_futures_asset_details(
1037 &self,
1038 params: QueryManagedSubAccountFuturesAssetDetailsParams,
1039 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountFuturesAssetDetailsResponse>>
1040 {
1041 let QueryManagedSubAccountFuturesAssetDetailsParams {
1042 email,
1043 account_type,
1044 } = params;
1045
1046 let mut query_params = BTreeMap::new();
1047 let body_params = BTreeMap::new();
1048
1049 query_params.insert("email".to_string(), json!(email));
1050
1051 if let Some(rw) = account_type {
1052 query_params.insert("accountType".to_string(), json!(rw));
1053 }
1054
1055 send_request::<models::QueryManagedSubAccountFuturesAssetDetailsResponse>(
1056 &self.configuration,
1057 "/sapi/v1/managed-subaccount/fetch-future-asset",
1058 reqwest::Method::GET,
1059 query_params,
1060 body_params,
1061 if HAS_TIME_UNIT {
1062 self.configuration.time_unit
1063 } else {
1064 None
1065 },
1066 true,
1067 )
1068 .await
1069 }
1070
1071 async fn query_managed_sub_account_list(
1072 &self,
1073 params: QueryManagedSubAccountListParams,
1074 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountListResponse>> {
1075 let QueryManagedSubAccountListParams {
1076 email,
1077 page,
1078 limit,
1079 recv_window,
1080 } = params;
1081
1082 let mut query_params = BTreeMap::new();
1083 let body_params = BTreeMap::new();
1084
1085 if let Some(rw) = email {
1086 query_params.insert("email".to_string(), json!(rw));
1087 }
1088
1089 if let Some(rw) = page {
1090 query_params.insert("page".to_string(), json!(rw));
1091 }
1092
1093 if let Some(rw) = limit {
1094 query_params.insert("limit".to_string(), json!(rw));
1095 }
1096
1097 if let Some(rw) = recv_window {
1098 query_params.insert("recvWindow".to_string(), json!(rw));
1099 }
1100
1101 send_request::<models::QueryManagedSubAccountListResponse>(
1102 &self.configuration,
1103 "/sapi/v1/managed-subaccount/info",
1104 reqwest::Method::GET,
1105 query_params,
1106 body_params,
1107 if HAS_TIME_UNIT {
1108 self.configuration.time_unit
1109 } else {
1110 None
1111 },
1112 true,
1113 )
1114 .await
1115 }
1116
1117 async fn query_managed_sub_account_margin_asset_details(
1118 &self,
1119 params: QueryManagedSubAccountMarginAssetDetailsParams,
1120 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountMarginAssetDetailsResponse>>
1121 {
1122 let QueryManagedSubAccountMarginAssetDetailsParams {
1123 email,
1124 account_type,
1125 } = params;
1126
1127 let mut query_params = BTreeMap::new();
1128 let body_params = BTreeMap::new();
1129
1130 query_params.insert("email".to_string(), json!(email));
1131
1132 if let Some(rw) = account_type {
1133 query_params.insert("accountType".to_string(), json!(rw));
1134 }
1135
1136 send_request::<models::QueryManagedSubAccountMarginAssetDetailsResponse>(
1137 &self.configuration,
1138 "/sapi/v1/managed-subaccount/marginAsset",
1139 reqwest::Method::GET,
1140 query_params,
1141 body_params,
1142 if HAS_TIME_UNIT {
1143 self.configuration.time_unit
1144 } else {
1145 None
1146 },
1147 true,
1148 )
1149 .await
1150 }
1151
1152 async fn query_managed_sub_account_snapshot(
1153 &self,
1154 params: QueryManagedSubAccountSnapshotParams,
1155 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountSnapshotResponse>> {
1156 let QueryManagedSubAccountSnapshotParams {
1157 email,
1158 r#type,
1159 start_time,
1160 end_time,
1161 limit,
1162 recv_window,
1163 } = params;
1164
1165 let mut query_params = BTreeMap::new();
1166 let body_params = BTreeMap::new();
1167
1168 query_params.insert("email".to_string(), json!(email));
1169
1170 query_params.insert("type".to_string(), json!(r#type));
1171
1172 if let Some(rw) = start_time {
1173 query_params.insert("startTime".to_string(), json!(rw));
1174 }
1175
1176 if let Some(rw) = end_time {
1177 query_params.insert("endTime".to_string(), json!(rw));
1178 }
1179
1180 if let Some(rw) = limit {
1181 query_params.insert("limit".to_string(), json!(rw));
1182 }
1183
1184 if let Some(rw) = recv_window {
1185 query_params.insert("recvWindow".to_string(), json!(rw));
1186 }
1187
1188 send_request::<models::QueryManagedSubAccountSnapshotResponse>(
1189 &self.configuration,
1190 "/sapi/v1/managed-subaccount/accountSnapshot",
1191 reqwest::Method::GET,
1192 query_params,
1193 body_params,
1194 if HAS_TIME_UNIT {
1195 self.configuration.time_unit
1196 } else {
1197 None
1198 },
1199 true,
1200 )
1201 .await
1202 }
1203
1204 async fn query_managed_sub_account_transfer_log_master_account_investor(
1205 &self,
1206 params: QueryManagedSubAccountTransferLogMasterAccountInvestorParams,
1207 ) -> anyhow::Result<
1208 RestApiResponse<models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse>,
1209 > {
1210 let QueryManagedSubAccountTransferLogMasterAccountInvestorParams {
1211 email,
1212 start_time,
1213 end_time,
1214 page,
1215 limit,
1216 transfers,
1217 transfer_function_account_type,
1218 } = params;
1219
1220 let mut query_params = BTreeMap::new();
1221 let body_params = BTreeMap::new();
1222
1223 query_params.insert("email".to_string(), json!(email));
1224
1225 query_params.insert("startTime".to_string(), json!(start_time));
1226
1227 query_params.insert("endTime".to_string(), json!(end_time));
1228
1229 query_params.insert("page".to_string(), json!(page));
1230
1231 query_params.insert("limit".to_string(), json!(limit));
1232
1233 if let Some(rw) = transfers {
1234 query_params.insert("transfers".to_string(), json!(rw));
1235 }
1236
1237 if let Some(rw) = transfer_function_account_type {
1238 query_params.insert("transferFunctionAccountType".to_string(), json!(rw));
1239 }
1240
1241 send_request::<models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse>(
1242 &self.configuration,
1243 "/sapi/v1/managed-subaccount/queryTransLogForInvestor",
1244 reqwest::Method::GET,
1245 query_params,
1246 body_params,
1247 if HAS_TIME_UNIT {
1248 self.configuration.time_unit
1249 } else {
1250 None
1251 },
1252 true,
1253 )
1254 .await
1255 }
1256
1257 async fn query_managed_sub_account_transfer_log_master_account_trading(
1258 &self,
1259 params: QueryManagedSubAccountTransferLogMasterAccountTradingParams,
1260 ) -> anyhow::Result<
1261 RestApiResponse<models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse>,
1262 > {
1263 let QueryManagedSubAccountTransferLogMasterAccountTradingParams {
1264 email,
1265 start_time,
1266 end_time,
1267 page,
1268 limit,
1269 transfers,
1270 transfer_function_account_type,
1271 } = params;
1272
1273 let mut query_params = BTreeMap::new();
1274 let body_params = BTreeMap::new();
1275
1276 query_params.insert("email".to_string(), json!(email));
1277
1278 query_params.insert("startTime".to_string(), json!(start_time));
1279
1280 query_params.insert("endTime".to_string(), json!(end_time));
1281
1282 query_params.insert("page".to_string(), json!(page));
1283
1284 query_params.insert("limit".to_string(), json!(limit));
1285
1286 if let Some(rw) = transfers {
1287 query_params.insert("transfers".to_string(), json!(rw));
1288 }
1289
1290 if let Some(rw) = transfer_function_account_type {
1291 query_params.insert("transferFunctionAccountType".to_string(), json!(rw));
1292 }
1293
1294 send_request::<models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse>(
1295 &self.configuration,
1296 "/sapi/v1/managed-subaccount/queryTransLogForTradeParent",
1297 reqwest::Method::GET,
1298 query_params,
1299 body_params,
1300 if HAS_TIME_UNIT {
1301 self.configuration.time_unit
1302 } else {
1303 None
1304 },
1305 true,
1306 )
1307 .await
1308 }
1309
1310 async fn query_managed_sub_account_transfer_log_sub_account_trading(
1311 &self,
1312 params: QueryManagedSubAccountTransferLogSubAccountTradingParams,
1313 ) -> anyhow::Result<
1314 RestApiResponse<models::QueryManagedSubAccountTransferLogSubAccountTradingResponse>,
1315 > {
1316 let QueryManagedSubAccountTransferLogSubAccountTradingParams {
1317 start_time,
1318 end_time,
1319 page,
1320 limit,
1321 transfers,
1322 transfer_function_account_type,
1323 recv_window,
1324 } = params;
1325
1326 let mut query_params = BTreeMap::new();
1327 let body_params = BTreeMap::new();
1328
1329 query_params.insert("startTime".to_string(), json!(start_time));
1330
1331 query_params.insert("endTime".to_string(), json!(end_time));
1332
1333 query_params.insert("page".to_string(), json!(page));
1334
1335 query_params.insert("limit".to_string(), json!(limit));
1336
1337 if let Some(rw) = transfers {
1338 query_params.insert("transfers".to_string(), json!(rw));
1339 }
1340
1341 if let Some(rw) = transfer_function_account_type {
1342 query_params.insert("transferFunctionAccountType".to_string(), json!(rw));
1343 }
1344
1345 if let Some(rw) = recv_window {
1346 query_params.insert("recvWindow".to_string(), json!(rw));
1347 }
1348
1349 send_request::<models::QueryManagedSubAccountTransferLogSubAccountTradingResponse>(
1350 &self.configuration,
1351 "/sapi/v1/managed-subaccount/query-trans-log",
1352 reqwest::Method::GET,
1353 query_params,
1354 body_params,
1355 if HAS_TIME_UNIT {
1356 self.configuration.time_unit
1357 } else {
1358 None
1359 },
1360 true,
1361 )
1362 .await
1363 }
1364
1365 async fn withdrawl_assets_from_the_managed_sub_account(
1366 &self,
1367 params: WithdrawlAssetsFromTheManagedSubAccountParams,
1368 ) -> anyhow::Result<RestApiResponse<models::WithdrawlAssetsFromTheManagedSubAccountResponse>>
1369 {
1370 let WithdrawlAssetsFromTheManagedSubAccountParams {
1371 from_email,
1372 asset,
1373 amount,
1374 transfer_date,
1375 recv_window,
1376 } = params;
1377
1378 let mut query_params = BTreeMap::new();
1379 let body_params = BTreeMap::new();
1380
1381 query_params.insert("fromEmail".to_string(), json!(from_email));
1382
1383 query_params.insert("asset".to_string(), json!(asset));
1384
1385 query_params.insert("amount".to_string(), json!(amount));
1386
1387 if let Some(rw) = transfer_date {
1388 query_params.insert("transferDate".to_string(), json!(rw));
1389 }
1390
1391 if let Some(rw) = recv_window {
1392 query_params.insert("recvWindow".to_string(), json!(rw));
1393 }
1394
1395 send_request::<models::WithdrawlAssetsFromTheManagedSubAccountResponse>(
1396 &self.configuration,
1397 "/sapi/v1/managed-subaccount/withdraw",
1398 reqwest::Method::POST,
1399 query_params,
1400 body_params,
1401 if HAS_TIME_UNIT {
1402 self.configuration.time_unit
1403 } else {
1404 None
1405 },
1406 true,
1407 )
1408 .await
1409 }
1410}
1411
1412#[cfg(all(test, feature = "sub_account"))]
1413mod tests {
1414 use super::*;
1415 use crate::TOKIO_SHARED_RT;
1416 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
1417 use async_trait::async_trait;
1418 use std::collections::HashMap;
1419
1420 struct DummyRestApiResponse<T> {
1421 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
1422 status: u16,
1423 headers: HashMap<String, String>,
1424 rate_limits: Option<Vec<RestApiRateLimit>>,
1425 }
1426
1427 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
1428 fn from(dummy: DummyRestApiResponse<T>) -> Self {
1429 Self {
1430 data_fn: dummy.inner,
1431 status: dummy.status,
1432 headers: dummy.headers,
1433 rate_limits: dummy.rate_limits,
1434 }
1435 }
1436 }
1437
1438 struct MockManagedSubAccountApiClient {
1439 force_error: bool,
1440 }
1441
1442 #[async_trait]
1443 impl ManagedSubAccountApi for MockManagedSubAccountApiClient {
1444 async fn deposit_assets_into_the_managed_sub_account(
1445 &self,
1446 _params: DepositAssetsIntoTheManagedSubAccountParams,
1447 ) -> anyhow::Result<RestApiResponse<models::DepositAssetsIntoTheManagedSubAccountResponse>>
1448 {
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#"{"tranId":66157362489}"#)
1458 .unwrap_or_else(|_| serde_json::json!({}));
1459 let dummy_response: models::DepositAssetsIntoTheManagedSubAccountResponse =
1460 serde_json::from_value(resp_json.clone()).expect(
1461 "should parse into models::DepositAssetsIntoTheManagedSubAccountResponse",
1462 );
1463
1464 let dummy = DummyRestApiResponse {
1465 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1466 status: 200,
1467 headers: HashMap::new(),
1468 rate_limits: None,
1469 };
1470
1471 Ok(dummy.into())
1472 }
1473
1474 async fn get_managed_sub_account_deposit_address(
1475 &self,
1476 _params: GetManagedSubAccountDepositAddressParams,
1477 ) -> anyhow::Result<RestApiResponse<models::GetManagedSubAccountDepositAddressResponse>>
1478 {
1479 if self.force_error {
1480 return Err(ConnectorError::ConnectorClientError {
1481 msg: "ResponseError".to_string(),
1482 code: None,
1483 }
1484 .into());
1485 }
1486
1487 let resp_json: Value = serde_json::from_str(r#"{"coin":"USDT","address":"0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d","tag":"","url":"https://etherscan.io/address/0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d"}"#).unwrap_or_else(|_| serde_json::json!({}));
1488 let dummy_response: models::GetManagedSubAccountDepositAddressResponse =
1489 serde_json::from_value(resp_json.clone())
1490 .expect("should parse into models::GetManagedSubAccountDepositAddressResponse");
1491
1492 let dummy = DummyRestApiResponse {
1493 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1494 status: 200,
1495 headers: HashMap::new(),
1496 rate_limits: None,
1497 };
1498
1499 Ok(dummy.into())
1500 }
1501
1502 async fn query_managed_sub_account_asset_details(
1503 &self,
1504 _params: QueryManagedSubAccountAssetDetailsParams,
1505 ) -> anyhow::Result<
1506 RestApiResponse<Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>>,
1507 > {
1508 if self.force_error {
1509 return Err(ConnectorError::ConnectorClientError {
1510 msg: "ResponseError".to_string(),
1511 code: None,
1512 }
1513 .into());
1514 }
1515
1516 let resp_json: Value = serde_json::from_str(r#"[{"coin":"INJ","name":"Injective Protocol","totalBalance":"0","availableBalance":"0","inOrder":"0","btcValue":"0"}]"#).unwrap_or_else(|_| serde_json::json!({}));
1517 let dummy_response : Vec<models::QueryManagedSubAccountAssetDetailsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>");
1518
1519 let dummy = DummyRestApiResponse {
1520 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1521 status: 200,
1522 headers: HashMap::new(),
1523 rate_limits: None,
1524 };
1525
1526 Ok(dummy.into())
1527 }
1528
1529 async fn query_managed_sub_account_futures_asset_details(
1530 &self,
1531 _params: QueryManagedSubAccountFuturesAssetDetailsParams,
1532 ) -> anyhow::Result<
1533 RestApiResponse<models::QueryManagedSubAccountFuturesAssetDetailsResponse>,
1534 > {
1535 if self.force_error {
1536 return Err(ConnectorError::ConnectorClientError {
1537 msg: "ResponseError".to_string(),
1538 code: None,
1539 }
1540 .into());
1541 }
1542
1543 let resp_json: Value = serde_json::from_str(r#"{"code":"200","message":"OK","snapshotVos":[{"type":"FUTURES","updateTime":1672893855394,"data":{"assets":[{"asset":"USDT","marginBalance":100,"walletBalance":120}],"position":[{"symbol":"BTCUSDT","entryPrice":17000,"markPrice":17000,"positionAmt":1.0E-4}]}}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1544 let dummy_response: models::QueryManagedSubAccountFuturesAssetDetailsResponse =
1545 serde_json::from_value(resp_json.clone()).expect(
1546 "should parse into models::QueryManagedSubAccountFuturesAssetDetailsResponse",
1547 );
1548
1549 let dummy = DummyRestApiResponse {
1550 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1551 status: 200,
1552 headers: HashMap::new(),
1553 rate_limits: None,
1554 };
1555
1556 Ok(dummy.into())
1557 }
1558
1559 async fn query_managed_sub_account_list(
1560 &self,
1561 _params: QueryManagedSubAccountListParams,
1562 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountListResponse>> {
1563 if self.force_error {
1564 return Err(ConnectorError::ConnectorClientError {
1565 msg: "ResponseError".to_string(),
1566 code: None,
1567 }
1568 .into());
1569 }
1570
1571 let resp_json: Value = serde_json::from_str(r#"{"total":3,"managerSubUserInfoVoList":[{"rootUserId":1000138475670,"managersubUserId":1000137842513,"bindParentUserId":1000138475669,"email":"test_0_virtual@kq3kno9imanagedsub.com","insertTimeStamp":1678435149000,"bindParentEmail":"wdyw8xsh8pey@test.com","isSubUserEnabled":true,"isUserActive":true,"isMarginEnabled":false,"isFutureEnabled":false,"isSignedLVTRiskAgreement":false}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1572 let dummy_response: models::QueryManagedSubAccountListResponse =
1573 serde_json::from_value(resp_json.clone())
1574 .expect("should parse into models::QueryManagedSubAccountListResponse");
1575
1576 let dummy = DummyRestApiResponse {
1577 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1578 status: 200,
1579 headers: HashMap::new(),
1580 rate_limits: None,
1581 };
1582
1583 Ok(dummy.into())
1584 }
1585
1586 async fn query_managed_sub_account_margin_asset_details(
1587 &self,
1588 _params: QueryManagedSubAccountMarginAssetDetailsParams,
1589 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountMarginAssetDetailsResponse>>
1590 {
1591 if self.force_error {
1592 return Err(ConnectorError::ConnectorClientError {
1593 msg: "ResponseError".to_string(),
1594 code: None,
1595 }
1596 .into());
1597 }
1598
1599 let resp_json: Value = serde_json::from_str(r#"{"marginLevel":"999","totalAssetOfBtc":"0","totalLiabilityOfBtc":"0","totalNetAssetOfBtc":"0","userAssets":[{"asset":"MATIC","borrowed":"0","free":"0","interest":"0","locked":"0","netAsset":"0"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1600 let dummy_response: models::QueryManagedSubAccountMarginAssetDetailsResponse =
1601 serde_json::from_value(resp_json.clone()).expect(
1602 "should parse into models::QueryManagedSubAccountMarginAssetDetailsResponse",
1603 );
1604
1605 let dummy = DummyRestApiResponse {
1606 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1607 status: 200,
1608 headers: HashMap::new(),
1609 rate_limits: None,
1610 };
1611
1612 Ok(dummy.into())
1613 }
1614
1615 async fn query_managed_sub_account_snapshot(
1616 &self,
1617 _params: QueryManagedSubAccountSnapshotParams,
1618 ) -> anyhow::Result<RestApiResponse<models::QueryManagedSubAccountSnapshotResponse>>
1619 {
1620 if self.force_error {
1621 return Err(ConnectorError::ConnectorClientError {
1622 msg: "ResponseError".to_string(),
1623 code: None,
1624 }
1625 .into());
1626 }
1627
1628 let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"","snapshotVos":[{"data":{"balances":[{"asset":"BTC","free":"0.09905021","locked":"0.00000000"}],"totalAssetOfBtc":"0.09942700","marginLevel":"2748.02909813","totalLiabilityOfBtc":"0.00000100","totalNetAssetOfBtc":"0.00274750","userAssets":[{"asset":"XRP","borrowed":"0.00000000","free":"1.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"1.00000000"}],"assets":[{"asset":"USDT","marginBalance":"118.99782335","walletBalance":"120.23811389"}],"position":[{"entryPrice":"7130.41000000","markPrice":"7257.66239673","positionAmt":"0.01000000","symbol":"BTCUSDT","unRealizedProfit":"1.24029054"}]},"type":"spot","updateTime":1576281599000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1629 let dummy_response: models::QueryManagedSubAccountSnapshotResponse =
1630 serde_json::from_value(resp_json.clone())
1631 .expect("should parse into models::QueryManagedSubAccountSnapshotResponse");
1632
1633 let dummy = DummyRestApiResponse {
1634 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1635 status: 200,
1636 headers: HashMap::new(),
1637 rate_limits: None,
1638 };
1639
1640 Ok(dummy.into())
1641 }
1642
1643 async fn query_managed_sub_account_transfer_log_master_account_investor(
1644 &self,
1645 _params: QueryManagedSubAccountTransferLogMasterAccountInvestorParams,
1646 ) -> anyhow::Result<
1647 RestApiResponse<models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse>,
1648 > {
1649 if self.force_error {
1650 return Err(ConnectorError::ConnectorClientError {
1651 msg: "ResponseError".to_string(),
1652 code: None,
1653 }
1654 .into());
1655 }
1656
1657 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
1658 let dummy_response : models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse");
1659
1660 let dummy = DummyRestApiResponse {
1661 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1662 status: 200,
1663 headers: HashMap::new(),
1664 rate_limits: None,
1665 };
1666
1667 Ok(dummy.into())
1668 }
1669
1670 async fn query_managed_sub_account_transfer_log_master_account_trading(
1671 &self,
1672 _params: QueryManagedSubAccountTransferLogMasterAccountTradingParams,
1673 ) -> anyhow::Result<
1674 RestApiResponse<models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse>,
1675 > {
1676 if self.force_error {
1677 return Err(ConnectorError::ConnectorClientError {
1678 msg: "ResponseError".to_string(),
1679 code: None,
1680 }
1681 .into());
1682 }
1683
1684 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
1685 let dummy_response : models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse");
1686
1687 let dummy = DummyRestApiResponse {
1688 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1689 status: 200,
1690 headers: HashMap::new(),
1691 rate_limits: None,
1692 };
1693
1694 Ok(dummy.into())
1695 }
1696
1697 async fn query_managed_sub_account_transfer_log_sub_account_trading(
1698 &self,
1699 _params: QueryManagedSubAccountTransferLogSubAccountTradingParams,
1700 ) -> anyhow::Result<
1701 RestApiResponse<models::QueryManagedSubAccountTransferLogSubAccountTradingResponse>,
1702 > {
1703 if self.force_error {
1704 return Err(ConnectorError::ConnectorClientError {
1705 msg: "ResponseError".to_string(),
1706 code: None,
1707 }
1708 .into());
1709 }
1710
1711 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
1712 let dummy_response : models::QueryManagedSubAccountTransferLogSubAccountTradingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogSubAccountTradingResponse");
1713
1714 let dummy = DummyRestApiResponse {
1715 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1716 status: 200,
1717 headers: HashMap::new(),
1718 rate_limits: None,
1719 };
1720
1721 Ok(dummy.into())
1722 }
1723
1724 async fn withdrawl_assets_from_the_managed_sub_account(
1725 &self,
1726 _params: WithdrawlAssetsFromTheManagedSubAccountParams,
1727 ) -> anyhow::Result<RestApiResponse<models::WithdrawlAssetsFromTheManagedSubAccountResponse>>
1728 {
1729 if self.force_error {
1730 return Err(ConnectorError::ConnectorClientError {
1731 msg: "ResponseError".to_string(),
1732 code: None,
1733 }
1734 .into());
1735 }
1736
1737 let resp_json: Value = serde_json::from_str(r#"{"tranId":66157362489}"#)
1738 .unwrap_or_else(|_| serde_json::json!({}));
1739 let dummy_response: models::WithdrawlAssetsFromTheManagedSubAccountResponse =
1740 serde_json::from_value(resp_json.clone()).expect(
1741 "should parse into models::WithdrawlAssetsFromTheManagedSubAccountResponse",
1742 );
1743
1744 let dummy = DummyRestApiResponse {
1745 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1746 status: 200,
1747 headers: HashMap::new(),
1748 rate_limits: None,
1749 };
1750
1751 Ok(dummy.into())
1752 }
1753 }
1754
1755 #[test]
1756 fn deposit_assets_into_the_managed_sub_account_required_params_success() {
1757 TOKIO_SHARED_RT.block_on(async {
1758 let client = MockManagedSubAccountApiClient { force_error: false };
1759
1760 let params = DepositAssetsIntoTheManagedSubAccountParams::builder(
1761 "abc@test.com".to_string(),
1762 "BTC".to_string(),
1763 dec!(1.0),
1764 )
1765 .build()
1766 .unwrap();
1767
1768 let resp_json: Value = serde_json::from_str(r#"{"tranId":66157362489}"#)
1769 .unwrap_or_else(|_| serde_json::json!({}));
1770 let expected_response: models::DepositAssetsIntoTheManagedSubAccountResponse =
1771 serde_json::from_value(resp_json.clone()).expect(
1772 "should parse into models::DepositAssetsIntoTheManagedSubAccountResponse",
1773 );
1774
1775 let resp = client
1776 .deposit_assets_into_the_managed_sub_account(params)
1777 .await
1778 .expect("Expected a response");
1779 let data_future = resp.data();
1780 let actual_response = data_future.await.unwrap();
1781 assert_eq!(actual_response, expected_response);
1782 });
1783 }
1784
1785 #[test]
1786 fn deposit_assets_into_the_managed_sub_account_optional_params_success() {
1787 TOKIO_SHARED_RT.block_on(async {
1788 let client = MockManagedSubAccountApiClient { force_error: false };
1789
1790 let params = DepositAssetsIntoTheManagedSubAccountParams::builder(
1791 "abc@test.com".to_string(),
1792 "BTC".to_string(),
1793 dec!(1.0),
1794 )
1795 .recv_window(5000)
1796 .build()
1797 .unwrap();
1798
1799 let resp_json: Value = serde_json::from_str(r#"{"tranId":66157362489}"#)
1800 .unwrap_or_else(|_| serde_json::json!({}));
1801 let expected_response: models::DepositAssetsIntoTheManagedSubAccountResponse =
1802 serde_json::from_value(resp_json.clone()).expect(
1803 "should parse into models::DepositAssetsIntoTheManagedSubAccountResponse",
1804 );
1805
1806 let resp = client
1807 .deposit_assets_into_the_managed_sub_account(params)
1808 .await
1809 .expect("Expected a response");
1810 let data_future = resp.data();
1811 let actual_response = data_future.await.unwrap();
1812 assert_eq!(actual_response, expected_response);
1813 });
1814 }
1815
1816 #[test]
1817 fn deposit_assets_into_the_managed_sub_account_response_error() {
1818 TOKIO_SHARED_RT.block_on(async {
1819 let client = MockManagedSubAccountApiClient { force_error: true };
1820
1821 let params = DepositAssetsIntoTheManagedSubAccountParams::builder(
1822 "abc@test.com".to_string(),
1823 "BTC".to_string(),
1824 dec!(1.0),
1825 )
1826 .build()
1827 .unwrap();
1828
1829 match client
1830 .deposit_assets_into_the_managed_sub_account(params)
1831 .await
1832 {
1833 Ok(_) => panic!("Expected an error"),
1834 Err(err) => {
1835 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1836 }
1837 }
1838 });
1839 }
1840
1841 #[test]
1842 fn get_managed_sub_account_deposit_address_required_params_success() {
1843 TOKIO_SHARED_RT.block_on(async {
1844 let client = MockManagedSubAccountApiClient { force_error: false };
1845
1846 let params = GetManagedSubAccountDepositAddressParams::builder("abc@test.com".to_string(),"USDT".to_string(),).build().unwrap();
1847
1848 let resp_json: Value = serde_json::from_str(r#"{"coin":"USDT","address":"0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d","tag":"","url":"https://etherscan.io/address/0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d"}"#).unwrap_or_else(|_| serde_json::json!({}));
1849 let expected_response : models::GetManagedSubAccountDepositAddressResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetManagedSubAccountDepositAddressResponse");
1850
1851 let resp = client.get_managed_sub_account_deposit_address(params).await.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 get_managed_sub_account_deposit_address_optional_params_success() {
1860 TOKIO_SHARED_RT.block_on(async {
1861 let client = MockManagedSubAccountApiClient { force_error: false };
1862
1863 let params = GetManagedSubAccountDepositAddressParams::builder("abc@test.com".to_string(),"USDT".to_string(),).network("LIGHTNING".to_string()).amount(dec!(1.0)).recv_window(5000).build().unwrap();
1864
1865 let resp_json: Value = serde_json::from_str(r#"{"coin":"USDT","address":"0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d","tag":"","url":"https://etherscan.io/address/0x206c22d833bb0bb2102da6b7c7d4c3eb14bcf73d"}"#).unwrap_or_else(|_| serde_json::json!({}));
1866 let expected_response : models::GetManagedSubAccountDepositAddressResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetManagedSubAccountDepositAddressResponse");
1867
1868 let resp = client.get_managed_sub_account_deposit_address(params).await.expect("Expected a response");
1869 let data_future = resp.data();
1870 let actual_response = data_future.await.unwrap();
1871 assert_eq!(actual_response, expected_response);
1872 });
1873 }
1874
1875 #[test]
1876 fn get_managed_sub_account_deposit_address_response_error() {
1877 TOKIO_SHARED_RT.block_on(async {
1878 let client = MockManagedSubAccountApiClient { force_error: true };
1879
1880 let params = GetManagedSubAccountDepositAddressParams::builder(
1881 "abc@test.com".to_string(),
1882 "USDT".to_string(),
1883 )
1884 .build()
1885 .unwrap();
1886
1887 match client.get_managed_sub_account_deposit_address(params).await {
1888 Ok(_) => panic!("Expected an error"),
1889 Err(err) => {
1890 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1891 }
1892 }
1893 });
1894 }
1895
1896 #[test]
1897 fn query_managed_sub_account_asset_details_required_params_success() {
1898 TOKIO_SHARED_RT.block_on(async {
1899 let client = MockManagedSubAccountApiClient { force_error: false };
1900
1901 let params = QueryManagedSubAccountAssetDetailsParams::builder("abc@test.com".to_string(),).build().unwrap();
1902
1903 let resp_json: Value = serde_json::from_str(r#"[{"coin":"INJ","name":"Injective Protocol","totalBalance":"0","availableBalance":"0","inOrder":"0","btcValue":"0"}]"#).unwrap_or_else(|_| serde_json::json!({}));
1904 let expected_response : Vec<models::QueryManagedSubAccountAssetDetailsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>");
1905
1906 let resp = client.query_managed_sub_account_asset_details(params).await.expect("Expected a response");
1907 let data_future = resp.data();
1908 let actual_response = data_future.await.unwrap();
1909 assert_eq!(actual_response, expected_response);
1910 });
1911 }
1912
1913 #[test]
1914 fn query_managed_sub_account_asset_details_optional_params_success() {
1915 TOKIO_SHARED_RT.block_on(async {
1916 let client = MockManagedSubAccountApiClient { force_error: false };
1917
1918 let params = QueryManagedSubAccountAssetDetailsParams::builder("abc@test.com".to_string(),).recv_window(5000).build().unwrap();
1919
1920 let resp_json: Value = serde_json::from_str(r#"[{"coin":"INJ","name":"Injective Protocol","totalBalance":"0","availableBalance":"0","inOrder":"0","btcValue":"0"}]"#).unwrap_or_else(|_| serde_json::json!({}));
1921 let expected_response : Vec<models::QueryManagedSubAccountAssetDetailsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryManagedSubAccountAssetDetailsResponseInner>");
1922
1923 let resp = client.query_managed_sub_account_asset_details(params).await.expect("Expected a response");
1924 let data_future = resp.data();
1925 let actual_response = data_future.await.unwrap();
1926 assert_eq!(actual_response, expected_response);
1927 });
1928 }
1929
1930 #[test]
1931 fn query_managed_sub_account_asset_details_response_error() {
1932 TOKIO_SHARED_RT.block_on(async {
1933 let client = MockManagedSubAccountApiClient { force_error: true };
1934
1935 let params =
1936 QueryManagedSubAccountAssetDetailsParams::builder("abc@test.com".to_string())
1937 .build()
1938 .unwrap();
1939
1940 match client.query_managed_sub_account_asset_details(params).await {
1941 Ok(_) => panic!("Expected an error"),
1942 Err(err) => {
1943 assert_eq!(err.to_string(), "Connector client error: ResponseError");
1944 }
1945 }
1946 });
1947 }
1948
1949 #[test]
1950 fn query_managed_sub_account_futures_asset_details_required_params_success() {
1951 TOKIO_SHARED_RT.block_on(async {
1952 let client = MockManagedSubAccountApiClient { force_error: false };
1953
1954 let params = QueryManagedSubAccountFuturesAssetDetailsParams::builder("abc@test.com".to_string(),).build().unwrap();
1955
1956 let resp_json: Value = serde_json::from_str(r#"{"code":"200","message":"OK","snapshotVos":[{"type":"FUTURES","updateTime":1672893855394,"data":{"assets":[{"asset":"USDT","marginBalance":100,"walletBalance":120}],"position":[{"symbol":"BTCUSDT","entryPrice":17000,"markPrice":17000,"positionAmt":1.0E-4}]}}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1957 let expected_response : models::QueryManagedSubAccountFuturesAssetDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountFuturesAssetDetailsResponse");
1958
1959 let resp = client.query_managed_sub_account_futures_asset_details(params).await.expect("Expected a response");
1960 let data_future = resp.data();
1961 let actual_response = data_future.await.unwrap();
1962 assert_eq!(actual_response, expected_response);
1963 });
1964 }
1965
1966 #[test]
1967 fn query_managed_sub_account_futures_asset_details_optional_params_success() {
1968 TOKIO_SHARED_RT.block_on(async {
1969 let client = MockManagedSubAccountApiClient { force_error: false };
1970
1971 let params = QueryManagedSubAccountFuturesAssetDetailsParams::builder("abc@test.com".to_string(),).account_type("MARGIN".to_string()).build().unwrap();
1972
1973 let resp_json: Value = serde_json::from_str(r#"{"code":"200","message":"OK","snapshotVos":[{"type":"FUTURES","updateTime":1672893855394,"data":{"assets":[{"asset":"USDT","marginBalance":100,"walletBalance":120}],"position":[{"symbol":"BTCUSDT","entryPrice":17000,"markPrice":17000,"positionAmt":1.0E-4}]}}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1974 let expected_response : models::QueryManagedSubAccountFuturesAssetDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountFuturesAssetDetailsResponse");
1975
1976 let resp = client.query_managed_sub_account_futures_asset_details(params).await.expect("Expected a response");
1977 let data_future = resp.data();
1978 let actual_response = data_future.await.unwrap();
1979 assert_eq!(actual_response, expected_response);
1980 });
1981 }
1982
1983 #[test]
1984 fn query_managed_sub_account_futures_asset_details_response_error() {
1985 TOKIO_SHARED_RT.block_on(async {
1986 let client = MockManagedSubAccountApiClient { force_error: true };
1987
1988 let params = QueryManagedSubAccountFuturesAssetDetailsParams::builder(
1989 "abc@test.com".to_string(),
1990 )
1991 .build()
1992 .unwrap();
1993
1994 match client
1995 .query_managed_sub_account_futures_asset_details(params)
1996 .await
1997 {
1998 Ok(_) => panic!("Expected an error"),
1999 Err(err) => {
2000 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2001 }
2002 }
2003 });
2004 }
2005
2006 #[test]
2007 fn query_managed_sub_account_list_required_params_success() {
2008 TOKIO_SHARED_RT.block_on(async {
2009 let client = MockManagedSubAccountApiClient { force_error: false };
2010
2011 let params = QueryManagedSubAccountListParams::builder().build().unwrap();
2012
2013 let resp_json: Value = serde_json::from_str(r#"{"total":3,"managerSubUserInfoVoList":[{"rootUserId":1000138475670,"managersubUserId":1000137842513,"bindParentUserId":1000138475669,"email":"test_0_virtual@kq3kno9imanagedsub.com","insertTimeStamp":1678435149000,"bindParentEmail":"wdyw8xsh8pey@test.com","isSubUserEnabled":true,"isUserActive":true,"isMarginEnabled":false,"isFutureEnabled":false,"isSignedLVTRiskAgreement":false}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2014 let expected_response : models::QueryManagedSubAccountListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountListResponse");
2015
2016 let resp = client.query_managed_sub_account_list(params).await.expect("Expected a response");
2017 let data_future = resp.data();
2018 let actual_response = data_future.await.unwrap();
2019 assert_eq!(actual_response, expected_response);
2020 });
2021 }
2022
2023 #[test]
2024 fn query_managed_sub_account_list_optional_params_success() {
2025 TOKIO_SHARED_RT.block_on(async {
2026 let client = MockManagedSubAccountApiClient { force_error: false };
2027
2028 let params = QueryManagedSubAccountListParams::builder().email("abc@test.com".to_string()).page(1).limit(10).recv_window(5000).build().unwrap();
2029
2030 let resp_json: Value = serde_json::from_str(r#"{"total":3,"managerSubUserInfoVoList":[{"rootUserId":1000138475670,"managersubUserId":1000137842513,"bindParentUserId":1000138475669,"email":"test_0_virtual@kq3kno9imanagedsub.com","insertTimeStamp":1678435149000,"bindParentEmail":"wdyw8xsh8pey@test.com","isSubUserEnabled":true,"isUserActive":true,"isMarginEnabled":false,"isFutureEnabled":false,"isSignedLVTRiskAgreement":false}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2031 let expected_response : models::QueryManagedSubAccountListResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountListResponse");
2032
2033 let resp = client.query_managed_sub_account_list(params).await.expect("Expected a response");
2034 let data_future = resp.data();
2035 let actual_response = data_future.await.unwrap();
2036 assert_eq!(actual_response, expected_response);
2037 });
2038 }
2039
2040 #[test]
2041 fn query_managed_sub_account_list_response_error() {
2042 TOKIO_SHARED_RT.block_on(async {
2043 let client = MockManagedSubAccountApiClient { force_error: true };
2044
2045 let params = QueryManagedSubAccountListParams::builder().build().unwrap();
2046
2047 match client.query_managed_sub_account_list(params).await {
2048 Ok(_) => panic!("Expected an error"),
2049 Err(err) => {
2050 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2051 }
2052 }
2053 });
2054 }
2055
2056 #[test]
2057 fn query_managed_sub_account_margin_asset_details_required_params_success() {
2058 TOKIO_SHARED_RT.block_on(async {
2059 let client = MockManagedSubAccountApiClient { force_error: false };
2060
2061 let params = QueryManagedSubAccountMarginAssetDetailsParams::builder("abc@test.com".to_string(),).build().unwrap();
2062
2063 let resp_json: Value = serde_json::from_str(r#"{"marginLevel":"999","totalAssetOfBtc":"0","totalLiabilityOfBtc":"0","totalNetAssetOfBtc":"0","userAssets":[{"asset":"MATIC","borrowed":"0","free":"0","interest":"0","locked":"0","netAsset":"0"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2064 let expected_response : models::QueryManagedSubAccountMarginAssetDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountMarginAssetDetailsResponse");
2065
2066 let resp = client.query_managed_sub_account_margin_asset_details(params).await.expect("Expected a response");
2067 let data_future = resp.data();
2068 let actual_response = data_future.await.unwrap();
2069 assert_eq!(actual_response, expected_response);
2070 });
2071 }
2072
2073 #[test]
2074 fn query_managed_sub_account_margin_asset_details_optional_params_success() {
2075 TOKIO_SHARED_RT.block_on(async {
2076 let client = MockManagedSubAccountApiClient { force_error: false };
2077
2078 let params = QueryManagedSubAccountMarginAssetDetailsParams::builder("abc@test.com".to_string(),).account_type("MARGIN".to_string()).build().unwrap();
2079
2080 let resp_json: Value = serde_json::from_str(r#"{"marginLevel":"999","totalAssetOfBtc":"0","totalLiabilityOfBtc":"0","totalNetAssetOfBtc":"0","userAssets":[{"asset":"MATIC","borrowed":"0","free":"0","interest":"0","locked":"0","netAsset":"0"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2081 let expected_response : models::QueryManagedSubAccountMarginAssetDetailsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountMarginAssetDetailsResponse");
2082
2083 let resp = client.query_managed_sub_account_margin_asset_details(params).await.expect("Expected a response");
2084 let data_future = resp.data();
2085 let actual_response = data_future.await.unwrap();
2086 assert_eq!(actual_response, expected_response);
2087 });
2088 }
2089
2090 #[test]
2091 fn query_managed_sub_account_margin_asset_details_response_error() {
2092 TOKIO_SHARED_RT.block_on(async {
2093 let client = MockManagedSubAccountApiClient { force_error: true };
2094
2095 let params =
2096 QueryManagedSubAccountMarginAssetDetailsParams::builder("abc@test.com".to_string())
2097 .build()
2098 .unwrap();
2099
2100 match client
2101 .query_managed_sub_account_margin_asset_details(params)
2102 .await
2103 {
2104 Ok(_) => panic!("Expected an error"),
2105 Err(err) => {
2106 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2107 }
2108 }
2109 });
2110 }
2111
2112 #[test]
2113 fn query_managed_sub_account_snapshot_required_params_success() {
2114 TOKIO_SHARED_RT.block_on(async {
2115 let client = MockManagedSubAccountApiClient { force_error: false };
2116
2117 let params = QueryManagedSubAccountSnapshotParams::builder("abc@test.com".to_string(),QueryManagedSubAccountSnapshotTypeEnum::Spot,).build().unwrap();
2118
2119 let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"","snapshotVos":[{"data":{"balances":[{"asset":"BTC","free":"0.09905021","locked":"0.00000000"}],"totalAssetOfBtc":"0.09942700","marginLevel":"2748.02909813","totalLiabilityOfBtc":"0.00000100","totalNetAssetOfBtc":"0.00274750","userAssets":[{"asset":"XRP","borrowed":"0.00000000","free":"1.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"1.00000000"}],"assets":[{"asset":"USDT","marginBalance":"118.99782335","walletBalance":"120.23811389"}],"position":[{"entryPrice":"7130.41000000","markPrice":"7257.66239673","positionAmt":"0.01000000","symbol":"BTCUSDT","unRealizedProfit":"1.24029054"}]},"type":"spot","updateTime":1576281599000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2120 let expected_response : models::QueryManagedSubAccountSnapshotResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountSnapshotResponse");
2121
2122 let resp = client.query_managed_sub_account_snapshot(params).await.expect("Expected a response");
2123 let data_future = resp.data();
2124 let actual_response = data_future.await.unwrap();
2125 assert_eq!(actual_response, expected_response);
2126 });
2127 }
2128
2129 #[test]
2130 fn query_managed_sub_account_snapshot_optional_params_success() {
2131 TOKIO_SHARED_RT.block_on(async {
2132 let client = MockManagedSubAccountApiClient { force_error: false };
2133
2134 let params = QueryManagedSubAccountSnapshotParams::builder("abc@test.com".to_string(),QueryManagedSubAccountSnapshotTypeEnum::Spot,).start_time(1623319461670).end_time(1641782889000).limit(10).recv_window(5000).build().unwrap();
2135
2136 let resp_json: Value = serde_json::from_str(r#"{"code":200,"msg":"","snapshotVos":[{"data":{"balances":[{"asset":"BTC","free":"0.09905021","locked":"0.00000000"}],"totalAssetOfBtc":"0.09942700","marginLevel":"2748.02909813","totalLiabilityOfBtc":"0.00000100","totalNetAssetOfBtc":"0.00274750","userAssets":[{"asset":"XRP","borrowed":"0.00000000","free":"1.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"1.00000000"}],"assets":[{"asset":"USDT","marginBalance":"118.99782335","walletBalance":"120.23811389"}],"position":[{"entryPrice":"7130.41000000","markPrice":"7257.66239673","positionAmt":"0.01000000","symbol":"BTCUSDT","unRealizedProfit":"1.24029054"}]},"type":"spot","updateTime":1576281599000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2137 let expected_response : models::QueryManagedSubAccountSnapshotResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountSnapshotResponse");
2138
2139 let resp = client.query_managed_sub_account_snapshot(params).await.expect("Expected a response");
2140 let data_future = resp.data();
2141 let actual_response = data_future.await.unwrap();
2142 assert_eq!(actual_response, expected_response);
2143 });
2144 }
2145
2146 #[test]
2147 fn query_managed_sub_account_snapshot_response_error() {
2148 TOKIO_SHARED_RT.block_on(async {
2149 let client = MockManagedSubAccountApiClient { force_error: true };
2150
2151 let params = QueryManagedSubAccountSnapshotParams::builder(
2152 "abc@test.com".to_string(),
2153 QueryManagedSubAccountSnapshotTypeEnum::Spot,
2154 )
2155 .build()
2156 .unwrap();
2157
2158 match client.query_managed_sub_account_snapshot(params).await {
2159 Ok(_) => panic!("Expected an error"),
2160 Err(err) => {
2161 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2162 }
2163 }
2164 });
2165 }
2166
2167 #[test]
2168 fn query_managed_sub_account_transfer_log_master_account_investor_required_params_success() {
2169 TOKIO_SHARED_RT.block_on(async {
2170 let client = MockManagedSubAccountApiClient { force_error: false };
2171
2172 let params = QueryManagedSubAccountTransferLogMasterAccountInvestorParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,1,1,).build().unwrap();
2173
2174 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2175 let expected_response : models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse");
2176
2177 let resp = client.query_managed_sub_account_transfer_log_master_account_investor(params).await.expect("Expected a response");
2178 let data_future = resp.data();
2179 let actual_response = data_future.await.unwrap();
2180 assert_eq!(actual_response, expected_response);
2181 });
2182 }
2183
2184 #[test]
2185 fn query_managed_sub_account_transfer_log_master_account_investor_optional_params_success() {
2186 TOKIO_SHARED_RT.block_on(async {
2187 let client = MockManagedSubAccountApiClient { force_error: false };
2188
2189 let params = QueryManagedSubAccountTransferLogMasterAccountInvestorParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,1,1,).transfers("transfers_example".to_string()).transfer_function_account_type(QueryManagedSubAccountTransferLogMasterAccountInvestorTransferFunctionAccountTypeEnum::Spot).build().unwrap();
2190
2191 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2192 let expected_response : models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogMasterAccountInvestorResponse");
2193
2194 let resp = client.query_managed_sub_account_transfer_log_master_account_investor(params).await.expect("Expected a response");
2195 let data_future = resp.data();
2196 let actual_response = data_future.await.unwrap();
2197 assert_eq!(actual_response, expected_response);
2198 });
2199 }
2200
2201 #[test]
2202 fn query_managed_sub_account_transfer_log_master_account_investor_response_error() {
2203 TOKIO_SHARED_RT.block_on(async {
2204 let client = MockManagedSubAccountApiClient { force_error: true };
2205
2206 let params = QueryManagedSubAccountTransferLogMasterAccountInvestorParams::builder(
2207 "abc@test.com".to_string(),
2208 1623319461670,
2209 1641782889000,
2210 1,
2211 1,
2212 )
2213 .build()
2214 .unwrap();
2215
2216 match client
2217 .query_managed_sub_account_transfer_log_master_account_investor(params)
2218 .await
2219 {
2220 Ok(_) => panic!("Expected an error"),
2221 Err(err) => {
2222 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2223 }
2224 }
2225 });
2226 }
2227
2228 #[test]
2229 fn query_managed_sub_account_transfer_log_master_account_trading_required_params_success() {
2230 TOKIO_SHARED_RT.block_on(async {
2231 let client = MockManagedSubAccountApiClient { force_error: false };
2232
2233 let params = QueryManagedSubAccountTransferLogMasterAccountTradingParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,1,10,).build().unwrap();
2234
2235 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2236 let expected_response : models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse");
2237
2238 let resp = client.query_managed_sub_account_transfer_log_master_account_trading(params).await.expect("Expected a response");
2239 let data_future = resp.data();
2240 let actual_response = data_future.await.unwrap();
2241 assert_eq!(actual_response, expected_response);
2242 });
2243 }
2244
2245 #[test]
2246 fn query_managed_sub_account_transfer_log_master_account_trading_optional_params_success() {
2247 TOKIO_SHARED_RT.block_on(async {
2248 let client = MockManagedSubAccountApiClient { force_error: false };
2249
2250 let params = QueryManagedSubAccountTransferLogMasterAccountTradingParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,1,10,).transfers("transfers_example".to_string()).transfer_function_account_type(QueryManagedSubAccountTransferLogMasterAccountTradingTransferFunctionAccountTypeEnum::Spot).build().unwrap();
2251
2252 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2253 let expected_response : models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogMasterAccountTradingResponse");
2254
2255 let resp = client.query_managed_sub_account_transfer_log_master_account_trading(params).await.expect("Expected a response");
2256 let data_future = resp.data();
2257 let actual_response = data_future.await.unwrap();
2258 assert_eq!(actual_response, expected_response);
2259 });
2260 }
2261
2262 #[test]
2263 fn query_managed_sub_account_transfer_log_master_account_trading_response_error() {
2264 TOKIO_SHARED_RT.block_on(async {
2265 let client = MockManagedSubAccountApiClient { force_error: true };
2266
2267 let params = QueryManagedSubAccountTransferLogMasterAccountTradingParams::builder(
2268 "abc@test.com".to_string(),
2269 1623319461670,
2270 1641782889000,
2271 1,
2272 10,
2273 )
2274 .build()
2275 .unwrap();
2276
2277 match client
2278 .query_managed_sub_account_transfer_log_master_account_trading(params)
2279 .await
2280 {
2281 Ok(_) => panic!("Expected an error"),
2282 Err(err) => {
2283 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2284 }
2285 }
2286 });
2287 }
2288
2289 #[test]
2290 fn query_managed_sub_account_transfer_log_sub_account_trading_required_params_success() {
2291 TOKIO_SHARED_RT.block_on(async {
2292 let client = MockManagedSubAccountApiClient { force_error: false };
2293
2294 let params = QueryManagedSubAccountTransferLogSubAccountTradingParams::builder(1623319461670,1641782889000,1,10,).build().unwrap();
2295
2296 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2297 let expected_response : models::QueryManagedSubAccountTransferLogSubAccountTradingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogSubAccountTradingResponse");
2298
2299 let resp = client.query_managed_sub_account_transfer_log_sub_account_trading(params).await.expect("Expected a response");
2300 let data_future = resp.data();
2301 let actual_response = data_future.await.unwrap();
2302 assert_eq!(actual_response, expected_response);
2303 });
2304 }
2305
2306 #[test]
2307 fn query_managed_sub_account_transfer_log_sub_account_trading_optional_params_success() {
2308 TOKIO_SHARED_RT.block_on(async {
2309 let client = MockManagedSubAccountApiClient { force_error: false };
2310
2311 let params = QueryManagedSubAccountTransferLogSubAccountTradingParams::builder(1623319461670,1641782889000,1,10,).transfers("transfers_example".to_string()).transfer_function_account_type(QueryManagedSubAccountTransferLogSubAccountTradingTransferFunctionAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
2312
2313 let resp_json: Value = serde_json::from_str(r#"{"managerSubTransferHistoryVos":[{"fromEmail":"test_0_virtual@kq3kno9imanagedsub.com","fromAccountType":"SPOT","toEmail":"wdywl0lddakh@test.com","toAccountType":"SPOT","asset":"BNB","amount":"0.01","scheduledData":1679416673000,"createTime":1679416673000,"status":"SUCCESS","tranId":91077779}],"count":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2314 let expected_response : models::QueryManagedSubAccountTransferLogSubAccountTradingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryManagedSubAccountTransferLogSubAccountTradingResponse");
2315
2316 let resp = client.query_managed_sub_account_transfer_log_sub_account_trading(params).await.expect("Expected a response");
2317 let data_future = resp.data();
2318 let actual_response = data_future.await.unwrap();
2319 assert_eq!(actual_response, expected_response);
2320 });
2321 }
2322
2323 #[test]
2324 fn query_managed_sub_account_transfer_log_sub_account_trading_response_error() {
2325 TOKIO_SHARED_RT.block_on(async {
2326 let client = MockManagedSubAccountApiClient { force_error: true };
2327
2328 let params = QueryManagedSubAccountTransferLogSubAccountTradingParams::builder(
2329 1623319461670,
2330 1641782889000,
2331 1,
2332 10,
2333 )
2334 .build()
2335 .unwrap();
2336
2337 match client
2338 .query_managed_sub_account_transfer_log_sub_account_trading(params)
2339 .await
2340 {
2341 Ok(_) => panic!("Expected an error"),
2342 Err(err) => {
2343 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2344 }
2345 }
2346 });
2347 }
2348
2349 #[test]
2350 fn withdrawl_assets_from_the_managed_sub_account_required_params_success() {
2351 TOKIO_SHARED_RT.block_on(async {
2352 let client = MockManagedSubAccountApiClient { force_error: false };
2353
2354 let params = WithdrawlAssetsFromTheManagedSubAccountParams::builder(
2355 "from@test.com".to_string(),
2356 "BTC".to_string(),
2357 dec!(1.0),
2358 )
2359 .build()
2360 .unwrap();
2361
2362 let resp_json: Value = serde_json::from_str(r#"{"tranId":66157362489}"#)
2363 .unwrap_or_else(|_| serde_json::json!({}));
2364 let expected_response: models::WithdrawlAssetsFromTheManagedSubAccountResponse =
2365 serde_json::from_value(resp_json.clone()).expect(
2366 "should parse into models::WithdrawlAssetsFromTheManagedSubAccountResponse",
2367 );
2368
2369 let resp = client
2370 .withdrawl_assets_from_the_managed_sub_account(params)
2371 .await
2372 .expect("Expected a response");
2373 let data_future = resp.data();
2374 let actual_response = data_future.await.unwrap();
2375 assert_eq!(actual_response, expected_response);
2376 });
2377 }
2378
2379 #[test]
2380 fn withdrawl_assets_from_the_managed_sub_account_optional_params_success() {
2381 TOKIO_SHARED_RT.block_on(async {
2382 let client = MockManagedSubAccountApiClient { force_error: false };
2383
2384 let params = WithdrawlAssetsFromTheManagedSubAccountParams::builder(
2385 "from@test.com".to_string(),
2386 "BTC".to_string(),
2387 dec!(1.0),
2388 )
2389 .transfer_date(789)
2390 .recv_window(5000)
2391 .build()
2392 .unwrap();
2393
2394 let resp_json: Value = serde_json::from_str(r#"{"tranId":66157362489}"#)
2395 .unwrap_or_else(|_| serde_json::json!({}));
2396 let expected_response: models::WithdrawlAssetsFromTheManagedSubAccountResponse =
2397 serde_json::from_value(resp_json.clone()).expect(
2398 "should parse into models::WithdrawlAssetsFromTheManagedSubAccountResponse",
2399 );
2400
2401 let resp = client
2402 .withdrawl_assets_from_the_managed_sub_account(params)
2403 .await
2404 .expect("Expected a response");
2405 let data_future = resp.data();
2406 let actual_response = data_future.await.unwrap();
2407 assert_eq!(actual_response, expected_response);
2408 });
2409 }
2410
2411 #[test]
2412 fn withdrawl_assets_from_the_managed_sub_account_response_error() {
2413 TOKIO_SHARED_RT.block_on(async {
2414 let client = MockManagedSubAccountApiClient { force_error: true };
2415
2416 let params = WithdrawlAssetsFromTheManagedSubAccountParams::builder(
2417 "from@test.com".to_string(),
2418 "BTC".to_string(),
2419 dec!(1.0),
2420 )
2421 .build()
2422 .unwrap();
2423
2424 match client
2425 .withdrawl_assets_from_the_managed_sub_account(params)
2426 .await
2427 {
2428 Ok(_) => panic!("Expected an error"),
2429 Err(err) => {
2430 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2431 }
2432 }
2433 });
2434 }
2435}