Skip to main content

binance_sdk/sub_account/rest_api/apis/
asset_management_api.rs

1/*
2 * Binance Sub Account REST API
3 *
4 * OpenAPI Specification for the Binance Sub Account REST API
5 *
6 * The version of the OpenAPI document: 1.0.0
7 *
8 *
9 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10 * https://openapi-generator.tech
11 * Do not edit the class manually.
12 */
13
14#![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/// Request parameters for the [`futures_transfer_for_sub_account`] operation.
142///
143/// This struct holds all of the inputs you can pass when calling
144/// [`futures_transfer_for_sub_account`](#method.futures_transfer_for_sub_account).
145#[derive(Clone, Debug, Builder)]
146#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
147pub struct FuturesTransferForSubAccountParams {
148    /// [Sub-account email](#email-address)
149    ///
150    /// This field is **required.
151    #[builder(setter(into))]
152    pub email: String,
153    ///
154    /// The `asset` parameter.
155    ///
156    /// This field is **required.
157    #[builder(setter(into))]
158    pub asset: String,
159    ///
160    /// The `amount` parameter.
161    ///
162    /// This field is **required.
163    #[builder(setter(into))]
164    pub amount: rust_decimal::Decimal,
165    /// 1: transfer from subaccount's  spot account to margin account 2: transfer from subaccount's margin account to its spot account
166    ///
167    /// This field is **required.
168    #[builder(setter(into))]
169    pub r#type: i64,
170    ///
171    /// The `recv_window` parameter.
172    ///
173    /// This field is **optional.
174    #[builder(setter(into), default)]
175    pub recv_window: Option<i64>,
176}
177
178impl FuturesTransferForSubAccountParams {
179    /// Create a builder for [`futures_transfer_for_sub_account`].
180    ///
181    /// Required parameters:
182    ///
183    /// * `email` — [Sub-account email](#email-address)
184    /// * `asset` — String
185    /// * `amount` — `rust_decimal::Decimal`
186    /// * `r#type` — 1: transfer from subaccount's  spot account to margin account 2: transfer from subaccount's margin account to its spot account
187    ///
188    #[must_use]
189    pub fn builder(
190        email: String,
191        asset: String,
192        amount: rust_decimal::Decimal,
193        r#type: i64,
194    ) -> FuturesTransferForSubAccountParamsBuilder {
195        FuturesTransferForSubAccountParamsBuilder::default()
196            .email(email)
197            .asset(asset)
198            .amount(amount)
199            .r#type(r#type)
200    }
201}
202/// Request parameters for the [`get_detail_on_sub_accounts_futures_account`] operation.
203///
204/// This struct holds all of the inputs you can pass when calling
205/// [`get_detail_on_sub_accounts_futures_account`](#method.get_detail_on_sub_accounts_futures_account).
206#[derive(Clone, Debug, Builder)]
207#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
208pub struct GetDetailOnSubAccountsFuturesAccountParams {
209    /// [Sub-account email](#email-address)
210    ///
211    /// This field is **required.
212    #[builder(setter(into))]
213    pub email: String,
214    ///
215    /// The `recv_window` parameter.
216    ///
217    /// This field is **optional.
218    #[builder(setter(into), default)]
219    pub recv_window: Option<i64>,
220}
221
222impl GetDetailOnSubAccountsFuturesAccountParams {
223    /// Create a builder for [`get_detail_on_sub_accounts_futures_account`].
224    ///
225    /// Required parameters:
226    ///
227    /// * `email` — [Sub-account email](#email-address)
228    ///
229    #[must_use]
230    pub fn builder(email: String) -> GetDetailOnSubAccountsFuturesAccountParamsBuilder {
231        GetDetailOnSubAccountsFuturesAccountParamsBuilder::default().email(email)
232    }
233}
234/// Request parameters for the [`get_detail_on_sub_accounts_futures_account_v2`] operation.
235///
236/// This struct holds all of the inputs you can pass when calling
237/// [`get_detail_on_sub_accounts_futures_account_v2`](#method.get_detail_on_sub_accounts_futures_account_v2).
238#[derive(Clone, Debug, Builder)]
239#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
240pub struct GetDetailOnSubAccountsFuturesAccountV2Params {
241    /// [Sub-account email](#email-address)
242    ///
243    /// This field is **required.
244    #[builder(setter(into))]
245    pub email: String,
246    /// 1:USDT-margined Futures,2: Coin-margined Futures
247    ///
248    /// This field is **required.
249    #[builder(setter(into))]
250    pub futures_type: i64,
251    ///
252    /// The `recv_window` parameter.
253    ///
254    /// This field is **optional.
255    #[builder(setter(into), default)]
256    pub recv_window: Option<i64>,
257}
258
259impl GetDetailOnSubAccountsFuturesAccountV2Params {
260    /// Create a builder for [`get_detail_on_sub_accounts_futures_account_v2`].
261    ///
262    /// Required parameters:
263    ///
264    /// * `email` — [Sub-account email](#email-address)
265    /// * `futures_type` — 1:USDT-margined Futures,2: Coin-margined Futures
266    ///
267    #[must_use]
268    pub fn builder(
269        email: String,
270        futures_type: i64,
271    ) -> GetDetailOnSubAccountsFuturesAccountV2ParamsBuilder {
272        GetDetailOnSubAccountsFuturesAccountV2ParamsBuilder::default()
273            .email(email)
274            .futures_type(futures_type)
275    }
276}
277/// Request parameters for the [`get_detail_on_sub_accounts_margin_account`] operation.
278///
279/// This struct holds all of the inputs you can pass when calling
280/// [`get_detail_on_sub_accounts_margin_account`](#method.get_detail_on_sub_accounts_margin_account).
281#[derive(Clone, Debug, Builder)]
282#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
283pub struct GetDetailOnSubAccountsMarginAccountParams {
284    /// [Sub-account email](#email-address)
285    ///
286    /// This field is **required.
287    #[builder(setter(into))]
288    pub email: String,
289    ///
290    /// The `recv_window` parameter.
291    ///
292    /// This field is **optional.
293    #[builder(setter(into), default)]
294    pub recv_window: Option<i64>,
295}
296
297impl GetDetailOnSubAccountsMarginAccountParams {
298    /// Create a builder for [`get_detail_on_sub_accounts_margin_account`].
299    ///
300    /// Required parameters:
301    ///
302    /// * `email` — [Sub-account email](#email-address)
303    ///
304    #[must_use]
305    pub fn builder(email: String) -> GetDetailOnSubAccountsMarginAccountParamsBuilder {
306        GetDetailOnSubAccountsMarginAccountParamsBuilder::default().email(email)
307    }
308}
309/// Request parameters for the [`get_move_position_history_for_sub_account`] operation.
310///
311/// This struct holds all of the inputs you can pass when calling
312/// [`get_move_position_history_for_sub_account`](#method.get_move_position_history_for_sub_account).
313#[derive(Clone, Debug, Builder)]
314#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
315pub struct GetMovePositionHistoryForSubAccountParams {
316    ///
317    /// The `symbol` parameter.
318    ///
319    /// This field is **required.
320    #[builder(setter(into))]
321    pub symbol: String,
322    /// Page
323    ///
324    /// This field is **required.
325    #[builder(setter(into))]
326    pub page: i64,
327    ///
328    /// The `rows` parameter.
329    ///
330    /// This field is **required.
331    #[builder(setter(into))]
332    pub rows: i64,
333    ///
334    /// The `start_time` parameter.
335    ///
336    /// This field is **optional.
337    #[builder(setter(into), default)]
338    pub start_time: Option<i64>,
339    ///
340    /// The `end_time` parameter.
341    ///
342    /// This field is **optional.
343    #[builder(setter(into), default)]
344    pub end_time: Option<i64>,
345    ///
346    /// The `recv_window` parameter.
347    ///
348    /// This field is **optional.
349    #[builder(setter(into), default)]
350    pub recv_window: Option<i64>,
351}
352
353impl GetMovePositionHistoryForSubAccountParams {
354    /// Create a builder for [`get_move_position_history_for_sub_account`].
355    ///
356    /// Required parameters:
357    ///
358    /// * `symbol` — String
359    /// * `page` — Page
360    /// * `rows` — i64
361    ///
362    #[must_use]
363    pub fn builder(
364        symbol: String,
365        page: i64,
366        rows: i64,
367    ) -> GetMovePositionHistoryForSubAccountParamsBuilder {
368        GetMovePositionHistoryForSubAccountParamsBuilder::default()
369            .symbol(symbol)
370            .page(page)
371            .rows(rows)
372    }
373}
374/// Request parameters for the [`get_sub_account_deposit_address`] operation.
375///
376/// This struct holds all of the inputs you can pass when calling
377/// [`get_sub_account_deposit_address`](#method.get_sub_account_deposit_address).
378#[derive(Clone, Debug, Builder)]
379#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
380pub struct GetSubAccountDepositAddressParams {
381    /// [Sub-account email](#email-address)
382    ///
383    /// This field is **required.
384    #[builder(setter(into))]
385    pub email: String,
386    ///
387    /// The `coin` parameter.
388    ///
389    /// This field is **required.
390    #[builder(setter(into))]
391    pub coin: String,
392    /// networks can be found in `GET /sapi/v1/capital/deposit/address`
393    ///
394    /// This field is **optional.
395    #[builder(setter(into), default)]
396    pub network: Option<String>,
397    ///
398    /// The `amount` parameter.
399    ///
400    /// This field is **optional.
401    #[builder(setter(into), default)]
402    pub amount: Option<rust_decimal::Decimal>,
403    ///
404    /// The `recv_window` parameter.
405    ///
406    /// This field is **optional.
407    #[builder(setter(into), default)]
408    pub recv_window: Option<i64>,
409}
410
411impl GetSubAccountDepositAddressParams {
412    /// Create a builder for [`get_sub_account_deposit_address`].
413    ///
414    /// Required parameters:
415    ///
416    /// * `email` — [Sub-account email](#email-address)
417    /// * `coin` — String
418    ///
419    #[must_use]
420    pub fn builder(email: String, coin: String) -> GetSubAccountDepositAddressParamsBuilder {
421        GetSubAccountDepositAddressParamsBuilder::default()
422            .email(email)
423            .coin(coin)
424    }
425}
426/// Request parameters for the [`get_sub_account_deposit_history`] operation.
427///
428/// This struct holds all of the inputs you can pass when calling
429/// [`get_sub_account_deposit_history`](#method.get_sub_account_deposit_history).
430#[derive(Clone, Debug, Builder)]
431#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
432pub struct GetSubAccountDepositHistoryParams {
433    /// [Sub-account email](#email-address)
434    ///
435    /// This field is **required.
436    #[builder(setter(into))]
437    pub email: String,
438    /// Default: `false`, return `sourceAddress`field when set to `true`
439    ///
440    /// This field is **optional.
441    #[builder(setter(into), default)]
442    pub include_source: Option<bool>,
443    ///
444    /// The `coin` parameter.
445    ///
446    /// This field is **optional.
447    #[builder(setter(into), default)]
448    pub coin: Option<String>,
449    /// 0(0:pending,6: credited but cannot withdraw,7:Wrong Deposit,8:Waiting User confirm,1:success)
450    ///
451    /// This field is **optional.
452    #[builder(setter(into), default)]
453    pub status: Option<i64>,
454    ///
455    /// The `start_time` parameter.
456    ///
457    /// This field is **optional.
458    #[builder(setter(into), default)]
459    pub start_time: Option<i64>,
460    ///
461    /// The `end_time` parameter.
462    ///
463    /// This field is **optional.
464    #[builder(setter(into), default)]
465    pub end_time: Option<i64>,
466    /// Default value: 1, Max value: 200
467    ///
468    /// This field is **optional.
469    #[builder(setter(into), default)]
470    pub limit: Option<i64>,
471    /// default:0
472    ///
473    /// This field is **optional.
474    #[builder(setter(into), default)]
475    pub offset: Option<i64>,
476    ///
477    /// The `recv_window` parameter.
478    ///
479    /// This field is **optional.
480    #[builder(setter(into), default)]
481    pub recv_window: Option<i64>,
482    ///
483    /// The `tx_id` parameter.
484    ///
485    /// This field is **optional.
486    #[builder(setter(into), default)]
487    pub tx_id: Option<String>,
488}
489
490impl GetSubAccountDepositHistoryParams {
491    /// Create a builder for [`get_sub_account_deposit_history`].
492    ///
493    /// Required parameters:
494    ///
495    /// * `email` — [Sub-account email](#email-address)
496    ///
497    #[must_use]
498    pub fn builder(email: String) -> GetSubAccountDepositHistoryParamsBuilder {
499        GetSubAccountDepositHistoryParamsBuilder::default().email(email)
500    }
501}
502/// Request parameters for the [`get_summary_of_sub_accounts_futures_account`] operation.
503///
504/// This struct holds all of the inputs you can pass when calling
505/// [`get_summary_of_sub_accounts_futures_account`](#method.get_summary_of_sub_accounts_futures_account).
506#[derive(Clone, Debug, Builder)]
507#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
508pub struct GetSummaryOfSubAccountsFuturesAccountParams {
509    /// Page
510    ///
511    /// This field is **required.
512    #[builder(setter(into))]
513    pub page: i64,
514    /// Limit (Max: 500)
515    ///
516    /// This field is **required.
517    #[builder(setter(into))]
518    pub limit: i64,
519    ///
520    /// The `recv_window` parameter.
521    ///
522    /// This field is **optional.
523    #[builder(setter(into), default)]
524    pub recv_window: Option<i64>,
525}
526
527impl GetSummaryOfSubAccountsFuturesAccountParams {
528    /// Create a builder for [`get_summary_of_sub_accounts_futures_account`].
529    ///
530    /// Required parameters:
531    ///
532    /// * `page` — Page
533    /// * `limit` — Limit (Max: 500)
534    ///
535    #[must_use]
536    pub fn builder(page: i64, limit: i64) -> GetSummaryOfSubAccountsFuturesAccountParamsBuilder {
537        GetSummaryOfSubAccountsFuturesAccountParamsBuilder::default()
538            .page(page)
539            .limit(limit)
540    }
541}
542/// Request parameters for the [`get_summary_of_sub_accounts_futures_account_v2`] operation.
543///
544/// This struct holds all of the inputs you can pass when calling
545/// [`get_summary_of_sub_accounts_futures_account_v2`](#method.get_summary_of_sub_accounts_futures_account_v2).
546#[derive(Clone, Debug, Builder)]
547#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
548pub struct GetSummaryOfSubAccountsFuturesAccountV2Params {
549    /// 1:USDT-margined Futures,2: Coin-margined Futures
550    ///
551    /// This field is **required.
552    #[builder(setter(into))]
553    pub futures_type: i64,
554    /// Default value: 1
555    ///
556    /// This field is **optional.
557    #[builder(setter(into), default)]
558    pub page: Option<i64>,
559    /// Default value: 1, Max value: 200
560    ///
561    /// This field is **optional.
562    #[builder(setter(into), default)]
563    pub limit: Option<i64>,
564    ///
565    /// The `recv_window` parameter.
566    ///
567    /// This field is **optional.
568    #[builder(setter(into), default)]
569    pub recv_window: Option<i64>,
570}
571
572impl GetSummaryOfSubAccountsFuturesAccountV2Params {
573    /// Create a builder for [`get_summary_of_sub_accounts_futures_account_v2`].
574    ///
575    /// Required parameters:
576    ///
577    /// * `futures_type` — 1:USDT-margined Futures,2: Coin-margined Futures
578    ///
579    #[must_use]
580    pub fn builder(futures_type: i64) -> GetSummaryOfSubAccountsFuturesAccountV2ParamsBuilder {
581        GetSummaryOfSubAccountsFuturesAccountV2ParamsBuilder::default().futures_type(futures_type)
582    }
583}
584/// Request parameters for the [`get_summary_of_sub_accounts_margin_account`] operation.
585///
586/// This struct holds all of the inputs you can pass when calling
587/// [`get_summary_of_sub_accounts_margin_account`](#method.get_summary_of_sub_accounts_margin_account).
588#[derive(Clone, Debug, Builder, Default)]
589#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
590pub struct GetSummaryOfSubAccountsMarginAccountParams {
591    ///
592    /// The `recv_window` parameter.
593    ///
594    /// This field is **optional.
595    #[builder(setter(into), default)]
596    pub recv_window: Option<i64>,
597}
598
599impl GetSummaryOfSubAccountsMarginAccountParams {
600    /// Create a builder for [`get_summary_of_sub_accounts_margin_account`].
601    ///
602    #[must_use]
603    pub fn builder() -> GetSummaryOfSubAccountsMarginAccountParamsBuilder {
604        GetSummaryOfSubAccountsMarginAccountParamsBuilder::default()
605    }
606}
607/// Request parameters for the [`margin_transfer_for_sub_account`] operation.
608///
609/// This struct holds all of the inputs you can pass when calling
610/// [`margin_transfer_for_sub_account`](#method.margin_transfer_for_sub_account).
611#[derive(Clone, Debug, Builder)]
612#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
613pub struct MarginTransferForSubAccountParams {
614    /// [Sub-account email](#email-address)
615    ///
616    /// This field is **required.
617    #[builder(setter(into))]
618    pub email: String,
619    ///
620    /// The `asset` parameter.
621    ///
622    /// This field is **required.
623    #[builder(setter(into))]
624    pub asset: String,
625    ///
626    /// The `amount` parameter.
627    ///
628    /// This field is **required.
629    #[builder(setter(into))]
630    pub amount: rust_decimal::Decimal,
631    /// 1: transfer from subaccount's  spot account to margin account 2: transfer from subaccount's margin account to its spot account
632    ///
633    /// This field is **required.
634    #[builder(setter(into))]
635    pub r#type: i64,
636    ///
637    /// The `recv_window` parameter.
638    ///
639    /// This field is **optional.
640    #[builder(setter(into), default)]
641    pub recv_window: Option<i64>,
642}
643
644impl MarginTransferForSubAccountParams {
645    /// Create a builder for [`margin_transfer_for_sub_account`].
646    ///
647    /// Required parameters:
648    ///
649    /// * `email` — [Sub-account email](#email-address)
650    /// * `asset` — String
651    /// * `amount` — `rust_decimal::Decimal`
652    /// * `r#type` — 1: transfer from subaccount's  spot account to margin account 2: transfer from subaccount's margin account to its spot account
653    ///
654    #[must_use]
655    pub fn builder(
656        email: String,
657        asset: String,
658        amount: rust_decimal::Decimal,
659        r#type: i64,
660    ) -> MarginTransferForSubAccountParamsBuilder {
661        MarginTransferForSubAccountParamsBuilder::default()
662            .email(email)
663            .asset(asset)
664            .amount(amount)
665            .r#type(r#type)
666    }
667}
668/// Request parameters for the [`move_position_for_sub_account`] operation.
669///
670/// This struct holds all of the inputs you can pass when calling
671/// [`move_position_for_sub_account`](#method.move_position_for_sub_account).
672#[derive(Clone, Debug, Builder)]
673#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
674pub struct MovePositionForSubAccountParams {
675    ///
676    /// The `from_user_email` parameter.
677    ///
678    /// This field is **required.
679    #[builder(setter(into))]
680    pub from_user_email: String,
681    ///
682    /// The `to_user_email` parameter.
683    ///
684    /// This field is **required.
685    #[builder(setter(into))]
686    pub to_user_email: String,
687    /// Only support UM
688    ///
689    /// This field is **required.
690    #[builder(setter(into))]
691    pub product_type: String,
692    /// Max 10 positions supported. When input request parameter,orderArgs.symbol should be STRING, orderArgs.quantity should be BIGDECIMAL, and orderArgs.positionSide should be STRING, positionSide support BOTH,LONG and SHORT. Each entry should be like orderArgs[0].symbol=BTCUSDT,orderArgs[0].quantity=0.001,orderArgs[0].positionSide=BOTH. Example of the request parameter array: orderArgs[0].symbol=BTCUSDT orderArgs[0].quantity=0.001 orderArgs[0].positionSide=BOTH orderArgs[1].symbol=ETHUSDT orderArgs[1].quantity=0.01 orderArgs[1].positionSide=BOTH
693    ///
694    /// This field is **required.
695    #[builder(setter(into))]
696    pub order_args: Vec<models::MovePositionForSubAccountOrderArgsParameterInner>,
697    ///
698    /// The `recv_window` parameter.
699    ///
700    /// This field is **optional.
701    #[builder(setter(into), default)]
702    pub recv_window: Option<i64>,
703}
704
705impl MovePositionForSubAccountParams {
706    /// Create a builder for [`move_position_for_sub_account`].
707    ///
708    /// Required parameters:
709    ///
710    /// * `from_user_email` — String
711    /// * `to_user_email` — String
712    /// * `product_type` — Only support UM
713    /// * `order_args` — Max 10 positions supported. When input request parameter,orderArgs.symbol should be STRING, orderArgs.quantity should be BIGDECIMAL, and orderArgs.positionSide should be STRING, positionSide support BOTH,LONG and SHORT. Each entry should be like orderArgs[0].symbol=BTCUSDT,orderArgs[0].quantity=0.001,orderArgs[0].positionSide=BOTH. Example of the request parameter array: orderArgs[0].symbol=BTCUSDT orderArgs[0].quantity=0.001 orderArgs[0].positionSide=BOTH orderArgs[1].symbol=ETHUSDT orderArgs[1].quantity=0.01 orderArgs[1].positionSide=BOTH
714    ///
715    #[must_use]
716    pub fn builder(
717        from_user_email: String,
718        to_user_email: String,
719        product_type: String,
720        order_args: Vec<models::MovePositionForSubAccountOrderArgsParameterInner>,
721    ) -> MovePositionForSubAccountParamsBuilder {
722        MovePositionForSubAccountParamsBuilder::default()
723            .from_user_email(from_user_email)
724            .to_user_email(to_user_email)
725            .product_type(product_type)
726            .order_args(order_args)
727    }
728}
729/// Request parameters for the [`query_sub_account_assets`] operation.
730///
731/// This struct holds all of the inputs you can pass when calling
732/// [`query_sub_account_assets`](#method.query_sub_account_assets).
733#[derive(Clone, Debug, Builder)]
734#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
735pub struct QuerySubAccountAssetsParams {
736    /// [Sub-account email](#email-address)
737    ///
738    /// This field is **required.
739    #[builder(setter(into))]
740    pub email: String,
741    ///
742    /// The `recv_window` parameter.
743    ///
744    /// This field is **optional.
745    #[builder(setter(into), default)]
746    pub recv_window: Option<i64>,
747}
748
749impl QuerySubAccountAssetsParams {
750    /// Create a builder for [`query_sub_account_assets`].
751    ///
752    /// Required parameters:
753    ///
754    /// * `email` — [Sub-account email](#email-address)
755    ///
756    #[must_use]
757    pub fn builder(email: String) -> QuerySubAccountAssetsParamsBuilder {
758        QuerySubAccountAssetsParamsBuilder::default().email(email)
759    }
760}
761/// Request parameters for the [`query_sub_account_assets_asset_management`] operation.
762///
763/// This struct holds all of the inputs you can pass when calling
764/// [`query_sub_account_assets_asset_management`](#method.query_sub_account_assets_asset_management).
765#[derive(Clone, Debug, Builder)]
766#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
767pub struct QuerySubAccountAssetsAssetManagementParams {
768    /// [Sub-account email](#email-address)
769    ///
770    /// This field is **required.
771    #[builder(setter(into))]
772    pub email: String,
773    ///
774    /// The `recv_window` parameter.
775    ///
776    /// This field is **optional.
777    #[builder(setter(into), default)]
778    pub recv_window: Option<i64>,
779}
780
781impl QuerySubAccountAssetsAssetManagementParams {
782    /// Create a builder for [`query_sub_account_assets_asset_management`].
783    ///
784    /// Required parameters:
785    ///
786    /// * `email` — [Sub-account email](#email-address)
787    ///
788    #[must_use]
789    pub fn builder(email: String) -> QuerySubAccountAssetsAssetManagementParamsBuilder {
790        QuerySubAccountAssetsAssetManagementParamsBuilder::default().email(email)
791    }
792}
793/// Request parameters for the [`query_sub_account_futures_asset_transfer_history`] operation.
794///
795/// This struct holds all of the inputs you can pass when calling
796/// [`query_sub_account_futures_asset_transfer_history`](#method.query_sub_account_futures_asset_transfer_history).
797#[derive(Clone, Debug, Builder)]
798#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
799pub struct QuerySubAccountFuturesAssetTransferHistoryParams {
800    /// [Sub-account email](#email-address)
801    ///
802    /// This field is **required.
803    #[builder(setter(into))]
804    pub email: String,
805    /// 1:USDT-margined Futures,2: Coin-margined Futures
806    ///
807    /// This field is **required.
808    #[builder(setter(into))]
809    pub futures_type: i64,
810    ///
811    /// The `start_time` parameter.
812    ///
813    /// This field is **optional.
814    #[builder(setter(into), default)]
815    pub start_time: Option<i64>,
816    ///
817    /// The `end_time` parameter.
818    ///
819    /// This field is **optional.
820    #[builder(setter(into), default)]
821    pub end_time: Option<i64>,
822    /// Default value: 1
823    ///
824    /// This field is **optional.
825    #[builder(setter(into), default)]
826    pub page: Option<i64>,
827    /// Default value: 1, Max value: 200
828    ///
829    /// This field is **optional.
830    #[builder(setter(into), default)]
831    pub limit: Option<i64>,
832    ///
833    /// The `recv_window` parameter.
834    ///
835    /// This field is **optional.
836    #[builder(setter(into), default)]
837    pub recv_window: Option<i64>,
838}
839
840impl QuerySubAccountFuturesAssetTransferHistoryParams {
841    /// Create a builder for [`query_sub_account_futures_asset_transfer_history`].
842    ///
843    /// Required parameters:
844    ///
845    /// * `email` — [Sub-account email](#email-address)
846    /// * `futures_type` — 1:USDT-margined Futures,2: Coin-margined Futures
847    ///
848    #[must_use]
849    pub fn builder(
850        email: String,
851        futures_type: i64,
852    ) -> QuerySubAccountFuturesAssetTransferHistoryParamsBuilder {
853        QuerySubAccountFuturesAssetTransferHistoryParamsBuilder::default()
854            .email(email)
855            .futures_type(futures_type)
856    }
857}
858/// Request parameters for the [`query_sub_account_spot_asset_transfer_history`] operation.
859///
860/// This struct holds all of the inputs you can pass when calling
861/// [`query_sub_account_spot_asset_transfer_history`](#method.query_sub_account_spot_asset_transfer_history).
862#[derive(Clone, Debug, Builder, Default)]
863#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
864pub struct QuerySubAccountSpotAssetTransferHistoryParams {
865    ///
866    /// The `from_email` parameter.
867    ///
868    /// This field is **optional.
869    #[builder(setter(into), default)]
870    pub from_email: Option<String>,
871    ///
872    /// The `to_email` parameter.
873    ///
874    /// This field is **optional.
875    #[builder(setter(into), default)]
876    pub to_email: Option<String>,
877    ///
878    /// The `start_time` parameter.
879    ///
880    /// This field is **optional.
881    #[builder(setter(into), default)]
882    pub start_time: Option<i64>,
883    ///
884    /// The `end_time` parameter.
885    ///
886    /// This field is **optional.
887    #[builder(setter(into), default)]
888    pub end_time: Option<i64>,
889    /// Default value: 1
890    ///
891    /// This field is **optional.
892    #[builder(setter(into), default)]
893    pub page: Option<i64>,
894    /// Default value: 1, Max value: 200
895    ///
896    /// This field is **optional.
897    #[builder(setter(into), default)]
898    pub limit: Option<i64>,
899    ///
900    /// The `recv_window` parameter.
901    ///
902    /// This field is **optional.
903    #[builder(setter(into), default)]
904    pub recv_window: Option<i64>,
905}
906
907impl QuerySubAccountSpotAssetTransferHistoryParams {
908    /// Create a builder for [`query_sub_account_spot_asset_transfer_history`].
909    ///
910    #[must_use]
911    pub fn builder() -> QuerySubAccountSpotAssetTransferHistoryParamsBuilder {
912        QuerySubAccountSpotAssetTransferHistoryParamsBuilder::default()
913    }
914}
915/// Request parameters for the [`query_sub_account_spot_assets_summary`] operation.
916///
917/// This struct holds all of the inputs you can pass when calling
918/// [`query_sub_account_spot_assets_summary`](#method.query_sub_account_spot_assets_summary).
919#[derive(Clone, Debug, Builder, Default)]
920#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
921pub struct QuerySubAccountSpotAssetsSummaryParams {
922    /// Managed sub-account email
923    ///
924    /// This field is **optional.
925    #[builder(setter(into), default)]
926    pub email: Option<String>,
927    /// Default value: 1
928    ///
929    /// This field is **optional.
930    #[builder(setter(into), default)]
931    pub page: Option<i64>,
932    /// default 10, max 20
933    ///
934    /// This field is **optional.
935    #[builder(setter(into), default)]
936    pub size: Option<i64>,
937    ///
938    /// The `recv_window` parameter.
939    ///
940    /// This field is **optional.
941    #[builder(setter(into), default)]
942    pub recv_window: Option<i64>,
943}
944
945impl QuerySubAccountSpotAssetsSummaryParams {
946    /// Create a builder for [`query_sub_account_spot_assets_summary`].
947    ///
948    #[must_use]
949    pub fn builder() -> QuerySubAccountSpotAssetsSummaryParamsBuilder {
950        QuerySubAccountSpotAssetsSummaryParamsBuilder::default()
951    }
952}
953/// Request parameters for the [`query_universal_transfer_history`] operation.
954///
955/// This struct holds all of the inputs you can pass when calling
956/// [`query_universal_transfer_history`](#method.query_universal_transfer_history).
957#[derive(Clone, Debug, Builder, Default)]
958#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
959pub struct QueryUniversalTransferHistoryParams {
960    ///
961    /// The `from_email` parameter.
962    ///
963    /// This field is **optional.
964    #[builder(setter(into), default)]
965    pub from_email: Option<String>,
966    ///
967    /// The `to_email` parameter.
968    ///
969    /// This field is **optional.
970    #[builder(setter(into), default)]
971    pub to_email: Option<String>,
972    ///
973    /// The `client_tran_id` parameter.
974    ///
975    /// This field is **optional.
976    #[builder(setter(into), default)]
977    pub client_tran_id: Option<String>,
978    ///
979    /// The `start_time` parameter.
980    ///
981    /// This field is **optional.
982    #[builder(setter(into), default)]
983    pub start_time: Option<i64>,
984    ///
985    /// The `end_time` parameter.
986    ///
987    /// This field is **optional.
988    #[builder(setter(into), default)]
989    pub end_time: Option<i64>,
990    /// Default value: 1
991    ///
992    /// This field is **optional.
993    #[builder(setter(into), default)]
994    pub page: Option<i64>,
995    /// Default value: 1, Max value: 200
996    ///
997    /// This field is **optional.
998    #[builder(setter(into), default)]
999    pub limit: Option<i64>,
1000    ///
1001    /// The `recv_window` parameter.
1002    ///
1003    /// This field is **optional.
1004    #[builder(setter(into), default)]
1005    pub recv_window: Option<i64>,
1006}
1007
1008impl QueryUniversalTransferHistoryParams {
1009    /// Create a builder for [`query_universal_transfer_history`].
1010    ///
1011    #[must_use]
1012    pub fn builder() -> QueryUniversalTransferHistoryParamsBuilder {
1013        QueryUniversalTransferHistoryParamsBuilder::default()
1014    }
1015}
1016/// Request parameters for the [`sub_account_futures_asset_transfer`] operation.
1017///
1018/// This struct holds all of the inputs you can pass when calling
1019/// [`sub_account_futures_asset_transfer`](#method.sub_account_futures_asset_transfer).
1020#[derive(Clone, Debug, Builder)]
1021#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1022pub struct SubAccountFuturesAssetTransferParams {
1023    ///
1024    /// The `from_email` parameter.
1025    ///
1026    /// This field is **required.
1027    #[builder(setter(into))]
1028    pub from_email: String,
1029    ///
1030    /// The `to_email` parameter.
1031    ///
1032    /// This field is **required.
1033    #[builder(setter(into))]
1034    pub to_email: String,
1035    /// 1:USDT-margined Futures,2: Coin-margined Futures
1036    ///
1037    /// This field is **required.
1038    #[builder(setter(into))]
1039    pub futures_type: i64,
1040    ///
1041    /// The `asset` parameter.
1042    ///
1043    /// This field is **required.
1044    #[builder(setter(into))]
1045    pub asset: String,
1046    ///
1047    /// The `amount` parameter.
1048    ///
1049    /// This field is **required.
1050    #[builder(setter(into))]
1051    pub amount: rust_decimal::Decimal,
1052    ///
1053    /// The `recv_window` parameter.
1054    ///
1055    /// This field is **optional.
1056    #[builder(setter(into), default)]
1057    pub recv_window: Option<i64>,
1058}
1059
1060impl SubAccountFuturesAssetTransferParams {
1061    /// Create a builder for [`sub_account_futures_asset_transfer`].
1062    ///
1063    /// Required parameters:
1064    ///
1065    /// * `from_email` — String
1066    /// * `to_email` — String
1067    /// * `futures_type` — 1:USDT-margined Futures,2: Coin-margined Futures
1068    /// * `asset` — String
1069    /// * `amount` — `rust_decimal::Decimal`
1070    ///
1071    #[must_use]
1072    pub fn builder(
1073        from_email: String,
1074        to_email: String,
1075        futures_type: i64,
1076        asset: String,
1077        amount: rust_decimal::Decimal,
1078    ) -> SubAccountFuturesAssetTransferParamsBuilder {
1079        SubAccountFuturesAssetTransferParamsBuilder::default()
1080            .from_email(from_email)
1081            .to_email(to_email)
1082            .futures_type(futures_type)
1083            .asset(asset)
1084            .amount(amount)
1085    }
1086}
1087/// Request parameters for the [`sub_account_transfer_history`] operation.
1088///
1089/// This struct holds all of the inputs you can pass when calling
1090/// [`sub_account_transfer_history`](#method.sub_account_transfer_history).
1091#[derive(Clone, Debug, Builder, Default)]
1092#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1093pub struct SubAccountTransferHistoryParams {
1094    /// If not sent, result of all assets will be returned
1095    ///
1096    /// This field is **optional.
1097    #[builder(setter(into), default)]
1098    pub asset: Option<String>,
1099    /// 1: transfer in, 2: transfer out
1100    ///
1101    /// This field is **optional.
1102    #[builder(setter(into), default)]
1103    pub r#type: Option<i64>,
1104    ///
1105    /// The `start_time` parameter.
1106    ///
1107    /// This field is **optional.
1108    #[builder(setter(into), default)]
1109    pub start_time: Option<i64>,
1110    ///
1111    /// The `end_time` parameter.
1112    ///
1113    /// This field is **optional.
1114    #[builder(setter(into), default)]
1115    pub end_time: Option<i64>,
1116    /// Default value: 1, Max value: 200
1117    ///
1118    /// This field is **optional.
1119    #[builder(setter(into), default)]
1120    pub limit: Option<i64>,
1121    /// Default `False`, return PROCESS and SUCCESS status history; If `True`,return PROCESS and SUCCESS and FAILURE status history
1122    ///
1123    /// This field is **optional.
1124    #[builder(setter(into), default)]
1125    pub return_fail_history: Option<bool>,
1126    ///
1127    /// The `recv_window` parameter.
1128    ///
1129    /// This field is **optional.
1130    #[builder(setter(into), default)]
1131    pub recv_window: Option<i64>,
1132}
1133
1134impl SubAccountTransferHistoryParams {
1135    /// Create a builder for [`sub_account_transfer_history`].
1136    ///
1137    #[must_use]
1138    pub fn builder() -> SubAccountTransferHistoryParamsBuilder {
1139        SubAccountTransferHistoryParamsBuilder::default()
1140    }
1141}
1142/// Request parameters for the [`transfer_to_master`] operation.
1143///
1144/// This struct holds all of the inputs you can pass when calling
1145/// [`transfer_to_master`](#method.transfer_to_master).
1146#[derive(Clone, Debug, Builder)]
1147#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1148pub struct TransferToMasterParams {
1149    ///
1150    /// The `asset` parameter.
1151    ///
1152    /// This field is **required.
1153    #[builder(setter(into))]
1154    pub asset: String,
1155    ///
1156    /// The `amount` parameter.
1157    ///
1158    /// This field is **required.
1159    #[builder(setter(into))]
1160    pub amount: rust_decimal::Decimal,
1161    ///
1162    /// The `recv_window` parameter.
1163    ///
1164    /// This field is **optional.
1165    #[builder(setter(into), default)]
1166    pub recv_window: Option<i64>,
1167}
1168
1169impl TransferToMasterParams {
1170    /// Create a builder for [`transfer_to_master`].
1171    ///
1172    /// Required parameters:
1173    ///
1174    /// * `asset` — String
1175    /// * `amount` — `rust_decimal::Decimal`
1176    ///
1177    #[must_use]
1178    pub fn builder(asset: String, amount: rust_decimal::Decimal) -> TransferToMasterParamsBuilder {
1179        TransferToMasterParamsBuilder::default()
1180            .asset(asset)
1181            .amount(amount)
1182    }
1183}
1184/// Request parameters for the [`transfer_to_sub_account_of_same_master`] operation.
1185///
1186/// This struct holds all of the inputs you can pass when calling
1187/// [`transfer_to_sub_account_of_same_master`](#method.transfer_to_sub_account_of_same_master).
1188#[derive(Clone, Debug, Builder)]
1189#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1190pub struct TransferToSubAccountOfSameMasterParams {
1191    ///
1192    /// The `to_email` parameter.
1193    ///
1194    /// This field is **required.
1195    #[builder(setter(into))]
1196    pub to_email: String,
1197    ///
1198    /// The `asset` parameter.
1199    ///
1200    /// This field is **required.
1201    #[builder(setter(into))]
1202    pub asset: String,
1203    ///
1204    /// The `amount` parameter.
1205    ///
1206    /// This field is **required.
1207    #[builder(setter(into))]
1208    pub amount: rust_decimal::Decimal,
1209    ///
1210    /// The `recv_window` parameter.
1211    ///
1212    /// This field is **optional.
1213    #[builder(setter(into), default)]
1214    pub recv_window: Option<i64>,
1215}
1216
1217impl TransferToSubAccountOfSameMasterParams {
1218    /// Create a builder for [`transfer_to_sub_account_of_same_master`].
1219    ///
1220    /// Required parameters:
1221    ///
1222    /// * `to_email` — String
1223    /// * `asset` — String
1224    /// * `amount` — `rust_decimal::Decimal`
1225    ///
1226    #[must_use]
1227    pub fn builder(
1228        to_email: String,
1229        asset: String,
1230        amount: rust_decimal::Decimal,
1231    ) -> TransferToSubAccountOfSameMasterParamsBuilder {
1232        TransferToSubAccountOfSameMasterParamsBuilder::default()
1233            .to_email(to_email)
1234            .asset(asset)
1235            .amount(amount)
1236    }
1237}
1238/// Request parameters for the [`universal_transfer`] operation.
1239///
1240/// This struct holds all of the inputs you can pass when calling
1241/// [`universal_transfer`](#method.universal_transfer).
1242#[derive(Clone, Debug, Builder)]
1243#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1244pub struct UniversalTransferParams {
1245    /// "`SPOT","USDT_FUTURE","COIN_FUTURE","MARGIN"(Cross),"ISOLATED_MARGIN`"
1246    ///
1247    /// This field is **required.
1248    #[builder(setter(into))]
1249    pub from_account_type: String,
1250    /// "`SPOT","USDT_FUTURE","COIN_FUTURE","MARGIN"(Cross),"ISOLATED_MARGIN`"
1251    ///
1252    /// This field is **required.
1253    #[builder(setter(into))]
1254    pub to_account_type: String,
1255    ///
1256    /// The `asset` parameter.
1257    ///
1258    /// This field is **required.
1259    #[builder(setter(into))]
1260    pub asset: String,
1261    ///
1262    /// The `amount` parameter.
1263    ///
1264    /// This field is **required.
1265    #[builder(setter(into))]
1266    pub amount: rust_decimal::Decimal,
1267    ///
1268    /// The `from_email` parameter.
1269    ///
1270    /// This field is **optional.
1271    #[builder(setter(into), default)]
1272    pub from_email: Option<String>,
1273    ///
1274    /// The `to_email` parameter.
1275    ///
1276    /// This field is **optional.
1277    #[builder(setter(into), default)]
1278    pub to_email: Option<String>,
1279    ///
1280    /// The `client_tran_id` parameter.
1281    ///
1282    /// This field is **optional.
1283    #[builder(setter(into), default)]
1284    pub client_tran_id: Option<String>,
1285    /// Only supported under `ISOLATED_MARGIN` type
1286    ///
1287    /// This field is **optional.
1288    #[builder(setter(into), default)]
1289    pub symbol: Option<String>,
1290    ///
1291    /// The `recv_window` parameter.
1292    ///
1293    /// This field is **optional.
1294    #[builder(setter(into), default)]
1295    pub recv_window: Option<i64>,
1296}
1297
1298impl UniversalTransferParams {
1299    /// Create a builder for [`universal_transfer`].
1300    ///
1301    /// Required parameters:
1302    ///
1303    /// * `from_account_type` — \"SPOT\",\"`USDT_FUTURE`\",\"`COIN_FUTURE`\",\"MARGIN\"(Cross),\"`ISOLATED_MARGIN`\"
1304    /// * `to_account_type` — \"SPOT\",\"`USDT_FUTURE`\",\"`COIN_FUTURE`\",\"MARGIN\"(Cross),\"`ISOLATED_MARGIN`\"
1305    /// * `asset` — String
1306    /// * `amount` — `rust_decimal::Decimal`
1307    ///
1308    #[must_use]
1309    pub fn builder(
1310        from_account_type: String,
1311        to_account_type: String,
1312        asset: String,
1313        amount: rust_decimal::Decimal,
1314    ) -> UniversalTransferParamsBuilder {
1315        UniversalTransferParamsBuilder::default()
1316            .from_account_type(from_account_type)
1317            .to_account_type(to_account_type)
1318            .asset(asset)
1319            .amount(amount)
1320    }
1321}
1322
1323#[async_trait]
1324impl AssetManagementApi for AssetManagementApiClient {
1325    async fn futures_transfer_for_sub_account(
1326        &self,
1327        params: FuturesTransferForSubAccountParams,
1328    ) -> anyhow::Result<RestApiResponse<models::FuturesTransferForSubAccountResponse>> {
1329        let FuturesTransferForSubAccountParams {
1330            email,
1331            asset,
1332            amount,
1333            r#type,
1334            recv_window,
1335        } = params;
1336
1337        let mut query_params = BTreeMap::new();
1338        let body_params = BTreeMap::new();
1339
1340        query_params.insert("email".to_string(), json!(email));
1341
1342        query_params.insert("asset".to_string(), json!(asset));
1343
1344        query_params.insert("amount".to_string(), json!(amount));
1345
1346        query_params.insert("type".to_string(), json!(r#type));
1347
1348        if let Some(rw) = recv_window {
1349            query_params.insert("recvWindow".to_string(), json!(rw));
1350        }
1351
1352        send_request::<models::FuturesTransferForSubAccountResponse>(
1353            &self.configuration,
1354            "/sapi/v1/sub-account/futures/transfer",
1355            reqwest::Method::POST,
1356            query_params,
1357            body_params,
1358            if HAS_TIME_UNIT {
1359                self.configuration.time_unit
1360            } else {
1361                None
1362            },
1363            true,
1364        )
1365        .await
1366    }
1367
1368    async fn get_detail_on_sub_accounts_futures_account(
1369        &self,
1370        params: GetDetailOnSubAccountsFuturesAccountParams,
1371    ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountResponse>> {
1372        let GetDetailOnSubAccountsFuturesAccountParams { email, recv_window } = params;
1373
1374        let mut query_params = BTreeMap::new();
1375        let body_params = BTreeMap::new();
1376
1377        query_params.insert("email".to_string(), json!(email));
1378
1379        if let Some(rw) = recv_window {
1380            query_params.insert("recvWindow".to_string(), json!(rw));
1381        }
1382
1383        send_request::<models::GetDetailOnSubAccountsFuturesAccountResponse>(
1384            &self.configuration,
1385            "/sapi/v1/sub-account/futures/account",
1386            reqwest::Method::GET,
1387            query_params,
1388            body_params,
1389            if HAS_TIME_UNIT {
1390                self.configuration.time_unit
1391            } else {
1392                None
1393            },
1394            true,
1395        )
1396        .await
1397    }
1398
1399    async fn get_detail_on_sub_accounts_futures_account_v2(
1400        &self,
1401        params: GetDetailOnSubAccountsFuturesAccountV2Params,
1402    ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountV2Response>>
1403    {
1404        let GetDetailOnSubAccountsFuturesAccountV2Params {
1405            email,
1406            futures_type,
1407            recv_window,
1408        } = params;
1409
1410        let mut query_params = BTreeMap::new();
1411        let body_params = BTreeMap::new();
1412
1413        query_params.insert("email".to_string(), json!(email));
1414
1415        query_params.insert("futuresType".to_string(), json!(futures_type));
1416
1417        if let Some(rw) = recv_window {
1418            query_params.insert("recvWindow".to_string(), json!(rw));
1419        }
1420
1421        send_request::<models::GetDetailOnSubAccountsFuturesAccountV2Response>(
1422            &self.configuration,
1423            "/sapi/v2/sub-account/futures/account",
1424            reqwest::Method::GET,
1425            query_params,
1426            body_params,
1427            if HAS_TIME_UNIT {
1428                self.configuration.time_unit
1429            } else {
1430                None
1431            },
1432            true,
1433        )
1434        .await
1435    }
1436
1437    async fn get_detail_on_sub_accounts_margin_account(
1438        &self,
1439        params: GetDetailOnSubAccountsMarginAccountParams,
1440    ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsMarginAccountResponse>> {
1441        let GetDetailOnSubAccountsMarginAccountParams { email, recv_window } = params;
1442
1443        let mut query_params = BTreeMap::new();
1444        let body_params = BTreeMap::new();
1445
1446        query_params.insert("email".to_string(), json!(email));
1447
1448        if let Some(rw) = recv_window {
1449            query_params.insert("recvWindow".to_string(), json!(rw));
1450        }
1451
1452        send_request::<models::GetDetailOnSubAccountsMarginAccountResponse>(
1453            &self.configuration,
1454            "/sapi/v1/sub-account/margin/account",
1455            reqwest::Method::GET,
1456            query_params,
1457            body_params,
1458            if HAS_TIME_UNIT {
1459                self.configuration.time_unit
1460            } else {
1461                None
1462            },
1463            true,
1464        )
1465        .await
1466    }
1467
1468    async fn get_move_position_history_for_sub_account(
1469        &self,
1470        params: GetMovePositionHistoryForSubAccountParams,
1471    ) -> anyhow::Result<RestApiResponse<models::GetMovePositionHistoryForSubAccountResponse>> {
1472        let GetMovePositionHistoryForSubAccountParams {
1473            symbol,
1474            page,
1475            rows,
1476            start_time,
1477            end_time,
1478            recv_window,
1479        } = params;
1480
1481        let mut query_params = BTreeMap::new();
1482        let body_params = BTreeMap::new();
1483
1484        query_params.insert("symbol".to_string(), json!(symbol));
1485
1486        if let Some(rw) = start_time {
1487            query_params.insert("startTime".to_string(), json!(rw));
1488        }
1489
1490        if let Some(rw) = end_time {
1491            query_params.insert("endTime".to_string(), json!(rw));
1492        }
1493
1494        query_params.insert("page".to_string(), json!(page));
1495
1496        query_params.insert("rows".to_string(), json!(rows));
1497
1498        if let Some(rw) = recv_window {
1499            query_params.insert("recvWindow".to_string(), json!(rw));
1500        }
1501
1502        send_request::<models::GetMovePositionHistoryForSubAccountResponse>(
1503            &self.configuration,
1504            "/sapi/v1/sub-account/futures/move-position",
1505            reqwest::Method::GET,
1506            query_params,
1507            body_params,
1508            if HAS_TIME_UNIT {
1509                self.configuration.time_unit
1510            } else {
1511                None
1512            },
1513            true,
1514        )
1515        .await
1516    }
1517
1518    async fn get_sub_account_deposit_address(
1519        &self,
1520        params: GetSubAccountDepositAddressParams,
1521    ) -> anyhow::Result<RestApiResponse<models::GetSubAccountDepositAddressResponse>> {
1522        let GetSubAccountDepositAddressParams {
1523            email,
1524            coin,
1525            network,
1526            amount,
1527            recv_window,
1528        } = params;
1529
1530        let mut query_params = BTreeMap::new();
1531        let body_params = BTreeMap::new();
1532
1533        query_params.insert("email".to_string(), json!(email));
1534
1535        query_params.insert("coin".to_string(), json!(coin));
1536
1537        if let Some(rw) = network {
1538            query_params.insert("network".to_string(), json!(rw));
1539        }
1540
1541        if let Some(rw) = amount {
1542            query_params.insert("amount".to_string(), json!(rw));
1543        }
1544
1545        if let Some(rw) = recv_window {
1546            query_params.insert("recvWindow".to_string(), json!(rw));
1547        }
1548
1549        send_request::<models::GetSubAccountDepositAddressResponse>(
1550            &self.configuration,
1551            "/sapi/v1/capital/deposit/subAddress",
1552            reqwest::Method::GET,
1553            query_params,
1554            body_params,
1555            if HAS_TIME_UNIT {
1556                self.configuration.time_unit
1557            } else {
1558                None
1559            },
1560            true,
1561        )
1562        .await
1563    }
1564
1565    async fn get_sub_account_deposit_history(
1566        &self,
1567        params: GetSubAccountDepositHistoryParams,
1568    ) -> anyhow::Result<RestApiResponse<Vec<models::GetSubAccountDepositHistoryResponseInner>>>
1569    {
1570        let GetSubAccountDepositHistoryParams {
1571            email,
1572            include_source,
1573            coin,
1574            status,
1575            start_time,
1576            end_time,
1577            limit,
1578            offset,
1579            recv_window,
1580            tx_id,
1581        } = params;
1582
1583        let mut query_params = BTreeMap::new();
1584        let body_params = BTreeMap::new();
1585
1586        query_params.insert("email".to_string(), json!(email));
1587
1588        if let Some(rw) = include_source {
1589            query_params.insert("includeSource".to_string(), json!(rw));
1590        }
1591
1592        if let Some(rw) = coin {
1593            query_params.insert("coin".to_string(), json!(rw));
1594        }
1595
1596        if let Some(rw) = status {
1597            query_params.insert("status".to_string(), json!(rw));
1598        }
1599
1600        if let Some(rw) = start_time {
1601            query_params.insert("startTime".to_string(), json!(rw));
1602        }
1603
1604        if let Some(rw) = end_time {
1605            query_params.insert("endTime".to_string(), json!(rw));
1606        }
1607
1608        if let Some(rw) = limit {
1609            query_params.insert("limit".to_string(), json!(rw));
1610        }
1611
1612        if let Some(rw) = offset {
1613            query_params.insert("offset".to_string(), json!(rw));
1614        }
1615
1616        if let Some(rw) = recv_window {
1617            query_params.insert("recvWindow".to_string(), json!(rw));
1618        }
1619
1620        if let Some(rw) = tx_id {
1621            query_params.insert("txId".to_string(), json!(rw));
1622        }
1623
1624        send_request::<Vec<models::GetSubAccountDepositHistoryResponseInner>>(
1625            &self.configuration,
1626            "/sapi/v1/capital/deposit/subHisrec",
1627            reqwest::Method::GET,
1628            query_params,
1629            body_params,
1630            if HAS_TIME_UNIT {
1631                self.configuration.time_unit
1632            } else {
1633                None
1634            },
1635            true,
1636        )
1637        .await
1638    }
1639
1640    async fn get_summary_of_sub_accounts_futures_account(
1641        &self,
1642        params: GetSummaryOfSubAccountsFuturesAccountParams,
1643    ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountResponse>>
1644    {
1645        let GetSummaryOfSubAccountsFuturesAccountParams {
1646            page,
1647            limit,
1648            recv_window,
1649        } = params;
1650
1651        let mut query_params = BTreeMap::new();
1652        let body_params = BTreeMap::new();
1653
1654        query_params.insert("page".to_string(), json!(page));
1655
1656        query_params.insert("limit".to_string(), json!(limit));
1657
1658        if let Some(rw) = recv_window {
1659            query_params.insert("recvWindow".to_string(), json!(rw));
1660        }
1661
1662        send_request::<models::GetSummaryOfSubAccountsFuturesAccountResponse>(
1663            &self.configuration,
1664            "/sapi/v1/sub-account/futures/accountSummary",
1665            reqwest::Method::GET,
1666            query_params,
1667            body_params,
1668            if HAS_TIME_UNIT {
1669                self.configuration.time_unit
1670            } else {
1671                None
1672            },
1673            true,
1674        )
1675        .await
1676    }
1677
1678    async fn get_summary_of_sub_accounts_futures_account_v2(
1679        &self,
1680        params: GetSummaryOfSubAccountsFuturesAccountV2Params,
1681    ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountV2Response>>
1682    {
1683        let GetSummaryOfSubAccountsFuturesAccountV2Params {
1684            futures_type,
1685            page,
1686            limit,
1687            recv_window,
1688        } = params;
1689
1690        let mut query_params = BTreeMap::new();
1691        let body_params = BTreeMap::new();
1692
1693        query_params.insert("futuresType".to_string(), json!(futures_type));
1694
1695        if let Some(rw) = page {
1696            query_params.insert("page".to_string(), json!(rw));
1697        }
1698
1699        if let Some(rw) = limit {
1700            query_params.insert("limit".to_string(), json!(rw));
1701        }
1702
1703        if let Some(rw) = recv_window {
1704            query_params.insert("recvWindow".to_string(), json!(rw));
1705        }
1706
1707        send_request::<models::GetSummaryOfSubAccountsFuturesAccountV2Response>(
1708            &self.configuration,
1709            "/sapi/v2/sub-account/futures/accountSummary",
1710            reqwest::Method::GET,
1711            query_params,
1712            body_params,
1713            if HAS_TIME_UNIT {
1714                self.configuration.time_unit
1715            } else {
1716                None
1717            },
1718            true,
1719        )
1720        .await
1721    }
1722
1723    async fn get_summary_of_sub_accounts_margin_account(
1724        &self,
1725        params: GetSummaryOfSubAccountsMarginAccountParams,
1726    ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsMarginAccountResponse>> {
1727        let GetSummaryOfSubAccountsMarginAccountParams { recv_window } = params;
1728
1729        let mut query_params = BTreeMap::new();
1730        let body_params = BTreeMap::new();
1731
1732        if let Some(rw) = recv_window {
1733            query_params.insert("recvWindow".to_string(), json!(rw));
1734        }
1735
1736        send_request::<models::GetSummaryOfSubAccountsMarginAccountResponse>(
1737            &self.configuration,
1738            "/sapi/v1/sub-account/margin/accountSummary",
1739            reqwest::Method::GET,
1740            query_params,
1741            body_params,
1742            if HAS_TIME_UNIT {
1743                self.configuration.time_unit
1744            } else {
1745                None
1746            },
1747            true,
1748        )
1749        .await
1750    }
1751
1752    async fn margin_transfer_for_sub_account(
1753        &self,
1754        params: MarginTransferForSubAccountParams,
1755    ) -> anyhow::Result<RestApiResponse<models::MarginTransferForSubAccountResponse>> {
1756        let MarginTransferForSubAccountParams {
1757            email,
1758            asset,
1759            amount,
1760            r#type,
1761            recv_window,
1762        } = params;
1763
1764        let mut query_params = BTreeMap::new();
1765        let body_params = BTreeMap::new();
1766
1767        query_params.insert("email".to_string(), json!(email));
1768
1769        query_params.insert("asset".to_string(), json!(asset));
1770
1771        query_params.insert("amount".to_string(), json!(amount));
1772
1773        query_params.insert("type".to_string(), json!(r#type));
1774
1775        if let Some(rw) = recv_window {
1776            query_params.insert("recvWindow".to_string(), json!(rw));
1777        }
1778
1779        send_request::<models::MarginTransferForSubAccountResponse>(
1780            &self.configuration,
1781            "/sapi/v1/sub-account/margin/transfer",
1782            reqwest::Method::POST,
1783            query_params,
1784            body_params,
1785            if HAS_TIME_UNIT {
1786                self.configuration.time_unit
1787            } else {
1788                None
1789            },
1790            true,
1791        )
1792        .await
1793    }
1794
1795    async fn move_position_for_sub_account(
1796        &self,
1797        params: MovePositionForSubAccountParams,
1798    ) -> anyhow::Result<RestApiResponse<models::MovePositionForSubAccountResponse>> {
1799        let MovePositionForSubAccountParams {
1800            from_user_email,
1801            to_user_email,
1802            product_type,
1803            order_args,
1804            recv_window,
1805        } = params;
1806
1807        let mut query_params = BTreeMap::new();
1808        let body_params = BTreeMap::new();
1809
1810        query_params.insert("fromUserEmail".to_string(), json!(from_user_email));
1811
1812        query_params.insert("toUserEmail".to_string(), json!(to_user_email));
1813
1814        query_params.insert("productType".to_string(), json!(product_type));
1815
1816        query_params.insert("orderArgs".to_string(), json!(order_args));
1817
1818        if let Some(rw) = recv_window {
1819            query_params.insert("recvWindow".to_string(), json!(rw));
1820        }
1821
1822        send_request::<models::MovePositionForSubAccountResponse>(
1823            &self.configuration,
1824            "/sapi/v1/sub-account/futures/move-position",
1825            reqwest::Method::POST,
1826            query_params,
1827            body_params,
1828            if HAS_TIME_UNIT {
1829                self.configuration.time_unit
1830            } else {
1831                None
1832            },
1833            true,
1834        )
1835        .await
1836    }
1837
1838    async fn query_sub_account_assets(
1839        &self,
1840        params: QuerySubAccountAssetsParams,
1841    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsResponse>> {
1842        let QuerySubAccountAssetsParams { email, recv_window } = params;
1843
1844        let mut query_params = BTreeMap::new();
1845        let body_params = BTreeMap::new();
1846
1847        query_params.insert("email".to_string(), json!(email));
1848
1849        if let Some(rw) = recv_window {
1850            query_params.insert("recvWindow".to_string(), json!(rw));
1851        }
1852
1853        send_request::<models::QuerySubAccountAssetsResponse>(
1854            &self.configuration,
1855            "/sapi/v3/sub-account/assets",
1856            reqwest::Method::GET,
1857            query_params,
1858            body_params,
1859            if HAS_TIME_UNIT {
1860                self.configuration.time_unit
1861            } else {
1862                None
1863            },
1864            true,
1865        )
1866        .await
1867    }
1868
1869    async fn query_sub_account_assets_asset_management(
1870        &self,
1871        params: QuerySubAccountAssetsAssetManagementParams,
1872    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsAssetManagementResponse>> {
1873        let QuerySubAccountAssetsAssetManagementParams { email, recv_window } = params;
1874
1875        let mut query_params = BTreeMap::new();
1876        let body_params = BTreeMap::new();
1877
1878        query_params.insert("email".to_string(), json!(email));
1879
1880        if let Some(rw) = recv_window {
1881            query_params.insert("recvWindow".to_string(), json!(rw));
1882        }
1883
1884        send_request::<models::QuerySubAccountAssetsAssetManagementResponse>(
1885            &self.configuration,
1886            "/sapi/v4/sub-account/assets",
1887            reqwest::Method::GET,
1888            query_params,
1889            body_params,
1890            if HAS_TIME_UNIT {
1891                self.configuration.time_unit
1892            } else {
1893                None
1894            },
1895            true,
1896        )
1897        .await
1898    }
1899
1900    async fn query_sub_account_futures_asset_transfer_history(
1901        &self,
1902        params: QuerySubAccountFuturesAssetTransferHistoryParams,
1903    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountFuturesAssetTransferHistoryResponse>>
1904    {
1905        let QuerySubAccountFuturesAssetTransferHistoryParams {
1906            email,
1907            futures_type,
1908            start_time,
1909            end_time,
1910            page,
1911            limit,
1912            recv_window,
1913        } = params;
1914
1915        let mut query_params = BTreeMap::new();
1916        let body_params = BTreeMap::new();
1917
1918        query_params.insert("email".to_string(), json!(email));
1919
1920        query_params.insert("futuresType".to_string(), json!(futures_type));
1921
1922        if let Some(rw) = start_time {
1923            query_params.insert("startTime".to_string(), json!(rw));
1924        }
1925
1926        if let Some(rw) = end_time {
1927            query_params.insert("endTime".to_string(), json!(rw));
1928        }
1929
1930        if let Some(rw) = page {
1931            query_params.insert("page".to_string(), json!(rw));
1932        }
1933
1934        if let Some(rw) = limit {
1935            query_params.insert("limit".to_string(), json!(rw));
1936        }
1937
1938        if let Some(rw) = recv_window {
1939            query_params.insert("recvWindow".to_string(), json!(rw));
1940        }
1941
1942        send_request::<models::QuerySubAccountFuturesAssetTransferHistoryResponse>(
1943            &self.configuration,
1944            "/sapi/v1/sub-account/futures/internalTransfer",
1945            reqwest::Method::GET,
1946            query_params,
1947            body_params,
1948            if HAS_TIME_UNIT {
1949                self.configuration.time_unit
1950            } else {
1951                None
1952            },
1953            true,
1954        )
1955        .await
1956    }
1957
1958    async fn query_sub_account_spot_asset_transfer_history(
1959        &self,
1960        params: QuerySubAccountSpotAssetTransferHistoryParams,
1961    ) -> anyhow::Result<
1962        RestApiResponse<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>,
1963    > {
1964        let QuerySubAccountSpotAssetTransferHistoryParams {
1965            from_email,
1966            to_email,
1967            start_time,
1968            end_time,
1969            page,
1970            limit,
1971            recv_window,
1972        } = params;
1973
1974        let mut query_params = BTreeMap::new();
1975        let body_params = BTreeMap::new();
1976
1977        if let Some(rw) = from_email {
1978            query_params.insert("fromEmail".to_string(), json!(rw));
1979        }
1980
1981        if let Some(rw) = to_email {
1982            query_params.insert("toEmail".to_string(), json!(rw));
1983        }
1984
1985        if let Some(rw) = start_time {
1986            query_params.insert("startTime".to_string(), json!(rw));
1987        }
1988
1989        if let Some(rw) = end_time {
1990            query_params.insert("endTime".to_string(), json!(rw));
1991        }
1992
1993        if let Some(rw) = page {
1994            query_params.insert("page".to_string(), json!(rw));
1995        }
1996
1997        if let Some(rw) = limit {
1998            query_params.insert("limit".to_string(), json!(rw));
1999        }
2000
2001        if let Some(rw) = recv_window {
2002            query_params.insert("recvWindow".to_string(), json!(rw));
2003        }
2004
2005        send_request::<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>(
2006            &self.configuration,
2007            "/sapi/v1/sub-account/sub/transfer/history",
2008            reqwest::Method::GET,
2009            query_params,
2010            body_params,
2011            if HAS_TIME_UNIT {
2012                self.configuration.time_unit
2013            } else {
2014                None
2015            },
2016            true,
2017        )
2018        .await
2019    }
2020
2021    async fn query_sub_account_spot_assets_summary(
2022        &self,
2023        params: QuerySubAccountSpotAssetsSummaryParams,
2024    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountSpotAssetsSummaryResponse>> {
2025        let QuerySubAccountSpotAssetsSummaryParams {
2026            email,
2027            page,
2028            size,
2029            recv_window,
2030        } = params;
2031
2032        let mut query_params = BTreeMap::new();
2033        let body_params = BTreeMap::new();
2034
2035        if let Some(rw) = email {
2036            query_params.insert("email".to_string(), json!(rw));
2037        }
2038
2039        if let Some(rw) = page {
2040            query_params.insert("page".to_string(), json!(rw));
2041        }
2042
2043        if let Some(rw) = size {
2044            query_params.insert("size".to_string(), json!(rw));
2045        }
2046
2047        if let Some(rw) = recv_window {
2048            query_params.insert("recvWindow".to_string(), json!(rw));
2049        }
2050
2051        send_request::<models::QuerySubAccountSpotAssetsSummaryResponse>(
2052            &self.configuration,
2053            "/sapi/v1/sub-account/spotSummary",
2054            reqwest::Method::GET,
2055            query_params,
2056            body_params,
2057            if HAS_TIME_UNIT {
2058                self.configuration.time_unit
2059            } else {
2060                None
2061            },
2062            true,
2063        )
2064        .await
2065    }
2066
2067    async fn query_universal_transfer_history(
2068        &self,
2069        params: QueryUniversalTransferHistoryParams,
2070    ) -> anyhow::Result<RestApiResponse<models::QueryUniversalTransferHistoryResponse>> {
2071        let QueryUniversalTransferHistoryParams {
2072            from_email,
2073            to_email,
2074            client_tran_id,
2075            start_time,
2076            end_time,
2077            page,
2078            limit,
2079            recv_window,
2080        } = params;
2081
2082        let mut query_params = BTreeMap::new();
2083        let body_params = BTreeMap::new();
2084
2085        if let Some(rw) = from_email {
2086            query_params.insert("fromEmail".to_string(), json!(rw));
2087        }
2088
2089        if let Some(rw) = to_email {
2090            query_params.insert("toEmail".to_string(), json!(rw));
2091        }
2092
2093        if let Some(rw) = client_tran_id {
2094            query_params.insert("clientTranId".to_string(), json!(rw));
2095        }
2096
2097        if let Some(rw) = start_time {
2098            query_params.insert("startTime".to_string(), json!(rw));
2099        }
2100
2101        if let Some(rw) = end_time {
2102            query_params.insert("endTime".to_string(), json!(rw));
2103        }
2104
2105        if let Some(rw) = page {
2106            query_params.insert("page".to_string(), json!(rw));
2107        }
2108
2109        if let Some(rw) = limit {
2110            query_params.insert("limit".to_string(), json!(rw));
2111        }
2112
2113        if let Some(rw) = recv_window {
2114            query_params.insert("recvWindow".to_string(), json!(rw));
2115        }
2116
2117        send_request::<models::QueryUniversalTransferHistoryResponse>(
2118            &self.configuration,
2119            "/sapi/v1/sub-account/universalTransfer",
2120            reqwest::Method::GET,
2121            query_params,
2122            body_params,
2123            if HAS_TIME_UNIT {
2124                self.configuration.time_unit
2125            } else {
2126                None
2127            },
2128            true,
2129        )
2130        .await
2131    }
2132
2133    async fn sub_account_futures_asset_transfer(
2134        &self,
2135        params: SubAccountFuturesAssetTransferParams,
2136    ) -> anyhow::Result<RestApiResponse<models::SubAccountFuturesAssetTransferResponse>> {
2137        let SubAccountFuturesAssetTransferParams {
2138            from_email,
2139            to_email,
2140            futures_type,
2141            asset,
2142            amount,
2143            recv_window,
2144        } = params;
2145
2146        let mut query_params = BTreeMap::new();
2147        let body_params = BTreeMap::new();
2148
2149        query_params.insert("fromEmail".to_string(), json!(from_email));
2150
2151        query_params.insert("toEmail".to_string(), json!(to_email));
2152
2153        query_params.insert("futuresType".to_string(), json!(futures_type));
2154
2155        query_params.insert("asset".to_string(), json!(asset));
2156
2157        query_params.insert("amount".to_string(), json!(amount));
2158
2159        if let Some(rw) = recv_window {
2160            query_params.insert("recvWindow".to_string(), json!(rw));
2161        }
2162
2163        send_request::<models::SubAccountFuturesAssetTransferResponse>(
2164            &self.configuration,
2165            "/sapi/v1/sub-account/futures/internalTransfer",
2166            reqwest::Method::POST,
2167            query_params,
2168            body_params,
2169            if HAS_TIME_UNIT {
2170                self.configuration.time_unit
2171            } else {
2172                None
2173            },
2174            true,
2175        )
2176        .await
2177    }
2178
2179    async fn sub_account_transfer_history(
2180        &self,
2181        params: SubAccountTransferHistoryParams,
2182    ) -> anyhow::Result<RestApiResponse<Vec<models::SubAccountTransferHistoryResponseInner>>> {
2183        let SubAccountTransferHistoryParams {
2184            asset,
2185            r#type,
2186            start_time,
2187            end_time,
2188            limit,
2189            return_fail_history,
2190            recv_window,
2191        } = params;
2192
2193        let mut query_params = BTreeMap::new();
2194        let body_params = BTreeMap::new();
2195
2196        if let Some(rw) = asset {
2197            query_params.insert("asset".to_string(), json!(rw));
2198        }
2199
2200        if let Some(rw) = r#type {
2201            query_params.insert("type".to_string(), json!(rw));
2202        }
2203
2204        if let Some(rw) = start_time {
2205            query_params.insert("startTime".to_string(), json!(rw));
2206        }
2207
2208        if let Some(rw) = end_time {
2209            query_params.insert("endTime".to_string(), json!(rw));
2210        }
2211
2212        if let Some(rw) = limit {
2213            query_params.insert("limit".to_string(), json!(rw));
2214        }
2215
2216        if let Some(rw) = return_fail_history {
2217            query_params.insert("returnFailHistory".to_string(), json!(rw));
2218        }
2219
2220        if let Some(rw) = recv_window {
2221            query_params.insert("recvWindow".to_string(), json!(rw));
2222        }
2223
2224        send_request::<Vec<models::SubAccountTransferHistoryResponseInner>>(
2225            &self.configuration,
2226            "/sapi/v1/sub-account/transfer/subUserHistory",
2227            reqwest::Method::GET,
2228            query_params,
2229            body_params,
2230            if HAS_TIME_UNIT {
2231                self.configuration.time_unit
2232            } else {
2233                None
2234            },
2235            true,
2236        )
2237        .await
2238    }
2239
2240    async fn transfer_to_master(
2241        &self,
2242        params: TransferToMasterParams,
2243    ) -> anyhow::Result<RestApiResponse<models::TransferToMasterResponse>> {
2244        let TransferToMasterParams {
2245            asset,
2246            amount,
2247            recv_window,
2248        } = params;
2249
2250        let mut query_params = BTreeMap::new();
2251        let body_params = BTreeMap::new();
2252
2253        query_params.insert("asset".to_string(), json!(asset));
2254
2255        query_params.insert("amount".to_string(), json!(amount));
2256
2257        if let Some(rw) = recv_window {
2258            query_params.insert("recvWindow".to_string(), json!(rw));
2259        }
2260
2261        send_request::<models::TransferToMasterResponse>(
2262            &self.configuration,
2263            "/sapi/v1/sub-account/transfer/subToMaster",
2264            reqwest::Method::POST,
2265            query_params,
2266            body_params,
2267            if HAS_TIME_UNIT {
2268                self.configuration.time_unit
2269            } else {
2270                None
2271            },
2272            true,
2273        )
2274        .await
2275    }
2276
2277    async fn transfer_to_sub_account_of_same_master(
2278        &self,
2279        params: TransferToSubAccountOfSameMasterParams,
2280    ) -> anyhow::Result<RestApiResponse<models::TransferToSubAccountOfSameMasterResponse>> {
2281        let TransferToSubAccountOfSameMasterParams {
2282            to_email,
2283            asset,
2284            amount,
2285            recv_window,
2286        } = params;
2287
2288        let mut query_params = BTreeMap::new();
2289        let body_params = BTreeMap::new();
2290
2291        query_params.insert("toEmail".to_string(), json!(to_email));
2292
2293        query_params.insert("asset".to_string(), json!(asset));
2294
2295        query_params.insert("amount".to_string(), json!(amount));
2296
2297        if let Some(rw) = recv_window {
2298            query_params.insert("recvWindow".to_string(), json!(rw));
2299        }
2300
2301        send_request::<models::TransferToSubAccountOfSameMasterResponse>(
2302            &self.configuration,
2303            "/sapi/v1/sub-account/transfer/subToSub",
2304            reqwest::Method::POST,
2305            query_params,
2306            body_params,
2307            if HAS_TIME_UNIT {
2308                self.configuration.time_unit
2309            } else {
2310                None
2311            },
2312            true,
2313        )
2314        .await
2315    }
2316
2317    async fn universal_transfer(
2318        &self,
2319        params: UniversalTransferParams,
2320    ) -> anyhow::Result<RestApiResponse<models::UniversalTransferResponse>> {
2321        let UniversalTransferParams {
2322            from_account_type,
2323            to_account_type,
2324            asset,
2325            amount,
2326            from_email,
2327            to_email,
2328            client_tran_id,
2329            symbol,
2330            recv_window,
2331        } = params;
2332
2333        let mut query_params = BTreeMap::new();
2334        let body_params = BTreeMap::new();
2335
2336        if let Some(rw) = from_email {
2337            query_params.insert("fromEmail".to_string(), json!(rw));
2338        }
2339
2340        if let Some(rw) = to_email {
2341            query_params.insert("toEmail".to_string(), json!(rw));
2342        }
2343
2344        query_params.insert("fromAccountType".to_string(), json!(from_account_type));
2345
2346        query_params.insert("toAccountType".to_string(), json!(to_account_type));
2347
2348        if let Some(rw) = client_tran_id {
2349            query_params.insert("clientTranId".to_string(), json!(rw));
2350        }
2351
2352        if let Some(rw) = symbol {
2353            query_params.insert("symbol".to_string(), json!(rw));
2354        }
2355
2356        query_params.insert("asset".to_string(), json!(asset));
2357
2358        query_params.insert("amount".to_string(), json!(amount));
2359
2360        if let Some(rw) = recv_window {
2361            query_params.insert("recvWindow".to_string(), json!(rw));
2362        }
2363
2364        send_request::<models::UniversalTransferResponse>(
2365            &self.configuration,
2366            "/sapi/v1/sub-account/universalTransfer",
2367            reqwest::Method::POST,
2368            query_params,
2369            body_params,
2370            if HAS_TIME_UNIT {
2371                self.configuration.time_unit
2372            } else {
2373                None
2374            },
2375            true,
2376        )
2377        .await
2378    }
2379}
2380
2381#[cfg(all(test, feature = "sub_account"))]
2382mod tests {
2383    use super::*;
2384    use crate::TOKIO_SHARED_RT;
2385    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
2386    use async_trait::async_trait;
2387    use std::collections::HashMap;
2388
2389    struct DummyRestApiResponse<T> {
2390        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
2391        status: u16,
2392        headers: HashMap<String, String>,
2393        rate_limits: Option<Vec<RestApiRateLimit>>,
2394    }
2395
2396    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
2397        fn from(dummy: DummyRestApiResponse<T>) -> Self {
2398            Self {
2399                data_fn: dummy.inner,
2400                status: dummy.status,
2401                headers: dummy.headers,
2402                rate_limits: dummy.rate_limits,
2403            }
2404        }
2405    }
2406
2407    struct MockAssetManagementApiClient {
2408        force_error: bool,
2409    }
2410
2411    #[async_trait]
2412    impl AssetManagementApi for MockAssetManagementApiClient {
2413        async fn futures_transfer_for_sub_account(
2414            &self,
2415            _params: FuturesTransferForSubAccountParams,
2416        ) -> anyhow::Result<RestApiResponse<models::FuturesTransferForSubAccountResponse>> {
2417            if self.force_error {
2418                return Err(ConnectorError::ConnectorClientError {
2419                    msg: "ResponseError".to_string(),
2420                    code: None,
2421                }
2422                .into());
2423            }
2424
2425            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
2426            let dummy_response: models::FuturesTransferForSubAccountResponse =
2427                serde_json::from_value(resp_json.clone())
2428                    .expect("should parse into models::FuturesTransferForSubAccountResponse");
2429
2430            let dummy = DummyRestApiResponse {
2431                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2432                status: 200,
2433                headers: HashMap::new(),
2434                rate_limits: None,
2435            };
2436
2437            Ok(dummy.into())
2438        }
2439
2440        async fn get_detail_on_sub_accounts_futures_account(
2441            &self,
2442            _params: GetDetailOnSubAccountsFuturesAccountParams,
2443        ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountResponse>>
2444        {
2445            if self.force_error {
2446                return Err(ConnectorError::ConnectorClientError {
2447                    msg: "ResponseError".to_string(),
2448                    code: None,
2449                }
2450                .into());
2451            }
2452
2453            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();
2454            let dummy_response: models::GetDetailOnSubAccountsFuturesAccountResponse =
2455                serde_json::from_value(resp_json.clone()).expect(
2456                    "should parse into models::GetDetailOnSubAccountsFuturesAccountResponse",
2457                );
2458
2459            let dummy = DummyRestApiResponse {
2460                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2461                status: 200,
2462                headers: HashMap::new(),
2463                rate_limits: None,
2464            };
2465
2466            Ok(dummy.into())
2467        }
2468
2469        async fn get_detail_on_sub_accounts_futures_account_v2(
2470            &self,
2471            _params: GetDetailOnSubAccountsFuturesAccountV2Params,
2472        ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsFuturesAccountV2Response>>
2473        {
2474            if self.force_error {
2475                return Err(ConnectorError::ConnectorClientError {
2476                    msg: "ResponseError".to_string(),
2477                    code: None,
2478                }
2479                .into());
2480            }
2481
2482            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();
2483            let dummy_response: models::GetDetailOnSubAccountsFuturesAccountV2Response =
2484                serde_json::from_value(resp_json.clone()).expect(
2485                    "should parse into models::GetDetailOnSubAccountsFuturesAccountV2Response",
2486                );
2487
2488            let dummy = DummyRestApiResponse {
2489                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2490                status: 200,
2491                headers: HashMap::new(),
2492                rate_limits: None,
2493            };
2494
2495            Ok(dummy.into())
2496        }
2497
2498        async fn get_detail_on_sub_accounts_margin_account(
2499            &self,
2500            _params: GetDetailOnSubAccountsMarginAccountParams,
2501        ) -> anyhow::Result<RestApiResponse<models::GetDetailOnSubAccountsMarginAccountResponse>>
2502        {
2503            if self.force_error {
2504                return Err(ConnectorError::ConnectorClientError {
2505                    msg: "ResponseError".to_string(),
2506                    code: None,
2507                }
2508                .into());
2509            }
2510
2511            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"},{"asset":"BNB","borrowed":"201.66666672","free":"2346.50000000","interest":"0.00000000","locked":"0.00000000","netAsset":"2144.83333328"},{"asset":"ETH","borrowed":"0.00000000","free":"0.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00000000"},{"asset":"USDT","borrowed":"0.00000000","free":"0.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00000000"}]}"#).unwrap();
2512            let dummy_response: models::GetDetailOnSubAccountsMarginAccountResponse =
2513                serde_json::from_value(resp_json.clone()).expect(
2514                    "should parse into models::GetDetailOnSubAccountsMarginAccountResponse",
2515                );
2516
2517            let dummy = DummyRestApiResponse {
2518                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2519                status: 200,
2520                headers: HashMap::new(),
2521                rate_limits: None,
2522            };
2523
2524            Ok(dummy.into())
2525        }
2526
2527        async fn get_move_position_history_for_sub_account(
2528            &self,
2529            _params: GetMovePositionHistoryForSubAccountParams,
2530        ) -> anyhow::Result<RestApiResponse<models::GetMovePositionHistoryForSubAccountResponse>>
2531        {
2532            if self.force_error {
2533                return Err(ConnectorError::ConnectorClientError {
2534                    msg: "ResponseError".to_string(),
2535                    code: None,
2536                }
2537                .into());
2538            }
2539
2540            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},{"fromUserEmail":"testFrom1@google.com","toUserEmail":"testTo1@google.com","productType":"UM","symbol":"BTCUSDT","price":"97100.00000000","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1740041627000},{"fromUserEmail":"testFrom2@google.com","toUserEmail":"testTo2@google.com","productType":"UM","symbol":"BTCUSDT","price":"97108.62068889","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1740041959000}]}"#).unwrap();
2541            let dummy_response: models::GetMovePositionHistoryForSubAccountResponse =
2542                serde_json::from_value(resp_json.clone()).expect(
2543                    "should parse into models::GetMovePositionHistoryForSubAccountResponse",
2544                );
2545
2546            let dummy = DummyRestApiResponse {
2547                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2548                status: 200,
2549                headers: HashMap::new(),
2550                rate_limits: None,
2551            };
2552
2553            Ok(dummy.into())
2554        }
2555
2556        async fn get_sub_account_deposit_address(
2557            &self,
2558            _params: GetSubAccountDepositAddressParams,
2559        ) -> anyhow::Result<RestApiResponse<models::GetSubAccountDepositAddressResponse>> {
2560            if self.force_error {
2561                return Err(ConnectorError::ConnectorClientError {
2562                    msg: "ResponseError".to_string(),
2563                    code: None,
2564                }
2565                .into());
2566            }
2567
2568            let resp_json: Value = serde_json::from_str(r#"{"address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV","coin":"USDT","tag":"","url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV"}"#).unwrap();
2569            let dummy_response: models::GetSubAccountDepositAddressResponse =
2570                serde_json::from_value(resp_json.clone())
2571                    .expect("should parse into models::GetSubAccountDepositAddressResponse");
2572
2573            let dummy = DummyRestApiResponse {
2574                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2575                status: 200,
2576                headers: HashMap::new(),
2577                rate_limits: None,
2578            };
2579
2580            Ok(dummy.into())
2581        }
2582
2583        async fn get_sub_account_deposit_history(
2584            &self,
2585            _params: GetSubAccountDepositHistoryParams,
2586        ) -> anyhow::Result<RestApiResponse<Vec<models::GetSubAccountDepositHistoryResponseInner>>>
2587        {
2588            if self.force_error {
2589                return Err(ConnectorError::ConnectorClientError {
2590                    msg: "ResponseError".to_string(),
2591                    code: None,
2592                }
2593                .into());
2594            }
2595
2596            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},{"id":"769754833590042625","amount":"0.50000000","coin":"IOTA","network":"IOTA","status":1,"address":"SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW","addressTag":"","txId":"ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999","insertTime":1599620082000,"transferType":0,"confirmTimes":"1/1","unlockConfirm":0,"walletType":0}]"#).unwrap();
2597            let dummy_response: Vec<models::GetSubAccountDepositHistoryResponseInner> =
2598                serde_json::from_value(resp_json.clone()).expect(
2599                    "should parse into Vec<models::GetSubAccountDepositHistoryResponseInner>",
2600                );
2601
2602            let dummy = DummyRestApiResponse {
2603                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2604                status: 200,
2605                headers: HashMap::new(),
2606                rate_limits: None,
2607            };
2608
2609            Ok(dummy.into())
2610        }
2611
2612        async fn get_summary_of_sub_accounts_futures_account(
2613            &self,
2614            _params: GetSummaryOfSubAccountsFuturesAccountParams,
2615        ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountResponse>>
2616        {
2617            if self.force_error {
2618                return Err(ConnectorError::ConnectorClientError {
2619                    msg: "ResponseError".to_string(),
2620                    code: None,
2621                }
2622                .into());
2623            }
2624
2625            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"},{"email":"345@test.com","totalInitialMargin":"0.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"0.90575887","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","asset":"USD"}]}"#).unwrap();
2626            let dummy_response: models::GetSummaryOfSubAccountsFuturesAccountResponse =
2627                serde_json::from_value(resp_json.clone()).expect(
2628                    "should parse into models::GetSummaryOfSubAccountsFuturesAccountResponse",
2629                );
2630
2631            let dummy = DummyRestApiResponse {
2632                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2633                status: 200,
2634                headers: HashMap::new(),
2635                rate_limits: None,
2636            };
2637
2638            Ok(dummy.into())
2639        }
2640
2641        async fn get_summary_of_sub_accounts_futures_account_v2(
2642            &self,
2643            _params: GetSummaryOfSubAccountsFuturesAccountV2Params,
2644        ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsFuturesAccountV2Response>>
2645        {
2646            if self.force_error {
2647                return Err(ConnectorError::ConnectorClientError {
2648                    msg: "ResponseError".to_string(),
2649                    code: None,
2650                }
2651                .into());
2652            }
2653
2654            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"},{"email":"345@test.com","totalInitialMargin":"0.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"0.90575887","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","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"},{"email":"345@test.com","totalMarginBalance":"0.90575887","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","asset":"BTC"}]}}"#).unwrap();
2655            let dummy_response: models::GetSummaryOfSubAccountsFuturesAccountV2Response =
2656                serde_json::from_value(resp_json.clone()).expect(
2657                    "should parse into models::GetSummaryOfSubAccountsFuturesAccountV2Response",
2658                );
2659
2660            let dummy = DummyRestApiResponse {
2661                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2662                status: 200,
2663                headers: HashMap::new(),
2664                rate_limits: None,
2665            };
2666
2667            Ok(dummy.into())
2668        }
2669
2670        async fn get_summary_of_sub_accounts_margin_account(
2671            &self,
2672            _params: GetSummaryOfSubAccountsMarginAccountParams,
2673        ) -> anyhow::Result<RestApiResponse<models::GetSummaryOfSubAccountsMarginAccountResponse>>
2674        {
2675            if self.force_error {
2676                return Err(ConnectorError::ConnectorClientError {
2677                    msg: "ResponseError".to_string(),
2678                    code: None,
2679                }
2680                .into());
2681            }
2682
2683            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"},{"email":"345@test.com","totalAssetOfBtc":"2.22222222","totalLiabilityOfBtc":"1.00000001","totalNetAssetOfBtc":"1.22222221"}]}"#).unwrap();
2684            let dummy_response: models::GetSummaryOfSubAccountsMarginAccountResponse =
2685                serde_json::from_value(resp_json.clone()).expect(
2686                    "should parse into models::GetSummaryOfSubAccountsMarginAccountResponse",
2687                );
2688
2689            let dummy = DummyRestApiResponse {
2690                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2691                status: 200,
2692                headers: HashMap::new(),
2693                rate_limits: None,
2694            };
2695
2696            Ok(dummy.into())
2697        }
2698
2699        async fn margin_transfer_for_sub_account(
2700            &self,
2701            _params: MarginTransferForSubAccountParams,
2702        ) -> anyhow::Result<RestApiResponse<models::MarginTransferForSubAccountResponse>> {
2703            if self.force_error {
2704                return Err(ConnectorError::ConnectorClientError {
2705                    msg: "ResponseError".to_string(),
2706                    code: None,
2707                }
2708                .into());
2709            }
2710
2711            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
2712            let dummy_response: models::MarginTransferForSubAccountResponse =
2713                serde_json::from_value(resp_json.clone())
2714                    .expect("should parse into models::MarginTransferForSubAccountResponse");
2715
2716            let dummy = DummyRestApiResponse {
2717                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2718                status: 200,
2719                headers: HashMap::new(),
2720                rate_limits: None,
2721            };
2722
2723            Ok(dummy.into())
2724        }
2725
2726        async fn move_position_for_sub_account(
2727            &self,
2728            _params: MovePositionForSubAccountParams,
2729        ) -> anyhow::Result<RestApiResponse<models::MovePositionForSubAccountResponse>> {
2730            if self.force_error {
2731                return Err(ConnectorError::ConnectorClientError {
2732                    msg: "ResponseError".to_string(),
2733                    code: None,
2734                }
2735                .into());
2736            }
2737
2738            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},{"fromUserEmail":"testFrom1@google.com","toUserEmail":"1testTo@google.com","productType":"UM","symbol":"BTCUSDT","priceType":"MARK_PRICE","price":"97139.00000000","quantity":"0.0011","positionSide":"BOTH","side":"BUY","success":true}]}"#).unwrap();
2739            let dummy_response: models::MovePositionForSubAccountResponse =
2740                serde_json::from_value(resp_json.clone())
2741                    .expect("should parse into models::MovePositionForSubAccountResponse");
2742
2743            let dummy = DummyRestApiResponse {
2744                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2745                status: 200,
2746                headers: HashMap::new(),
2747                rate_limits: None,
2748            };
2749
2750            Ok(dummy.into())
2751        }
2752
2753        async fn query_sub_account_assets(
2754            &self,
2755            _params: QuerySubAccountAssetsParams,
2756        ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsResponse>> {
2757            if self.force_error {
2758                return Err(ConnectorError::ConnectorClientError {
2759                    msg: "ResponseError".to_string(),
2760                    code: None,
2761                }
2762                .into());
2763            }
2764
2765            let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":0,"withdrawing":0,"asset":"ADA","free":10000,"locked":0},{"freeze":0,"withdrawing":0,"asset":"BNB","free":10003,"locked":0},{"freeze":0,"withdrawing":0,"asset":"BTC","free":11467.6399,"locked":0},{"freeze":0,"withdrawing":0,"asset":"ETH","free":10004.995,"locked":0},{"freeze":0,"withdrawing":0,"asset":"USDT","free":11652.14213,"locked":0}]}"#).unwrap();
2766            let dummy_response: models::QuerySubAccountAssetsResponse =
2767                serde_json::from_value(resp_json.clone())
2768                    .expect("should parse into models::QuerySubAccountAssetsResponse");
2769
2770            let dummy = DummyRestApiResponse {
2771                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2772                status: 200,
2773                headers: HashMap::new(),
2774                rate_limits: None,
2775            };
2776
2777            Ok(dummy.into())
2778        }
2779
2780        async fn query_sub_account_assets_asset_management(
2781            &self,
2782            _params: QuerySubAccountAssetsAssetManagementParams,
2783        ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountAssetsAssetManagementResponse>>
2784        {
2785            if self.force_error {
2786                return Err(ConnectorError::ConnectorClientError {
2787                    msg: "ResponseError".to_string(),
2788                    code: None,
2789                }
2790                .into());
2791            }
2792
2793            let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":"0","withdrawing":"0","asset":"ADA","free":"10000","locked":"0"},{"freeze":"0","withdrawing":"0","asset":"BNB","free":"10003","locked":"0"},{"freeze":"0","withdrawing":"0","asset":"BTC","free":"11467.6399","locked":"0"}]}"#).unwrap();
2794            let dummy_response: models::QuerySubAccountAssetsAssetManagementResponse =
2795                serde_json::from_value(resp_json.clone()).expect(
2796                    "should parse into models::QuerySubAccountAssetsAssetManagementResponse",
2797                );
2798
2799            let dummy = DummyRestApiResponse {
2800                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2801                status: 200,
2802                headers: HashMap::new(),
2803                rate_limits: None,
2804            };
2805
2806            Ok(dummy.into())
2807        }
2808
2809        async fn query_sub_account_futures_asset_transfer_history(
2810            &self,
2811            _params: QuerySubAccountFuturesAssetTransferHistoryParams,
2812        ) -> anyhow::Result<
2813            RestApiResponse<models::QuerySubAccountFuturesAssetTransferHistoryResponse>,
2814        > {
2815            if self.force_error {
2816                return Err(ConnectorError::ConnectorClientError {
2817                    msg: "ResponseError".to_string(),
2818                    code: None,
2819                }
2820                .into());
2821            }
2822
2823            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},{"from":"bbb@test.com","to":"ccc@test.com","asset":"ETH","qty":"2","tranId":11631474902,"time":1544433328000}]}"#).unwrap();
2824            let dummy_response: models::QuerySubAccountFuturesAssetTransferHistoryResponse =
2825                serde_json::from_value(resp_json.clone()).expect(
2826                    "should parse into models::QuerySubAccountFuturesAssetTransferHistoryResponse",
2827                );
2828
2829            let dummy = DummyRestApiResponse {
2830                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2831                status: 200,
2832                headers: HashMap::new(),
2833                rate_limits: None,
2834            };
2835
2836            Ok(dummy.into())
2837        }
2838
2839        async fn query_sub_account_spot_asset_transfer_history(
2840            &self,
2841            _params: QuerySubAccountSpotAssetTransferHistoryParams,
2842        ) -> anyhow::Result<
2843            RestApiResponse<Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>>,
2844        > {
2845            if self.force_error {
2846                return Err(ConnectorError::ConnectorClientError {
2847                    msg: "ResponseError".to_string(),
2848                    code: None,
2849                }
2850                .into());
2851            }
2852
2853            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},{"from":"bbb@test.com","to":"ccc@test.com","asset":"ETH","qty":"2","status":"SUCCESS","tranId":6489938713,"time":1544433328000}]"#).unwrap();
2854            let dummy_response : Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>");
2855
2856            let dummy = DummyRestApiResponse {
2857                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2858                status: 200,
2859                headers: HashMap::new(),
2860                rate_limits: None,
2861            };
2862
2863            Ok(dummy.into())
2864        }
2865
2866        async fn query_sub_account_spot_assets_summary(
2867            &self,
2868            _params: QuerySubAccountSpotAssetsSummaryParams,
2869        ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountSpotAssetsSummaryResponse>>
2870        {
2871            if self.force_error {
2872                return Err(ConnectorError::ConnectorClientError {
2873                    msg: "ResponseError".to_string(),
2874                    code: None,
2875                }
2876                .into());
2877            }
2878
2879            let resp_json: Value = serde_json::from_str(r#"{"totalCount":2,"masterAccountTotalAsset":"0.23231201","spotSubUserAssetBtcVoList":[{"email":"sub123@test.com","totalAsset":"9999.00000000"},{"email":"test456@test.com","totalAsset":"0.00000000"}]}"#).unwrap();
2880            let dummy_response: models::QuerySubAccountSpotAssetsSummaryResponse =
2881                serde_json::from_value(resp_json.clone())
2882                    .expect("should parse into models::QuerySubAccountSpotAssetsSummaryResponse");
2883
2884            let dummy = DummyRestApiResponse {
2885                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2886                status: 200,
2887                headers: HashMap::new(),
2888                rate_limits: None,
2889            };
2890
2891            Ok(dummy.into())
2892        }
2893
2894        async fn query_universal_transfer_history(
2895            &self,
2896            _params: QueryUniversalTransferHistoryParams,
2897        ) -> anyhow::Result<RestApiResponse<models::QueryUniversalTransferHistoryResponse>>
2898        {
2899            if self.force_error {
2900                return Err(ConnectorError::ConnectorClientError {
2901                    msg: "ResponseError".to_string(),
2902                    code: None,
2903                }
2904                .into());
2905            }
2906
2907            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();
2908            let dummy_response: models::QueryUniversalTransferHistoryResponse =
2909                serde_json::from_value(resp_json.clone())
2910                    .expect("should parse into models::QueryUniversalTransferHistoryResponse");
2911
2912            let dummy = DummyRestApiResponse {
2913                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2914                status: 200,
2915                headers: HashMap::new(),
2916                rate_limits: None,
2917            };
2918
2919            Ok(dummy.into())
2920        }
2921
2922        async fn sub_account_futures_asset_transfer(
2923            &self,
2924            _params: SubAccountFuturesAssetTransferParams,
2925        ) -> anyhow::Result<RestApiResponse<models::SubAccountFuturesAssetTransferResponse>>
2926        {
2927            if self.force_error {
2928                return Err(ConnectorError::ConnectorClientError {
2929                    msg: "ResponseError".to_string(),
2930                    code: None,
2931                }
2932                .into());
2933            }
2934
2935            let resp_json: Value =
2936                serde_json::from_str(r#"{"success":true,"txnId":"2934662589"}"#).unwrap();
2937            let dummy_response: models::SubAccountFuturesAssetTransferResponse =
2938                serde_json::from_value(resp_json.clone())
2939                    .expect("should parse into models::SubAccountFuturesAssetTransferResponse");
2940
2941            let dummy = DummyRestApiResponse {
2942                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2943                status: 200,
2944                headers: HashMap::new(),
2945                rate_limits: None,
2946            };
2947
2948            Ok(dummy.into())
2949        }
2950
2951        async fn sub_account_transfer_history(
2952            &self,
2953            _params: SubAccountTransferHistoryParams,
2954        ) -> anyhow::Result<RestApiResponse<Vec<models::SubAccountTransferHistoryResponseInner>>>
2955        {
2956            if self.force_error {
2957                return Err(ConnectorError::ConnectorClientError {
2958                    msg: "ResponseError".to_string(),
2959                    code: None,
2960                }
2961                .into());
2962            }
2963
2964            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},{"counterParty":"subAccount","email":"sub2@test.com","type":1,"asset":"ETH","qty":"2","fromAccountType":"SPOT","toAccountType":"COIN_FUTURE","status":"SUCCESS","tranId":11798829519,"time":1544433326000}]"#).unwrap();
2965            let dummy_response: Vec<models::SubAccountTransferHistoryResponseInner> =
2966                serde_json::from_value(resp_json.clone()).expect(
2967                    "should parse into Vec<models::SubAccountTransferHistoryResponseInner>",
2968                );
2969
2970            let dummy = DummyRestApiResponse {
2971                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2972                status: 200,
2973                headers: HashMap::new(),
2974                rate_limits: None,
2975            };
2976
2977            Ok(dummy.into())
2978        }
2979
2980        async fn transfer_to_master(
2981            &self,
2982            _params: TransferToMasterParams,
2983        ) -> anyhow::Result<RestApiResponse<models::TransferToMasterResponse>> {
2984            if self.force_error {
2985                return Err(ConnectorError::ConnectorClientError {
2986                    msg: "ResponseError".to_string(),
2987                    code: None,
2988                }
2989                .into());
2990            }
2991
2992            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
2993            let dummy_response: models::TransferToMasterResponse =
2994                serde_json::from_value(resp_json.clone())
2995                    .expect("should parse into models::TransferToMasterResponse");
2996
2997            let dummy = DummyRestApiResponse {
2998                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2999                status: 200,
3000                headers: HashMap::new(),
3001                rate_limits: None,
3002            };
3003
3004            Ok(dummy.into())
3005        }
3006
3007        async fn transfer_to_sub_account_of_same_master(
3008            &self,
3009            _params: TransferToSubAccountOfSameMasterParams,
3010        ) -> anyhow::Result<RestApiResponse<models::TransferToSubAccountOfSameMasterResponse>>
3011        {
3012            if self.force_error {
3013                return Err(ConnectorError::ConnectorClientError {
3014                    msg: "ResponseError".to_string(),
3015                    code: None,
3016                }
3017                .into());
3018            }
3019
3020            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
3021            let dummy_response: models::TransferToSubAccountOfSameMasterResponse =
3022                serde_json::from_value(resp_json.clone())
3023                    .expect("should parse into models::TransferToSubAccountOfSameMasterResponse");
3024
3025            let dummy = DummyRestApiResponse {
3026                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3027                status: 200,
3028                headers: HashMap::new(),
3029                rate_limits: None,
3030            };
3031
3032            Ok(dummy.into())
3033        }
3034
3035        async fn universal_transfer(
3036            &self,
3037            _params: UniversalTransferParams,
3038        ) -> anyhow::Result<RestApiResponse<models::UniversalTransferResponse>> {
3039            if self.force_error {
3040                return Err(ConnectorError::ConnectorClientError {
3041                    msg: "ResponseError".to_string(),
3042                    code: None,
3043                }
3044                .into());
3045            }
3046
3047            let resp_json: Value =
3048                serde_json::from_str(r#"{"tranId":11945860693,"clientTranId":"test"}"#).unwrap();
3049            let dummy_response: models::UniversalTransferResponse =
3050                serde_json::from_value(resp_json.clone())
3051                    .expect("should parse into models::UniversalTransferResponse");
3052
3053            let dummy = DummyRestApiResponse {
3054                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
3055                status: 200,
3056                headers: HashMap::new(),
3057                rate_limits: None,
3058            };
3059
3060            Ok(dummy.into())
3061        }
3062    }
3063
3064    #[test]
3065    fn futures_transfer_for_sub_account_required_params_success() {
3066        TOKIO_SHARED_RT.block_on(async {
3067            let client = MockAssetManagementApiClient { force_error: false };
3068
3069            let params = FuturesTransferForSubAccountParams::builder(
3070                "sub-account-email@email.com".to_string(),
3071                "asset_example".to_string(),
3072                dec!(1.0),
3073                789,
3074            )
3075            .build()
3076            .unwrap();
3077
3078            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
3079            let expected_response: models::FuturesTransferForSubAccountResponse =
3080                serde_json::from_value(resp_json.clone())
3081                    .expect("should parse into models::FuturesTransferForSubAccountResponse");
3082
3083            let resp = client
3084                .futures_transfer_for_sub_account(params)
3085                .await
3086                .expect("Expected a response");
3087            let data_future = resp.data();
3088            let actual_response = data_future.await.unwrap();
3089            assert_eq!(actual_response, expected_response);
3090        });
3091    }
3092
3093    #[test]
3094    fn futures_transfer_for_sub_account_optional_params_success() {
3095        TOKIO_SHARED_RT.block_on(async {
3096            let client = MockAssetManagementApiClient { force_error: false };
3097
3098            let params = FuturesTransferForSubAccountParams::builder(
3099                "sub-account-email@email.com".to_string(),
3100                "asset_example".to_string(),
3101                dec!(1.0),
3102                789,
3103            )
3104            .recv_window(5000)
3105            .build()
3106            .unwrap();
3107
3108            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
3109            let expected_response: models::FuturesTransferForSubAccountResponse =
3110                serde_json::from_value(resp_json.clone())
3111                    .expect("should parse into models::FuturesTransferForSubAccountResponse");
3112
3113            let resp = client
3114                .futures_transfer_for_sub_account(params)
3115                .await
3116                .expect("Expected a response");
3117            let data_future = resp.data();
3118            let actual_response = data_future.await.unwrap();
3119            assert_eq!(actual_response, expected_response);
3120        });
3121    }
3122
3123    #[test]
3124    fn futures_transfer_for_sub_account_response_error() {
3125        TOKIO_SHARED_RT.block_on(async {
3126            let client = MockAssetManagementApiClient { force_error: true };
3127
3128            let params = FuturesTransferForSubAccountParams::builder(
3129                "sub-account-email@email.com".to_string(),
3130                "asset_example".to_string(),
3131                dec!(1.0),
3132                789,
3133            )
3134            .build()
3135            .unwrap();
3136
3137            match client.futures_transfer_for_sub_account(params).await {
3138                Ok(_) => panic!("Expected an error"),
3139                Err(err) => {
3140                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3141                }
3142            }
3143        });
3144    }
3145
3146    #[test]
3147    fn get_detail_on_sub_accounts_futures_account_required_params_success() {
3148        TOKIO_SHARED_RT.block_on(async {
3149            let client = MockAssetManagementApiClient { force_error: false };
3150
3151            let params = GetDetailOnSubAccountsFuturesAccountParams::builder("sub-account-email@email.com".to_string(),).build().unwrap();
3152
3153            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();
3154            let expected_response : models::GetDetailOnSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountResponse");
3155
3156            let resp = client.get_detail_on_sub_accounts_futures_account(params).await.expect("Expected a response");
3157            let data_future = resp.data();
3158            let actual_response = data_future.await.unwrap();
3159            assert_eq!(actual_response, expected_response);
3160        });
3161    }
3162
3163    #[test]
3164    fn get_detail_on_sub_accounts_futures_account_optional_params_success() {
3165        TOKIO_SHARED_RT.block_on(async {
3166            let client = MockAssetManagementApiClient { force_error: false };
3167
3168            let params = GetDetailOnSubAccountsFuturesAccountParams::builder("sub-account-email@email.com".to_string(),).recv_window(5000).build().unwrap();
3169
3170            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();
3171            let expected_response : models::GetDetailOnSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountResponse");
3172
3173            let resp = client.get_detail_on_sub_accounts_futures_account(params).await.expect("Expected a response");
3174            let data_future = resp.data();
3175            let actual_response = data_future.await.unwrap();
3176            assert_eq!(actual_response, expected_response);
3177        });
3178    }
3179
3180    #[test]
3181    fn get_detail_on_sub_accounts_futures_account_response_error() {
3182        TOKIO_SHARED_RT.block_on(async {
3183            let client = MockAssetManagementApiClient { force_error: true };
3184
3185            let params = GetDetailOnSubAccountsFuturesAccountParams::builder(
3186                "sub-account-email@email.com".to_string(),
3187            )
3188            .build()
3189            .unwrap();
3190
3191            match client
3192                .get_detail_on_sub_accounts_futures_account(params)
3193                .await
3194            {
3195                Ok(_) => panic!("Expected an error"),
3196                Err(err) => {
3197                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3198                }
3199            }
3200        });
3201    }
3202
3203    #[test]
3204    fn get_detail_on_sub_accounts_futures_account_v2_required_params_success() {
3205        TOKIO_SHARED_RT.block_on(async {
3206            let client = MockAssetManagementApiClient { force_error: false };
3207
3208            let params = GetDetailOnSubAccountsFuturesAccountV2Params::builder("sub-account-email@email.com".to_string(),789,).build().unwrap();
3209
3210            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();
3211            let expected_response : models::GetDetailOnSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountV2Response");
3212
3213            let resp = client.get_detail_on_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3214            let data_future = resp.data();
3215            let actual_response = data_future.await.unwrap();
3216            assert_eq!(actual_response, expected_response);
3217        });
3218    }
3219
3220    #[test]
3221    fn get_detail_on_sub_accounts_futures_account_v2_optional_params_success() {
3222        TOKIO_SHARED_RT.block_on(async {
3223            let client = MockAssetManagementApiClient { force_error: false };
3224
3225            let params = GetDetailOnSubAccountsFuturesAccountV2Params::builder("sub-account-email@email.com".to_string(),789,).recv_window(5000).build().unwrap();
3226
3227            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();
3228            let expected_response : models::GetDetailOnSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsFuturesAccountV2Response");
3229
3230            let resp = client.get_detail_on_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3231            let data_future = resp.data();
3232            let actual_response = data_future.await.unwrap();
3233            assert_eq!(actual_response, expected_response);
3234        });
3235    }
3236
3237    #[test]
3238    fn get_detail_on_sub_accounts_futures_account_v2_response_error() {
3239        TOKIO_SHARED_RT.block_on(async {
3240            let client = MockAssetManagementApiClient { force_error: true };
3241
3242            let params = GetDetailOnSubAccountsFuturesAccountV2Params::builder(
3243                "sub-account-email@email.com".to_string(),
3244                789,
3245            )
3246            .build()
3247            .unwrap();
3248
3249            match client
3250                .get_detail_on_sub_accounts_futures_account_v2(params)
3251                .await
3252            {
3253                Ok(_) => panic!("Expected an error"),
3254                Err(err) => {
3255                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3256                }
3257            }
3258        });
3259    }
3260
3261    #[test]
3262    fn get_detail_on_sub_accounts_margin_account_required_params_success() {
3263        TOKIO_SHARED_RT.block_on(async {
3264            let client = MockAssetManagementApiClient { force_error: false };
3265
3266            let params = GetDetailOnSubAccountsMarginAccountParams::builder("sub-account-email@email.com".to_string(),).build().unwrap();
3267
3268            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"},{"asset":"BNB","borrowed":"201.66666672","free":"2346.50000000","interest":"0.00000000","locked":"0.00000000","netAsset":"2144.83333328"},{"asset":"ETH","borrowed":"0.00000000","free":"0.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00000000"},{"asset":"USDT","borrowed":"0.00000000","free":"0.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00000000"}]}"#).unwrap();
3269            let expected_response : models::GetDetailOnSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsMarginAccountResponse");
3270
3271            let resp = client.get_detail_on_sub_accounts_margin_account(params).await.expect("Expected a response");
3272            let data_future = resp.data();
3273            let actual_response = data_future.await.unwrap();
3274            assert_eq!(actual_response, expected_response);
3275        });
3276    }
3277
3278    #[test]
3279    fn get_detail_on_sub_accounts_margin_account_optional_params_success() {
3280        TOKIO_SHARED_RT.block_on(async {
3281            let client = MockAssetManagementApiClient { force_error: false };
3282
3283            let params = GetDetailOnSubAccountsMarginAccountParams::builder("sub-account-email@email.com".to_string(),).recv_window(5000).build().unwrap();
3284
3285            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"},{"asset":"BNB","borrowed":"201.66666672","free":"2346.50000000","interest":"0.00000000","locked":"0.00000000","netAsset":"2144.83333328"},{"asset":"ETH","borrowed":"0.00000000","free":"0.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00000000"},{"asset":"USDT","borrowed":"0.00000000","free":"0.00000000","interest":"0.00000000","locked":"0.00000000","netAsset":"0.00000000"}]}"#).unwrap();
3286            let expected_response : models::GetDetailOnSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetDetailOnSubAccountsMarginAccountResponse");
3287
3288            let resp = client.get_detail_on_sub_accounts_margin_account(params).await.expect("Expected a response");
3289            let data_future = resp.data();
3290            let actual_response = data_future.await.unwrap();
3291            assert_eq!(actual_response, expected_response);
3292        });
3293    }
3294
3295    #[test]
3296    fn get_detail_on_sub_accounts_margin_account_response_error() {
3297        TOKIO_SHARED_RT.block_on(async {
3298            let client = MockAssetManagementApiClient { force_error: true };
3299
3300            let params = GetDetailOnSubAccountsMarginAccountParams::builder(
3301                "sub-account-email@email.com".to_string(),
3302            )
3303            .build()
3304            .unwrap();
3305
3306            match client
3307                .get_detail_on_sub_accounts_margin_account(params)
3308                .await
3309            {
3310                Ok(_) => panic!("Expected an error"),
3311                Err(err) => {
3312                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3313                }
3314            }
3315        });
3316    }
3317
3318    #[test]
3319    fn get_move_position_history_for_sub_account_required_params_success() {
3320        TOKIO_SHARED_RT.block_on(async {
3321            let client = MockAssetManagementApiClient { force_error: false };
3322
3323            let params = GetMovePositionHistoryForSubAccountParams::builder("symbol_example".to_string(),789,789,).build().unwrap();
3324
3325            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},{"fromUserEmail":"testFrom1@google.com","toUserEmail":"testTo1@google.com","productType":"UM","symbol":"BTCUSDT","price":"97100.00000000","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1740041627000},{"fromUserEmail":"testFrom2@google.com","toUserEmail":"testTo2@google.com","productType":"UM","symbol":"BTCUSDT","price":"97108.62068889","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1740041959000}]}"#).unwrap();
3326            let expected_response : models::GetMovePositionHistoryForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetMovePositionHistoryForSubAccountResponse");
3327
3328            let resp = client.get_move_position_history_for_sub_account(params).await.expect("Expected a response");
3329            let data_future = resp.data();
3330            let actual_response = data_future.await.unwrap();
3331            assert_eq!(actual_response, expected_response);
3332        });
3333    }
3334
3335    #[test]
3336    fn get_move_position_history_for_sub_account_optional_params_success() {
3337        TOKIO_SHARED_RT.block_on(async {
3338            let client = MockAssetManagementApiClient { force_error: false };
3339
3340            let params = GetMovePositionHistoryForSubAccountParams::builder("symbol_example".to_string(),789,789,).start_time(1623319461670).end_time(1641782889000).recv_window(5000).build().unwrap();
3341
3342            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},{"fromUserEmail":"testFrom1@google.com","toUserEmail":"testTo1@google.com","productType":"UM","symbol":"BTCUSDT","price":"97100.00000000","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1740041627000},{"fromUserEmail":"testFrom2@google.com","toUserEmail":"testTo2@google.com","productType":"UM","symbol":"BTCUSDT","price":"97108.62068889","quantity":"0.00100000","positionSide":"BOTH","side":"SELL","timeStamp":1740041959000}]}"#).unwrap();
3343            let expected_response : models::GetMovePositionHistoryForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetMovePositionHistoryForSubAccountResponse");
3344
3345            let resp = client.get_move_position_history_for_sub_account(params).await.expect("Expected a response");
3346            let data_future = resp.data();
3347            let actual_response = data_future.await.unwrap();
3348            assert_eq!(actual_response, expected_response);
3349        });
3350    }
3351
3352    #[test]
3353    fn get_move_position_history_for_sub_account_response_error() {
3354        TOKIO_SHARED_RT.block_on(async {
3355            let client = MockAssetManagementApiClient { force_error: true };
3356
3357            let params = GetMovePositionHistoryForSubAccountParams::builder(
3358                "symbol_example".to_string(),
3359                789,
3360                789,
3361            )
3362            .build()
3363            .unwrap();
3364
3365            match client
3366                .get_move_position_history_for_sub_account(params)
3367                .await
3368            {
3369                Ok(_) => panic!("Expected an error"),
3370                Err(err) => {
3371                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3372                }
3373            }
3374        });
3375    }
3376
3377    #[test]
3378    fn get_sub_account_deposit_address_required_params_success() {
3379        TOKIO_SHARED_RT.block_on(async {
3380            let client = MockAssetManagementApiClient { force_error: false };
3381
3382            let params = GetSubAccountDepositAddressParams::builder("sub-account-email@email.com".to_string(),"coin_example".to_string(),).build().unwrap();
3383
3384            let resp_json: Value = serde_json::from_str(r#"{"address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV","coin":"USDT","tag":"","url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV"}"#).unwrap();
3385            let expected_response : models::GetSubAccountDepositAddressResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSubAccountDepositAddressResponse");
3386
3387            let resp = client.get_sub_account_deposit_address(params).await.expect("Expected a response");
3388            let data_future = resp.data();
3389            let actual_response = data_future.await.unwrap();
3390            assert_eq!(actual_response, expected_response);
3391        });
3392    }
3393
3394    #[test]
3395    fn get_sub_account_deposit_address_optional_params_success() {
3396        TOKIO_SHARED_RT.block_on(async {
3397            let client = MockAssetManagementApiClient { force_error: false };
3398
3399            let params = GetSubAccountDepositAddressParams::builder("sub-account-email@email.com".to_string(),"coin_example".to_string(),).network("network_example".to_string()).amount(dec!(1.0)).recv_window(5000).build().unwrap();
3400
3401            let resp_json: Value = serde_json::from_str(r#"{"address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV","coin":"USDT","tag":"","url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV"}"#).unwrap();
3402            let expected_response : models::GetSubAccountDepositAddressResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSubAccountDepositAddressResponse");
3403
3404            let resp = client.get_sub_account_deposit_address(params).await.expect("Expected a response");
3405            let data_future = resp.data();
3406            let actual_response = data_future.await.unwrap();
3407            assert_eq!(actual_response, expected_response);
3408        });
3409    }
3410
3411    #[test]
3412    fn get_sub_account_deposit_address_response_error() {
3413        TOKIO_SHARED_RT.block_on(async {
3414            let client = MockAssetManagementApiClient { force_error: true };
3415
3416            let params = GetSubAccountDepositAddressParams::builder(
3417                "sub-account-email@email.com".to_string(),
3418                "coin_example".to_string(),
3419            )
3420            .build()
3421            .unwrap();
3422
3423            match client.get_sub_account_deposit_address(params).await {
3424                Ok(_) => panic!("Expected an error"),
3425                Err(err) => {
3426                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3427                }
3428            }
3429        });
3430    }
3431
3432    #[test]
3433    fn get_sub_account_deposit_history_required_params_success() {
3434        TOKIO_SHARED_RT.block_on(async {
3435            let client = MockAssetManagementApiClient { force_error: false };
3436
3437            let params = GetSubAccountDepositHistoryParams::builder("sub-account-email@email.com".to_string(),).build().unwrap();
3438
3439            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},{"id":"769754833590042625","amount":"0.50000000","coin":"IOTA","network":"IOTA","status":1,"address":"SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW","addressTag":"","txId":"ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999","insertTime":1599620082000,"transferType":0,"confirmTimes":"1/1","unlockConfirm":0,"walletType":0}]"#).unwrap();
3440            let expected_response : Vec<models::GetSubAccountDepositHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountDepositHistoryResponseInner>");
3441
3442            let resp = client.get_sub_account_deposit_history(params).await.expect("Expected a response");
3443            let data_future = resp.data();
3444            let actual_response = data_future.await.unwrap();
3445            assert_eq!(actual_response, expected_response);
3446        });
3447    }
3448
3449    #[test]
3450    fn get_sub_account_deposit_history_optional_params_success() {
3451        TOKIO_SHARED_RT.block_on(async {
3452            let client = MockAssetManagementApiClient { force_error: false };
3453
3454            let params = GetSubAccountDepositHistoryParams::builder("sub-account-email@email.com".to_string(),).include_source(false).coin("coin_example".to_string()).status(789).start_time(1623319461670).end_time(1641782889000).limit(1).offset(0).recv_window(5000).tx_id("1".to_string()).build().unwrap();
3455
3456            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},{"id":"769754833590042625","amount":"0.50000000","coin":"IOTA","network":"IOTA","status":1,"address":"SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW","addressTag":"","txId":"ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999","insertTime":1599620082000,"transferType":0,"confirmTimes":"1/1","unlockConfirm":0,"walletType":0}]"#).unwrap();
3457            let expected_response : Vec<models::GetSubAccountDepositHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSubAccountDepositHistoryResponseInner>");
3458
3459            let resp = client.get_sub_account_deposit_history(params).await.expect("Expected a response");
3460            let data_future = resp.data();
3461            let actual_response = data_future.await.unwrap();
3462            assert_eq!(actual_response, expected_response);
3463        });
3464    }
3465
3466    #[test]
3467    fn get_sub_account_deposit_history_response_error() {
3468        TOKIO_SHARED_RT.block_on(async {
3469            let client = MockAssetManagementApiClient { force_error: true };
3470
3471            let params = GetSubAccountDepositHistoryParams::builder(
3472                "sub-account-email@email.com".to_string(),
3473            )
3474            .build()
3475            .unwrap();
3476
3477            match client.get_sub_account_deposit_history(params).await {
3478                Ok(_) => panic!("Expected an error"),
3479                Err(err) => {
3480                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3481                }
3482            }
3483        });
3484    }
3485
3486    #[test]
3487    fn get_summary_of_sub_accounts_futures_account_required_params_success() {
3488        TOKIO_SHARED_RT.block_on(async {
3489            let client = MockAssetManagementApiClient { force_error: false };
3490
3491            let params = GetSummaryOfSubAccountsFuturesAccountParams::builder(789,789,).build().unwrap();
3492
3493            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"},{"email":"345@test.com","totalInitialMargin":"0.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"0.90575887","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","asset":"USD"}]}"#).unwrap();
3494            let expected_response : models::GetSummaryOfSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountResponse");
3495
3496            let resp = client.get_summary_of_sub_accounts_futures_account(params).await.expect("Expected a response");
3497            let data_future = resp.data();
3498            let actual_response = data_future.await.unwrap();
3499            assert_eq!(actual_response, expected_response);
3500        });
3501    }
3502
3503    #[test]
3504    fn get_summary_of_sub_accounts_futures_account_optional_params_success() {
3505        TOKIO_SHARED_RT.block_on(async {
3506            let client = MockAssetManagementApiClient { force_error: false };
3507
3508            let params = GetSummaryOfSubAccountsFuturesAccountParams::builder(789,789,).recv_window(5000).build().unwrap();
3509
3510            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"},{"email":"345@test.com","totalInitialMargin":"0.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"0.90575887","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","asset":"USD"}]}"#).unwrap();
3511            let expected_response : models::GetSummaryOfSubAccountsFuturesAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountResponse");
3512
3513            let resp = client.get_summary_of_sub_accounts_futures_account(params).await.expect("Expected a response");
3514            let data_future = resp.data();
3515            let actual_response = data_future.await.unwrap();
3516            assert_eq!(actual_response, expected_response);
3517        });
3518    }
3519
3520    #[test]
3521    fn get_summary_of_sub_accounts_futures_account_response_error() {
3522        TOKIO_SHARED_RT.block_on(async {
3523            let client = MockAssetManagementApiClient { force_error: true };
3524
3525            let params = GetSummaryOfSubAccountsFuturesAccountParams::builder(789, 789)
3526                .build()
3527                .unwrap();
3528
3529            match client
3530                .get_summary_of_sub_accounts_futures_account(params)
3531                .await
3532            {
3533                Ok(_) => panic!("Expected an error"),
3534                Err(err) => {
3535                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3536                }
3537            }
3538        });
3539    }
3540
3541    #[test]
3542    fn get_summary_of_sub_accounts_futures_account_v2_required_params_success() {
3543        TOKIO_SHARED_RT.block_on(async {
3544            let client = MockAssetManagementApiClient { force_error: false };
3545
3546            let params = GetSummaryOfSubAccountsFuturesAccountV2Params::builder(789,).build().unwrap();
3547
3548            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"},{"email":"345@test.com","totalInitialMargin":"0.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"0.90575887","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","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"},{"email":"345@test.com","totalMarginBalance":"0.90575887","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","asset":"BTC"}]}}"#).unwrap();
3549            let expected_response : models::GetSummaryOfSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountV2Response");
3550
3551            let resp = client.get_summary_of_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3552            let data_future = resp.data();
3553            let actual_response = data_future.await.unwrap();
3554            assert_eq!(actual_response, expected_response);
3555        });
3556    }
3557
3558    #[test]
3559    fn get_summary_of_sub_accounts_futures_account_v2_optional_params_success() {
3560        TOKIO_SHARED_RT.block_on(async {
3561            let client = MockAssetManagementApiClient { force_error: false };
3562
3563            let params = GetSummaryOfSubAccountsFuturesAccountV2Params::builder(789,).page(1).limit(1).recv_window(5000).build().unwrap();
3564
3565            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"},{"email":"345@test.com","totalInitialMargin":"0.83137400","totalMaintenanceMargin":"0.41568700","totalMarginBalance":"0.90575887","totalOpenOrderInitialMargin":"0.00000000","totalPositionInitialMargin":"0.83137400","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","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"},{"email":"345@test.com","totalMarginBalance":"0.90575887","totalUnrealizedProfit":"0.03219710","totalWalletBalance":"0.87356177","asset":"BTC"}]}}"#).unwrap();
3566            let expected_response : models::GetSummaryOfSubAccountsFuturesAccountV2Response = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsFuturesAccountV2Response");
3567
3568            let resp = client.get_summary_of_sub_accounts_futures_account_v2(params).await.expect("Expected a response");
3569            let data_future = resp.data();
3570            let actual_response = data_future.await.unwrap();
3571            assert_eq!(actual_response, expected_response);
3572        });
3573    }
3574
3575    #[test]
3576    fn get_summary_of_sub_accounts_futures_account_v2_response_error() {
3577        TOKIO_SHARED_RT.block_on(async {
3578            let client = MockAssetManagementApiClient { force_error: true };
3579
3580            let params = GetSummaryOfSubAccountsFuturesAccountV2Params::builder(789)
3581                .build()
3582                .unwrap();
3583
3584            match client
3585                .get_summary_of_sub_accounts_futures_account_v2(params)
3586                .await
3587            {
3588                Ok(_) => panic!("Expected an error"),
3589                Err(err) => {
3590                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3591                }
3592            }
3593        });
3594    }
3595
3596    #[test]
3597    fn get_summary_of_sub_accounts_margin_account_required_params_success() {
3598        TOKIO_SHARED_RT.block_on(async {
3599            let client = MockAssetManagementApiClient { force_error: false };
3600
3601            let params = GetSummaryOfSubAccountsMarginAccountParams::builder().build().unwrap();
3602
3603            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"},{"email":"345@test.com","totalAssetOfBtc":"2.22222222","totalLiabilityOfBtc":"1.00000001","totalNetAssetOfBtc":"1.22222221"}]}"#).unwrap();
3604            let expected_response : models::GetSummaryOfSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsMarginAccountResponse");
3605
3606            let resp = client.get_summary_of_sub_accounts_margin_account(params).await.expect("Expected a response");
3607            let data_future = resp.data();
3608            let actual_response = data_future.await.unwrap();
3609            assert_eq!(actual_response, expected_response);
3610        });
3611    }
3612
3613    #[test]
3614    fn get_summary_of_sub_accounts_margin_account_optional_params_success() {
3615        TOKIO_SHARED_RT.block_on(async {
3616            let client = MockAssetManagementApiClient { force_error: false };
3617
3618            let params = GetSummaryOfSubAccountsMarginAccountParams::builder().recv_window(5000).build().unwrap();
3619
3620            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"},{"email":"345@test.com","totalAssetOfBtc":"2.22222222","totalLiabilityOfBtc":"1.00000001","totalNetAssetOfBtc":"1.22222221"}]}"#).unwrap();
3621            let expected_response : models::GetSummaryOfSubAccountsMarginAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetSummaryOfSubAccountsMarginAccountResponse");
3622
3623            let resp = client.get_summary_of_sub_accounts_margin_account(params).await.expect("Expected a response");
3624            let data_future = resp.data();
3625            let actual_response = data_future.await.unwrap();
3626            assert_eq!(actual_response, expected_response);
3627        });
3628    }
3629
3630    #[test]
3631    fn get_summary_of_sub_accounts_margin_account_response_error() {
3632        TOKIO_SHARED_RT.block_on(async {
3633            let client = MockAssetManagementApiClient { force_error: true };
3634
3635            let params = GetSummaryOfSubAccountsMarginAccountParams::builder()
3636                .build()
3637                .unwrap();
3638
3639            match client
3640                .get_summary_of_sub_accounts_margin_account(params)
3641                .await
3642            {
3643                Ok(_) => panic!("Expected an error"),
3644                Err(err) => {
3645                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3646                }
3647            }
3648        });
3649    }
3650
3651    #[test]
3652    fn margin_transfer_for_sub_account_required_params_success() {
3653        TOKIO_SHARED_RT.block_on(async {
3654            let client = MockAssetManagementApiClient { force_error: false };
3655
3656            let params = MarginTransferForSubAccountParams::builder(
3657                "sub-account-email@email.com".to_string(),
3658                "asset_example".to_string(),
3659                dec!(1.0),
3660                789,
3661            )
3662            .build()
3663            .unwrap();
3664
3665            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
3666            let expected_response: models::MarginTransferForSubAccountResponse =
3667                serde_json::from_value(resp_json.clone())
3668                    .expect("should parse into models::MarginTransferForSubAccountResponse");
3669
3670            let resp = client
3671                .margin_transfer_for_sub_account(params)
3672                .await
3673                .expect("Expected a response");
3674            let data_future = resp.data();
3675            let actual_response = data_future.await.unwrap();
3676            assert_eq!(actual_response, expected_response);
3677        });
3678    }
3679
3680    #[test]
3681    fn margin_transfer_for_sub_account_optional_params_success() {
3682        TOKIO_SHARED_RT.block_on(async {
3683            let client = MockAssetManagementApiClient { force_error: false };
3684
3685            let params = MarginTransferForSubAccountParams::builder(
3686                "sub-account-email@email.com".to_string(),
3687                "asset_example".to_string(),
3688                dec!(1.0),
3689                789,
3690            )
3691            .recv_window(5000)
3692            .build()
3693            .unwrap();
3694
3695            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
3696            let expected_response: models::MarginTransferForSubAccountResponse =
3697                serde_json::from_value(resp_json.clone())
3698                    .expect("should parse into models::MarginTransferForSubAccountResponse");
3699
3700            let resp = client
3701                .margin_transfer_for_sub_account(params)
3702                .await
3703                .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 margin_transfer_for_sub_account_response_error() {
3712        TOKIO_SHARED_RT.block_on(async {
3713            let client = MockAssetManagementApiClient { force_error: true };
3714
3715            let params = MarginTransferForSubAccountParams::builder(
3716                "sub-account-email@email.com".to_string(),
3717                "asset_example".to_string(),
3718                dec!(1.0),
3719                789,
3720            )
3721            .build()
3722            .unwrap();
3723
3724            match client.margin_transfer_for_sub_account(params).await {
3725                Ok(_) => panic!("Expected an error"),
3726                Err(err) => {
3727                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3728                }
3729            }
3730        });
3731    }
3732
3733    #[test]
3734    fn move_position_for_sub_account_required_params_success() {
3735        TOKIO_SHARED_RT.block_on(async {
3736            let client = MockAssetManagementApiClient { force_error: false };
3737
3738            let params = MovePositionForSubAccountParams::builder("from_user_email_example".to_string(),"to_user_email_example".to_string(),"product_type_example".to_string(),vec![],).build().unwrap();
3739
3740            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},{"fromUserEmail":"testFrom1@google.com","toUserEmail":"1testTo@google.com","productType":"UM","symbol":"BTCUSDT","priceType":"MARK_PRICE","price":"97139.00000000","quantity":"0.0011","positionSide":"BOTH","side":"BUY","success":true}]}"#).unwrap();
3741            let expected_response : models::MovePositionForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MovePositionForSubAccountResponse");
3742
3743            let resp = client.move_position_for_sub_account(params).await.expect("Expected a response");
3744            let data_future = resp.data();
3745            let actual_response = data_future.await.unwrap();
3746            assert_eq!(actual_response, expected_response);
3747        });
3748    }
3749
3750    #[test]
3751    fn move_position_for_sub_account_optional_params_success() {
3752        TOKIO_SHARED_RT.block_on(async {
3753            let client = MockAssetManagementApiClient { force_error: false };
3754
3755            let params = MovePositionForSubAccountParams::builder("from_user_email_example".to_string(),"to_user_email_example".to_string(),"product_type_example".to_string(),vec![],).recv_window(5000).build().unwrap();
3756
3757            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},{"fromUserEmail":"testFrom1@google.com","toUserEmail":"1testTo@google.com","productType":"UM","symbol":"BTCUSDT","priceType":"MARK_PRICE","price":"97139.00000000","quantity":"0.0011","positionSide":"BOTH","side":"BUY","success":true}]}"#).unwrap();
3758            let expected_response : models::MovePositionForSubAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::MovePositionForSubAccountResponse");
3759
3760            let resp = client.move_position_for_sub_account(params).await.expect("Expected a response");
3761            let data_future = resp.data();
3762            let actual_response = data_future.await.unwrap();
3763            assert_eq!(actual_response, expected_response);
3764        });
3765    }
3766
3767    #[test]
3768    fn move_position_for_sub_account_response_error() {
3769        TOKIO_SHARED_RT.block_on(async {
3770            let client = MockAssetManagementApiClient { force_error: true };
3771
3772            let params = MovePositionForSubAccountParams::builder(
3773                "from_user_email_example".to_string(),
3774                "to_user_email_example".to_string(),
3775                "product_type_example".to_string(),
3776                vec![],
3777            )
3778            .build()
3779            .unwrap();
3780
3781            match client.move_position_for_sub_account(params).await {
3782                Ok(_) => panic!("Expected an error"),
3783                Err(err) => {
3784                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3785                }
3786            }
3787        });
3788    }
3789
3790    #[test]
3791    fn query_sub_account_assets_required_params_success() {
3792        TOKIO_SHARED_RT.block_on(async {
3793            let client = MockAssetManagementApiClient { force_error: false };
3794
3795            let params = QuerySubAccountAssetsParams::builder("sub-account-email@email.com".to_string(),).build().unwrap();
3796
3797            let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":0,"withdrawing":0,"asset":"ADA","free":10000,"locked":0},{"freeze":0,"withdrawing":0,"asset":"BNB","free":10003,"locked":0},{"freeze":0,"withdrawing":0,"asset":"BTC","free":11467.6399,"locked":0},{"freeze":0,"withdrawing":0,"asset":"ETH","free":10004.995,"locked":0},{"freeze":0,"withdrawing":0,"asset":"USDT","free":11652.14213,"locked":0}]}"#).unwrap();
3798            let expected_response : models::QuerySubAccountAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsResponse");
3799
3800            let resp = client.query_sub_account_assets(params).await.expect("Expected a response");
3801            let data_future = resp.data();
3802            let actual_response = data_future.await.unwrap();
3803            assert_eq!(actual_response, expected_response);
3804        });
3805    }
3806
3807    #[test]
3808    fn query_sub_account_assets_optional_params_success() {
3809        TOKIO_SHARED_RT.block_on(async {
3810            let client = MockAssetManagementApiClient { force_error: false };
3811
3812            let params = QuerySubAccountAssetsParams::builder("sub-account-email@email.com".to_string(),).recv_window(5000).build().unwrap();
3813
3814            let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":0,"withdrawing":0,"asset":"ADA","free":10000,"locked":0},{"freeze":0,"withdrawing":0,"asset":"BNB","free":10003,"locked":0},{"freeze":0,"withdrawing":0,"asset":"BTC","free":11467.6399,"locked":0},{"freeze":0,"withdrawing":0,"asset":"ETH","free":10004.995,"locked":0},{"freeze":0,"withdrawing":0,"asset":"USDT","free":11652.14213,"locked":0}]}"#).unwrap();
3815            let expected_response : models::QuerySubAccountAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsResponse");
3816
3817            let resp = client.query_sub_account_assets(params).await.expect("Expected a response");
3818            let data_future = resp.data();
3819            let actual_response = data_future.await.unwrap();
3820            assert_eq!(actual_response, expected_response);
3821        });
3822    }
3823
3824    #[test]
3825    fn query_sub_account_assets_response_error() {
3826        TOKIO_SHARED_RT.block_on(async {
3827            let client = MockAssetManagementApiClient { force_error: true };
3828
3829            let params =
3830                QuerySubAccountAssetsParams::builder("sub-account-email@email.com".to_string())
3831                    .build()
3832                    .unwrap();
3833
3834            match client.query_sub_account_assets(params).await {
3835                Ok(_) => panic!("Expected an error"),
3836                Err(err) => {
3837                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3838                }
3839            }
3840        });
3841    }
3842
3843    #[test]
3844    fn query_sub_account_assets_asset_management_required_params_success() {
3845        TOKIO_SHARED_RT.block_on(async {
3846            let client = MockAssetManagementApiClient { force_error: false };
3847
3848            let params = QuerySubAccountAssetsAssetManagementParams::builder("sub-account-email@email.com".to_string(),).build().unwrap();
3849
3850            let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":"0","withdrawing":"0","asset":"ADA","free":"10000","locked":"0"},{"freeze":"0","withdrawing":"0","asset":"BNB","free":"10003","locked":"0"},{"freeze":"0","withdrawing":"0","asset":"BTC","free":"11467.6399","locked":"0"}]}"#).unwrap();
3851            let expected_response : models::QuerySubAccountAssetsAssetManagementResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsAssetManagementResponse");
3852
3853            let resp = client.query_sub_account_assets_asset_management(params).await.expect("Expected a response");
3854            let data_future = resp.data();
3855            let actual_response = data_future.await.unwrap();
3856            assert_eq!(actual_response, expected_response);
3857        });
3858    }
3859
3860    #[test]
3861    fn query_sub_account_assets_asset_management_optional_params_success() {
3862        TOKIO_SHARED_RT.block_on(async {
3863            let client = MockAssetManagementApiClient { force_error: false };
3864
3865            let params = QuerySubAccountAssetsAssetManagementParams::builder("sub-account-email@email.com".to_string(),).recv_window(5000).build().unwrap();
3866
3867            let resp_json: Value = serde_json::from_str(r#"{"balances":[{"freeze":"0","withdrawing":"0","asset":"ADA","free":"10000","locked":"0"},{"freeze":"0","withdrawing":"0","asset":"BNB","free":"10003","locked":"0"},{"freeze":"0","withdrawing":"0","asset":"BTC","free":"11467.6399","locked":"0"}]}"#).unwrap();
3868            let expected_response : models::QuerySubAccountAssetsAssetManagementResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountAssetsAssetManagementResponse");
3869
3870            let resp = client.query_sub_account_assets_asset_management(params).await.expect("Expected a response");
3871            let data_future = resp.data();
3872            let actual_response = data_future.await.unwrap();
3873            assert_eq!(actual_response, expected_response);
3874        });
3875    }
3876
3877    #[test]
3878    fn query_sub_account_assets_asset_management_response_error() {
3879        TOKIO_SHARED_RT.block_on(async {
3880            let client = MockAssetManagementApiClient { force_error: true };
3881
3882            let params = QuerySubAccountAssetsAssetManagementParams::builder(
3883                "sub-account-email@email.com".to_string(),
3884            )
3885            .build()
3886            .unwrap();
3887
3888            match client
3889                .query_sub_account_assets_asset_management(params)
3890                .await
3891            {
3892                Ok(_) => panic!("Expected an error"),
3893                Err(err) => {
3894                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3895                }
3896            }
3897        });
3898    }
3899
3900    #[test]
3901    fn query_sub_account_futures_asset_transfer_history_required_params_success() {
3902        TOKIO_SHARED_RT.block_on(async {
3903            let client = MockAssetManagementApiClient { force_error: false };
3904
3905            let params = QuerySubAccountFuturesAssetTransferHistoryParams::builder("sub-account-email@email.com".to_string(),789,).build().unwrap();
3906
3907            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},{"from":"bbb@test.com","to":"ccc@test.com","asset":"ETH","qty":"2","tranId":11631474902,"time":1544433328000}]}"#).unwrap();
3908            let expected_response : models::QuerySubAccountFuturesAssetTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountFuturesAssetTransferHistoryResponse");
3909
3910            let resp = client.query_sub_account_futures_asset_transfer_history(params).await.expect("Expected a response");
3911            let data_future = resp.data();
3912            let actual_response = data_future.await.unwrap();
3913            assert_eq!(actual_response, expected_response);
3914        });
3915    }
3916
3917    #[test]
3918    fn query_sub_account_futures_asset_transfer_history_optional_params_success() {
3919        TOKIO_SHARED_RT.block_on(async {
3920            let client = MockAssetManagementApiClient { force_error: false };
3921
3922            let params = QuerySubAccountFuturesAssetTransferHistoryParams::builder("sub-account-email@email.com".to_string(),789,).start_time(1623319461670).end_time(1641782889000).page(1).limit(1).recv_window(5000).build().unwrap();
3923
3924            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},{"from":"bbb@test.com","to":"ccc@test.com","asset":"ETH","qty":"2","tranId":11631474902,"time":1544433328000}]}"#).unwrap();
3925            let expected_response : models::QuerySubAccountFuturesAssetTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountFuturesAssetTransferHistoryResponse");
3926
3927            let resp = client.query_sub_account_futures_asset_transfer_history(params).await.expect("Expected a response");
3928            let data_future = resp.data();
3929            let actual_response = data_future.await.unwrap();
3930            assert_eq!(actual_response, expected_response);
3931        });
3932    }
3933
3934    #[test]
3935    fn query_sub_account_futures_asset_transfer_history_response_error() {
3936        TOKIO_SHARED_RT.block_on(async {
3937            let client = MockAssetManagementApiClient { force_error: true };
3938
3939            let params = QuerySubAccountFuturesAssetTransferHistoryParams::builder(
3940                "sub-account-email@email.com".to_string(),
3941                789,
3942            )
3943            .build()
3944            .unwrap();
3945
3946            match client
3947                .query_sub_account_futures_asset_transfer_history(params)
3948                .await
3949            {
3950                Ok(_) => panic!("Expected an error"),
3951                Err(err) => {
3952                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
3953                }
3954            }
3955        });
3956    }
3957
3958    #[test]
3959    fn query_sub_account_spot_asset_transfer_history_required_params_success() {
3960        TOKIO_SHARED_RT.block_on(async {
3961            let client = MockAssetManagementApiClient { force_error: false };
3962
3963            let params = QuerySubAccountSpotAssetTransferHistoryParams::builder().build().unwrap();
3964
3965            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},{"from":"bbb@test.com","to":"ccc@test.com","asset":"ETH","qty":"2","status":"SUCCESS","tranId":6489938713,"time":1544433328000}]"#).unwrap();
3966            let expected_response : Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>");
3967
3968            let resp = client.query_sub_account_spot_asset_transfer_history(params).await.expect("Expected a response");
3969            let data_future = resp.data();
3970            let actual_response = data_future.await.unwrap();
3971            assert_eq!(actual_response, expected_response);
3972        });
3973    }
3974
3975    #[test]
3976    fn query_sub_account_spot_asset_transfer_history_optional_params_success() {
3977        TOKIO_SHARED_RT.block_on(async {
3978            let client = MockAssetManagementApiClient { force_error: false };
3979
3980            let params = QuerySubAccountSpotAssetTransferHistoryParams::builder().from_email("from_email_example".to_string()).to_email("to_email_example".to_string()).start_time(1623319461670).end_time(1641782889000).page(1).limit(1).recv_window(5000).build().unwrap();
3981
3982            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},{"from":"bbb@test.com","to":"ccc@test.com","asset":"ETH","qty":"2","status":"SUCCESS","tranId":6489938713,"time":1544433328000}]"#).unwrap();
3983            let expected_response : Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QuerySubAccountSpotAssetTransferHistoryResponseInner>");
3984
3985            let resp = client.query_sub_account_spot_asset_transfer_history(params).await.expect("Expected a response");
3986            let data_future = resp.data();
3987            let actual_response = data_future.await.unwrap();
3988            assert_eq!(actual_response, expected_response);
3989        });
3990    }
3991
3992    #[test]
3993    fn query_sub_account_spot_asset_transfer_history_response_error() {
3994        TOKIO_SHARED_RT.block_on(async {
3995            let client = MockAssetManagementApiClient { force_error: true };
3996
3997            let params = QuerySubAccountSpotAssetTransferHistoryParams::builder()
3998                .build()
3999                .unwrap();
4000
4001            match client
4002                .query_sub_account_spot_asset_transfer_history(params)
4003                .await
4004            {
4005                Ok(_) => panic!("Expected an error"),
4006                Err(err) => {
4007                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4008                }
4009            }
4010        });
4011    }
4012
4013    #[test]
4014    fn query_sub_account_spot_assets_summary_required_params_success() {
4015        TOKIO_SHARED_RT.block_on(async {
4016            let client = MockAssetManagementApiClient { force_error: false };
4017
4018            let params = QuerySubAccountSpotAssetsSummaryParams::builder().build().unwrap();
4019
4020            let resp_json: Value = serde_json::from_str(r#"{"totalCount":2,"masterAccountTotalAsset":"0.23231201","spotSubUserAssetBtcVoList":[{"email":"sub123@test.com","totalAsset":"9999.00000000"},{"email":"test456@test.com","totalAsset":"0.00000000"}]}"#).unwrap();
4021            let expected_response : models::QuerySubAccountSpotAssetsSummaryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountSpotAssetsSummaryResponse");
4022
4023            let resp = client.query_sub_account_spot_assets_summary(params).await.expect("Expected a response");
4024            let data_future = resp.data();
4025            let actual_response = data_future.await.unwrap();
4026            assert_eq!(actual_response, expected_response);
4027        });
4028    }
4029
4030    #[test]
4031    fn query_sub_account_spot_assets_summary_optional_params_success() {
4032        TOKIO_SHARED_RT.block_on(async {
4033            let client = MockAssetManagementApiClient { force_error: false };
4034
4035            let params = QuerySubAccountSpotAssetsSummaryParams::builder().email("email_example".to_string()).page(1).size(10).recv_window(5000).build().unwrap();
4036
4037            let resp_json: Value = serde_json::from_str(r#"{"totalCount":2,"masterAccountTotalAsset":"0.23231201","spotSubUserAssetBtcVoList":[{"email":"sub123@test.com","totalAsset":"9999.00000000"},{"email":"test456@test.com","totalAsset":"0.00000000"}]}"#).unwrap();
4038            let expected_response : models::QuerySubAccountSpotAssetsSummaryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountSpotAssetsSummaryResponse");
4039
4040            let resp = client.query_sub_account_spot_assets_summary(params).await.expect("Expected a response");
4041            let data_future = resp.data();
4042            let actual_response = data_future.await.unwrap();
4043            assert_eq!(actual_response, expected_response);
4044        });
4045    }
4046
4047    #[test]
4048    fn query_sub_account_spot_assets_summary_response_error() {
4049        TOKIO_SHARED_RT.block_on(async {
4050            let client = MockAssetManagementApiClient { force_error: true };
4051
4052            let params = QuerySubAccountSpotAssetsSummaryParams::builder()
4053                .build()
4054                .unwrap();
4055
4056            match client.query_sub_account_spot_assets_summary(params).await {
4057                Ok(_) => panic!("Expected an error"),
4058                Err(err) => {
4059                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4060                }
4061            }
4062        });
4063    }
4064
4065    #[test]
4066    fn query_universal_transfer_history_required_params_success() {
4067        TOKIO_SHARED_RT.block_on(async {
4068            let client = MockAssetManagementApiClient { force_error: false };
4069
4070            let params = QueryUniversalTransferHistoryParams::builder().build().unwrap();
4071
4072            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();
4073            let expected_response : models::QueryUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUniversalTransferHistoryResponse");
4074
4075            let resp = client.query_universal_transfer_history(params).await.expect("Expected a response");
4076            let data_future = resp.data();
4077            let actual_response = data_future.await.unwrap();
4078            assert_eq!(actual_response, expected_response);
4079        });
4080    }
4081
4082    #[test]
4083    fn query_universal_transfer_history_optional_params_success() {
4084        TOKIO_SHARED_RT.block_on(async {
4085            let client = MockAssetManagementApiClient { force_error: false };
4086
4087            let params = QueryUniversalTransferHistoryParams::builder().from_email("from_email_example".to_string()).to_email("to_email_example".to_string()).client_tran_id("1".to_string()).start_time(1623319461670).end_time(1641782889000).page(1).limit(1).recv_window(5000).build().unwrap();
4088
4089            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();
4090            let expected_response : models::QueryUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUniversalTransferHistoryResponse");
4091
4092            let resp = client.query_universal_transfer_history(params).await.expect("Expected a response");
4093            let data_future = resp.data();
4094            let actual_response = data_future.await.unwrap();
4095            assert_eq!(actual_response, expected_response);
4096        });
4097    }
4098
4099    #[test]
4100    fn query_universal_transfer_history_response_error() {
4101        TOKIO_SHARED_RT.block_on(async {
4102            let client = MockAssetManagementApiClient { force_error: true };
4103
4104            let params = QueryUniversalTransferHistoryParams::builder()
4105                .build()
4106                .unwrap();
4107
4108            match client.query_universal_transfer_history(params).await {
4109                Ok(_) => panic!("Expected an error"),
4110                Err(err) => {
4111                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4112                }
4113            }
4114        });
4115    }
4116
4117    #[test]
4118    fn sub_account_futures_asset_transfer_required_params_success() {
4119        TOKIO_SHARED_RT.block_on(async {
4120            let client = MockAssetManagementApiClient { force_error: false };
4121
4122            let params = SubAccountFuturesAssetTransferParams::builder(
4123                "from_email_example".to_string(),
4124                "to_email_example".to_string(),
4125                789,
4126                "asset_example".to_string(),
4127                dec!(1.0),
4128            )
4129            .build()
4130            .unwrap();
4131
4132            let resp_json: Value =
4133                serde_json::from_str(r#"{"success":true,"txnId":"2934662589"}"#).unwrap();
4134            let expected_response: models::SubAccountFuturesAssetTransferResponse =
4135                serde_json::from_value(resp_json.clone())
4136                    .expect("should parse into models::SubAccountFuturesAssetTransferResponse");
4137
4138            let resp = client
4139                .sub_account_futures_asset_transfer(params)
4140                .await
4141                .expect("Expected a response");
4142            let data_future = resp.data();
4143            let actual_response = data_future.await.unwrap();
4144            assert_eq!(actual_response, expected_response);
4145        });
4146    }
4147
4148    #[test]
4149    fn sub_account_futures_asset_transfer_optional_params_success() {
4150        TOKIO_SHARED_RT.block_on(async {
4151            let client = MockAssetManagementApiClient { force_error: false };
4152
4153            let params = SubAccountFuturesAssetTransferParams::builder(
4154                "from_email_example".to_string(),
4155                "to_email_example".to_string(),
4156                789,
4157                "asset_example".to_string(),
4158                dec!(1.0),
4159            )
4160            .recv_window(5000)
4161            .build()
4162            .unwrap();
4163
4164            let resp_json: Value =
4165                serde_json::from_str(r#"{"success":true,"txnId":"2934662589"}"#).unwrap();
4166            let expected_response: models::SubAccountFuturesAssetTransferResponse =
4167                serde_json::from_value(resp_json.clone())
4168                    .expect("should parse into models::SubAccountFuturesAssetTransferResponse");
4169
4170            let resp = client
4171                .sub_account_futures_asset_transfer(params)
4172                .await
4173                .expect("Expected a response");
4174            let data_future = resp.data();
4175            let actual_response = data_future.await.unwrap();
4176            assert_eq!(actual_response, expected_response);
4177        });
4178    }
4179
4180    #[test]
4181    fn sub_account_futures_asset_transfer_response_error() {
4182        TOKIO_SHARED_RT.block_on(async {
4183            let client = MockAssetManagementApiClient { force_error: true };
4184
4185            let params = SubAccountFuturesAssetTransferParams::builder(
4186                "from_email_example".to_string(),
4187                "to_email_example".to_string(),
4188                789,
4189                "asset_example".to_string(),
4190                dec!(1.0),
4191            )
4192            .build()
4193            .unwrap();
4194
4195            match client.sub_account_futures_asset_transfer(params).await {
4196                Ok(_) => panic!("Expected an error"),
4197                Err(err) => {
4198                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4199                }
4200            }
4201        });
4202    }
4203
4204    #[test]
4205    fn sub_account_transfer_history_required_params_success() {
4206        TOKIO_SHARED_RT.block_on(async {
4207            let client = MockAssetManagementApiClient { force_error: false };
4208
4209            let params = SubAccountTransferHistoryParams::builder().build().unwrap();
4210
4211            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},{"counterParty":"subAccount","email":"sub2@test.com","type":1,"asset":"ETH","qty":"2","fromAccountType":"SPOT","toAccountType":"COIN_FUTURE","status":"SUCCESS","tranId":11798829519,"time":1544433326000}]"#).unwrap();
4212            let expected_response : Vec<models::SubAccountTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::SubAccountTransferHistoryResponseInner>");
4213
4214            let resp = client.sub_account_transfer_history(params).await.expect("Expected a response");
4215            let data_future = resp.data();
4216            let actual_response = data_future.await.unwrap();
4217            assert_eq!(actual_response, expected_response);
4218        });
4219    }
4220
4221    #[test]
4222    fn sub_account_transfer_history_optional_params_success() {
4223        TOKIO_SHARED_RT.block_on(async {
4224            let client = MockAssetManagementApiClient { force_error: false };
4225
4226            let params = SubAccountTransferHistoryParams::builder().asset("asset_example".to_string()).r#type(789).start_time(1623319461670).end_time(1641782889000).limit(1).return_fail_history(false).recv_window(5000).build().unwrap();
4227
4228            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},{"counterParty":"subAccount","email":"sub2@test.com","type":1,"asset":"ETH","qty":"2","fromAccountType":"SPOT","toAccountType":"COIN_FUTURE","status":"SUCCESS","tranId":11798829519,"time":1544433326000}]"#).unwrap();
4229            let expected_response : Vec<models::SubAccountTransferHistoryResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::SubAccountTransferHistoryResponseInner>");
4230
4231            let resp = client.sub_account_transfer_history(params).await.expect("Expected a response");
4232            let data_future = resp.data();
4233            let actual_response = data_future.await.unwrap();
4234            assert_eq!(actual_response, expected_response);
4235        });
4236    }
4237
4238    #[test]
4239    fn sub_account_transfer_history_response_error() {
4240        TOKIO_SHARED_RT.block_on(async {
4241            let client = MockAssetManagementApiClient { force_error: true };
4242
4243            let params = SubAccountTransferHistoryParams::builder().build().unwrap();
4244
4245            match client.sub_account_transfer_history(params).await {
4246                Ok(_) => panic!("Expected an error"),
4247                Err(err) => {
4248                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4249                }
4250            }
4251        });
4252    }
4253
4254    #[test]
4255    fn transfer_to_master_required_params_success() {
4256        TOKIO_SHARED_RT.block_on(async {
4257            let client = MockAssetManagementApiClient { force_error: false };
4258
4259            let params = TransferToMasterParams::builder("asset_example".to_string(), dec!(1.0))
4260                .build()
4261                .unwrap();
4262
4263            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
4264            let expected_response: models::TransferToMasterResponse =
4265                serde_json::from_value(resp_json.clone())
4266                    .expect("should parse into models::TransferToMasterResponse");
4267
4268            let resp = client
4269                .transfer_to_master(params)
4270                .await
4271                .expect("Expected a response");
4272            let data_future = resp.data();
4273            let actual_response = data_future.await.unwrap();
4274            assert_eq!(actual_response, expected_response);
4275        });
4276    }
4277
4278    #[test]
4279    fn transfer_to_master_optional_params_success() {
4280        TOKIO_SHARED_RT.block_on(async {
4281            let client = MockAssetManagementApiClient { force_error: false };
4282
4283            let params = TransferToMasterParams::builder("asset_example".to_string(), dec!(1.0))
4284                .recv_window(5000)
4285                .build()
4286                .unwrap();
4287
4288            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
4289            let expected_response: models::TransferToMasterResponse =
4290                serde_json::from_value(resp_json.clone())
4291                    .expect("should parse into models::TransferToMasterResponse");
4292
4293            let resp = client
4294                .transfer_to_master(params)
4295                .await
4296                .expect("Expected a response");
4297            let data_future = resp.data();
4298            let actual_response = data_future.await.unwrap();
4299            assert_eq!(actual_response, expected_response);
4300        });
4301    }
4302
4303    #[test]
4304    fn transfer_to_master_response_error() {
4305        TOKIO_SHARED_RT.block_on(async {
4306            let client = MockAssetManagementApiClient { force_error: true };
4307
4308            let params = TransferToMasterParams::builder("asset_example".to_string(), dec!(1.0))
4309                .build()
4310                .unwrap();
4311
4312            match client.transfer_to_master(params).await {
4313                Ok(_) => panic!("Expected an error"),
4314                Err(err) => {
4315                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4316                }
4317            }
4318        });
4319    }
4320
4321    #[test]
4322    fn transfer_to_sub_account_of_same_master_required_params_success() {
4323        TOKIO_SHARED_RT.block_on(async {
4324            let client = MockAssetManagementApiClient { force_error: false };
4325
4326            let params = TransferToSubAccountOfSameMasterParams::builder(
4327                "to_email_example".to_string(),
4328                "asset_example".to_string(),
4329                dec!(1.0),
4330            )
4331            .build()
4332            .unwrap();
4333
4334            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
4335            let expected_response: models::TransferToSubAccountOfSameMasterResponse =
4336                serde_json::from_value(resp_json.clone())
4337                    .expect("should parse into models::TransferToSubAccountOfSameMasterResponse");
4338
4339            let resp = client
4340                .transfer_to_sub_account_of_same_master(params)
4341                .await
4342                .expect("Expected a response");
4343            let data_future = resp.data();
4344            let actual_response = data_future.await.unwrap();
4345            assert_eq!(actual_response, expected_response);
4346        });
4347    }
4348
4349    #[test]
4350    fn transfer_to_sub_account_of_same_master_optional_params_success() {
4351        TOKIO_SHARED_RT.block_on(async {
4352            let client = MockAssetManagementApiClient { force_error: false };
4353
4354            let params = TransferToSubAccountOfSameMasterParams::builder(
4355                "to_email_example".to_string(),
4356                "asset_example".to_string(),
4357                dec!(1.0),
4358            )
4359            .recv_window(5000)
4360            .build()
4361            .unwrap();
4362
4363            let resp_json: Value = serde_json::from_str(r#"{"txnId":"2966662589"}"#).unwrap();
4364            let expected_response: models::TransferToSubAccountOfSameMasterResponse =
4365                serde_json::from_value(resp_json.clone())
4366                    .expect("should parse into models::TransferToSubAccountOfSameMasterResponse");
4367
4368            let resp = client
4369                .transfer_to_sub_account_of_same_master(params)
4370                .await
4371                .expect("Expected a response");
4372            let data_future = resp.data();
4373            let actual_response = data_future.await.unwrap();
4374            assert_eq!(actual_response, expected_response);
4375        });
4376    }
4377
4378    #[test]
4379    fn transfer_to_sub_account_of_same_master_response_error() {
4380        TOKIO_SHARED_RT.block_on(async {
4381            let client = MockAssetManagementApiClient { force_error: true };
4382
4383            let params = TransferToSubAccountOfSameMasterParams::builder(
4384                "to_email_example".to_string(),
4385                "asset_example".to_string(),
4386                dec!(1.0),
4387            )
4388            .build()
4389            .unwrap();
4390
4391            match client.transfer_to_sub_account_of_same_master(params).await {
4392                Ok(_) => panic!("Expected an error"),
4393                Err(err) => {
4394                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4395                }
4396            }
4397        });
4398    }
4399
4400    #[test]
4401    fn universal_transfer_required_params_success() {
4402        TOKIO_SHARED_RT.block_on(async {
4403            let client = MockAssetManagementApiClient { force_error: false };
4404
4405            let params = UniversalTransferParams::builder(
4406                "from_account_type_example".to_string(),
4407                "to_account_type_example".to_string(),
4408                "asset_example".to_string(),
4409                dec!(1.0),
4410            )
4411            .build()
4412            .unwrap();
4413
4414            let resp_json: Value =
4415                serde_json::from_str(r#"{"tranId":11945860693,"clientTranId":"test"}"#).unwrap();
4416            let expected_response: models::UniversalTransferResponse =
4417                serde_json::from_value(resp_json.clone())
4418                    .expect("should parse into models::UniversalTransferResponse");
4419
4420            let resp = client
4421                .universal_transfer(params)
4422                .await
4423                .expect("Expected a response");
4424            let data_future = resp.data();
4425            let actual_response = data_future.await.unwrap();
4426            assert_eq!(actual_response, expected_response);
4427        });
4428    }
4429
4430    #[test]
4431    fn universal_transfer_optional_params_success() {
4432        TOKIO_SHARED_RT.block_on(async {
4433            let client = MockAssetManagementApiClient { force_error: false };
4434
4435            let params = UniversalTransferParams::builder(
4436                "from_account_type_example".to_string(),
4437                "to_account_type_example".to_string(),
4438                "asset_example".to_string(),
4439                dec!(1.0),
4440            )
4441            .from_email("from_email_example".to_string())
4442            .to_email("to_email_example".to_string())
4443            .client_tran_id("1".to_string())
4444            .symbol("symbol_example".to_string())
4445            .recv_window(5000)
4446            .build()
4447            .unwrap();
4448
4449            let resp_json: Value =
4450                serde_json::from_str(r#"{"tranId":11945860693,"clientTranId":"test"}"#).unwrap();
4451            let expected_response: models::UniversalTransferResponse =
4452                serde_json::from_value(resp_json.clone())
4453                    .expect("should parse into models::UniversalTransferResponse");
4454
4455            let resp = client
4456                .universal_transfer(params)
4457                .await
4458                .expect("Expected a response");
4459            let data_future = resp.data();
4460            let actual_response = data_future.await.unwrap();
4461            assert_eq!(actual_response, expected_response);
4462        });
4463    }
4464
4465    #[test]
4466    fn universal_transfer_response_error() {
4467        TOKIO_SHARED_RT.block_on(async {
4468            let client = MockAssetManagementApiClient { force_error: true };
4469
4470            let params = UniversalTransferParams::builder(
4471                "from_account_type_example".to_string(),
4472                "to_account_type_example".to_string(),
4473                "asset_example".to_string(),
4474                dec!(1.0),
4475            )
4476            .build()
4477            .unwrap();
4478
4479            match client.universal_transfer(params).await {
4480                Ok(_) => panic!("Expected an error"),
4481                Err(err) => {
4482                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
4483                }
4484            }
4485        });
4486    }
4487}