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 AssetManagementApi: Send + Sync {
34 async fn futures_transfer_for_sub_account(
35 &self,
36 params: FuturesTransferForSubAccountParams,
37 ) -> anyhow::Result<RestApiResponse<models::FuturesTransferForSubAccountResponse>>;
38 async fn get_detail_on_sub_accounts_futures_account(
39 &self,
40 params: GetDetailOnSubAccountsFuturesAccountParams,
41 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountResponse>>;
42 async fn get_detail_on_sub_accounts_futures_account_v2(
43 &self,
44 params: GetDetailOnSubAccountsFuturesAccountV2Params,
45 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountV2Response>>;
46 async fn get_detail_on_sub_accounts_margin_account(
47 &self,
48 params: GetDetailOnSubAccountsMarginAccountParams,
49 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsMarginAccountResponse>>;
50 async fn get_move_position_history_for_sub_account(
51 &self,
52 params: GetMovePositionHistoryForSubAccountParams,
53 ) -> anyhow::Result<RestApiResponse<models::GetMovePositionHistoryForSubAccountResponse>>;
54 async fn get_sub_account_deposit_address(
55 &self,
56 params: GetSubAccountDepositAddressParams,
57 ) -> anyhow::Result<RestApiResponse<models::GetSubAccountDepositAddressResponse>>;
58 async fn get_sub_account_deposit_history(
59 &self,
60 params: GetSubAccountDepositHistoryParams,
61 ) -> anyhow::Result<RestApiResponse<Vec<models::GetSubAccountDepositHistoryResponseInner>>>;
62 async fn get_summary_of_sub_accounts_futures_account(
63 &self,
64 params: GetSummaryOfSubAccountsFuturesAccountParams,
65 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountResponse>>;
66 async fn get_summary_of_sub_accounts_futures_account_v2(
67 &self,
68 params: GetSummaryOfSubAccountsFuturesAccountV2Params,
69 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountV2Response>>;
70 async fn get_summary_of_sub_accounts_margin_account(
71 &self,
72 params: GetSummaryOfSubAccountsMarginAccountParams,
73 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsMarginAccountResponse>>;
74 async fn margin_transfer_for_sub_account(
75 &self,
76 params: MarginTransferForSubAccountParams,
77 ) -> anyhow::Result<RestApiResponse<models::MarginTransferForSubAccountResponse>>;
78 async fn move_position_for_sub_account(
79 &self,
80 params: MovePositionForSubAccountParams,
81 ) -> anyhow::Result<RestApiResponse<models::MovePositionForSubAccountResponse>>;
82 async fn query_sub_account_assets(
83 &self,
84 params: QuerySubAccountAssetsParams,
85 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsResponse>>;
86 async fn query_sub_account_assets_asset_management(
87 &self,
88 params: QuerySubAccountAssetsAssetManagementParams,
89 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsAssetManagementResponse>>;
90 async fn query_sub_account_futures_asset_transfer_history(
91 &self,
92 params: QuerySubAccountFuturesAssetTransferHistoryParams,
93 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountFuturesAssetTransferHistoryResponse>>;
94 async fn query_sub_account_spot_asset_transfer_history(
95 &self,
96 params: QuerySubAccountSpotAssetTransferHistoryParams,
97 ) -> anyhow::Result<
98 RestApiResponse<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>,
99 >;
100 async fn query_sub_account_spot_assets_summary(
101 &self,
102 params: QuerySubAccountSpotAssetsSummaryParams,
103 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountSpotAssetsSummaryResponse>>;
104 async fn query_universal_transfer_history(
105 &self,
106 params: QueryUniversalTransferHistoryParams,
107 ) -> anyhow::Result<RestApiResponse<models::QueryUniversalTransferHistoryResponse>>;
108 async fn sub_account_futures_asset_transfer(
109 &self,
110 params: SubAccountFuturesAssetTransferParams,
111 ) -> anyhow::Result<RestApiResponse<models::SubAccountFuturesAssetTransferResponse>>;
112 async fn sub_account_transfer_history(
113 &self,
114 params: SubAccountTransferHistoryParams,
115 ) -> anyhow::Result<RestApiResponse<Vec<models::SubAccountTransferHistoryResponseInner>>>;
116 async fn transfer_to_master(
117 &self,
118 params: TransferToMasterParams,
119 ) -> anyhow::Result<RestApiResponse<models::TransferToMasterResponse>>;
120 async fn transfer_to_sub_account_of_same_master(
121 &self,
122 params: TransferToSubAccountOfSameMasterParams,
123 ) -> anyhow::Result<RestApiResponse<models::TransferToSubAccountOfSameMasterResponse>>;
124 async fn universal_transfer(
125 &self,
126 params: UniversalTransferParams,
127 ) -> anyhow::Result<RestApiResponse<models::UniversalTransferResponse>>;
128}
129
130#[derive(Debug, Clone)]
131pub struct AssetManagementApiClient {
132 configuration: ConfigurationRestApi,
133}
134
135impl AssetManagementApiClient {
136 pub fn new(configuration: ConfigurationRestApi) -> Self {
137 Self { configuration }
138 }
139}
140
141#[allow(non_camel_case_types)]
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub enum MovePositionForSubAccountProductTypeEnum {
144 #[serde(rename = "UM")]
145 Um,
146}
147
148impl MovePositionForSubAccountProductTypeEnum {
149 #[must_use]
150 pub fn as_str(&self) -> &'static str {
151 match self {
152 Self::Um => "UM",
153 }
154 }
155}
156
157impl std::str::FromStr for MovePositionForSubAccountProductTypeEnum {
158 type Err = Box<dyn std::error::Error + Send + Sync>;
159
160 fn from_str(s: &str) -> Result<Self, Self::Err> {
161 match s {
162 "UM" => Ok(Self::Um),
163 other => Err(format!(
164 "invalid MovePositionForSubAccountProductTypeEnum: {}",
165 other
166 )
167 .into()),
168 }
169 }
170}
171
172#[allow(non_camel_case_types)]
173#[derive(Debug, Clone, Serialize, Deserialize)]
174pub enum UniversalTransferFromAccountTypeEnum {
175 #[serde(rename = "SPOT")]
176 Spot,
177 #[serde(rename = "USDT_FUTURE")]
178 UsdtFuture,
179 #[serde(rename = "COIN_FUTURE")]
180 CoinFuture,
181 #[serde(rename = "MARGIN")]
182 Margin,
183 #[serde(rename = "ISOLATED_MARGIN")]
184 IsolatedMargin,
185}
186
187impl UniversalTransferFromAccountTypeEnum {
188 #[must_use]
189 pub fn as_str(&self) -> &'static str {
190 match self {
191 Self::Spot => "SPOT",
192 Self::UsdtFuture => "USDT_FUTURE",
193 Self::CoinFuture => "COIN_FUTURE",
194 Self::Margin => "MARGIN",
195 Self::IsolatedMargin => "ISOLATED_MARGIN",
196 }
197 }
198}
199
200impl std::str::FromStr for UniversalTransferFromAccountTypeEnum {
201 type Err = Box<dyn std::error::Error + Send + Sync>;
202
203 fn from_str(s: &str) -> Result<Self, Self::Err> {
204 match s {
205 "SPOT" => Ok(Self::Spot),
206 "USDT_FUTURE" => Ok(Self::UsdtFuture),
207 "COIN_FUTURE" => Ok(Self::CoinFuture),
208 "MARGIN" => Ok(Self::Margin),
209 "ISOLATED_MARGIN" => Ok(Self::IsolatedMargin),
210 other => Err(format!("invalid UniversalTransferFromAccountTypeEnum: {}", other).into()),
211 }
212 }
213}
214
215#[allow(non_camel_case_types)]
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub enum UniversalTransferToAccountTypeEnum {
218 #[serde(rename = "SPOT")]
219 Spot,
220 #[serde(rename = "USDT_FUTURE")]
221 UsdtFuture,
222 #[serde(rename = "COIN_FUTURE")]
223 CoinFuture,
224 #[serde(rename = "MARGIN")]
225 Margin,
226 #[serde(rename = "ISOLATED_MARGIN")]
227 IsolatedMargin,
228}
229
230impl UniversalTransferToAccountTypeEnum {
231 #[must_use]
232 pub fn as_str(&self) -> &'static str {
233 match self {
234 Self::Spot => "SPOT",
235 Self::UsdtFuture => "USDT_FUTURE",
236 Self::CoinFuture => "COIN_FUTURE",
237 Self::Margin => "MARGIN",
238 Self::IsolatedMargin => "ISOLATED_MARGIN",
239 }
240 }
241}
242
243impl std::str::FromStr for UniversalTransferToAccountTypeEnum {
244 type Err = Box<dyn std::error::Error + Send + Sync>;
245
246 fn from_str(s: &str) -> Result<Self, Self::Err> {
247 match s {
248 "SPOT" => Ok(Self::Spot),
249 "USDT_FUTURE" => Ok(Self::UsdtFuture),
250 "COIN_FUTURE" => Ok(Self::CoinFuture),
251 "MARGIN" => Ok(Self::Margin),
252 "ISOLATED_MARGIN" => Ok(Self::IsolatedMargin),
253 other => Err(format!("invalid UniversalTransferToAccountTypeEnum: {}", other).into()),
254 }
255 }
256}
257
258#[derive(Clone, Debug, Builder, Deserialize)]
263#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
264pub struct FuturesTransferForSubAccountParams {
265 #[builder(setter(into))]
270 #[serde(rename = "email")]
271 pub email: String,
272 #[builder(setter(into))]
276 #[serde(rename = "asset")]
277 pub asset: String,
278 #[builder(setter(into))]
282 #[serde(rename = "amount")]
283 pub amount: rust_decimal::Decimal,
284 #[builder(setter(into))]
291 #[serde(rename = "type")]
292 pub r#type: i64,
293 #[builder(setter(into), default)]
298 #[serde(rename = "recvWindow", default)]
299 pub recv_window: Option<i64>,
300}
301
302impl FuturesTransferForSubAccountParams {
303 #[must_use]
313 pub fn builder(
314 email: String,
315 asset: String,
316 amount: rust_decimal::Decimal,
317 r#type: i64,
318 ) -> FuturesTransferForSubAccountParamsBuilder {
319 FuturesTransferForSubAccountParamsBuilder::default()
320 .email(email)
321 .asset(asset)
322 .amount(amount)
323 .r#type(r#type)
324 }
325}
326#[derive(Clone, Debug, Builder, Deserialize)]
331#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
332pub struct GetDetailOnSubAccountsFuturesAccountParams {
333 #[builder(setter(into))]
338 #[serde(rename = "email")]
339 pub email: String,
340 #[builder(setter(into), default)]
345 #[serde(rename = "recvWindow", default)]
346 pub recv_window: Option<i64>,
347}
348
349impl GetDetailOnSubAccountsFuturesAccountParams {
350 #[must_use]
357 pub fn builder(email: String) -> GetDetailOnSubAccountsFuturesAccountParamsBuilder {
358 GetDetailOnSubAccountsFuturesAccountParamsBuilder::default().email(email)
359 }
360}
361#[derive(Clone, Debug, Builder, Deserialize)]
366#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
367pub struct GetDetailOnSubAccountsFuturesAccountV2Params {
368 #[builder(setter(into))]
373 #[serde(rename = "email")]
374 pub email: String,
375 #[builder(setter(into))]
379 #[serde(rename = "futuresType")]
380 pub futures_type: i64,
381 #[builder(setter(into), default)]
386 #[serde(rename = "recvWindow", default)]
387 pub recv_window: Option<i64>,
388}
389
390impl GetDetailOnSubAccountsFuturesAccountV2Params {
391 #[must_use]
399 pub fn builder(
400 email: String,
401 futures_type: i64,
402 ) -> GetDetailOnSubAccountsFuturesAccountV2ParamsBuilder {
403 GetDetailOnSubAccountsFuturesAccountV2ParamsBuilder::default()
404 .email(email)
405 .futures_type(futures_type)
406 }
407}
408#[derive(Clone, Debug, Builder, Deserialize)]
413#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
414pub struct GetDetailOnSubAccountsMarginAccountParams {
415 #[builder(setter(into))]
420 #[serde(rename = "email")]
421 pub email: String,
422 #[builder(setter(into), default)]
427 #[serde(rename = "recvWindow", default)]
428 pub recv_window: Option<i64>,
429}
430
431impl GetDetailOnSubAccountsMarginAccountParams {
432 #[must_use]
439 pub fn builder(email: String) -> GetDetailOnSubAccountsMarginAccountParamsBuilder {
440 GetDetailOnSubAccountsMarginAccountParamsBuilder::default().email(email)
441 }
442}
443#[derive(Clone, Debug, Builder, Deserialize)]
448#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
449pub struct GetMovePositionHistoryForSubAccountParams {
450 #[builder(setter(into))]
455 #[serde(rename = "symbol")]
456 pub symbol: String,
457 #[builder(setter(into))]
462 #[serde(rename = "page")]
463 pub page: i64,
464 #[builder(setter(into))]
469 #[serde(rename = "rows")]
470 pub rows: i64,
471 #[builder(setter(into), default)]
476 #[serde(rename = "startTime", default)]
477 pub start_time: Option<i64>,
478 #[builder(setter(into), default)]
483 #[serde(rename = "endTime", default)]
484 pub end_time: Option<i64>,
485 #[builder(setter(into), default)]
490 #[serde(rename = "recvWindow", default)]
491 pub recv_window: Option<i64>,
492}
493
494impl GetMovePositionHistoryForSubAccountParams {
495 #[must_use]
504 pub fn builder(
505 symbol: String,
506 page: i64,
507 rows: i64,
508 ) -> GetMovePositionHistoryForSubAccountParamsBuilder {
509 GetMovePositionHistoryForSubAccountParamsBuilder::default()
510 .symbol(symbol)
511 .page(page)
512 .rows(rows)
513 }
514}
515#[derive(Clone, Debug, Builder, Deserialize)]
520#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
521pub struct GetSubAccountDepositAddressParams {
522 #[builder(setter(into))]
527 #[serde(rename = "email")]
528 pub email: String,
529 #[builder(setter(into))]
534 #[serde(rename = "coin")]
535 pub coin: String,
536 #[builder(setter(into), default)]
540 #[serde(rename = "network", default)]
541 pub network: Option<String>,
542 #[builder(setter(into), default)]
547 #[serde(rename = "amount", default)]
548 pub amount: Option<rust_decimal::Decimal>,
549 #[builder(setter(into), default)]
554 #[serde(rename = "recvWindow", default)]
555 pub recv_window: Option<i64>,
556}
557
558impl GetSubAccountDepositAddressParams {
559 #[must_use]
567 pub fn builder(email: String, coin: String) -> GetSubAccountDepositAddressParamsBuilder {
568 GetSubAccountDepositAddressParamsBuilder::default()
569 .email(email)
570 .coin(coin)
571 }
572}
573#[derive(Clone, Debug, Builder, Deserialize)]
578#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
579pub struct GetSubAccountDepositHistoryParams {
580 #[builder(setter(into))]
585 #[serde(rename = "email")]
586 pub email: String,
587 #[builder(setter(into), default)]
591 #[serde(rename = "includeSource", default)]
592 pub include_source: Option<bool>,
593 #[builder(setter(into), default)]
598 #[serde(rename = "coin", default)]
599 pub coin: Option<String>,
600 #[builder(setter(into), default)]
604 #[serde(rename = "status", default)]
605 pub status: Option<i64>,
606 #[builder(setter(into), default)]
611 #[serde(rename = "startTime", default)]
612 pub start_time: Option<i64>,
613 #[builder(setter(into), default)]
618 #[serde(rename = "endTime", default)]
619 pub end_time: Option<i64>,
620 #[builder(setter(into), default)]
625 #[serde(rename = "limit", default)]
626 pub limit: Option<i64>,
627 #[builder(setter(into), default)]
632 #[serde(rename = "offset", default)]
633 pub offset: Option<i64>,
634 #[builder(setter(into), default)]
639 #[serde(rename = "recvWindow", default)]
640 pub recv_window: Option<i64>,
641 #[builder(setter(into), default)]
646 #[serde(rename = "txId", default)]
647 pub tx_id: Option<String>,
648}
649
650impl GetSubAccountDepositHistoryParams {
651 #[must_use]
658 pub fn builder(email: String) -> GetSubAccountDepositHistoryParamsBuilder {
659 GetSubAccountDepositHistoryParamsBuilder::default().email(email)
660 }
661}
662#[derive(Clone, Debug, Builder, Deserialize)]
667#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
668pub struct GetSummaryOfSubAccountsFuturesAccountParams {
669 #[builder(setter(into))]
674 #[serde(rename = "page")]
675 pub page: i64,
676 #[builder(setter(into))]
681 #[serde(rename = "limit")]
682 pub limit: i64,
683 #[builder(setter(into), default)]
688 #[serde(rename = "recvWindow", default)]
689 pub recv_window: Option<i64>,
690}
691
692impl GetSummaryOfSubAccountsFuturesAccountParams {
693 #[must_use]
701 pub fn builder(page: i64, limit: i64) -> GetSummaryOfSubAccountsFuturesAccountParamsBuilder {
702 GetSummaryOfSubAccountsFuturesAccountParamsBuilder::default()
703 .page(page)
704 .limit(limit)
705 }
706}
707#[derive(Clone, Debug, Builder, Deserialize)]
712#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
713pub struct GetSummaryOfSubAccountsFuturesAccountV2Params {
714 #[builder(setter(into))]
718 #[serde(rename = "futuresType")]
719 pub futures_type: i64,
720 #[builder(setter(into), default)]
725 #[serde(rename = "page", default)]
726 pub page: Option<i64>,
727 #[builder(setter(into), default)]
732 #[serde(rename = "limit", default)]
733 pub limit: Option<i64>,
734 #[builder(setter(into), default)]
739 #[serde(rename = "recvWindow", default)]
740 pub recv_window: Option<i64>,
741}
742
743impl GetSummaryOfSubAccountsFuturesAccountV2Params {
744 #[must_use]
751 pub fn builder(futures_type: i64) -> GetSummaryOfSubAccountsFuturesAccountV2ParamsBuilder {
752 GetSummaryOfSubAccountsFuturesAccountV2ParamsBuilder::default().futures_type(futures_type)
753 }
754}
755#[derive(Clone, Debug, Builder, Deserialize, Default)]
760#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
761pub struct GetSummaryOfSubAccountsMarginAccountParams {
762 #[builder(setter(into), default)]
767 #[serde(rename = "recvWindow", default)]
768 pub recv_window: Option<i64>,
769}
770
771impl GetSummaryOfSubAccountsMarginAccountParams {
772 #[must_use]
775 pub fn builder() -> GetSummaryOfSubAccountsMarginAccountParamsBuilder {
776 GetSummaryOfSubAccountsMarginAccountParamsBuilder::default()
777 }
778}
779#[derive(Clone, Debug, Builder, Deserialize)]
784#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
785pub struct MarginTransferForSubAccountParams {
786 #[builder(setter(into))]
791 #[serde(rename = "email")]
792 pub email: String,
793 #[builder(setter(into))]
797 #[serde(rename = "asset")]
798 pub asset: String,
799 #[builder(setter(into))]
803 #[serde(rename = "amount")]
804 pub amount: rust_decimal::Decimal,
805 #[builder(setter(into))]
810 #[serde(rename = "type")]
811 pub r#type: i64,
812 #[builder(setter(into), default)]
817 #[serde(rename = "recvWindow", default)]
818 pub recv_window: Option<i64>,
819}
820
821impl MarginTransferForSubAccountParams {
822 #[must_use]
832 pub fn builder(
833 email: String,
834 asset: String,
835 amount: rust_decimal::Decimal,
836 r#type: i64,
837 ) -> MarginTransferForSubAccountParamsBuilder {
838 MarginTransferForSubAccountParamsBuilder::default()
839 .email(email)
840 .asset(asset)
841 .amount(amount)
842 .r#type(r#type)
843 }
844}
845#[derive(Clone, Debug, Builder, Deserialize)]
850#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
851pub struct MovePositionForSubAccountParams {
852 #[builder(setter(into))]
857 #[serde(rename = "fromUserEmail")]
858 pub from_user_email: String,
859 #[builder(setter(into))]
864 #[serde(rename = "toUserEmail")]
865 pub to_user_email: String,
866 #[builder(setter(into))]
871 #[serde(rename = "productType")]
872 pub product_type: MovePositionForSubAccountProductTypeEnum,
873 #[builder(setter(into))]
883 #[serde(rename = "orderArgs")]
884 pub order_args: Vec<models::MovePositionForSubAccountOrderArgsParameterInner>,
885 #[builder(setter(into), default)]
890 #[serde(rename = "recvWindow", default)]
891 pub recv_window: Option<i64>,
892}
893
894impl MovePositionForSubAccountParams {
895 #[must_use]
905 pub fn builder(
906 from_user_email: String,
907 to_user_email: String,
908 product_type: MovePositionForSubAccountProductTypeEnum,
909 order_args: Vec<models::MovePositionForSubAccountOrderArgsParameterInner>,
910 ) -> MovePositionForSubAccountParamsBuilder {
911 MovePositionForSubAccountParamsBuilder::default()
912 .from_user_email(from_user_email)
913 .to_user_email(to_user_email)
914 .product_type(product_type)
915 .order_args(order_args)
916 }
917}
918#[derive(Clone, Debug, Builder, Deserialize)]
923#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
924pub struct QuerySubAccountAssetsParams {
925 #[builder(setter(into))]
930 #[serde(rename = "email")]
931 pub email: String,
932 #[builder(setter(into), default)]
937 #[serde(rename = "recvWindow", default)]
938 pub recv_window: Option<i64>,
939}
940
941impl QuerySubAccountAssetsParams {
942 #[must_use]
949 pub fn builder(email: String) -> QuerySubAccountAssetsParamsBuilder {
950 QuerySubAccountAssetsParamsBuilder::default().email(email)
951 }
952}
953#[derive(Clone, Debug, Builder, Deserialize)]
958#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
959pub struct QuerySubAccountAssetsAssetManagementParams {
960 #[builder(setter(into))]
965 #[serde(rename = "email")]
966 pub email: String,
967 #[builder(setter(into), default)]
972 #[serde(rename = "recvWindow", default)]
973 pub recv_window: Option<i64>,
974}
975
976impl QuerySubAccountAssetsAssetManagementParams {
977 #[must_use]
984 pub fn builder(email: String) -> QuerySubAccountAssetsAssetManagementParamsBuilder {
985 QuerySubAccountAssetsAssetManagementParamsBuilder::default().email(email)
986 }
987}
988#[derive(Clone, Debug, Builder, Deserialize)]
993#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
994pub struct QuerySubAccountFuturesAssetTransferHistoryParams {
995 #[builder(setter(into))]
1000 #[serde(rename = "email")]
1001 pub email: String,
1002 #[builder(setter(into))]
1006 #[serde(rename = "futuresType")]
1007 pub futures_type: i64,
1008 #[builder(setter(into), default)]
1012 #[serde(rename = "startTime", default)]
1013 pub start_time: Option<i64>,
1014 #[builder(setter(into), default)]
1019 #[serde(rename = "endTime", default)]
1020 pub end_time: Option<i64>,
1021 #[builder(setter(into), default)]
1026 #[serde(rename = "page", default)]
1027 pub page: Option<i64>,
1028 #[builder(setter(into), default)]
1033 #[serde(rename = "limit", default)]
1034 pub limit: Option<i64>,
1035 #[builder(setter(into), default)]
1040 #[serde(rename = "recvWindow", default)]
1041 pub recv_window: Option<i64>,
1042}
1043
1044impl QuerySubAccountFuturesAssetTransferHistoryParams {
1045 #[must_use]
1053 pub fn builder(
1054 email: String,
1055 futures_type: i64,
1056 ) -> QuerySubAccountFuturesAssetTransferHistoryParamsBuilder {
1057 QuerySubAccountFuturesAssetTransferHistoryParamsBuilder::default()
1058 .email(email)
1059 .futures_type(futures_type)
1060 }
1061}
1062#[derive(Clone, Debug, Builder, Deserialize, Default)]
1067#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1068pub struct QuerySubAccountSpotAssetTransferHistoryParams {
1069 #[builder(setter(into), default)]
1074 #[serde(rename = "fromEmail", default)]
1075 pub from_email: Option<String>,
1076 #[builder(setter(into), default)]
1081 #[serde(rename = "toEmail", default)]
1082 pub to_email: Option<String>,
1083 #[builder(setter(into), default)]
1088 #[serde(rename = "startTime", default)]
1089 pub start_time: Option<i64>,
1090 #[builder(setter(into), default)]
1095 #[serde(rename = "endTime", default)]
1096 pub end_time: Option<i64>,
1097 #[builder(setter(into), default)]
1102 #[serde(rename = "page", default)]
1103 pub page: Option<i64>,
1104 #[builder(setter(into), default)]
1109 #[serde(rename = "limit", default)]
1110 pub limit: Option<i64>,
1111 #[builder(setter(into), default)]
1116 #[serde(rename = "recvWindow", default)]
1117 pub recv_window: Option<i64>,
1118}
1119
1120impl QuerySubAccountSpotAssetTransferHistoryParams {
1121 #[must_use]
1124 pub fn builder() -> QuerySubAccountSpotAssetTransferHistoryParamsBuilder {
1125 QuerySubAccountSpotAssetTransferHistoryParamsBuilder::default()
1126 }
1127}
1128#[derive(Clone, Debug, Builder, Deserialize, Default)]
1133#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1134pub struct QuerySubAccountSpotAssetsSummaryParams {
1135 #[builder(setter(into), default)]
1139 #[serde(rename = "email", default)]
1140 pub email: Option<String>,
1141 #[builder(setter(into), default)]
1146 #[serde(rename = "page", default)]
1147 pub page: Option<i64>,
1148 #[builder(setter(into), default)]
1153 #[serde(rename = "size", default)]
1154 pub size: Option<i64>,
1155 #[builder(setter(into), default)]
1160 #[serde(rename = "recvWindow", default)]
1161 pub recv_window: Option<i64>,
1162}
1163
1164impl QuerySubAccountSpotAssetsSummaryParams {
1165 #[must_use]
1168 pub fn builder() -> QuerySubAccountSpotAssetsSummaryParamsBuilder {
1169 QuerySubAccountSpotAssetsSummaryParamsBuilder::default()
1170 }
1171}
1172#[derive(Clone, Debug, Builder, Deserialize, Default)]
1177#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1178pub struct QueryUniversalTransferHistoryParams {
1179 #[builder(setter(into), default)]
1184 #[serde(rename = "fromEmail", default)]
1185 pub from_email: Option<String>,
1186 #[builder(setter(into), default)]
1191 #[serde(rename = "toEmail", default)]
1192 pub to_email: Option<String>,
1193 #[builder(setter(into), default)]
1198 #[serde(rename = "clientTranId", default)]
1199 pub client_tran_id: Option<String>,
1200 #[builder(setter(into), default)]
1205 #[serde(rename = "startTime", default)]
1206 pub start_time: Option<i64>,
1207 #[builder(setter(into), default)]
1212 #[serde(rename = "endTime", default)]
1213 pub end_time: Option<i64>,
1214 #[builder(setter(into), default)]
1219 #[serde(rename = "page", default)]
1220 pub page: Option<i64>,
1221 #[builder(setter(into), default)]
1226 #[serde(rename = "limit", default)]
1227 pub limit: Option<i64>,
1228 #[builder(setter(into), default)]
1233 #[serde(rename = "recvWindow", default)]
1234 pub recv_window: Option<i64>,
1235}
1236
1237impl QueryUniversalTransferHistoryParams {
1238 #[must_use]
1241 pub fn builder() -> QueryUniversalTransferHistoryParamsBuilder {
1242 QueryUniversalTransferHistoryParamsBuilder::default()
1243 }
1244}
1245#[derive(Clone, Debug, Builder, Deserialize)]
1250#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1251pub struct SubAccountFuturesAssetTransferParams {
1252 #[builder(setter(into))]
1256 #[serde(rename = "fromEmail")]
1257 pub from_email: String,
1258 #[builder(setter(into))]
1262 #[serde(rename = "toEmail")]
1263 pub to_email: String,
1264 #[builder(setter(into))]
1268 #[serde(rename = "futuresType")]
1269 pub futures_type: i64,
1270 #[builder(setter(into))]
1275 #[serde(rename = "asset")]
1276 pub asset: String,
1277 #[builder(setter(into))]
1282 #[serde(rename = "amount")]
1283 pub amount: rust_decimal::Decimal,
1284 #[builder(setter(into), default)]
1289 #[serde(rename = "recvWindow", default)]
1290 pub recv_window: Option<i64>,
1291}
1292
1293impl SubAccountFuturesAssetTransferParams {
1294 #[must_use]
1305 pub fn builder(
1306 from_email: String,
1307 to_email: String,
1308 futures_type: i64,
1309 asset: String,
1310 amount: rust_decimal::Decimal,
1311 ) -> SubAccountFuturesAssetTransferParamsBuilder {
1312 SubAccountFuturesAssetTransferParamsBuilder::default()
1313 .from_email(from_email)
1314 .to_email(to_email)
1315 .futures_type(futures_type)
1316 .asset(asset)
1317 .amount(amount)
1318 }
1319}
1320#[derive(Clone, Debug, Builder, Deserialize, Default)]
1325#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1326pub struct SubAccountTransferHistoryParams {
1327 #[builder(setter(into), default)]
1331 #[serde(rename = "asset", default)]
1332 pub asset: Option<String>,
1333 #[builder(setter(into), default)]
1337 #[serde(rename = "type", default)]
1338 pub r#type: Option<i64>,
1339 #[builder(setter(into), default)]
1344 #[serde(rename = "startTime", default)]
1345 pub start_time: Option<i64>,
1346 #[builder(setter(into), default)]
1351 #[serde(rename = "endTime", default)]
1352 pub end_time: Option<i64>,
1353 #[builder(setter(into), default)]
1358 #[serde(rename = "limit", default)]
1359 pub limit: Option<i64>,
1360 #[builder(setter(into), default)]
1365 #[serde(rename = "returnFailHistory", default)]
1366 pub return_fail_history: Option<bool>,
1367 #[builder(setter(into), default)]
1372 #[serde(rename = "recvWindow", default)]
1373 pub recv_window: Option<i64>,
1374}
1375
1376impl SubAccountTransferHistoryParams {
1377 #[must_use]
1380 pub fn builder() -> SubAccountTransferHistoryParamsBuilder {
1381 SubAccountTransferHistoryParamsBuilder::default()
1382 }
1383}
1384#[derive(Clone, Debug, Builder, Deserialize)]
1389#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1390pub struct TransferToMasterParams {
1391 #[builder(setter(into))]
1396 #[serde(rename = "asset")]
1397 pub asset: String,
1398 #[builder(setter(into))]
1403 #[serde(rename = "amount")]
1404 pub amount: rust_decimal::Decimal,
1405 #[builder(setter(into), default)]
1410 #[serde(rename = "recvWindow", default)]
1411 pub recv_window: Option<i64>,
1412}
1413
1414impl TransferToMasterParams {
1415 #[must_use]
1423 pub fn builder(asset: String, amount: rust_decimal::Decimal) -> TransferToMasterParamsBuilder {
1424 TransferToMasterParamsBuilder::default()
1425 .asset(asset)
1426 .amount(amount)
1427 }
1428}
1429#[derive(Clone, Debug, Builder, Deserialize)]
1434#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1435pub struct TransferToSubAccountOfSameMasterParams {
1436 #[builder(setter(into))]
1441 #[serde(rename = "toEmail")]
1442 pub to_email: String,
1443 #[builder(setter(into))]
1448 #[serde(rename = "asset")]
1449 pub asset: String,
1450 #[builder(setter(into))]
1455 #[serde(rename = "amount")]
1456 pub amount: rust_decimal::Decimal,
1457 #[builder(setter(into), default)]
1462 #[serde(rename = "recvWindow", default)]
1463 pub recv_window: Option<i64>,
1464}
1465
1466impl TransferToSubAccountOfSameMasterParams {
1467 #[must_use]
1476 pub fn builder(
1477 to_email: String,
1478 asset: String,
1479 amount: rust_decimal::Decimal,
1480 ) -> TransferToSubAccountOfSameMasterParamsBuilder {
1481 TransferToSubAccountOfSameMasterParamsBuilder::default()
1482 .to_email(to_email)
1483 .asset(asset)
1484 .amount(amount)
1485 }
1486}
1487#[derive(Clone, Debug, Builder, Deserialize)]
1492#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1493pub struct UniversalTransferParams {
1494 #[builder(setter(into))]
1499 #[serde(rename = "fromAccountType")]
1500 pub from_account_type: UniversalTransferFromAccountTypeEnum,
1501 #[builder(setter(into))]
1506 #[serde(rename = "toAccountType")]
1507 pub to_account_type: UniversalTransferToAccountTypeEnum,
1508 #[builder(setter(into))]
1513 #[serde(rename = "asset")]
1514 pub asset: String,
1515 #[builder(setter(into))]
1520 #[serde(rename = "amount")]
1521 pub amount: rust_decimal::Decimal,
1522 #[builder(setter(into), default)]
1527 #[serde(rename = "fromEmail", default)]
1528 pub from_email: Option<String>,
1529 #[builder(setter(into), default)]
1534 #[serde(rename = "toEmail", default)]
1535 pub to_email: Option<String>,
1536 #[builder(setter(into), default)]
1540 #[serde(rename = "clientTranId", default)]
1541 pub client_tran_id: Option<String>,
1542 #[builder(setter(into), default)]
1546 #[serde(rename = "symbol", default)]
1547 pub symbol: Option<String>,
1548 #[builder(setter(into), default)]
1553 #[serde(rename = "recvWindow", default)]
1554 pub recv_window: Option<i64>,
1555}
1556
1557impl UniversalTransferParams {
1558 #[must_use]
1568 pub fn builder(
1569 from_account_type: UniversalTransferFromAccountTypeEnum,
1570 to_account_type: UniversalTransferToAccountTypeEnum,
1571 asset: String,
1572 amount: rust_decimal::Decimal,
1573 ) -> UniversalTransferParamsBuilder {
1574 UniversalTransferParamsBuilder::default()
1575 .from_account_type(from_account_type)
1576 .to_account_type(to_account_type)
1577 .asset(asset)
1578 .amount(amount)
1579 }
1580}
1581
1582#[async_trait]
1583impl AssetManagementApi for AssetManagementApiClient {
1584 async fn futures_transfer_for_sub_account(
1585 &self,
1586 params: FuturesTransferForSubAccountParams,
1587 ) -> anyhow::Result<RestApiResponse<models::FuturesTransferForSubAccountResponse>> {
1588 let FuturesTransferForSubAccountParams {
1589 email,
1590 asset,
1591 amount,
1592 r#type,
1593 recv_window,
1594 } = params;
1595
1596 let mut query_params = BTreeMap::new();
1597 let body_params = BTreeMap::new();
1598
1599 query_params.insert("email".to_string(), json!(email));
1600
1601 query_params.insert("asset".to_string(), json!(asset));
1602
1603 query_params.insert("amount".to_string(), json!(amount));
1604
1605 query_params.insert("type".to_string(), json!(r#type));
1606
1607 if let Some(rw) = recv_window {
1608 query_params.insert("recvWindow".to_string(), json!(rw));
1609 }
1610
1611 send_request::<models::FuturesTransferForSubAccountResponse>(
1612 &self.configuration,
1613 "/sapi/v1/sub-account/futures/transfer",
1614 reqwest::Method::POST,
1615 query_params,
1616 body_params,
1617 if HAS_TIME_UNIT {
1618 self.configuration.time_unit
1619 } else {
1620 None
1621 },
1622 true,
1623 )
1624 .await
1625 }
1626
1627 async fn get_detail_on_sub_accounts_futures_account(
1628 &self,
1629 params: GetDetailOnSubAccountsFuturesAccountParams,
1630 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountResponse>> {
1631 let GetDetailOnSubAccountsFuturesAccountParams { email, recv_window } = params;
1632
1633 let mut query_params = BTreeMap::new();
1634 let body_params = BTreeMap::new();
1635
1636 query_params.insert("email".to_string(), json!(email));
1637
1638 if let Some(rw) = recv_window {
1639 query_params.insert("recvWindow".to_string(), json!(rw));
1640 }
1641
1642 send_request::<models::GetDetailOnSubAccountsFuturesAccountResponse>(
1643 &self.configuration,
1644 "/sapi/v1/sub-account/futures/account",
1645 reqwest::Method::GET,
1646 query_params,
1647 body_params,
1648 if HAS_TIME_UNIT {
1649 self.configuration.time_unit
1650 } else {
1651 None
1652 },
1653 true,
1654 )
1655 .await
1656 }
1657
1658 async fn get_detail_on_sub_accounts_futures_account_v2(
1659 &self,
1660 params: GetDetailOnSubAccountsFuturesAccountV2Params,
1661 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountV2Response>>
1662 {
1663 let GetDetailOnSubAccountsFuturesAccountV2Params {
1664 email,
1665 futures_type,
1666 recv_window,
1667 } = params;
1668
1669 let mut query_params = BTreeMap::new();
1670 let body_params = BTreeMap::new();
1671
1672 query_params.insert("email".to_string(), json!(email));
1673
1674 query_params.insert("futuresType".to_string(), json!(futures_type));
1675
1676 if let Some(rw) = recv_window {
1677 query_params.insert("recvWindow".to_string(), json!(rw));
1678 }
1679
1680 send_request::<models::GetDetailOnSubAccountsFuturesAccountV2Response>(
1681 &self.configuration,
1682 "/sapi/v2/sub-account/futures/account",
1683 reqwest::Method::GET,
1684 query_params,
1685 body_params,
1686 if HAS_TIME_UNIT {
1687 self.configuration.time_unit
1688 } else {
1689 None
1690 },
1691 true,
1692 )
1693 .await
1694 }
1695
1696 async fn get_detail_on_sub_accounts_margin_account(
1697 &self,
1698 params: GetDetailOnSubAccountsMarginAccountParams,
1699 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsMarginAccountResponse>> {
1700 let GetDetailOnSubAccountsMarginAccountParams { email, recv_window } = params;
1701
1702 let mut query_params = BTreeMap::new();
1703 let body_params = BTreeMap::new();
1704
1705 query_params.insert("email".to_string(), json!(email));
1706
1707 if let Some(rw) = recv_window {
1708 query_params.insert("recvWindow".to_string(), json!(rw));
1709 }
1710
1711 send_request::<models::GetDetailOnSubAccountsMarginAccountResponse>(
1712 &self.configuration,
1713 "/sapi/v1/sub-account/margin/account",
1714 reqwest::Method::GET,
1715 query_params,
1716 body_params,
1717 if HAS_TIME_UNIT {
1718 self.configuration.time_unit
1719 } else {
1720 None
1721 },
1722 true,
1723 )
1724 .await
1725 }
1726
1727 async fn get_move_position_history_for_sub_account(
1728 &self,
1729 params: GetMovePositionHistoryForSubAccountParams,
1730 ) -> anyhow::Result<RestApiResponse<models::GetMovePositionHistoryForSubAccountResponse>> {
1731 let GetMovePositionHistoryForSubAccountParams {
1732 symbol,
1733 page,
1734 rows,
1735 start_time,
1736 end_time,
1737 recv_window,
1738 } = params;
1739
1740 let mut query_params = BTreeMap::new();
1741 let body_params = BTreeMap::new();
1742
1743 query_params.insert("symbol".to_string(), json!(symbol));
1744
1745 if let Some(rw) = start_time {
1746 query_params.insert("startTime".to_string(), json!(rw));
1747 }
1748
1749 if let Some(rw) = end_time {
1750 query_params.insert("endTime".to_string(), json!(rw));
1751 }
1752
1753 query_params.insert("page".to_string(), json!(page));
1754
1755 query_params.insert("rows".to_string(), json!(rows));
1756
1757 if let Some(rw) = recv_window {
1758 query_params.insert("recvWindow".to_string(), json!(rw));
1759 }
1760
1761 send_request::<models::GetMovePositionHistoryForSubAccountResponse>(
1762 &self.configuration,
1763 "/sapi/v1/sub-account/futures/move-position",
1764 reqwest::Method::GET,
1765 query_params,
1766 body_params,
1767 if HAS_TIME_UNIT {
1768 self.configuration.time_unit
1769 } else {
1770 None
1771 },
1772 true,
1773 )
1774 .await
1775 }
1776
1777 async fn get_sub_account_deposit_address(
1778 &self,
1779 params: GetSubAccountDepositAddressParams,
1780 ) -> anyhow::Result<RestApiResponse<models::GetSubAccountDepositAddressResponse>> {
1781 let GetSubAccountDepositAddressParams {
1782 email,
1783 coin,
1784 network,
1785 amount,
1786 recv_window,
1787 } = params;
1788
1789 let mut query_params = BTreeMap::new();
1790 let body_params = BTreeMap::new();
1791
1792 query_params.insert("email".to_string(), json!(email));
1793
1794 query_params.insert("coin".to_string(), json!(coin));
1795
1796 if let Some(rw) = network {
1797 query_params.insert("network".to_string(), json!(rw));
1798 }
1799
1800 if let Some(rw) = amount {
1801 query_params.insert("amount".to_string(), json!(rw));
1802 }
1803
1804 if let Some(rw) = recv_window {
1805 query_params.insert("recvWindow".to_string(), json!(rw));
1806 }
1807
1808 send_request::<models::GetSubAccountDepositAddressResponse>(
1809 &self.configuration,
1810 "/sapi/v1/capital/deposit/subAddress",
1811 reqwest::Method::GET,
1812 query_params,
1813 body_params,
1814 if HAS_TIME_UNIT {
1815 self.configuration.time_unit
1816 } else {
1817 None
1818 },
1819 true,
1820 )
1821 .await
1822 }
1823
1824 async fn get_sub_account_deposit_history(
1825 &self,
1826 params: GetSubAccountDepositHistoryParams,
1827 ) -> anyhow::Result<RestApiResponse<Vec<models::GetSubAccountDepositHistoryResponseInner>>>
1828 {
1829 let GetSubAccountDepositHistoryParams {
1830 email,
1831 include_source,
1832 coin,
1833 status,
1834 start_time,
1835 end_time,
1836 limit,
1837 offset,
1838 recv_window,
1839 tx_id,
1840 } = params;
1841
1842 let mut query_params = BTreeMap::new();
1843 let body_params = BTreeMap::new();
1844
1845 query_params.insert("email".to_string(), json!(email));
1846
1847 if let Some(rw) = include_source {
1848 query_params.insert("includeSource".to_string(), json!(rw));
1849 }
1850
1851 if let Some(rw) = coin {
1852 query_params.insert("coin".to_string(), json!(rw));
1853 }
1854
1855 if let Some(rw) = status {
1856 query_params.insert("status".to_string(), json!(rw));
1857 }
1858
1859 if let Some(rw) = start_time {
1860 query_params.insert("startTime".to_string(), json!(rw));
1861 }
1862
1863 if let Some(rw) = end_time {
1864 query_params.insert("endTime".to_string(), json!(rw));
1865 }
1866
1867 if let Some(rw) = limit {
1868 query_params.insert("limit".to_string(), json!(rw));
1869 }
1870
1871 if let Some(rw) = offset {
1872 query_params.insert("offset".to_string(), json!(rw));
1873 }
1874
1875 if let Some(rw) = recv_window {
1876 query_params.insert("recvWindow".to_string(), json!(rw));
1877 }
1878
1879 if let Some(rw) = tx_id {
1880 query_params.insert("txId".to_string(), json!(rw));
1881 }
1882
1883 send_request::<Vec<models::GetSubAccountDepositHistoryResponseInner>>(
1884 &self.configuration,
1885 "/sapi/v1/capital/deposit/subHisrec",
1886 reqwest::Method::GET,
1887 query_params,
1888 body_params,
1889 if HAS_TIME_UNIT {
1890 self.configuration.time_unit
1891 } else {
1892 None
1893 },
1894 true,
1895 )
1896 .await
1897 }
1898
1899 async fn get_summary_of_sub_accounts_futures_account(
1900 &self,
1901 params: GetSummaryOfSubAccountsFuturesAccountParams,
1902 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountResponse>>
1903 {
1904 let GetSummaryOfSubAccountsFuturesAccountParams {
1905 page,
1906 limit,
1907 recv_window,
1908 } = params;
1909
1910 let mut query_params = BTreeMap::new();
1911 let body_params = BTreeMap::new();
1912
1913 query_params.insert("page".to_string(), json!(page));
1914
1915 query_params.insert("limit".to_string(), json!(limit));
1916
1917 if let Some(rw) = recv_window {
1918 query_params.insert("recvWindow".to_string(), json!(rw));
1919 }
1920
1921 send_request::<models::GetSummaryOfSubAccountsFuturesAccountResponse>(
1922 &self.configuration,
1923 "/sapi/v1/sub-account/futures/accountSummary",
1924 reqwest::Method::GET,
1925 query_params,
1926 body_params,
1927 if HAS_TIME_UNIT {
1928 self.configuration.time_unit
1929 } else {
1930 None
1931 },
1932 true,
1933 )
1934 .await
1935 }
1936
1937 async fn get_summary_of_sub_accounts_futures_account_v2(
1938 &self,
1939 params: GetSummaryOfSubAccountsFuturesAccountV2Params,
1940 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountV2Response>>
1941 {
1942 let GetSummaryOfSubAccountsFuturesAccountV2Params {
1943 futures_type,
1944 page,
1945 limit,
1946 recv_window,
1947 } = params;
1948
1949 let mut query_params = BTreeMap::new();
1950 let body_params = BTreeMap::new();
1951
1952 query_params.insert("futuresType".to_string(), json!(futures_type));
1953
1954 if let Some(rw) = page {
1955 query_params.insert("page".to_string(), json!(rw));
1956 }
1957
1958 if let Some(rw) = limit {
1959 query_params.insert("limit".to_string(), json!(rw));
1960 }
1961
1962 if let Some(rw) = recv_window {
1963 query_params.insert("recvWindow".to_string(), json!(rw));
1964 }
1965
1966 send_request::<models::GetSummaryOfSubAccountsFuturesAccountV2Response>(
1967 &self.configuration,
1968 "/sapi/v2/sub-account/futures/accountSummary",
1969 reqwest::Method::GET,
1970 query_params,
1971 body_params,
1972 if HAS_TIME_UNIT {
1973 self.configuration.time_unit
1974 } else {
1975 None
1976 },
1977 true,
1978 )
1979 .await
1980 }
1981
1982 async fn get_summary_of_sub_accounts_margin_account(
1983 &self,
1984 params: GetSummaryOfSubAccountsMarginAccountParams,
1985 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsMarginAccountResponse>> {
1986 let GetSummaryOfSubAccountsMarginAccountParams { recv_window } = params;
1987
1988 let mut query_params = BTreeMap::new();
1989 let body_params = BTreeMap::new();
1990
1991 if let Some(rw) = recv_window {
1992 query_params.insert("recvWindow".to_string(), json!(rw));
1993 }
1994
1995 send_request::<models::GetSummaryOfSubAccountsMarginAccountResponse>(
1996 &self.configuration,
1997 "/sapi/v1/sub-account/margin/accountSummary",
1998 reqwest::Method::GET,
1999 query_params,
2000 body_params,
2001 if HAS_TIME_UNIT {
2002 self.configuration.time_unit
2003 } else {
2004 None
2005 },
2006 true,
2007 )
2008 .await
2009 }
2010
2011 async fn margin_transfer_for_sub_account(
2012 &self,
2013 params: MarginTransferForSubAccountParams,
2014 ) -> anyhow::Result<RestApiResponse<models::MarginTransferForSubAccountResponse>> {
2015 let MarginTransferForSubAccountParams {
2016 email,
2017 asset,
2018 amount,
2019 r#type,
2020 recv_window,
2021 } = params;
2022
2023 let mut query_params = BTreeMap::new();
2024 let body_params = BTreeMap::new();
2025
2026 query_params.insert("email".to_string(), json!(email));
2027
2028 query_params.insert("asset".to_string(), json!(asset));
2029
2030 query_params.insert("amount".to_string(), json!(amount));
2031
2032 query_params.insert("type".to_string(), json!(r#type));
2033
2034 if let Some(rw) = recv_window {
2035 query_params.insert("recvWindow".to_string(), json!(rw));
2036 }
2037
2038 send_request::<models::MarginTransferForSubAccountResponse>(
2039 &self.configuration,
2040 "/sapi/v1/sub-account/margin/transfer",
2041 reqwest::Method::POST,
2042 query_params,
2043 body_params,
2044 if HAS_TIME_UNIT {
2045 self.configuration.time_unit
2046 } else {
2047 None
2048 },
2049 true,
2050 )
2051 .await
2052 }
2053
2054 async fn move_position_for_sub_account(
2055 &self,
2056 params: MovePositionForSubAccountParams,
2057 ) -> anyhow::Result<RestApiResponse<models::MovePositionForSubAccountResponse>> {
2058 let MovePositionForSubAccountParams {
2059 from_user_email,
2060 to_user_email,
2061 product_type,
2062 order_args,
2063 recv_window,
2064 } = params;
2065
2066 let mut query_params = BTreeMap::new();
2067 let body_params = BTreeMap::new();
2068
2069 query_params.insert("fromUserEmail".to_string(), json!(from_user_email));
2070
2071 query_params.insert("toUserEmail".to_string(), json!(to_user_email));
2072
2073 query_params.insert("productType".to_string(), json!(product_type));
2074
2075 query_params.insert("orderArgs".to_string(), json!(order_args));
2076
2077 if let Some(rw) = recv_window {
2078 query_params.insert("recvWindow".to_string(), json!(rw));
2079 }
2080
2081 send_request::<models::MovePositionForSubAccountResponse>(
2082 &self.configuration,
2083 "/sapi/v1/sub-account/futures/move-position",
2084 reqwest::Method::POST,
2085 query_params,
2086 body_params,
2087 if HAS_TIME_UNIT {
2088 self.configuration.time_unit
2089 } else {
2090 None
2091 },
2092 true,
2093 )
2094 .await
2095 }
2096
2097 async fn query_sub_account_assets(
2098 &self,
2099 params: QuerySubAccountAssetsParams,
2100 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsResponse>> {
2101 let QuerySubAccountAssetsParams { email, recv_window } = params;
2102
2103 let mut query_params = BTreeMap::new();
2104 let body_params = BTreeMap::new();
2105
2106 query_params.insert("email".to_string(), json!(email));
2107
2108 if let Some(rw) = recv_window {
2109 query_params.insert("recvWindow".to_string(), json!(rw));
2110 }
2111
2112 send_request::<models::QuerySubAccountAssetsResponse>(
2113 &self.configuration,
2114 "/sapi/v3/sub-account/assets",
2115 reqwest::Method::GET,
2116 query_params,
2117 body_params,
2118 if HAS_TIME_UNIT {
2119 self.configuration.time_unit
2120 } else {
2121 None
2122 },
2123 true,
2124 )
2125 .await
2126 }
2127
2128 async fn query_sub_account_assets_asset_management(
2129 &self,
2130 params: QuerySubAccountAssetsAssetManagementParams,
2131 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsAssetManagementResponse>> {
2132 let QuerySubAccountAssetsAssetManagementParams { email, recv_window } = params;
2133
2134 let mut query_params = BTreeMap::new();
2135 let body_params = BTreeMap::new();
2136
2137 query_params.insert("email".to_string(), json!(email));
2138
2139 if let Some(rw) = recv_window {
2140 query_params.insert("recvWindow".to_string(), json!(rw));
2141 }
2142
2143 send_request::<models::QuerySubAccountAssetsAssetManagementResponse>(
2144 &self.configuration,
2145 "/sapi/v4/sub-account/assets",
2146 reqwest::Method::GET,
2147 query_params,
2148 body_params,
2149 if HAS_TIME_UNIT {
2150 self.configuration.time_unit
2151 } else {
2152 None
2153 },
2154 true,
2155 )
2156 .await
2157 }
2158
2159 async fn query_sub_account_futures_asset_transfer_history(
2160 &self,
2161 params: QuerySubAccountFuturesAssetTransferHistoryParams,
2162 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountFuturesAssetTransferHistoryResponse>>
2163 {
2164 let QuerySubAccountFuturesAssetTransferHistoryParams {
2165 email,
2166 futures_type,
2167 start_time,
2168 end_time,
2169 page,
2170 limit,
2171 recv_window,
2172 } = params;
2173
2174 let mut query_params = BTreeMap::new();
2175 let body_params = BTreeMap::new();
2176
2177 query_params.insert("email".to_string(), json!(email));
2178
2179 query_params.insert("futuresType".to_string(), json!(futures_type));
2180
2181 if let Some(rw) = start_time {
2182 query_params.insert("startTime".to_string(), json!(rw));
2183 }
2184
2185 if let Some(rw) = end_time {
2186 query_params.insert("endTime".to_string(), json!(rw));
2187 }
2188
2189 if let Some(rw) = page {
2190 query_params.insert("page".to_string(), json!(rw));
2191 }
2192
2193 if let Some(rw) = limit {
2194 query_params.insert("limit".to_string(), json!(rw));
2195 }
2196
2197 if let Some(rw) = recv_window {
2198 query_params.insert("recvWindow".to_string(), json!(rw));
2199 }
2200
2201 send_request::<models::QuerySubAccountFuturesAssetTransferHistoryResponse>(
2202 &self.configuration,
2203 "/sapi/v1/sub-account/futures/internalTransfer",
2204 reqwest::Method::GET,
2205 query_params,
2206 body_params,
2207 if HAS_TIME_UNIT {
2208 self.configuration.time_unit
2209 } else {
2210 None
2211 },
2212 true,
2213 )
2214 .await
2215 }
2216
2217 async fn query_sub_account_spot_asset_transfer_history(
2218 &self,
2219 params: QuerySubAccountSpotAssetTransferHistoryParams,
2220 ) -> anyhow::Result<
2221 RestApiResponse<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>,
2222 > {
2223 let QuerySubAccountSpotAssetTransferHistoryParams {
2224 from_email,
2225 to_email,
2226 start_time,
2227 end_time,
2228 page,
2229 limit,
2230 recv_window,
2231 } = params;
2232
2233 let mut query_params = BTreeMap::new();
2234 let body_params = BTreeMap::new();
2235
2236 if let Some(rw) = from_email {
2237 query_params.insert("fromEmail".to_string(), json!(rw));
2238 }
2239
2240 if let Some(rw) = to_email {
2241 query_params.insert("toEmail".to_string(), json!(rw));
2242 }
2243
2244 if let Some(rw) = start_time {
2245 query_params.insert("startTime".to_string(), json!(rw));
2246 }
2247
2248 if let Some(rw) = end_time {
2249 query_params.insert("endTime".to_string(), json!(rw));
2250 }
2251
2252 if let Some(rw) = page {
2253 query_params.insert("page".to_string(), json!(rw));
2254 }
2255
2256 if let Some(rw) = limit {
2257 query_params.insert("limit".to_string(), json!(rw));
2258 }
2259
2260 if let Some(rw) = recv_window {
2261 query_params.insert("recvWindow".to_string(), json!(rw));
2262 }
2263
2264 send_request::<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>(
2265 &self.configuration,
2266 "/sapi/v1/sub-account/sub/transfer/history",
2267 reqwest::Method::GET,
2268 query_params,
2269 body_params,
2270 if HAS_TIME_UNIT {
2271 self.configuration.time_unit
2272 } else {
2273 None
2274 },
2275 true,
2276 )
2277 .await
2278 }
2279
2280 async fn query_sub_account_spot_assets_summary(
2281 &self,
2282 params: QuerySubAccountSpotAssetsSummaryParams,
2283 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountSpotAssetsSummaryResponse>> {
2284 let QuerySubAccountSpotAssetsSummaryParams {
2285 email,
2286 page,
2287 size,
2288 recv_window,
2289 } = params;
2290
2291 let mut query_params = BTreeMap::new();
2292 let body_params = BTreeMap::new();
2293
2294 if let Some(rw) = email {
2295 query_params.insert("email".to_string(), json!(rw));
2296 }
2297
2298 if let Some(rw) = page {
2299 query_params.insert("page".to_string(), json!(rw));
2300 }
2301
2302 if let Some(rw) = size {
2303 query_params.insert("size".to_string(), json!(rw));
2304 }
2305
2306 if let Some(rw) = recv_window {
2307 query_params.insert("recvWindow".to_string(), json!(rw));
2308 }
2309
2310 send_request::<models::QuerySubAccountSpotAssetsSummaryResponse>(
2311 &self.configuration,
2312 "/sapi/v1/sub-account/spotSummary",
2313 reqwest::Method::GET,
2314 query_params,
2315 body_params,
2316 if HAS_TIME_UNIT {
2317 self.configuration.time_unit
2318 } else {
2319 None
2320 },
2321 true,
2322 )
2323 .await
2324 }
2325
2326 async fn query_universal_transfer_history(
2327 &self,
2328 params: QueryUniversalTransferHistoryParams,
2329 ) -> anyhow::Result<RestApiResponse<models::QueryUniversalTransferHistoryResponse>> {
2330 let QueryUniversalTransferHistoryParams {
2331 from_email,
2332 to_email,
2333 client_tran_id,
2334 start_time,
2335 end_time,
2336 page,
2337 limit,
2338 recv_window,
2339 } = params;
2340
2341 let mut query_params = BTreeMap::new();
2342 let body_params = BTreeMap::new();
2343
2344 if let Some(rw) = from_email {
2345 query_params.insert("fromEmail".to_string(), json!(rw));
2346 }
2347
2348 if let Some(rw) = to_email {
2349 query_params.insert("toEmail".to_string(), json!(rw));
2350 }
2351
2352 if let Some(rw) = client_tran_id {
2353 query_params.insert("clientTranId".to_string(), json!(rw));
2354 }
2355
2356 if let Some(rw) = start_time {
2357 query_params.insert("startTime".to_string(), json!(rw));
2358 }
2359
2360 if let Some(rw) = end_time {
2361 query_params.insert("endTime".to_string(), json!(rw));
2362 }
2363
2364 if let Some(rw) = page {
2365 query_params.insert("page".to_string(), json!(rw));
2366 }
2367
2368 if let Some(rw) = limit {
2369 query_params.insert("limit".to_string(), json!(rw));
2370 }
2371
2372 if let Some(rw) = recv_window {
2373 query_params.insert("recvWindow".to_string(), json!(rw));
2374 }
2375
2376 send_request::<models::QueryUniversalTransferHistoryResponse>(
2377 &self.configuration,
2378 "/sapi/v1/sub-account/universalTransfer",
2379 reqwest::Method::GET,
2380 query_params,
2381 body_params,
2382 if HAS_TIME_UNIT {
2383 self.configuration.time_unit
2384 } else {
2385 None
2386 },
2387 true,
2388 )
2389 .await
2390 }
2391
2392 async fn sub_account_futures_asset_transfer(
2393 &self,
2394 params: SubAccountFuturesAssetTransferParams,
2395 ) -> anyhow::Result<RestApiResponse<models::SubAccountFuturesAssetTransferResponse>> {
2396 let SubAccountFuturesAssetTransferParams {
2397 from_email,
2398 to_email,
2399 futures_type,
2400 asset,
2401 amount,
2402 recv_window,
2403 } = params;
2404
2405 let mut query_params = BTreeMap::new();
2406 let body_params = BTreeMap::new();
2407
2408 query_params.insert("fromEmail".to_string(), json!(from_email));
2409
2410 query_params.insert("toEmail".to_string(), json!(to_email));
2411
2412 query_params.insert("futuresType".to_string(), json!(futures_type));
2413
2414 query_params.insert("asset".to_string(), json!(asset));
2415
2416 query_params.insert("amount".to_string(), json!(amount));
2417
2418 if let Some(rw) = recv_window {
2419 query_params.insert("recvWindow".to_string(), json!(rw));
2420 }
2421
2422 send_request::<models::SubAccountFuturesAssetTransferResponse>(
2423 &self.configuration,
2424 "/sapi/v1/sub-account/futures/internalTransfer",
2425 reqwest::Method::POST,
2426 query_params,
2427 body_params,
2428 if HAS_TIME_UNIT {
2429 self.configuration.time_unit
2430 } else {
2431 None
2432 },
2433 true,
2434 )
2435 .await
2436 }
2437
2438 async fn sub_account_transfer_history(
2439 &self,
2440 params: SubAccountTransferHistoryParams,
2441 ) -> anyhow::Result<RestApiResponse<Vec<models::SubAccountTransferHistoryResponseInner>>> {
2442 let SubAccountTransferHistoryParams {
2443 asset,
2444 r#type,
2445 start_time,
2446 end_time,
2447 limit,
2448 return_fail_history,
2449 recv_window,
2450 } = params;
2451
2452 let mut query_params = BTreeMap::new();
2453 let body_params = BTreeMap::new();
2454
2455 if let Some(rw) = asset {
2456 query_params.insert("asset".to_string(), json!(rw));
2457 }
2458
2459 if let Some(rw) = r#type {
2460 query_params.insert("type".to_string(), json!(rw));
2461 }
2462
2463 if let Some(rw) = start_time {
2464 query_params.insert("startTime".to_string(), json!(rw));
2465 }
2466
2467 if let Some(rw) = end_time {
2468 query_params.insert("endTime".to_string(), json!(rw));
2469 }
2470
2471 if let Some(rw) = limit {
2472 query_params.insert("limit".to_string(), json!(rw));
2473 }
2474
2475 if let Some(rw) = return_fail_history {
2476 query_params.insert("returnFailHistory".to_string(), json!(rw));
2477 }
2478
2479 if let Some(rw) = recv_window {
2480 query_params.insert("recvWindow".to_string(), json!(rw));
2481 }
2482
2483 send_request::<Vec<models::SubAccountTransferHistoryResponseInner>>(
2484 &self.configuration,
2485 "/sapi/v1/sub-account/transfer/subUserHistory",
2486 reqwest::Method::GET,
2487 query_params,
2488 body_params,
2489 if HAS_TIME_UNIT {
2490 self.configuration.time_unit
2491 } else {
2492 None
2493 },
2494 true,
2495 )
2496 .await
2497 }
2498
2499 async fn transfer_to_master(
2500 &self,
2501 params: TransferToMasterParams,
2502 ) -> anyhow::Result<RestApiResponse<models::TransferToMasterResponse>> {
2503 let TransferToMasterParams {
2504 asset,
2505 amount,
2506 recv_window,
2507 } = params;
2508
2509 let mut query_params = BTreeMap::new();
2510 let body_params = BTreeMap::new();
2511
2512 query_params.insert("asset".to_string(), json!(asset));
2513
2514 query_params.insert("amount".to_string(), json!(amount));
2515
2516 if let Some(rw) = recv_window {
2517 query_params.insert("recvWindow".to_string(), json!(rw));
2518 }
2519
2520 send_request::<models::TransferToMasterResponse>(
2521 &self.configuration,
2522 "/sapi/v1/sub-account/transfer/subToMaster",
2523 reqwest::Method::POST,
2524 query_params,
2525 body_params,
2526 if HAS_TIME_UNIT {
2527 self.configuration.time_unit
2528 } else {
2529 None
2530 },
2531 true,
2532 )
2533 .await
2534 }
2535
2536 async fn transfer_to_sub_account_of_same_master(
2537 &self,
2538 params: TransferToSubAccountOfSameMasterParams,
2539 ) -> anyhow::Result<RestApiResponse<models::TransferToSubAccountOfSameMasterResponse>> {
2540 let TransferToSubAccountOfSameMasterParams {
2541 to_email,
2542 asset,
2543 amount,
2544 recv_window,
2545 } = params;
2546
2547 let mut query_params = BTreeMap::new();
2548 let body_params = BTreeMap::new();
2549
2550 query_params.insert("toEmail".to_string(), json!(to_email));
2551
2552 query_params.insert("asset".to_string(), json!(asset));
2553
2554 query_params.insert("amount".to_string(), json!(amount));
2555
2556 if let Some(rw) = recv_window {
2557 query_params.insert("recvWindow".to_string(), json!(rw));
2558 }
2559
2560 send_request::<models::TransferToSubAccountOfSameMasterResponse>(
2561 &self.configuration,
2562 "/sapi/v1/sub-account/transfer/subToSub",
2563 reqwest::Method::POST,
2564 query_params,
2565 body_params,
2566 if HAS_TIME_UNIT {
2567 self.configuration.time_unit
2568 } else {
2569 None
2570 },
2571 true,
2572 )
2573 .await
2574 }
2575
2576 async fn universal_transfer(
2577 &self,
2578 params: UniversalTransferParams,
2579 ) -> anyhow::Result<RestApiResponse<models::UniversalTransferResponse>> {
2580 let UniversalTransferParams {
2581 from_account_type,
2582 to_account_type,
2583 asset,
2584 amount,
2585 from_email,
2586 to_email,
2587 client_tran_id,
2588 symbol,
2589 recv_window,
2590 } = params;
2591
2592 let mut query_params = BTreeMap::new();
2593 let body_params = BTreeMap::new();
2594
2595 if let Some(rw) = from_email {
2596 query_params.insert("fromEmail".to_string(), json!(rw));
2597 }
2598
2599 if let Some(rw) = to_email {
2600 query_params.insert("toEmail".to_string(), json!(rw));
2601 }
2602
2603 query_params.insert("fromAccountType".to_string(), json!(from_account_type));
2604
2605 query_params.insert("toAccountType".to_string(), json!(to_account_type));
2606
2607 if let Some(rw) = client_tran_id {
2608 query_params.insert("clientTranId".to_string(), json!(rw));
2609 }
2610
2611 if let Some(rw) = symbol {
2612 query_params.insert("symbol".to_string(), json!(rw));
2613 }
2614
2615 query_params.insert("asset".to_string(), json!(asset));
2616
2617 query_params.insert("amount".to_string(), json!(amount));
2618
2619 if let Some(rw) = recv_window {
2620 query_params.insert("recvWindow".to_string(), json!(rw));
2621 }
2622
2623 send_request::<models::UniversalTransferResponse>(
2624 &self.configuration,
2625 "/sapi/v1/sub-account/universalTransfer",
2626 reqwest::Method::POST,
2627 query_params,
2628 body_params,
2629 if HAS_TIME_UNIT {
2630 self.configuration.time_unit
2631 } else {
2632 None
2633 },
2634 true,
2635 )
2636 .await
2637 }
2638}
2639
2640#[cfg(all(test, feature = "sub_account"))]
2641mod tests {
2642 use super::*;
2643 use crate::TOKIO_SHARED_RT;
2644 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
2645 use async_trait::async_trait;
2646 use std::collections::HashMap;
2647
2648 struct DummyRestApiResponse<T> {
2649 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
2650 status: u16,
2651 headers: HashMap<String, String>,
2652 rate_limits: Option<Vec<RestApiRateLimit>>,
2653 }
2654
2655 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
2656 fn from(dummy: DummyRestApiResponse<T>) -> Self {
2657 Self {
2658 data_fn: dummy.inner,
2659 status: dummy.status,
2660 headers: dummy.headers,
2661 rate_limits: dummy.rate_limits,
2662 }
2663 }
2664 }
2665
2666 struct MockAssetManagementApiClient {
2667 force_error: bool,
2668 }
2669
2670 #[async_trait]
2671 impl AssetManagementApi for MockAssetManagementApiClient {
2672 async fn futures_transfer_for_sub_account(
2673 &self,
2674 _params: FuturesTransferForSubAccountParams,
2675 ) -> anyhow::Result<RestApiResponse<models::FuturesTransferForSubAccountResponse>> {
2676 if self.force_error {
2677 return Err(ConnectorError::ConnectorClientError {
2678 msg: "ResponseError".to_string(),
2679 code: None,
2680 }
2681 .into());
2682 }
2683
2684 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
2685 .unwrap_or_else(|_| serde_json::json!({}));
2686 let dummy_response: models::FuturesTransferForSubAccountResponse =
2687 serde_json::from_value(resp_json.clone())
2688 .expect("should parse into models::FuturesTransferForSubAccountResponse");
2689
2690 let dummy = DummyRestApiResponse {
2691 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2692 status: 200,
2693 headers: HashMap::new(),
2694 rate_limits: None,
2695 };
2696
2697 Ok(dummy.into())
2698 }
2699
2700 async fn get_detail_on_sub_accounts_futures_account(
2701 &self,
2702 _params: GetDetailOnSubAccountsFuturesAccountParams,
2703 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountResponse>>
2704 {
2705 if self.force_error {
2706 return Err(ConnectorError::ConnectorClientError {
2707 msg: "ResponseError".to_string(),
2708 code: None,
2709 }
2710 .into());
2711 }
2712
2713 let resp_json: Value = serde_json::from_str(r#"{"email":"abc@test.com","asset":"USDT","assets":[{"asset":"USDT","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"maxWithdrawAmount":"0.88308000","totalInitialMargin":"0.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"0.88308000","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"0.88308000","updateTime":1576756674610}"#).unwrap_or_else(|_| serde_json::json!({}));
2714 let dummy_response: models::GetDetailOnSubAccountsFuturesAccountResponse =
2715 serde_json::from_value(resp_json.clone()).expect(
2716 "should parse into models::GetDetailOnSubAccountsFuturesAccountResponse",
2717 );
2718
2719 let dummy = DummyRestApiResponse {
2720 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2721 status: 200,
2722 headers: HashMap::new(),
2723 rate_limits: None,
2724 };
2725
2726 Ok(dummy.into())
2727 }
2728
2729 async fn get_detail_on_sub_accounts_futures_account_v2(
2730 &self,
2731 _params: GetDetailOnSubAccountsFuturesAccountV2Params,
2732 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountV2Response>>
2733 {
2734 if self.force_error {
2735 return Err(ConnectorError::ConnectorClientError {
2736 msg: "ResponseError".to_string(),
2737 code: None,
2738 }
2739 .into());
2740 }
2741
2742 let resp_json: Value = serde_json::from_str(r#"{"futureAccountResp":{"email":"abc@test.com","assets":[{"asset":"USDT","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"maxWithdrawAmount":"0.88308000","totalInitialMargin":"0.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"0.88308000","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"0.88308000","updateTime":1576756674610},"deliveryAccountResp":{"email":"abc@test.com","assets":[{"asset":"BTC","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"updateTime":1598959682001}}"#).unwrap_or_else(|_| serde_json::json!({}));
2743 let dummy_response: models::GetDetailOnSubAccountsFuturesAccountV2Response =
2744 serde_json::from_value(resp_json.clone()).expect(
2745 "should parse into models::GetDetailOnSubAccountsFuturesAccountV2Response",
2746 );
2747
2748 let dummy = DummyRestApiResponse {
2749 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2750 status: 200,
2751 headers: HashMap::new(),
2752 rate_limits: None,
2753 };
2754
2755 Ok(dummy.into())
2756 }
2757
2758 async fn get_detail_on_sub_accounts_margin_account(
2759 &self,
2760 _params: GetDetailOnSubAccountsMarginAccountParams,
2761 ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsMarginAccountResponse>>
2762 {
2763 if self.force_error {
2764 return Err(ConnectorError::ConnectorClientError {
2765 msg: "ResponseError".to_string(),
2766 code: None,
2767 }
2768 .into());
2769 }
2770
2771 let resp_json: Value = serde_json::from_str(r#"{"email":"123@test.com","marginLevel":"11.64405625","totalAssetOfBtc":"6.82728457","totalLiabilityOfBtc":"0.58633215","totalNetAssetOfBtc":"6.24095242","marginTradeCoeffVo":{"forceLiquidationBar":"1.10000000","marginCallBar":"1.50000000","normalBar":"2.00000000"},"marginUserAssetVoList":[{"asset":"BTC","borrowed":"0.00000000","free":"0.00499500","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00499500"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2772 let dummy_response: models::GetDetailOnSubAccountsMarginAccountResponse =
2773 serde_json::from_value(resp_json.clone()).expect(
2774 "should parse into models::GetDetailOnSubAccountsMarginAccountResponse",
2775 );
2776
2777 let dummy = DummyRestApiResponse {
2778 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2779 status: 200,
2780 headers: HashMap::new(),
2781 rate_limits: None,
2782 };
2783
2784 Ok(dummy.into())
2785 }
2786
2787 async fn get_move_position_history_for_sub_account(
2788 &self,
2789 _params: GetMovePositionHistoryForSubAccountParams,
2790 ) -> anyhow::Result<RestApiResponse<models::GetMovePositionHistoryForSubAccountResponse>>
2791 {
2792 if self.force_error {
2793 return Err(ConnectorError::ConnectorClientError {
2794 msg: "ResponseError".to_string(),
2795 code: None,
2796 }
2797 .into());
2798 }
2799
2800 let resp_json: Value = serde_json::from_str(r#"{"total":3,"futureMovePositionOrderVoList":[{"fromUserEmail":"testFrom@google.com","toUserEmail":"testTo@google.com","productType":"UM","symbol":"BTCUSDT","price":"105025.50981609","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1737544712000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2801 let dummy_response: models::GetMovePositionHistoryForSubAccountResponse =
2802 serde_json::from_value(resp_json.clone()).expect(
2803 "should parse into models::GetMovePositionHistoryForSubAccountResponse",
2804 );
2805
2806 let dummy = DummyRestApiResponse {
2807 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2808 status: 200,
2809 headers: HashMap::new(),
2810 rate_limits: None,
2811 };
2812
2813 Ok(dummy.into())
2814 }
2815
2816 async fn get_sub_account_deposit_address(
2817 &self,
2818 _params: GetSubAccountDepositAddressParams,
2819 ) -> anyhow::Result<RestApiResponse<models::GetSubAccountDepositAddressResponse>> {
2820 if self.force_error {
2821 return Err(ConnectorError::ConnectorClientError {
2822 msg: "ResponseError".to_string(),
2823 code: None,
2824 }
2825 .into());
2826 }
2827
2828 let resp_json: Value = serde_json::from_str(r#"{"address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV","coin":"USDT","tag":"","url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV"}"#).unwrap_or_else(|_| serde_json::json!({}));
2829 let dummy_response: models::GetSubAccountDepositAddressResponse =
2830 serde_json::from_value(resp_json.clone())
2831 .expect("should parse into models::GetSubAccountDepositAddressResponse");
2832
2833 let dummy = DummyRestApiResponse {
2834 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2835 status: 200,
2836 headers: HashMap::new(),
2837 rate_limits: None,
2838 };
2839
2840 Ok(dummy.into())
2841 }
2842
2843 async fn get_sub_account_deposit_history(
2844 &self,
2845 _params: GetSubAccountDepositHistoryParams,
2846 ) -> anyhow::Result<RestApiResponse<Vec<models::GetSubAccountDepositHistoryResponseInner>>>
2847 {
2848 if self.force_error {
2849 return Err(ConnectorError::ConnectorClientError {
2850 msg: "ResponseError".to_string(),
2851 code: None,
2852 }
2853 .into());
2854 }
2855
2856 let resp_json: Value = serde_json::from_str(r#"[{"id":"769800519366885376","amount":"0.001","coin":"BNB","network":"BNB","status":0,"address":"bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23","addressTag":"101764890","txId":"98A3EA560C6B3336D348B6C83F0F95ECE4F1F5919E94BD006E5BF3BF264FACFC","insertTime":1661493146000,"transferType":0,"confirmTimes":"1/1","unlockConfirm":0,"walletType":0}]"#).unwrap_or_else(|_| serde_json::json!({}));
2857 let dummy_response: Vec<models::GetSubAccountDepositHistoryResponseInner> =
2858 serde_json::from_value(resp_json.clone()).expect(
2859 "should parse into Vec<models::GetSubAccountDepositHistoryResponseInner>",
2860 );
2861
2862 let dummy = DummyRestApiResponse {
2863 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2864 status: 200,
2865 headers: HashMap::new(),
2866 rate_limits: None,
2867 };
2868
2869 Ok(dummy.into())
2870 }
2871
2872 async fn get_summary_of_sub_accounts_futures_account(
2873 &self,
2874 _params: GetSummaryOfSubAccountsFuturesAccountParams,
2875 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountResponse>>
2876 {
2877 if self.force_error {
2878 return Err(ConnectorError::ConnectorClientError {
2879 msg: "ResponseError".to_string(),
2880 code: None,
2881 }
2882 .into());
2883 }
2884
2885 let resp_json: Value = serde_json::from_str(r#"{"totalInitialMargin":"9.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"23.03235621","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"22.15879444","asset":"USD","subAccountList":[{"email":"123@test.com","totalInitialMargin":"9.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"22.12659734","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"USD"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2886 let dummy_response: models::GetSummaryOfSubAccountsFuturesAccountResponse =
2887 serde_json::from_value(resp_json.clone()).expect(
2888 "should parse into models::GetSummaryOfSubAccountsFuturesAccountResponse",
2889 );
2890
2891 let dummy = DummyRestApiResponse {
2892 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2893 status: 200,
2894 headers: HashMap::new(),
2895 rate_limits: None,
2896 };
2897
2898 Ok(dummy.into())
2899 }
2900
2901 async fn get_summary_of_sub_accounts_futures_account_v2(
2902 &self,
2903 _params: GetSummaryOfSubAccountsFuturesAccountV2Params,
2904 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountV2Response>>
2905 {
2906 if self.force_error {
2907 return Err(ConnectorError::ConnectorClientError {
2908 msg: "ResponseError".to_string(),
2909 code: None,
2910 }
2911 .into());
2912 }
2913
2914 let resp_json: Value = serde_json::from_str(r#"{"futureAccountSummaryResp":{"totalInitialMargin":"9.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"23.03235621","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"22.15879444","asset":"USD","subAccountList":[{"email":"123@test.com","totalInitialMargin":"9.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"22.12659734","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"USD"}]},"deliveryAccountSummaryResp":{"totalMarginBalanceOfBTC":"25.03221121","totalUnrealizedProfitOfBTC":"0.12233410","totalWalletBalanceOfBTC":"22.15879444","asset":"BTC","subAccountList":[{"email":"123@test.com","totalMarginBalance":"22.12659734","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"BTC"}]}}"#).unwrap_or_else(|_| serde_json::json!({}));
2915 let dummy_response: models::GetSummaryOfSubAccountsFuturesAccountV2Response =
2916 serde_json::from_value(resp_json.clone()).expect(
2917 "should parse into models::GetSummaryOfSubAccountsFuturesAccountV2Response",
2918 );
2919
2920 let dummy = DummyRestApiResponse {
2921 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2922 status: 200,
2923 headers: HashMap::new(),
2924 rate_limits: None,
2925 };
2926
2927 Ok(dummy.into())
2928 }
2929
2930 async fn get_summary_of_sub_accounts_margin_account(
2931 &self,
2932 _params: GetSummaryOfSubAccountsMarginAccountParams,
2933 ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsMarginAccountResponse>>
2934 {
2935 if self.force_error {
2936 return Err(ConnectorError::ConnectorClientError {
2937 msg: "ResponseError".to_string(),
2938 code: None,
2939 }
2940 .into());
2941 }
2942
2943 let resp_json: Value = serde_json::from_str(r#"{"totalAssetOfBtc":"4.33333333","totalLiabilityOfBtc":"2.11111112","totalNetAssetOfBtc":"2.22222221","subAccountList":[{"email":"123@test.com","totalAssetOfBtc":"2.11111111","totalLiabilityOfBtc":"1.11111111","totalNetAssetOfBtc":"1.00000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2944 let dummy_response: models::GetSummaryOfSubAccountsMarginAccountResponse =
2945 serde_json::from_value(resp_json.clone()).expect(
2946 "should parse into models::GetSummaryOfSubAccountsMarginAccountResponse",
2947 );
2948
2949 let dummy = DummyRestApiResponse {
2950 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2951 status: 200,
2952 headers: HashMap::new(),
2953 rate_limits: None,
2954 };
2955
2956 Ok(dummy.into())
2957 }
2958
2959 async fn margin_transfer_for_sub_account(
2960 &self,
2961 _params: MarginTransferForSubAccountParams,
2962 ) -> anyhow::Result<RestApiResponse<models::MarginTransferForSubAccountResponse>> {
2963 if self.force_error {
2964 return Err(ConnectorError::ConnectorClientError {
2965 msg: "ResponseError".to_string(),
2966 code: None,
2967 }
2968 .into());
2969 }
2970
2971 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
2972 .unwrap_or_else(|_| serde_json::json!({}));
2973 let dummy_response: models::MarginTransferForSubAccountResponse =
2974 serde_json::from_value(resp_json.clone())
2975 .expect("should parse into models::MarginTransferForSubAccountResponse");
2976
2977 let dummy = DummyRestApiResponse {
2978 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2979 status: 200,
2980 headers: HashMap::new(),
2981 rate_limits: None,
2982 };
2983
2984 Ok(dummy.into())
2985 }
2986
2987 async fn move_position_for_sub_account(
2988 &self,
2989 _params: MovePositionForSubAccountParams,
2990 ) -> anyhow::Result<RestApiResponse<models::MovePositionForSubAccountResponse>> {
2991 if self.force_error {
2992 return Err(ConnectorError::ConnectorClientError {
2993 msg: "ResponseError".to_string(),
2994 code: None,
2995 }
2996 .into());
2997 }
2998
2999 let resp_json: Value = serde_json::from_str(r#"{"movePositionOrders":[{"fromUserEmail":"testFrom@google.com","toUserEmail":"testTo@google.com","productType":"UM","symbol":"BTCUSDT","priceType":"MARK_PRICE","price":"97139.00000000","quantity":"0.001","positionSide":"BOTH","side":"BUY","success":true}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3000 let dummy_response: models::MovePositionForSubAccountResponse =
3001 serde_json::from_value(resp_json.clone())
3002 .expect("should parse into models::MovePositionForSubAccountResponse");
3003
3004 let dummy = DummyRestApiResponse {
3005 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3006 status: 200,
3007 headers: HashMap::new(),
3008 rate_limits: None,
3009 };
3010
3011 Ok(dummy.into())
3012 }
3013
3014 async fn query_sub_account_assets(
3015 &self,
3016 _params: QuerySubAccountAssetsParams,
3017 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsResponse>> {
3018 if self.force_error {
3019 return Err(ConnectorError::ConnectorClientError {
3020 msg: "ResponseError".to_string(),
3021 code: None,
3022 }
3023 .into());
3024 }
3025
3026 let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":0,"withdrawing":0,"asset":"ADA","free":11467.6399,"locked":0}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3027 let dummy_response: models::QuerySubAccountAssetsResponse =
3028 serde_json::from_value(resp_json.clone())
3029 .expect("should parse into models::QuerySubAccountAssetsResponse");
3030
3031 let dummy = DummyRestApiResponse {
3032 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3033 status: 200,
3034 headers: HashMap::new(),
3035 rate_limits: None,
3036 };
3037
3038 Ok(dummy.into())
3039 }
3040
3041 async fn query_sub_account_assets_asset_management(
3042 &self,
3043 _params: QuerySubAccountAssetsAssetManagementParams,
3044 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsAssetManagementResponse>>
3045 {
3046 if self.force_error {
3047 return Err(ConnectorError::ConnectorClientError {
3048 msg: "ResponseError".to_string(),
3049 code: None,
3050 }
3051 .into());
3052 }
3053
3054 let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":"0","withdrawing":"0","asset":"ADA","free":"10000","locked":"0"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3055 let dummy_response: models::QuerySubAccountAssetsAssetManagementResponse =
3056 serde_json::from_value(resp_json.clone()).expect(
3057 "should parse into models::QuerySubAccountAssetsAssetManagementResponse",
3058 );
3059
3060 let dummy = DummyRestApiResponse {
3061 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3062 status: 200,
3063 headers: HashMap::new(),
3064 rate_limits: None,
3065 };
3066
3067 Ok(dummy.into())
3068 }
3069
3070 async fn query_sub_account_futures_asset_transfer_history(
3071 &self,
3072 _params: QuerySubAccountFuturesAssetTransferHistoryParams,
3073 ) -> anyhow::Result<
3074 RestApiResponse<models::QuerySubAccountFuturesAssetTransferHistoryResponse>,
3075 > {
3076 if self.force_error {
3077 return Err(ConnectorError::ConnectorClientError {
3078 msg: "ResponseError".to_string(),
3079 code: None,
3080 }
3081 .into());
3082 }
3083
3084 let resp_json: Value = serde_json::from_str(r#"{"success":true,"futuresType":2,"transfers":[{"from":"aaa@test.com","to":"bbb@test.com","asset":"BTC","qty":"1","tranId":11897001102,"time":1544433328000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3085 let dummy_response: models::QuerySubAccountFuturesAssetTransferHistoryResponse =
3086 serde_json::from_value(resp_json.clone()).expect(
3087 "should parse into models::QuerySubAccountFuturesAssetTransferHistoryResponse",
3088 );
3089
3090 let dummy = DummyRestApiResponse {
3091 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3092 status: 200,
3093 headers: HashMap::new(),
3094 rate_limits: None,
3095 };
3096
3097 Ok(dummy.into())
3098 }
3099
3100 async fn query_sub_account_spot_asset_transfer_history(
3101 &self,
3102 _params: QuerySubAccountSpotAssetTransferHistoryParams,
3103 ) -> anyhow::Result<
3104 RestApiResponse<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>,
3105 > {
3106 if self.force_error {
3107 return Err(ConnectorError::ConnectorClientError {
3108 msg: "ResponseError".to_string(),
3109 code: None,
3110 }
3111 .into());
3112 }
3113
3114 let resp_json: Value = serde_json::from_str(r#"[{"from":"aaa@test.com","to":"bbb@test.com","asset":"BTC","qty":"10","status":"SUCCESS","tranId":6489943656,"time":1544433328000}]"#).unwrap_or_else(|_| serde_json::json!({}));
3115 let dummy_response : Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>");
3116
3117 let dummy = DummyRestApiResponse {
3118 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3119 status: 200,
3120 headers: HashMap::new(),
3121 rate_limits: None,
3122 };
3123
3124 Ok(dummy.into())
3125 }
3126
3127 async fn query_sub_account_spot_assets_summary(
3128 &self,
3129 _params: QuerySubAccountSpotAssetsSummaryParams,
3130 ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountSpotAssetsSummaryResponse>>
3131 {
3132 if self.force_error {
3133 return Err(ConnectorError::ConnectorClientError {
3134 msg: "ResponseError".to_string(),
3135 code: None,
3136 }
3137 .into());
3138 }
3139
3140 let resp_json: Value = serde_json::from_str(r#"{"totalCount":2,"masterAccountTotalAsset":"0.23231201","spotSubUserAssetBtcVoList":[{"email":"sub123@test.com","totalAsset":"9999.00000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3141 let dummy_response: models::QuerySubAccountSpotAssetsSummaryResponse =
3142 serde_json::from_value(resp_json.clone())
3143 .expect("should parse into models::QuerySubAccountSpotAssetsSummaryResponse");
3144
3145 let dummy = DummyRestApiResponse {
3146 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3147 status: 200,
3148 headers: HashMap::new(),
3149 rate_limits: None,
3150 };
3151
3152 Ok(dummy.into())
3153 }
3154
3155 async fn query_universal_transfer_history(
3156 &self,
3157 _params: QueryUniversalTransferHistoryParams,
3158 ) -> anyhow::Result<RestApiResponse<models::QueryUniversalTransferHistoryResponse>>
3159 {
3160 if self.force_error {
3161 return Err(ConnectorError::ConnectorClientError {
3162 msg: "ResponseError".to_string(),
3163 code: None,
3164 }
3165 .into());
3166 }
3167
3168 let resp_json: Value = serde_json::from_str(r#"{"result":[{"tranId":92275823339,"fromEmail":"abctest@gmail.com","toEmail":"deftest@gmail.com","asset":"BNB","amount":"0.01","createTimeStamp":1640317374000,"fromAccountType":"USDT_FUTURE","toAccountType":"SPOT","status":"SUCCESS","clientTranId":"test"}],"totalCount":1}"#).unwrap_or_else(|_| serde_json::json!({}));
3169 let dummy_response: models::QueryUniversalTransferHistoryResponse =
3170 serde_json::from_value(resp_json.clone())
3171 .expect("should parse into models::QueryUniversalTransferHistoryResponse");
3172
3173 let dummy = DummyRestApiResponse {
3174 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3175 status: 200,
3176 headers: HashMap::new(),
3177 rate_limits: None,
3178 };
3179
3180 Ok(dummy.into())
3181 }
3182
3183 async fn sub_account_futures_asset_transfer(
3184 &self,
3185 _params: SubAccountFuturesAssetTransferParams,
3186 ) -> anyhow::Result<RestApiResponse<models::SubAccountFuturesAssetTransferResponse>>
3187 {
3188 if self.force_error {
3189 return Err(ConnectorError::ConnectorClientError {
3190 msg: "ResponseError".to_string(),
3191 code: None,
3192 }
3193 .into());
3194 }
3195
3196 let resp_json: Value = serde_json::from_str(r#"{"success":true,"txnId":"2934662589"}"#)
3197 .unwrap_or_else(|_| serde_json::json!({}));
3198 let dummy_response: models::SubAccountFuturesAssetTransferResponse =
3199 serde_json::from_value(resp_json.clone())
3200 .expect("should parse into models::SubAccountFuturesAssetTransferResponse");
3201
3202 let dummy = DummyRestApiResponse {
3203 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3204 status: 200,
3205 headers: HashMap::new(),
3206 rate_limits: None,
3207 };
3208
3209 Ok(dummy.into())
3210 }
3211
3212 async fn sub_account_transfer_history(
3213 &self,
3214 _params: SubAccountTransferHistoryParams,
3215 ) -> anyhow::Result<RestApiResponse<Vec<models::SubAccountTransferHistoryResponseInner>>>
3216 {
3217 if self.force_error {
3218 return Err(ConnectorError::ConnectorClientError {
3219 msg: "ResponseError".to_string(),
3220 code: None,
3221 }
3222 .into());
3223 }
3224
3225 let resp_json: Value = serde_json::from_str(r#"[{"counterParty":"master","email":"master@test.com","type":1,"asset":"BTC","qty":"1","fromAccountType":"SPOT","toAccountType":"SPOT","status":"SUCCESS","tranId":11798835829,"time":1544433325000}]"#).unwrap_or_else(|_| serde_json::json!({}));
3226 let dummy_response: Vec<models::SubAccountTransferHistoryResponseInner> =
3227 serde_json::from_value(resp_json.clone()).expect(
3228 "should parse into Vec<models::SubAccountTransferHistoryResponseInner>",
3229 );
3230
3231 let dummy = DummyRestApiResponse {
3232 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3233 status: 200,
3234 headers: HashMap::new(),
3235 rate_limits: None,
3236 };
3237
3238 Ok(dummy.into())
3239 }
3240
3241 async fn transfer_to_master(
3242 &self,
3243 _params: TransferToMasterParams,
3244 ) -> anyhow::Result<RestApiResponse<models::TransferToMasterResponse>> {
3245 if self.force_error {
3246 return Err(ConnectorError::ConnectorClientError {
3247 msg: "ResponseError".to_string(),
3248 code: None,
3249 }
3250 .into());
3251 }
3252
3253 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
3254 .unwrap_or_else(|_| serde_json::json!({}));
3255 let dummy_response: models::TransferToMasterResponse =
3256 serde_json::from_value(resp_json.clone())
3257 .expect("should parse into models::TransferToMasterResponse");
3258
3259 let dummy = DummyRestApiResponse {
3260 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3261 status: 200,
3262 headers: HashMap::new(),
3263 rate_limits: None,
3264 };
3265
3266 Ok(dummy.into())
3267 }
3268
3269 async fn transfer_to_sub_account_of_same_master(
3270 &self,
3271 _params: TransferToSubAccountOfSameMasterParams,
3272 ) -> anyhow::Result<RestApiResponse<models::TransferToSubAccountOfSameMasterResponse>>
3273 {
3274 if self.force_error {
3275 return Err(ConnectorError::ConnectorClientError {
3276 msg: "ResponseError".to_string(),
3277 code: None,
3278 }
3279 .into());
3280 }
3281
3282 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
3283 .unwrap_or_else(|_| serde_json::json!({}));
3284 let dummy_response: models::TransferToSubAccountOfSameMasterResponse =
3285 serde_json::from_value(resp_json.clone())
3286 .expect("should parse into models::TransferToSubAccountOfSameMasterResponse");
3287
3288 let dummy = DummyRestApiResponse {
3289 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3290 status: 200,
3291 headers: HashMap::new(),
3292 rate_limits: None,
3293 };
3294
3295 Ok(dummy.into())
3296 }
3297
3298 async fn universal_transfer(
3299 &self,
3300 _params: UniversalTransferParams,
3301 ) -> anyhow::Result<RestApiResponse<models::UniversalTransferResponse>> {
3302 if self.force_error {
3303 return Err(ConnectorError::ConnectorClientError {
3304 msg: "ResponseError".to_string(),
3305 code: None,
3306 }
3307 .into());
3308 }
3309
3310 let resp_json: Value =
3311 serde_json::from_str(r#"{"tranId":11945860693,"clientTranId":"test"}"#)
3312 .unwrap_or_else(|_| serde_json::json!({}));
3313 let dummy_response: models::UniversalTransferResponse =
3314 serde_json::from_value(resp_json.clone())
3315 .expect("should parse into models::UniversalTransferResponse");
3316
3317 let dummy = DummyRestApiResponse {
3318 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3319 status: 200,
3320 headers: HashMap::new(),
3321 rate_limits: None,
3322 };
3323
3324 Ok(dummy.into())
3325 }
3326 }
3327
3328 #[test]
3329 fn futures_transfer_for_sub_account_required_params_success() {
3330 TOKIO_SHARED_RT.block_on(async {
3331 let client = MockAssetManagementApiClient { force_error: false };
3332
3333 let params = FuturesTransferForSubAccountParams::builder(
3334 "123@test.com".to_string(),
3335 "USDT".to_string(),
3336 dec!(1.0),
3337 1,
3338 )
3339 .build()
3340 .unwrap();
3341
3342 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
3343 .unwrap_or_else(|_| serde_json::json!({}));
3344 let expected_response: models::FuturesTransferForSubAccountResponse =
3345 serde_json::from_value(resp_json.clone())
3346 .expect("should parse into models::FuturesTransferForSubAccountResponse");
3347
3348 let resp = client
3349 .futures_transfer_for_sub_account(params)
3350 .await
3351 .expect("Expected a response");
3352 let data_future = resp.data();
3353 let actual_response = data_future.await.unwrap();
3354 assert_eq!(actual_response, expected_response);
3355 });
3356 }
3357
3358 #[test]
3359 fn futures_transfer_for_sub_account_optional_params_success() {
3360 TOKIO_SHARED_RT.block_on(async {
3361 let client = MockAssetManagementApiClient { force_error: false };
3362
3363 let params = FuturesTransferForSubAccountParams::builder(
3364 "123@test.com".to_string(),
3365 "USDT".to_string(),
3366 dec!(1.0),
3367 1,
3368 )
3369 .recv_window(5000)
3370 .build()
3371 .unwrap();
3372
3373 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
3374 .unwrap_or_else(|_| serde_json::json!({}));
3375 let expected_response: models::FuturesTransferForSubAccountResponse =
3376 serde_json::from_value(resp_json.clone())
3377 .expect("should parse into models::FuturesTransferForSubAccountResponse");
3378
3379 let resp = client
3380 .futures_transfer_for_sub_account(params)
3381 .await
3382 .expect("Expected a response");
3383 let data_future = resp.data();
3384 let actual_response = data_future.await.unwrap();
3385 assert_eq!(actual_response, expected_response);
3386 });
3387 }
3388
3389 #[test]
3390 fn futures_transfer_for_sub_account_response_error() {
3391 TOKIO_SHARED_RT.block_on(async {
3392 let client = MockAssetManagementApiClient { force_error: true };
3393
3394 let params = FuturesTransferForSubAccountParams::builder(
3395 "123@test.com".to_string(),
3396 "USDT".to_string(),
3397 dec!(1.0),
3398 1,
3399 )
3400 .build()
3401 .unwrap();
3402
3403 match client.futures_transfer_for_sub_account(params).await {
3404 Ok(_) => panic!("Expected an error"),
3405 Err(err) => {
3406 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3407 }
3408 }
3409 });
3410 }
3411
3412 #[test]
3413 fn get_detail_on_sub_accounts_futures_account_required_params_success() {
3414 TOKIO_SHARED_RT.block_on(async {
3415 let client = MockAssetManagementApiClient { force_error: false };
3416
3417 let params = GetDetailOnSubAccountsFuturesAccountParams::builder("123@test.com".to_string(),).build().unwrap();
3418
3419 let resp_json: Value = serde_json::from_str(r#"{"email":"abc@test.com","asset":"USDT","assets":[{"asset":"USDT","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"maxWithdrawAmount":"0.88308000","totalInitialMargin":"0.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"0.88308000","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"0.88308000","updateTime":1576756674610}"#).unwrap_or_else(|_| serde_json::json!({}));
3420 let expected_response : models::GetDetailOnSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountResponse");
3421
3422 let resp = client.get_detail_on_sub_accounts_futures_account(params).await.expect("Expected a response");
3423 let data_future = resp.data();
3424 let actual_response = data_future.await.unwrap();
3425 assert_eq!(actual_response, expected_response);
3426 });
3427 }
3428
3429 #[test]
3430 fn get_detail_on_sub_accounts_futures_account_optional_params_success() {
3431 TOKIO_SHARED_RT.block_on(async {
3432 let client = MockAssetManagementApiClient { force_error: false };
3433
3434 let params = GetDetailOnSubAccountsFuturesAccountParams::builder("123@test.com".to_string(),).recv_window(5000).build().unwrap();
3435
3436 let resp_json: Value = serde_json::from_str(r#"{"email":"abc@test.com","asset":"USDT","assets":[{"asset":"USDT","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"maxWithdrawAmount":"0.88308000","totalInitialMargin":"0.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"0.88308000","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"0.88308000","updateTime":1576756674610}"#).unwrap_or_else(|_| serde_json::json!({}));
3437 let expected_response : models::GetDetailOnSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountResponse");
3438
3439 let resp = client.get_detail_on_sub_accounts_futures_account(params).await.expect("Expected a response");
3440 let data_future = resp.data();
3441 let actual_response = data_future.await.unwrap();
3442 assert_eq!(actual_response, expected_response);
3443 });
3444 }
3445
3446 #[test]
3447 fn get_detail_on_sub_accounts_futures_account_response_error() {
3448 TOKIO_SHARED_RT.block_on(async {
3449 let client = MockAssetManagementApiClient { force_error: true };
3450
3451 let params =
3452 GetDetailOnSubAccountsFuturesAccountParams::builder("123@test.com".to_string())
3453 .build()
3454 .unwrap();
3455
3456 match client
3457 .get_detail_on_sub_accounts_futures_account(params)
3458 .await
3459 {
3460 Ok(_) => panic!("Expected an error"),
3461 Err(err) => {
3462 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3463 }
3464 }
3465 });
3466 }
3467
3468 #[test]
3469 fn get_detail_on_sub_accounts_futures_account_v2_required_params_success() {
3470 TOKIO_SHARED_RT.block_on(async {
3471 let client = MockAssetManagementApiClient { force_error: false };
3472
3473 let params = GetDetailOnSubAccountsFuturesAccountV2Params::builder("123@test.com".to_string(),1,).build().unwrap();
3474
3475 let resp_json: Value = serde_json::from_str(r#"{"futureAccountResp":{"email":"abc@test.com","assets":[{"asset":"USDT","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"maxWithdrawAmount":"0.88308000","totalInitialMargin":"0.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"0.88308000","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"0.88308000","updateTime":1576756674610},"deliveryAccountResp":{"email":"abc@test.com","assets":[{"asset":"BTC","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"updateTime":1598959682001}}"#).unwrap_or_else(|_| serde_json::json!({}));
3476 let expected_response : models::GetDetailOnSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountV2Response");
3477
3478 let resp = client.get_detail_on_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3479 let data_future = resp.data();
3480 let actual_response = data_future.await.unwrap();
3481 assert_eq!(actual_response, expected_response);
3482 });
3483 }
3484
3485 #[test]
3486 fn get_detail_on_sub_accounts_futures_account_v2_optional_params_success() {
3487 TOKIO_SHARED_RT.block_on(async {
3488 let client = MockAssetManagementApiClient { force_error: false };
3489
3490 let params = GetDetailOnSubAccountsFuturesAccountV2Params::builder("123@test.com".to_string(),1,).recv_window(5000).build().unwrap();
3491
3492 let resp_json: Value = serde_json::from_str(r#"{"futureAccountResp":{"email":"abc@test.com","assets":[{"asset":"USDT","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"maxWithdrawAmount":"0.88308000","totalInitialMargin":"0.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"0.88308000","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"0.88308000","updateTime":1576756674610},"deliveryAccountResp":{"email":"abc@test.com","assets":[{"asset":"BTC","initialMargin":"0.00000000","maintenanceMargin":"0.00000000","marginBalance":"0.88308000","maxWithdrawAmount":"0.88308000","openOrderInitialMargin":"0.00000000","positionInitialMargin":"0.00000000","unrealizedProfit":"0.00000000","walletBalance":"0.88308000"}],"canDeposit":true,"canTrade":true,"canWithdraw":true,"feeTier":2,"updateTime":1598959682001}}"#).unwrap_or_else(|_| serde_json::json!({}));
3493 let expected_response : models::GetDetailOnSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountV2Response");
3494
3495 let resp = client.get_detail_on_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3496 let data_future = resp.data();
3497 let actual_response = data_future.await.unwrap();
3498 assert_eq!(actual_response, expected_response);
3499 });
3500 }
3501
3502 #[test]
3503 fn get_detail_on_sub_accounts_futures_account_v2_response_error() {
3504 TOKIO_SHARED_RT.block_on(async {
3505 let client = MockAssetManagementApiClient { force_error: true };
3506
3507 let params = GetDetailOnSubAccountsFuturesAccountV2Params::builder(
3508 "123@test.com".to_string(),
3509 1,
3510 )
3511 .build()
3512 .unwrap();
3513
3514 match client
3515 .get_detail_on_sub_accounts_futures_account_v2(params)
3516 .await
3517 {
3518 Ok(_) => panic!("Expected an error"),
3519 Err(err) => {
3520 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3521 }
3522 }
3523 });
3524 }
3525
3526 #[test]
3527 fn get_detail_on_sub_accounts_margin_account_required_params_success() {
3528 TOKIO_SHARED_RT.block_on(async {
3529 let client = MockAssetManagementApiClient { force_error: false };
3530
3531 let params = GetDetailOnSubAccountsMarginAccountParams::builder("123@test.com".to_string(),).build().unwrap();
3532
3533 let resp_json: Value = serde_json::from_str(r#"{"email":"123@test.com","marginLevel":"11.64405625","totalAssetOfBtc":"6.82728457","totalLiabilityOfBtc":"0.58633215","totalNetAssetOfBtc":"6.24095242","marginTradeCoeffVo":{"forceLiquidationBar":"1.10000000","marginCallBar":"1.50000000","normalBar":"2.00000000"},"marginUserAssetVoList":[{"asset":"BTC","borrowed":"0.00000000","free":"0.00499500","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00499500"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3534 let expected_response : models::GetDetailOnSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsMarginAccountResponse");
3535
3536 let resp = client.get_detail_on_sub_accounts_margin_account(params).await.expect("Expected a response");
3537 let data_future = resp.data();
3538 let actual_response = data_future.await.unwrap();
3539 assert_eq!(actual_response, expected_response);
3540 });
3541 }
3542
3543 #[test]
3544 fn get_detail_on_sub_accounts_margin_account_optional_params_success() {
3545 TOKIO_SHARED_RT.block_on(async {
3546 let client = MockAssetManagementApiClient { force_error: false };
3547
3548 let params = GetDetailOnSubAccountsMarginAccountParams::builder("123@test.com".to_string(),).recv_window(5000).build().unwrap();
3549
3550 let resp_json: Value = serde_json::from_str(r#"{"email":"123@test.com","marginLevel":"11.64405625","totalAssetOfBtc":"6.82728457","totalLiabilityOfBtc":"0.58633215","totalNetAssetOfBtc":"6.24095242","marginTradeCoeffVo":{"forceLiquidationBar":"1.10000000","marginCallBar":"1.50000000","normalBar":"2.00000000"},"marginUserAssetVoList":[{"asset":"BTC","borrowed":"0.00000000","free":"0.00499500","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00499500"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3551 let expected_response : models::GetDetailOnSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsMarginAccountResponse");
3552
3553 let resp = client.get_detail_on_sub_accounts_margin_account(params).await.expect("Expected a response");
3554 let data_future = resp.data();
3555 let actual_response = data_future.await.unwrap();
3556 assert_eq!(actual_response, expected_response);
3557 });
3558 }
3559
3560 #[test]
3561 fn get_detail_on_sub_accounts_margin_account_response_error() {
3562 TOKIO_SHARED_RT.block_on(async {
3563 let client = MockAssetManagementApiClient { force_error: true };
3564
3565 let params =
3566 GetDetailOnSubAccountsMarginAccountParams::builder("123@test.com".to_string())
3567 .build()
3568 .unwrap();
3569
3570 match client
3571 .get_detail_on_sub_accounts_margin_account(params)
3572 .await
3573 {
3574 Ok(_) => panic!("Expected an error"),
3575 Err(err) => {
3576 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3577 }
3578 }
3579 });
3580 }
3581
3582 #[test]
3583 fn get_move_position_history_for_sub_account_required_params_success() {
3584 TOKIO_SHARED_RT.block_on(async {
3585 let client = MockAssetManagementApiClient { force_error: false };
3586
3587 let params = GetMovePositionHistoryForSubAccountParams::builder("BTCUSDT".to_string(),1,1,).build().unwrap();
3588
3589 let resp_json: Value = serde_json::from_str(r#"{"total":3,"futureMovePositionOrderVoList":[{"fromUserEmail":"testFrom@google.com","toUserEmail":"testTo@google.com","productType":"UM","symbol":"BTCUSDT","price":"105025.50981609","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1737544712000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3590 let expected_response : models::GetMovePositionHistoryForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetMovePositionHistoryForSubAccountResponse");
3591
3592 let resp = client.get_move_position_history_for_sub_account(params).await.expect("Expected a response");
3593 let data_future = resp.data();
3594 let actual_response = data_future.await.unwrap();
3595 assert_eq!(actual_response, expected_response);
3596 });
3597 }
3598
3599 #[test]
3600 fn get_move_position_history_for_sub_account_optional_params_success() {
3601 TOKIO_SHARED_RT.block_on(async {
3602 let client = MockAssetManagementApiClient { force_error: false };
3603
3604 let params = GetMovePositionHistoryForSubAccountParams::builder("BTCUSDT".to_string(),1,1,).start_time(1623319461670).end_time(1641782889000).recv_window(5000).build().unwrap();
3605
3606 let resp_json: Value = serde_json::from_str(r#"{"total":3,"futureMovePositionOrderVoList":[{"fromUserEmail":"testFrom@google.com","toUserEmail":"testTo@google.com","productType":"UM","symbol":"BTCUSDT","price":"105025.50981609","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1737544712000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3607 let expected_response : models::GetMovePositionHistoryForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetMovePositionHistoryForSubAccountResponse");
3608
3609 let resp = client.get_move_position_history_for_sub_account(params).await.expect("Expected a response");
3610 let data_future = resp.data();
3611 let actual_response = data_future.await.unwrap();
3612 assert_eq!(actual_response, expected_response);
3613 });
3614 }
3615
3616 #[test]
3617 fn get_move_position_history_for_sub_account_response_error() {
3618 TOKIO_SHARED_RT.block_on(async {
3619 let client = MockAssetManagementApiClient { force_error: true };
3620
3621 let params =
3622 GetMovePositionHistoryForSubAccountParams::builder("BTCUSDT".to_string(), 1, 1)
3623 .build()
3624 .unwrap();
3625
3626 match client
3627 .get_move_position_history_for_sub_account(params)
3628 .await
3629 {
3630 Ok(_) => panic!("Expected an error"),
3631 Err(err) => {
3632 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3633 }
3634 }
3635 });
3636 }
3637
3638 #[test]
3639 fn get_sub_account_deposit_address_required_params_success() {
3640 TOKIO_SHARED_RT.block_on(async {
3641 let client = MockAssetManagementApiClient { force_error: false };
3642
3643 let params = GetSubAccountDepositAddressParams::builder("123@test.com".to_string(),"BTC".to_string(),).build().unwrap();
3644
3645 let resp_json: Value = serde_json::from_str(r#"{"address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV","coin":"USDT","tag":"","url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV"}"#).unwrap_or_else(|_| serde_json::json!({}));
3646 let expected_response : models::GetSubAccountDepositAddressResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSubAccountDepositAddressResponse");
3647
3648 let resp = client.get_sub_account_deposit_address(params).await.expect("Expected a response");
3649 let data_future = resp.data();
3650 let actual_response = data_future.await.unwrap();
3651 assert_eq!(actual_response, expected_response);
3652 });
3653 }
3654
3655 #[test]
3656 fn get_sub_account_deposit_address_optional_params_success() {
3657 TOKIO_SHARED_RT.block_on(async {
3658 let client = MockAssetManagementApiClient { force_error: false };
3659
3660 let params = GetSubAccountDepositAddressParams::builder("123@test.com".to_string(),"BTC".to_string(),).network("network_example".to_string()).amount(dec!(1.0)).recv_window(5000).build().unwrap();
3661
3662 let resp_json: Value = serde_json::from_str(r#"{"address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV","coin":"USDT","tag":"","url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV"}"#).unwrap_or_else(|_| serde_json::json!({}));
3663 let expected_response : models::GetSubAccountDepositAddressResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSubAccountDepositAddressResponse");
3664
3665 let resp = client.get_sub_account_deposit_address(params).await.expect("Expected a response");
3666 let data_future = resp.data();
3667 let actual_response = data_future.await.unwrap();
3668 assert_eq!(actual_response, expected_response);
3669 });
3670 }
3671
3672 #[test]
3673 fn get_sub_account_deposit_address_response_error() {
3674 TOKIO_SHARED_RT.block_on(async {
3675 let client = MockAssetManagementApiClient { force_error: true };
3676
3677 let params = GetSubAccountDepositAddressParams::builder(
3678 "123@test.com".to_string(),
3679 "BTC".to_string(),
3680 )
3681 .build()
3682 .unwrap();
3683
3684 match client.get_sub_account_deposit_address(params).await {
3685 Ok(_) => panic!("Expected an error"),
3686 Err(err) => {
3687 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3688 }
3689 }
3690 });
3691 }
3692
3693 #[test]
3694 fn get_sub_account_deposit_history_required_params_success() {
3695 TOKIO_SHARED_RT.block_on(async {
3696 let client = MockAssetManagementApiClient { force_error: false };
3697
3698 let params = GetSubAccountDepositHistoryParams::builder("123@test.com".to_string(),).build().unwrap();
3699
3700 let resp_json: Value = serde_json::from_str(r#"[{"id":"769800519366885376","amount":"0.001","coin":"BNB","network":"BNB","status":0,"address":"bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23","addressTag":"101764890","txId":"98A3EA560C6B3336D348B6C83F0F95ECE4F1F5919E94BD006E5BF3BF264FACFC","insertTime":1661493146000,"transferType":0,"confirmTimes":"1/1","unlockConfirm":0,"walletType":0}]"#).unwrap_or_else(|_| serde_json::json!({}));
3701 let expected_response : Vec<models::GetSubAccountDepositHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountDepositHistoryResponseInner>");
3702
3703 let resp = client.get_sub_account_deposit_history(params).await.expect("Expected a response");
3704 let data_future = resp.data();
3705 let actual_response = data_future.await.unwrap();
3706 assert_eq!(actual_response, expected_response);
3707 });
3708 }
3709
3710 #[test]
3711 fn get_sub_account_deposit_history_optional_params_success() {
3712 TOKIO_SHARED_RT.block_on(async {
3713 let client = MockAssetManagementApiClient { force_error: false };
3714
3715 let params = GetSubAccountDepositHistoryParams::builder("123@test.com".to_string(),).include_source(false).coin("BTC".to_string()).status(0).start_time(1623319461670).end_time(1641782889000).limit(1).offset(0).recv_window(5000).tx_id("1".to_string()).build().unwrap();
3716
3717 let resp_json: Value = serde_json::from_str(r#"[{"id":"769800519366885376","amount":"0.001","coin":"BNB","network":"BNB","status":0,"address":"bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23","addressTag":"101764890","txId":"98A3EA560C6B3336D348B6C83F0F95ECE4F1F5919E94BD006E5BF3BF264FACFC","insertTime":1661493146000,"transferType":0,"confirmTimes":"1/1","unlockConfirm":0,"walletType":0}]"#).unwrap_or_else(|_| serde_json::json!({}));
3718 let expected_response : Vec<models::GetSubAccountDepositHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountDepositHistoryResponseInner>");
3719
3720 let resp = client.get_sub_account_deposit_history(params).await.expect("Expected a response");
3721 let data_future = resp.data();
3722 let actual_response = data_future.await.unwrap();
3723 assert_eq!(actual_response, expected_response);
3724 });
3725 }
3726
3727 #[test]
3728 fn get_sub_account_deposit_history_response_error() {
3729 TOKIO_SHARED_RT.block_on(async {
3730 let client = MockAssetManagementApiClient { force_error: true };
3731
3732 let params = GetSubAccountDepositHistoryParams::builder("123@test.com".to_string())
3733 .build()
3734 .unwrap();
3735
3736 match client.get_sub_account_deposit_history(params).await {
3737 Ok(_) => panic!("Expected an error"),
3738 Err(err) => {
3739 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3740 }
3741 }
3742 });
3743 }
3744
3745 #[test]
3746 fn get_summary_of_sub_accounts_futures_account_required_params_success() {
3747 TOKIO_SHARED_RT.block_on(async {
3748 let client = MockAssetManagementApiClient { force_error: false };
3749
3750 let params = GetSummaryOfSubAccountsFuturesAccountParams::builder(1,1,).build().unwrap();
3751
3752 let resp_json: Value = serde_json::from_str(r#"{"totalInitialMargin":"9.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"23.03235621","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"22.15879444","asset":"USD","subAccountList":[{"email":"123@test.com","totalInitialMargin":"9.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"22.12659734","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"USD"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3753 let expected_response : models::GetSummaryOfSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountResponse");
3754
3755 let resp = client.get_summary_of_sub_accounts_futures_account(params).await.expect("Expected a response");
3756 let data_future = resp.data();
3757 let actual_response = data_future.await.unwrap();
3758 assert_eq!(actual_response, expected_response);
3759 });
3760 }
3761
3762 #[test]
3763 fn get_summary_of_sub_accounts_futures_account_optional_params_success() {
3764 TOKIO_SHARED_RT.block_on(async {
3765 let client = MockAssetManagementApiClient { force_error: false };
3766
3767 let params = GetSummaryOfSubAccountsFuturesAccountParams::builder(1,1,).recv_window(5000).build().unwrap();
3768
3769 let resp_json: Value = serde_json::from_str(r#"{"totalInitialMargin":"9.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"23.03235621","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"22.15879444","asset":"USD","subAccountList":[{"email":"123@test.com","totalInitialMargin":"9.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"22.12659734","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"USD"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3770 let expected_response : models::GetSummaryOfSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountResponse");
3771
3772 let resp = client.get_summary_of_sub_accounts_futures_account(params).await.expect("Expected a response");
3773 let data_future = resp.data();
3774 let actual_response = data_future.await.unwrap();
3775 assert_eq!(actual_response, expected_response);
3776 });
3777 }
3778
3779 #[test]
3780 fn get_summary_of_sub_accounts_futures_account_response_error() {
3781 TOKIO_SHARED_RT.block_on(async {
3782 let client = MockAssetManagementApiClient { force_error: true };
3783
3784 let params = GetSummaryOfSubAccountsFuturesAccountParams::builder(1, 1)
3785 .build()
3786 .unwrap();
3787
3788 match client
3789 .get_summary_of_sub_accounts_futures_account(params)
3790 .await
3791 {
3792 Ok(_) => panic!("Expected an error"),
3793 Err(err) => {
3794 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3795 }
3796 }
3797 });
3798 }
3799
3800 #[test]
3801 fn get_summary_of_sub_accounts_futures_account_v2_required_params_success() {
3802 TOKIO_SHARED_RT.block_on(async {
3803 let client = MockAssetManagementApiClient { force_error: false };
3804
3805 let params = GetSummaryOfSubAccountsFuturesAccountV2Params::builder(1,).build().unwrap();
3806
3807 let resp_json: Value = serde_json::from_str(r#"{"futureAccountSummaryResp":{"totalInitialMargin":"9.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"23.03235621","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"22.15879444","asset":"USD","subAccountList":[{"email":"123@test.com","totalInitialMargin":"9.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"22.12659734","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"USD"}]},"deliveryAccountSummaryResp":{"totalMarginBalanceOfBTC":"25.03221121","totalUnrealizedProfitOfBTC":"0.12233410","totalWalletBalanceOfBTC":"22.15879444","asset":"BTC","subAccountList":[{"email":"123@test.com","totalMarginBalance":"22.12659734","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"BTC"}]}}"#).unwrap_or_else(|_| serde_json::json!({}));
3808 let expected_response : models::GetSummaryOfSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountV2Response");
3809
3810 let resp = client.get_summary_of_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3811 let data_future = resp.data();
3812 let actual_response = data_future.await.unwrap();
3813 assert_eq!(actual_response, expected_response);
3814 });
3815 }
3816
3817 #[test]
3818 fn get_summary_of_sub_accounts_futures_account_v2_optional_params_success() {
3819 TOKIO_SHARED_RT.block_on(async {
3820 let client = MockAssetManagementApiClient { force_error: false };
3821
3822 let params = GetSummaryOfSubAccountsFuturesAccountV2Params::builder(1,).page(1).limit(10).recv_window(5000).build().unwrap();
3823
3824 let resp_json: Value = serde_json::from_str(r#"{"futureAccountSummaryResp":{"totalInitialMargin":"9.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"23.03235621","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"22.15879444","asset":"USD","subAccountList":[{"email":"123@test.com","totalInitialMargin":"9.00000000","totalMaintenanceMargin":"0.00000000","totalMarginBalance":"22.12659734","totalOpenOrderInitialMargin":"9.00000000","totalPositionInitialMargin":"0.00000000","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"USD"}]},"deliveryAccountSummaryResp":{"totalMarginBalanceOfBTC":"25.03221121","totalUnrealizedProfitOfBTC":"0.12233410","totalWalletBalanceOfBTC":"22.15879444","asset":"BTC","subAccountList":[{"email":"123@test.com","totalMarginBalance":"22.12659734","totalUnrealizedProfit":"0.00000000","totalWalletBalance":"22.12659734","asset":"BTC"}]}}"#).unwrap_or_else(|_| serde_json::json!({}));
3825 let expected_response : models::GetSummaryOfSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountV2Response");
3826
3827 let resp = client.get_summary_of_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3828 let data_future = resp.data();
3829 let actual_response = data_future.await.unwrap();
3830 assert_eq!(actual_response, expected_response);
3831 });
3832 }
3833
3834 #[test]
3835 fn get_summary_of_sub_accounts_futures_account_v2_response_error() {
3836 TOKIO_SHARED_RT.block_on(async {
3837 let client = MockAssetManagementApiClient { force_error: true };
3838
3839 let params = GetSummaryOfSubAccountsFuturesAccountV2Params::builder(1)
3840 .build()
3841 .unwrap();
3842
3843 match client
3844 .get_summary_of_sub_accounts_futures_account_v2(params)
3845 .await
3846 {
3847 Ok(_) => panic!("Expected an error"),
3848 Err(err) => {
3849 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3850 }
3851 }
3852 });
3853 }
3854
3855 #[test]
3856 fn get_summary_of_sub_accounts_margin_account_required_params_success() {
3857 TOKIO_SHARED_RT.block_on(async {
3858 let client = MockAssetManagementApiClient { force_error: false };
3859
3860 let params = GetSummaryOfSubAccountsMarginAccountParams::builder().build().unwrap();
3861
3862 let resp_json: Value = serde_json::from_str(r#"{"totalAssetOfBtc":"4.33333333","totalLiabilityOfBtc":"2.11111112","totalNetAssetOfBtc":"2.22222221","subAccountList":[{"email":"123@test.com","totalAssetOfBtc":"2.11111111","totalLiabilityOfBtc":"1.11111111","totalNetAssetOfBtc":"1.00000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3863 let expected_response : models::GetSummaryOfSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsMarginAccountResponse");
3864
3865 let resp = client.get_summary_of_sub_accounts_margin_account(params).await.expect("Expected a response");
3866 let data_future = resp.data();
3867 let actual_response = data_future.await.unwrap();
3868 assert_eq!(actual_response, expected_response);
3869 });
3870 }
3871
3872 #[test]
3873 fn get_summary_of_sub_accounts_margin_account_optional_params_success() {
3874 TOKIO_SHARED_RT.block_on(async {
3875 let client = MockAssetManagementApiClient { force_error: false };
3876
3877 let params = GetSummaryOfSubAccountsMarginAccountParams::builder().recv_window(5000).build().unwrap();
3878
3879 let resp_json: Value = serde_json::from_str(r#"{"totalAssetOfBtc":"4.33333333","totalLiabilityOfBtc":"2.11111112","totalNetAssetOfBtc":"2.22222221","subAccountList":[{"email":"123@test.com","totalAssetOfBtc":"2.11111111","totalLiabilityOfBtc":"1.11111111","totalNetAssetOfBtc":"1.00000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3880 let expected_response : models::GetSummaryOfSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsMarginAccountResponse");
3881
3882 let resp = client.get_summary_of_sub_accounts_margin_account(params).await.expect("Expected a response");
3883 let data_future = resp.data();
3884 let actual_response = data_future.await.unwrap();
3885 assert_eq!(actual_response, expected_response);
3886 });
3887 }
3888
3889 #[test]
3890 fn get_summary_of_sub_accounts_margin_account_response_error() {
3891 TOKIO_SHARED_RT.block_on(async {
3892 let client = MockAssetManagementApiClient { force_error: true };
3893
3894 let params = GetSummaryOfSubAccountsMarginAccountParams::builder()
3895 .build()
3896 .unwrap();
3897
3898 match client
3899 .get_summary_of_sub_accounts_margin_account(params)
3900 .await
3901 {
3902 Ok(_) => panic!("Expected an error"),
3903 Err(err) => {
3904 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3905 }
3906 }
3907 });
3908 }
3909
3910 #[test]
3911 fn margin_transfer_for_sub_account_required_params_success() {
3912 TOKIO_SHARED_RT.block_on(async {
3913 let client = MockAssetManagementApiClient { force_error: false };
3914
3915 let params = MarginTransferForSubAccountParams::builder(
3916 "123@test.com".to_string(),
3917 "BTC".to_string(),
3918 dec!(1.0),
3919 1,
3920 )
3921 .build()
3922 .unwrap();
3923
3924 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
3925 .unwrap_or_else(|_| serde_json::json!({}));
3926 let expected_response: models::MarginTransferForSubAccountResponse =
3927 serde_json::from_value(resp_json.clone())
3928 .expect("should parse into models::MarginTransferForSubAccountResponse");
3929
3930 let resp = client
3931 .margin_transfer_for_sub_account(params)
3932 .await
3933 .expect("Expected a response");
3934 let data_future = resp.data();
3935 let actual_response = data_future.await.unwrap();
3936 assert_eq!(actual_response, expected_response);
3937 });
3938 }
3939
3940 #[test]
3941 fn margin_transfer_for_sub_account_optional_params_success() {
3942 TOKIO_SHARED_RT.block_on(async {
3943 let client = MockAssetManagementApiClient { force_error: false };
3944
3945 let params = MarginTransferForSubAccountParams::builder(
3946 "123@test.com".to_string(),
3947 "BTC".to_string(),
3948 dec!(1.0),
3949 1,
3950 )
3951 .recv_window(5000)
3952 .build()
3953 .unwrap();
3954
3955 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
3956 .unwrap_or_else(|_| serde_json::json!({}));
3957 let expected_response: models::MarginTransferForSubAccountResponse =
3958 serde_json::from_value(resp_json.clone())
3959 .expect("should parse into models::MarginTransferForSubAccountResponse");
3960
3961 let resp = client
3962 .margin_transfer_for_sub_account(params)
3963 .await
3964 .expect("Expected a response");
3965 let data_future = resp.data();
3966 let actual_response = data_future.await.unwrap();
3967 assert_eq!(actual_response, expected_response);
3968 });
3969 }
3970
3971 #[test]
3972 fn margin_transfer_for_sub_account_response_error() {
3973 TOKIO_SHARED_RT.block_on(async {
3974 let client = MockAssetManagementApiClient { force_error: true };
3975
3976 let params = MarginTransferForSubAccountParams::builder(
3977 "123@test.com".to_string(),
3978 "BTC".to_string(),
3979 dec!(1.0),
3980 1,
3981 )
3982 .build()
3983 .unwrap();
3984
3985 match client.margin_transfer_for_sub_account(params).await {
3986 Ok(_) => panic!("Expected an error"),
3987 Err(err) => {
3988 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3989 }
3990 }
3991 });
3992 }
3993
3994 #[test]
3995 fn move_position_for_sub_account_required_params_success() {
3996 TOKIO_SHARED_RT.block_on(async {
3997 let client = MockAssetManagementApiClient { force_error: false };
3998
3999 let params = MovePositionForSubAccountParams::builder("testFrom@google.com".to_string(),"testTo@google.com".to_string(),MovePositionForSubAccountProductTypeEnum::Um,vec![],).build().unwrap();
4000
4001 let resp_json: Value = serde_json::from_str(r#"{"movePositionOrders":[{"fromUserEmail":"testFrom@google.com","toUserEmail":"testTo@google.com","productType":"UM","symbol":"BTCUSDT","priceType":"MARK_PRICE","price":"97139.00000000","quantity":"0.001","positionSide":"BOTH","side":"BUY","success":true}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4002 let expected_response : models::MovePositionForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MovePositionForSubAccountResponse");
4003
4004 let resp = client.move_position_for_sub_account(params).await.expect("Expected a response");
4005 let data_future = resp.data();
4006 let actual_response = data_future.await.unwrap();
4007 assert_eq!(actual_response, expected_response);
4008 });
4009 }
4010
4011 #[test]
4012 fn move_position_for_sub_account_optional_params_success() {
4013 TOKIO_SHARED_RT.block_on(async {
4014 let client = MockAssetManagementApiClient { force_error: false };
4015
4016 let params = MovePositionForSubAccountParams::builder("testFrom@google.com".to_string(),"testTo@google.com".to_string(),MovePositionForSubAccountProductTypeEnum::Um,vec![],).recv_window(5000).build().unwrap();
4017
4018 let resp_json: Value = serde_json::from_str(r#"{"movePositionOrders":[{"fromUserEmail":"testFrom@google.com","toUserEmail":"testTo@google.com","productType":"UM","symbol":"BTCUSDT","priceType":"MARK_PRICE","price":"97139.00000000","quantity":"0.001","positionSide":"BOTH","side":"BUY","success":true}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4019 let expected_response : models::MovePositionForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MovePositionForSubAccountResponse");
4020
4021 let resp = client.move_position_for_sub_account(params).await.expect("Expected a response");
4022 let data_future = resp.data();
4023 let actual_response = data_future.await.unwrap();
4024 assert_eq!(actual_response, expected_response);
4025 });
4026 }
4027
4028 #[test]
4029 fn move_position_for_sub_account_response_error() {
4030 TOKIO_SHARED_RT.block_on(async {
4031 let client = MockAssetManagementApiClient { force_error: true };
4032
4033 let params = MovePositionForSubAccountParams::builder(
4034 "testFrom@google.com".to_string(),
4035 "testTo@google.com".to_string(),
4036 MovePositionForSubAccountProductTypeEnum::Um,
4037 vec![],
4038 )
4039 .build()
4040 .unwrap();
4041
4042 match client.move_position_for_sub_account(params).await {
4043 Ok(_) => panic!("Expected an error"),
4044 Err(err) => {
4045 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4046 }
4047 }
4048 });
4049 }
4050
4051 #[test]
4052 fn query_sub_account_assets_required_params_success() {
4053 TOKIO_SHARED_RT.block_on(async {
4054 let client = MockAssetManagementApiClient { force_error: false };
4055
4056 let params = QuerySubAccountAssetsParams::builder("123@test.com".to_string(),).build().unwrap();
4057
4058 let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":0,"withdrawing":0,"asset":"ADA","free":11467.6399,"locked":0}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4059 let expected_response : models::QuerySubAccountAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsResponse");
4060
4061 let resp = client.query_sub_account_assets(params).await.expect("Expected a response");
4062 let data_future = resp.data();
4063 let actual_response = data_future.await.unwrap();
4064 assert_eq!(actual_response, expected_response);
4065 });
4066 }
4067
4068 #[test]
4069 fn query_sub_account_assets_optional_params_success() {
4070 TOKIO_SHARED_RT.block_on(async {
4071 let client = MockAssetManagementApiClient { force_error: false };
4072
4073 let params = QuerySubAccountAssetsParams::builder("123@test.com".to_string(),).recv_window(5000).build().unwrap();
4074
4075 let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":0,"withdrawing":0,"asset":"ADA","free":11467.6399,"locked":0}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4076 let expected_response : models::QuerySubAccountAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsResponse");
4077
4078 let resp = client.query_sub_account_assets(params).await.expect("Expected a response");
4079 let data_future = resp.data();
4080 let actual_response = data_future.await.unwrap();
4081 assert_eq!(actual_response, expected_response);
4082 });
4083 }
4084
4085 #[test]
4086 fn query_sub_account_assets_response_error() {
4087 TOKIO_SHARED_RT.block_on(async {
4088 let client = MockAssetManagementApiClient { force_error: true };
4089
4090 let params = QuerySubAccountAssetsParams::builder("123@test.com".to_string())
4091 .build()
4092 .unwrap();
4093
4094 match client.query_sub_account_assets(params).await {
4095 Ok(_) => panic!("Expected an error"),
4096 Err(err) => {
4097 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4098 }
4099 }
4100 });
4101 }
4102
4103 #[test]
4104 fn query_sub_account_assets_asset_management_required_params_success() {
4105 TOKIO_SHARED_RT.block_on(async {
4106 let client = MockAssetManagementApiClient { force_error: false };
4107
4108 let params = QuerySubAccountAssetsAssetManagementParams::builder("123@test.com".to_string(),).build().unwrap();
4109
4110 let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":"0","withdrawing":"0","asset":"ADA","free":"10000","locked":"0"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4111 let expected_response : models::QuerySubAccountAssetsAssetManagementResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsAssetManagementResponse");
4112
4113 let resp = client.query_sub_account_assets_asset_management(params).await.expect("Expected a response");
4114 let data_future = resp.data();
4115 let actual_response = data_future.await.unwrap();
4116 assert_eq!(actual_response, expected_response);
4117 });
4118 }
4119
4120 #[test]
4121 fn query_sub_account_assets_asset_management_optional_params_success() {
4122 TOKIO_SHARED_RT.block_on(async {
4123 let client = MockAssetManagementApiClient { force_error: false };
4124
4125 let params = QuerySubAccountAssetsAssetManagementParams::builder("123@test.com".to_string(),).recv_window(5000).build().unwrap();
4126
4127 let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":"0","withdrawing":"0","asset":"ADA","free":"10000","locked":"0"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4128 let expected_response : models::QuerySubAccountAssetsAssetManagementResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsAssetManagementResponse");
4129
4130 let resp = client.query_sub_account_assets_asset_management(params).await.expect("Expected a response");
4131 let data_future = resp.data();
4132 let actual_response = data_future.await.unwrap();
4133 assert_eq!(actual_response, expected_response);
4134 });
4135 }
4136
4137 #[test]
4138 fn query_sub_account_assets_asset_management_response_error() {
4139 TOKIO_SHARED_RT.block_on(async {
4140 let client = MockAssetManagementApiClient { force_error: true };
4141
4142 let params =
4143 QuerySubAccountAssetsAssetManagementParams::builder("123@test.com".to_string())
4144 .build()
4145 .unwrap();
4146
4147 match client
4148 .query_sub_account_assets_asset_management(params)
4149 .await
4150 {
4151 Ok(_) => panic!("Expected an error"),
4152 Err(err) => {
4153 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4154 }
4155 }
4156 });
4157 }
4158
4159 #[test]
4160 fn query_sub_account_futures_asset_transfer_history_required_params_success() {
4161 TOKIO_SHARED_RT.block_on(async {
4162 let client = MockAssetManagementApiClient { force_error: false };
4163
4164 let params = QuerySubAccountFuturesAssetTransferHistoryParams::builder("123@test.com".to_string(),1,).build().unwrap();
4165
4166 let resp_json: Value = serde_json::from_str(r#"{"success":true,"futuresType":2,"transfers":[{"from":"aaa@test.com","to":"bbb@test.com","asset":"BTC","qty":"1","tranId":11897001102,"time":1544433328000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4167 let expected_response : models::QuerySubAccountFuturesAssetTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountFuturesAssetTransferHistoryResponse");
4168
4169 let resp = client.query_sub_account_futures_asset_transfer_history(params).await.expect("Expected a response");
4170 let data_future = resp.data();
4171 let actual_response = data_future.await.unwrap();
4172 assert_eq!(actual_response, expected_response);
4173 });
4174 }
4175
4176 #[test]
4177 fn query_sub_account_futures_asset_transfer_history_optional_params_success() {
4178 TOKIO_SHARED_RT.block_on(async {
4179 let client = MockAssetManagementApiClient { force_error: false };
4180
4181 let params = QuerySubAccountFuturesAssetTransferHistoryParams::builder("123@test.com".to_string(),1,).start_time(1623319461670).end_time(1641782889000).page(1).limit(10).recv_window(5000).build().unwrap();
4182
4183 let resp_json: Value = serde_json::from_str(r#"{"success":true,"futuresType":2,"transfers":[{"from":"aaa@test.com","to":"bbb@test.com","asset":"BTC","qty":"1","tranId":11897001102,"time":1544433328000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4184 let expected_response : models::QuerySubAccountFuturesAssetTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountFuturesAssetTransferHistoryResponse");
4185
4186 let resp = client.query_sub_account_futures_asset_transfer_history(params).await.expect("Expected a response");
4187 let data_future = resp.data();
4188 let actual_response = data_future.await.unwrap();
4189 assert_eq!(actual_response, expected_response);
4190 });
4191 }
4192
4193 #[test]
4194 fn query_sub_account_futures_asset_transfer_history_response_error() {
4195 TOKIO_SHARED_RT.block_on(async {
4196 let client = MockAssetManagementApiClient { force_error: true };
4197
4198 let params = QuerySubAccountFuturesAssetTransferHistoryParams::builder(
4199 "123@test.com".to_string(),
4200 1,
4201 )
4202 .build()
4203 .unwrap();
4204
4205 match client
4206 .query_sub_account_futures_asset_transfer_history(params)
4207 .await
4208 {
4209 Ok(_) => panic!("Expected an error"),
4210 Err(err) => {
4211 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4212 }
4213 }
4214 });
4215 }
4216
4217 #[test]
4218 fn query_sub_account_spot_asset_transfer_history_required_params_success() {
4219 TOKIO_SHARED_RT.block_on(async {
4220 let client = MockAssetManagementApiClient { force_error: false };
4221
4222 let params = QuerySubAccountSpotAssetTransferHistoryParams::builder().build().unwrap();
4223
4224 let resp_json: Value = serde_json::from_str(r#"[{"from":"aaa@test.com","to":"bbb@test.com","asset":"BTC","qty":"10","status":"SUCCESS","tranId":6489943656,"time":1544433328000}]"#).unwrap_or_else(|_| serde_json::json!({}));
4225 let expected_response : Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>");
4226
4227 let resp = client.query_sub_account_spot_asset_transfer_history(params).await.expect("Expected a response");
4228 let data_future = resp.data();
4229 let actual_response = data_future.await.unwrap();
4230 assert_eq!(actual_response, expected_response);
4231 });
4232 }
4233
4234 #[test]
4235 fn query_sub_account_spot_asset_transfer_history_optional_params_success() {
4236 TOKIO_SHARED_RT.block_on(async {
4237 let client = MockAssetManagementApiClient { force_error: false };
4238
4239 let params = QuerySubAccountSpotAssetTransferHistoryParams::builder().from_email("aaa@test.com".to_string()).to_email("bbb@test.com".to_string()).start_time(1623319461670).end_time(1641782889000).page(1).limit(10).recv_window(5000).build().unwrap();
4240
4241 let resp_json: Value = serde_json::from_str(r#"[{"from":"aaa@test.com","to":"bbb@test.com","asset":"BTC","qty":"10","status":"SUCCESS","tranId":6489943656,"time":1544433328000}]"#).unwrap_or_else(|_| serde_json::json!({}));
4242 let expected_response : Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>");
4243
4244 let resp = client.query_sub_account_spot_asset_transfer_history(params).await.expect("Expected a response");
4245 let data_future = resp.data();
4246 let actual_response = data_future.await.unwrap();
4247 assert_eq!(actual_response, expected_response);
4248 });
4249 }
4250
4251 #[test]
4252 fn query_sub_account_spot_asset_transfer_history_response_error() {
4253 TOKIO_SHARED_RT.block_on(async {
4254 let client = MockAssetManagementApiClient { force_error: true };
4255
4256 let params = QuerySubAccountSpotAssetTransferHistoryParams::builder()
4257 .build()
4258 .unwrap();
4259
4260 match client
4261 .query_sub_account_spot_asset_transfer_history(params)
4262 .await
4263 {
4264 Ok(_) => panic!("Expected an error"),
4265 Err(err) => {
4266 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4267 }
4268 }
4269 });
4270 }
4271
4272 #[test]
4273 fn query_sub_account_spot_assets_summary_required_params_success() {
4274 TOKIO_SHARED_RT.block_on(async {
4275 let client = MockAssetManagementApiClient { force_error: false };
4276
4277 let params = QuerySubAccountSpotAssetsSummaryParams::builder().build().unwrap();
4278
4279 let resp_json: Value = serde_json::from_str(r#"{"totalCount":2,"masterAccountTotalAsset":"0.23231201","spotSubUserAssetBtcVoList":[{"email":"sub123@test.com","totalAsset":"9999.00000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4280 let expected_response : models::QuerySubAccountSpotAssetsSummaryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountSpotAssetsSummaryResponse");
4281
4282 let resp = client.query_sub_account_spot_assets_summary(params).await.expect("Expected a response");
4283 let data_future = resp.data();
4284 let actual_response = data_future.await.unwrap();
4285 assert_eq!(actual_response, expected_response);
4286 });
4287 }
4288
4289 #[test]
4290 fn query_sub_account_spot_assets_summary_optional_params_success() {
4291 TOKIO_SHARED_RT.block_on(async {
4292 let client = MockAssetManagementApiClient { force_error: false };
4293
4294 let params = QuerySubAccountSpotAssetsSummaryParams::builder().email("123@test.com".to_string()).page(1).size(10).recv_window(5000).build().unwrap();
4295
4296 let resp_json: Value = serde_json::from_str(r#"{"totalCount":2,"masterAccountTotalAsset":"0.23231201","spotSubUserAssetBtcVoList":[{"email":"sub123@test.com","totalAsset":"9999.00000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
4297 let expected_response : models::QuerySubAccountSpotAssetsSummaryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountSpotAssetsSummaryResponse");
4298
4299 let resp = client.query_sub_account_spot_assets_summary(params).await.expect("Expected a response");
4300 let data_future = resp.data();
4301 let actual_response = data_future.await.unwrap();
4302 assert_eq!(actual_response, expected_response);
4303 });
4304 }
4305
4306 #[test]
4307 fn query_sub_account_spot_assets_summary_response_error() {
4308 TOKIO_SHARED_RT.block_on(async {
4309 let client = MockAssetManagementApiClient { force_error: true };
4310
4311 let params = QuerySubAccountSpotAssetsSummaryParams::builder()
4312 .build()
4313 .unwrap();
4314
4315 match client.query_sub_account_spot_assets_summary(params).await {
4316 Ok(_) => panic!("Expected an error"),
4317 Err(err) => {
4318 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4319 }
4320 }
4321 });
4322 }
4323
4324 #[test]
4325 fn query_universal_transfer_history_required_params_success() {
4326 TOKIO_SHARED_RT.block_on(async {
4327 let client = MockAssetManagementApiClient { force_error: false };
4328
4329 let params = QueryUniversalTransferHistoryParams::builder().build().unwrap();
4330
4331 let resp_json: Value = serde_json::from_str(r#"{"result":[{"tranId":92275823339,"fromEmail":"abctest@gmail.com","toEmail":"deftest@gmail.com","asset":"BNB","amount":"0.01","createTimeStamp":1640317374000,"fromAccountType":"USDT_FUTURE","toAccountType":"SPOT","status":"SUCCESS","clientTranId":"test"}],"totalCount":1}"#).unwrap_or_else(|_| serde_json::json!({}));
4332 let expected_response : models::QueryUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUniversalTransferHistoryResponse");
4333
4334 let resp = client.query_universal_transfer_history(params).await.expect("Expected a response");
4335 let data_future = resp.data();
4336 let actual_response = data_future.await.unwrap();
4337 assert_eq!(actual_response, expected_response);
4338 });
4339 }
4340
4341 #[test]
4342 fn query_universal_transfer_history_optional_params_success() {
4343 TOKIO_SHARED_RT.block_on(async {
4344 let client = MockAssetManagementApiClient { force_error: false };
4345
4346 let params = QueryUniversalTransferHistoryParams::builder().from_email("abctest@gmail.com".to_string()).to_email("deftest@gmail.com".to_string()).client_tran_id("1".to_string()).start_time(1623319461670).end_time(1641782889000).page(1).limit(10).recv_window(5000).build().unwrap();
4347
4348 let resp_json: Value = serde_json::from_str(r#"{"result":[{"tranId":92275823339,"fromEmail":"abctest@gmail.com","toEmail":"deftest@gmail.com","asset":"BNB","amount":"0.01","createTimeStamp":1640317374000,"fromAccountType":"USDT_FUTURE","toAccountType":"SPOT","status":"SUCCESS","clientTranId":"test"}],"totalCount":1}"#).unwrap_or_else(|_| serde_json::json!({}));
4349 let expected_response : models::QueryUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUniversalTransferHistoryResponse");
4350
4351 let resp = client.query_universal_transfer_history(params).await.expect("Expected a response");
4352 let data_future = resp.data();
4353 let actual_response = data_future.await.unwrap();
4354 assert_eq!(actual_response, expected_response);
4355 });
4356 }
4357
4358 #[test]
4359 fn query_universal_transfer_history_response_error() {
4360 TOKIO_SHARED_RT.block_on(async {
4361 let client = MockAssetManagementApiClient { force_error: true };
4362
4363 let params = QueryUniversalTransferHistoryParams::builder()
4364 .build()
4365 .unwrap();
4366
4367 match client.query_universal_transfer_history(params).await {
4368 Ok(_) => panic!("Expected an error"),
4369 Err(err) => {
4370 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4371 }
4372 }
4373 });
4374 }
4375
4376 #[test]
4377 fn sub_account_futures_asset_transfer_required_params_success() {
4378 TOKIO_SHARED_RT.block_on(async {
4379 let client = MockAssetManagementApiClient { force_error: false };
4380
4381 let params = SubAccountFuturesAssetTransferParams::builder(
4382 "abc@test.com".to_string(),
4383 "def@test.com".to_string(),
4384 1,
4385 "BTC".to_string(),
4386 dec!(1.0),
4387 )
4388 .build()
4389 .unwrap();
4390
4391 let resp_json: Value = serde_json::from_str(r#"{"success":true,"txnId":"2934662589"}"#)
4392 .unwrap_or_else(|_| serde_json::json!({}));
4393 let expected_response: models::SubAccountFuturesAssetTransferResponse =
4394 serde_json::from_value(resp_json.clone())
4395 .expect("should parse into models::SubAccountFuturesAssetTransferResponse");
4396
4397 let resp = client
4398 .sub_account_futures_asset_transfer(params)
4399 .await
4400 .expect("Expected a response");
4401 let data_future = resp.data();
4402 let actual_response = data_future.await.unwrap();
4403 assert_eq!(actual_response, expected_response);
4404 });
4405 }
4406
4407 #[test]
4408 fn sub_account_futures_asset_transfer_optional_params_success() {
4409 TOKIO_SHARED_RT.block_on(async {
4410 let client = MockAssetManagementApiClient { force_error: false };
4411
4412 let params = SubAccountFuturesAssetTransferParams::builder(
4413 "abc@test.com".to_string(),
4414 "def@test.com".to_string(),
4415 1,
4416 "BTC".to_string(),
4417 dec!(1.0),
4418 )
4419 .recv_window(5000)
4420 .build()
4421 .unwrap();
4422
4423 let resp_json: Value = serde_json::from_str(r#"{"success":true,"txnId":"2934662589"}"#)
4424 .unwrap_or_else(|_| serde_json::json!({}));
4425 let expected_response: models::SubAccountFuturesAssetTransferResponse =
4426 serde_json::from_value(resp_json.clone())
4427 .expect("should parse into models::SubAccountFuturesAssetTransferResponse");
4428
4429 let resp = client
4430 .sub_account_futures_asset_transfer(params)
4431 .await
4432 .expect("Expected a response");
4433 let data_future = resp.data();
4434 let actual_response = data_future.await.unwrap();
4435 assert_eq!(actual_response, expected_response);
4436 });
4437 }
4438
4439 #[test]
4440 fn sub_account_futures_asset_transfer_response_error() {
4441 TOKIO_SHARED_RT.block_on(async {
4442 let client = MockAssetManagementApiClient { force_error: true };
4443
4444 let params = SubAccountFuturesAssetTransferParams::builder(
4445 "abc@test.com".to_string(),
4446 "def@test.com".to_string(),
4447 1,
4448 "BTC".to_string(),
4449 dec!(1.0),
4450 )
4451 .build()
4452 .unwrap();
4453
4454 match client.sub_account_futures_asset_transfer(params).await {
4455 Ok(_) => panic!("Expected an error"),
4456 Err(err) => {
4457 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4458 }
4459 }
4460 });
4461 }
4462
4463 #[test]
4464 fn sub_account_transfer_history_required_params_success() {
4465 TOKIO_SHARED_RT.block_on(async {
4466 let client = MockAssetManagementApiClient { force_error: false };
4467
4468 let params = SubAccountTransferHistoryParams::builder().build().unwrap();
4469
4470 let resp_json: Value = serde_json::from_str(r#"[{"counterParty":"master","email":"master@test.com","type":1,"asset":"BTC","qty":"1","fromAccountType":"SPOT","toAccountType":"SPOT","status":"SUCCESS","tranId":11798835829,"time":1544433325000}]"#).unwrap_or_else(|_| serde_json::json!({}));
4471 let expected_response : Vec<models::SubAccountTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::SubAccountTransferHistoryResponseInner>");
4472
4473 let resp = client.sub_account_transfer_history(params).await.expect("Expected a response");
4474 let data_future = resp.data();
4475 let actual_response = data_future.await.unwrap();
4476 assert_eq!(actual_response, expected_response);
4477 });
4478 }
4479
4480 #[test]
4481 fn sub_account_transfer_history_optional_params_success() {
4482 TOKIO_SHARED_RT.block_on(async {
4483 let client = MockAssetManagementApiClient { force_error: false };
4484
4485 let params = SubAccountTransferHistoryParams::builder().asset("BTC".to_string()).r#type(1).start_time(1623319461670).end_time(1641782889000).limit(10).return_fail_history(false).recv_window(5000).build().unwrap();
4486
4487 let resp_json: Value = serde_json::from_str(r#"[{"counterParty":"master","email":"master@test.com","type":1,"asset":"BTC","qty":"1","fromAccountType":"SPOT","toAccountType":"SPOT","status":"SUCCESS","tranId":11798835829,"time":1544433325000}]"#).unwrap_or_else(|_| serde_json::json!({}));
4488 let expected_response : Vec<models::SubAccountTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::SubAccountTransferHistoryResponseInner>");
4489
4490 let resp = client.sub_account_transfer_history(params).await.expect("Expected a response");
4491 let data_future = resp.data();
4492 let actual_response = data_future.await.unwrap();
4493 assert_eq!(actual_response, expected_response);
4494 });
4495 }
4496
4497 #[test]
4498 fn sub_account_transfer_history_response_error() {
4499 TOKIO_SHARED_RT.block_on(async {
4500 let client = MockAssetManagementApiClient { force_error: true };
4501
4502 let params = SubAccountTransferHistoryParams::builder().build().unwrap();
4503
4504 match client.sub_account_transfer_history(params).await {
4505 Ok(_) => panic!("Expected an error"),
4506 Err(err) => {
4507 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4508 }
4509 }
4510 });
4511 }
4512
4513 #[test]
4514 fn transfer_to_master_required_params_success() {
4515 TOKIO_SHARED_RT.block_on(async {
4516 let client = MockAssetManagementApiClient { force_error: false };
4517
4518 let params = TransferToMasterParams::builder("BTC".to_string(), dec!(1.0))
4519 .build()
4520 .unwrap();
4521
4522 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
4523 .unwrap_or_else(|_| serde_json::json!({}));
4524 let expected_response: models::TransferToMasterResponse =
4525 serde_json::from_value(resp_json.clone())
4526 .expect("should parse into models::TransferToMasterResponse");
4527
4528 let resp = client
4529 .transfer_to_master(params)
4530 .await
4531 .expect("Expected a response");
4532 let data_future = resp.data();
4533 let actual_response = data_future.await.unwrap();
4534 assert_eq!(actual_response, expected_response);
4535 });
4536 }
4537
4538 #[test]
4539 fn transfer_to_master_optional_params_success() {
4540 TOKIO_SHARED_RT.block_on(async {
4541 let client = MockAssetManagementApiClient { force_error: false };
4542
4543 let params = TransferToMasterParams::builder("BTC".to_string(), dec!(1.0))
4544 .recv_window(5000)
4545 .build()
4546 .unwrap();
4547
4548 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
4549 .unwrap_or_else(|_| serde_json::json!({}));
4550 let expected_response: models::TransferToMasterResponse =
4551 serde_json::from_value(resp_json.clone())
4552 .expect("should parse into models::TransferToMasterResponse");
4553
4554 let resp = client
4555 .transfer_to_master(params)
4556 .await
4557 .expect("Expected a response");
4558 let data_future = resp.data();
4559 let actual_response = data_future.await.unwrap();
4560 assert_eq!(actual_response, expected_response);
4561 });
4562 }
4563
4564 #[test]
4565 fn transfer_to_master_response_error() {
4566 TOKIO_SHARED_RT.block_on(async {
4567 let client = MockAssetManagementApiClient { force_error: true };
4568
4569 let params = TransferToMasterParams::builder("BTC".to_string(), dec!(1.0))
4570 .build()
4571 .unwrap();
4572
4573 match client.transfer_to_master(params).await {
4574 Ok(_) => panic!("Expected an error"),
4575 Err(err) => {
4576 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4577 }
4578 }
4579 });
4580 }
4581
4582 #[test]
4583 fn transfer_to_sub_account_of_same_master_required_params_success() {
4584 TOKIO_SHARED_RT.block_on(async {
4585 let client = MockAssetManagementApiClient { force_error: false };
4586
4587 let params = TransferToSubAccountOfSameMasterParams::builder(
4588 "abc@test.com".to_string(),
4589 "BTC".to_string(),
4590 dec!(1.0),
4591 )
4592 .build()
4593 .unwrap();
4594
4595 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
4596 .unwrap_or_else(|_| serde_json::json!({}));
4597 let expected_response: models::TransferToSubAccountOfSameMasterResponse =
4598 serde_json::from_value(resp_json.clone())
4599 .expect("should parse into models::TransferToSubAccountOfSameMasterResponse");
4600
4601 let resp = client
4602 .transfer_to_sub_account_of_same_master(params)
4603 .await
4604 .expect("Expected a response");
4605 let data_future = resp.data();
4606 let actual_response = data_future.await.unwrap();
4607 assert_eq!(actual_response, expected_response);
4608 });
4609 }
4610
4611 #[test]
4612 fn transfer_to_sub_account_of_same_master_optional_params_success() {
4613 TOKIO_SHARED_RT.block_on(async {
4614 let client = MockAssetManagementApiClient { force_error: false };
4615
4616 let params = TransferToSubAccountOfSameMasterParams::builder(
4617 "abc@test.com".to_string(),
4618 "BTC".to_string(),
4619 dec!(1.0),
4620 )
4621 .recv_window(5000)
4622 .build()
4623 .unwrap();
4624
4625 let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#)
4626 .unwrap_or_else(|_| serde_json::json!({}));
4627 let expected_response: models::TransferToSubAccountOfSameMasterResponse =
4628 serde_json::from_value(resp_json.clone())
4629 .expect("should parse into models::TransferToSubAccountOfSameMasterResponse");
4630
4631 let resp = client
4632 .transfer_to_sub_account_of_same_master(params)
4633 .await
4634 .expect("Expected a response");
4635 let data_future = resp.data();
4636 let actual_response = data_future.await.unwrap();
4637 assert_eq!(actual_response, expected_response);
4638 });
4639 }
4640
4641 #[test]
4642 fn transfer_to_sub_account_of_same_master_response_error() {
4643 TOKIO_SHARED_RT.block_on(async {
4644 let client = MockAssetManagementApiClient { force_error: true };
4645
4646 let params = TransferToSubAccountOfSameMasterParams::builder(
4647 "abc@test.com".to_string(),
4648 "BTC".to_string(),
4649 dec!(1.0),
4650 )
4651 .build()
4652 .unwrap();
4653
4654 match client.transfer_to_sub_account_of_same_master(params).await {
4655 Ok(_) => panic!("Expected an error"),
4656 Err(err) => {
4657 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4658 }
4659 }
4660 });
4661 }
4662
4663 #[test]
4664 fn universal_transfer_required_params_success() {
4665 TOKIO_SHARED_RT.block_on(async {
4666 let client = MockAssetManagementApiClient { force_error: false };
4667
4668 let params = UniversalTransferParams::builder(
4669 UniversalTransferFromAccountTypeEnum::Spot,
4670 UniversalTransferToAccountTypeEnum::Spot,
4671 "BTC".to_string(),
4672 dec!(1.0),
4673 )
4674 .build()
4675 .unwrap();
4676
4677 let resp_json: Value =
4678 serde_json::from_str(r#"{"tranId":11945860693,"clientTranId":"test"}"#)
4679 .unwrap_or_else(|_| serde_json::json!({}));
4680 let expected_response: models::UniversalTransferResponse =
4681 serde_json::from_value(resp_json.clone())
4682 .expect("should parse into models::UniversalTransferResponse");
4683
4684 let resp = client
4685 .universal_transfer(params)
4686 .await
4687 .expect("Expected a response");
4688 let data_future = resp.data();
4689 let actual_response = data_future.await.unwrap();
4690 assert_eq!(actual_response, expected_response);
4691 });
4692 }
4693
4694 #[test]
4695 fn universal_transfer_optional_params_success() {
4696 TOKIO_SHARED_RT.block_on(async {
4697 let client = MockAssetManagementApiClient { force_error: false };
4698
4699 let params = UniversalTransferParams::builder(
4700 UniversalTransferFromAccountTypeEnum::Spot,
4701 UniversalTransferToAccountTypeEnum::Spot,
4702 "BTC".to_string(),
4703 dec!(1.0),
4704 )
4705 .from_email("abc@test.com".to_string())
4706 .to_email("def@test.com".to_string())
4707 .client_tran_id("1".to_string())
4708 .symbol("BTCUSDT".to_string())
4709 .recv_window(5000)
4710 .build()
4711 .unwrap();
4712
4713 let resp_json: Value =
4714 serde_json::from_str(r#"{"tranId":11945860693,"clientTranId":"test"}"#)
4715 .unwrap_or_else(|_| serde_json::json!({}));
4716 let expected_response: models::UniversalTransferResponse =
4717 serde_json::from_value(resp_json.clone())
4718 .expect("should parse into models::UniversalTransferResponse");
4719
4720 let resp = client
4721 .universal_transfer(params)
4722 .await
4723 .expect("Expected a response");
4724 let data_future = resp.data();
4725 let actual_response = data_future.await.unwrap();
4726 assert_eq!(actual_response, expected_response);
4727 });
4728 }
4729
4730 #[test]
4731 fn universal_transfer_response_error() {
4732 TOKIO_SHARED_RT.block_on(async {
4733 let client = MockAssetManagementApiClient { force_error: true };
4734
4735 let params = UniversalTransferParams::builder(
4736 UniversalTransferFromAccountTypeEnum::Spot,
4737 UniversalTransferToAccountTypeEnum::Spot,
4738 "BTC".to_string(),
4739 dec!(1.0),
4740 )
4741 .build()
4742 .unwrap();
4743
4744 match client.universal_transfer(params).await {
4745 Ok(_) => panic!("Expected an error"),
4746 Err(err) => {
4747 assert_eq!(err.to_string(), "Connector client error: ResponseError");
4748 }
4749 }
4750 });
4751 }
4752}