Skip to main content

binance_sdk/sub_account/rest_api/apis/
api_management_api.rs

1/*
2 * Sub Account REST API
3 *
4 * Create and manage sub-accounts, control permissions, and transfer assets via the Sub Account 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 ApiManagementApi: Send + Sync {
34    async fn add_ip_restriction_for_sub_account_api_key(
35        &self,
36        params: AddIpRestrictionForSubAccountApiKeyParams,
37    ) -> anyhow::Result<RestApiResponse<models::AddIpRestrictionForSubAccountApiKeyResponse>>;
38    async fn create_sub_account_api_key(
39        &self,
40        params: CreateSubAccountApiKeyParams,
41    ) -> anyhow::Result<RestApiResponse<models::CreateSubAccountApiKeyResponse>>;
42    async fn delete_ip_list_for_a_sub_account_api_key(
43        &self,
44        params: DeleteIpListForASubAccountApiKeyParams,
45    ) -> anyhow::Result<RestApiResponse<models::DeleteIpListForASubAccountApiKeyResponse>>;
46    async fn delete_sub_account_api_key(
47        &self,
48        params: DeleteSubAccountApiKeyParams,
49    ) -> anyhow::Result<RestApiResponse<serde_json::Value>>;
50    async fn get_ip_restriction_for_a_sub_account_api_key(
51        &self,
52        params: GetIpRestrictionForASubAccountApiKeyParams,
53    ) -> anyhow::Result<RestApiResponse<models::GetIpRestrictionForASubAccountApiKeyResponse>>;
54    async fn modify_sub_account_api_key_permission(
55        &self,
56        params: ModifySubAccountApiKeyPermissionParams,
57    ) -> anyhow::Result<RestApiResponse<models::ModifySubAccountApiKeyPermissionResponse>>;
58    async fn query_sub_account_api_key(
59        &self,
60        params: QuerySubAccountApiKeyParams,
61    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountApiKeyResponse>>;
62}
63
64#[derive(Debug, Clone)]
65pub struct ApiManagementApiClient {
66    configuration: ConfigurationRestApi,
67}
68
69impl ApiManagementApiClient {
70    pub fn new(configuration: ConfigurationRestApi) -> Self {
71        Self { configuration }
72    }
73}
74
75/// Request parameters for the [`add_ip_restriction_for_sub_account_api_key`] operation.
76///
77/// This struct holds all of the inputs you can pass when calling
78/// [`add_ip_restriction_for_sub_account_api_key`](#method.add_ip_restriction_for_sub_account_api_key).
79#[derive(Clone, Debug, Builder, Deserialize)]
80#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
81pub struct AddIpRestrictionForSubAccountApiKeyParams {
82    ///
83    /// The `email` parameter.
84    ///
85    /// This field is **required.
86    #[builder(setter(into))]
87    #[serde(rename = "email")]
88    pub email: String,
89    ///
90    /// The `sub_account_api_key` parameter.
91    ///
92    /// This field is **required.
93    #[builder(setter(into))]
94    #[serde(rename = "subAccountApiKey")]
95    pub sub_account_api_key: String,
96    /// IP Restriction status. 1 = IP Unrestricted. 2 = Restrict access to trusted IPs only.
97    ///
98    /// This field is **required.
99    #[builder(setter(into))]
100    #[serde(rename = "status")]
101    pub status: i64,
102    /// Insert static IP in batch, separated by commas.
103    ///
104    /// This field is **optional.
105    #[builder(setter(into), default)]
106    #[serde(rename = "ipAddress", default)]
107    pub ip_address: Option<String>,
108    ///
109    /// The `recv_window` parameter.
110    ///
111    /// This field is **optional.
112    #[builder(setter(into), default)]
113    #[serde(rename = "recvWindow", default)]
114    pub recv_window: Option<i64>,
115}
116
117impl AddIpRestrictionForSubAccountApiKeyParams {
118    /// Create a builder for [`add_ip_restriction_for_sub_account_api_key`].
119    ///
120    /// Required parameters:
121    ///
122    /// * `email` — String
123    /// * `sub_account_api_key` — String
124    /// * `status` — IP Restriction status. 1 = IP Unrestricted. 2 = Restrict access to trusted IPs only.
125    ///
126    #[must_use]
127    pub fn builder(
128        email: String,
129        sub_account_api_key: String,
130        status: i64,
131    ) -> AddIpRestrictionForSubAccountApiKeyParamsBuilder {
132        AddIpRestrictionForSubAccountApiKeyParamsBuilder::default()
133            .email(email)
134            .sub_account_api_key(sub_account_api_key)
135            .status(status)
136    }
137}
138/// Request parameters for the [`create_sub_account_api_key`] operation.
139///
140/// This struct holds all of the inputs you can pass when calling
141/// [`create_sub_account_api_key`](#method.create_sub_account_api_key).
142#[derive(Clone, Debug, Builder, Deserialize)]
143#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
144pub struct CreateSubAccountApiKeyParams {
145    /// Sub-account email
146    ///
147    /// This field is **required.
148    #[builder(setter(into))]
149    #[serde(rename = "email")]
150    pub email: String,
151    /// API Key name
152    ///
153    /// This field is **required.
154    #[builder(setter(into))]
155    #[serde(rename = "apiName")]
156    pub api_name: String,
157    /// IP restriction status. 1 = unrestricted, 2 = restricted to trusted IPs, 3 = third-party IP restriction
158    ///
159    /// This field is **required.
160    #[builder(setter(into))]
161    #[serde(rename = "status")]
162    pub status: i64,
163    /// Spot & Margin trading permission, default false
164    ///
165    /// This field is **optional.
166    #[builder(setter(into), default)]
167    #[serde(rename = "canTrade", default)]
168    pub can_trade: Option<bool>,
169    /// Margin borrow/repay permission, default false
170    ///
171    /// This field is **optional.
172    #[builder(setter(into), default)]
173    #[serde(rename = "canMarginLoanRepay", default)]
174    pub can_margin_loan_repay: Option<bool>,
175    /// Futures trading permission, default false
176    ///
177    /// This field is **optional.
178    #[builder(setter(into), default)]
179    #[serde(rename = "canFuturesTrade", default)]
180    pub can_futures_trade: Option<bool>,
181    /// Universal transfer permission, default false
182    ///
183    /// This field is **optional.
184    #[builder(setter(into), default)]
185    #[serde(rename = "canUniversalTransfer", default)]
186    pub can_universal_transfer: Option<bool>,
187    /// Vanilla options permission, default false
188    ///
189    /// This field is **optional.
190    #[builder(setter(into), default)]
191    #[serde(rename = "canVanillaOptions", default)]
192    pub can_vanilla_options: Option<bool>,
193    /// Required when status=2. IP address list, max 500 chars
194    ///
195    /// This field is **optional.
196    #[builder(setter(into), default)]
197    #[serde(rename = "ipAddress", default)]
198    pub ip_address: Option<String>,
199    /// Required when status=3. Third-party name
200    ///
201    /// This field is **optional.
202    #[builder(setter(into), default)]
203    #[serde(rename = "thirdPartyName", default)]
204    pub third_party_name: Option<String>,
205    /// Ed25519 public key (optional, for Ed25519 type API Key)
206    ///
207    /// This field is **optional.
208    #[builder(setter(into), default)]
209    #[serde(rename = "publicKey", default)]
210    pub public_key: Option<String>,
211    ///
212    /// The `recv_window` parameter.
213    ///
214    /// This field is **optional.
215    #[builder(setter(into), default)]
216    #[serde(rename = "recvWindow", default)]
217    pub recv_window: Option<i64>,
218}
219
220impl CreateSubAccountApiKeyParams {
221    /// Create a builder for [`create_sub_account_api_key`].
222    ///
223    /// Required parameters:
224    ///
225    /// * `email` — Sub-account email
226    /// * `api_name` — API Key name
227    /// * `status` — IP restriction status. 1 = unrestricted, 2 = restricted to trusted IPs, 3 = third-party IP restriction
228    ///
229    #[must_use]
230    pub fn builder(
231        email: String,
232        api_name: String,
233        status: i64,
234    ) -> CreateSubAccountApiKeyParamsBuilder {
235        CreateSubAccountApiKeyParamsBuilder::default()
236            .email(email)
237            .api_name(api_name)
238            .status(status)
239    }
240}
241/// Request parameters for the [`delete_ip_list_for_a_sub_account_api_key`] operation.
242///
243/// This struct holds all of the inputs you can pass when calling
244/// [`delete_ip_list_for_a_sub_account_api_key`](#method.delete_ip_list_for_a_sub_account_api_key).
245#[derive(Clone, Debug, Builder, Deserialize)]
246#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
247pub struct DeleteIpListForASubAccountApiKeyParams {
248    ///
249    /// The `email` parameter.
250    ///
251    /// This field is **required.
252    #[builder(setter(into))]
253    #[serde(rename = "email")]
254    pub email: String,
255    ///
256    /// The `sub_account_api_key` parameter.
257    ///
258    /// This field is **required.
259    #[builder(setter(into))]
260    #[serde(rename = "subAccountApiKey")]
261    pub sub_account_api_key: String,
262    /// IPs to be deleted. Can be added in batches, separated by commas
263    ///
264    /// This field is **required.
265    #[builder(setter(into))]
266    #[serde(rename = "ipAddress")]
267    pub ip_address: String,
268    ///
269    /// The `recv_window` parameter.
270    ///
271    /// This field is **optional.
272    #[builder(setter(into), default)]
273    #[serde(rename = "recvWindow", default)]
274    pub recv_window: Option<i64>,
275}
276
277impl DeleteIpListForASubAccountApiKeyParams {
278    /// Create a builder for [`delete_ip_list_for_a_sub_account_api_key`].
279    ///
280    /// Required parameters:
281    ///
282    /// * `email` — String
283    /// * `sub_account_api_key` — String
284    /// * `ip_address` — IPs to be deleted. Can be added in batches, separated by commas
285    ///
286    #[must_use]
287    pub fn builder(
288        email: String,
289        sub_account_api_key: String,
290        ip_address: String,
291    ) -> DeleteIpListForASubAccountApiKeyParamsBuilder {
292        DeleteIpListForASubAccountApiKeyParamsBuilder::default()
293            .email(email)
294            .sub_account_api_key(sub_account_api_key)
295            .ip_address(ip_address)
296    }
297}
298/// Request parameters for the [`delete_sub_account_api_key`] operation.
299///
300/// This struct holds all of the inputs you can pass when calling
301/// [`delete_sub_account_api_key`](#method.delete_sub_account_api_key).
302#[derive(Clone, Debug, Builder, Deserialize)]
303#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
304pub struct DeleteSubAccountApiKeyParams {
305    /// Sub-account email
306    ///
307    /// This field is **required.
308    #[builder(setter(into))]
309    #[serde(rename = "email")]
310    pub email: String,
311    /// The sub-account API Key to be deleted
312    ///
313    /// This field is **required.
314    #[builder(setter(into))]
315    #[serde(rename = "subAccountApiKey")]
316    pub sub_account_api_key: String,
317    ///
318    /// The `recv_window` parameter.
319    ///
320    /// This field is **optional.
321    #[builder(setter(into), default)]
322    #[serde(rename = "recvWindow", default)]
323    pub recv_window: Option<i64>,
324}
325
326impl DeleteSubAccountApiKeyParams {
327    /// Create a builder for [`delete_sub_account_api_key`].
328    ///
329    /// Required parameters:
330    ///
331    /// * `email` — Sub-account email
332    /// * `sub_account_api_key` — The sub-account API Key to be deleted
333    ///
334    #[must_use]
335    pub fn builder(
336        email: String,
337        sub_account_api_key: String,
338    ) -> DeleteSubAccountApiKeyParamsBuilder {
339        DeleteSubAccountApiKeyParamsBuilder::default()
340            .email(email)
341            .sub_account_api_key(sub_account_api_key)
342    }
343}
344/// Request parameters for the [`get_ip_restriction_for_a_sub_account_api_key`] operation.
345///
346/// This struct holds all of the inputs you can pass when calling
347/// [`get_ip_restriction_for_a_sub_account_api_key`](#method.get_ip_restriction_for_a_sub_account_api_key).
348#[derive(Clone, Debug, Builder, Deserialize)]
349#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
350pub struct GetIpRestrictionForASubAccountApiKeyParams {
351    ///
352    /// The `email` parameter.
353    ///
354    /// This field is **required.
355    #[builder(setter(into))]
356    #[serde(rename = "email")]
357    pub email: String,
358    ///
359    /// The `sub_account_api_key` parameter.
360    ///
361    /// This field is **required.
362    #[builder(setter(into))]
363    #[serde(rename = "subAccountApiKey")]
364    pub sub_account_api_key: String,
365    ///
366    /// The `recv_window` parameter.
367    ///
368    /// This field is **optional.
369    #[builder(setter(into), default)]
370    #[serde(rename = "recvWindow", default)]
371    pub recv_window: Option<i64>,
372}
373
374impl GetIpRestrictionForASubAccountApiKeyParams {
375    /// Create a builder for [`get_ip_restriction_for_a_sub_account_api_key`].
376    ///
377    /// Required parameters:
378    ///
379    /// * `email` — String
380    /// * `sub_account_api_key` — String
381    ///
382    #[must_use]
383    pub fn builder(
384        email: String,
385        sub_account_api_key: String,
386    ) -> GetIpRestrictionForASubAccountApiKeyParamsBuilder {
387        GetIpRestrictionForASubAccountApiKeyParamsBuilder::default()
388            .email(email)
389            .sub_account_api_key(sub_account_api_key)
390    }
391}
392/// Request parameters for the [`modify_sub_account_api_key_permission`] operation.
393///
394/// This struct holds all of the inputs you can pass when calling
395/// [`modify_sub_account_api_key_permission`](#method.modify_sub_account_api_key_permission).
396#[derive(Clone, Debug, Builder, Deserialize)]
397#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
398pub struct ModifySubAccountApiKeyPermissionParams {
399    /// Sub-account email
400    ///
401    /// This field is **required.
402    #[builder(setter(into))]
403    #[serde(rename = "email")]
404    pub email: String,
405    /// Sub-account API Key
406    ///
407    /// This field is **required.
408    #[builder(setter(into))]
409    #[serde(rename = "subAccountApiKey")]
410    pub sub_account_api_key: String,
411    /// Spot & Margin trading permission
412    ///
413    /// This field is **optional.
414    #[builder(setter(into), default)]
415    #[serde(rename = "canTrade", default)]
416    pub can_trade: Option<bool>,
417    /// Margin borrow/repay permission
418    ///
419    /// This field is **optional.
420    #[builder(setter(into), default)]
421    #[serde(rename = "canMarginLoanRepay", default)]
422    pub can_margin_loan_repay: Option<bool>,
423    /// Futures trading permission
424    ///
425    /// This field is **optional.
426    #[builder(setter(into), default)]
427    #[serde(rename = "canFuturesTrade", default)]
428    pub can_futures_trade: Option<bool>,
429    /// Universal transfer permission
430    ///
431    /// This field is **optional.
432    #[builder(setter(into), default)]
433    #[serde(rename = "canUniversalTransfer", default)]
434    pub can_universal_transfer: Option<bool>,
435    /// Vanilla options permission
436    ///
437    /// This field is **optional.
438    #[builder(setter(into), default)]
439    #[serde(rename = "canVanillaOptions", default)]
440    pub can_vanilla_options: Option<bool>,
441    ///
442    /// The `recv_window` parameter.
443    ///
444    /// This field is **optional.
445    #[builder(setter(into), default)]
446    #[serde(rename = "recvWindow", default)]
447    pub recv_window: Option<i64>,
448}
449
450impl ModifySubAccountApiKeyPermissionParams {
451    /// Create a builder for [`modify_sub_account_api_key_permission`].
452    ///
453    /// Required parameters:
454    ///
455    /// * `email` — Sub-account email
456    /// * `sub_account_api_key` — Sub-account API Key
457    ///
458    #[must_use]
459    pub fn builder(
460        email: String,
461        sub_account_api_key: String,
462    ) -> ModifySubAccountApiKeyPermissionParamsBuilder {
463        ModifySubAccountApiKeyPermissionParamsBuilder::default()
464            .email(email)
465            .sub_account_api_key(sub_account_api_key)
466    }
467}
468/// Request parameters for the [`query_sub_account_api_key`] operation.
469///
470/// This struct holds all of the inputs you can pass when calling
471/// [`query_sub_account_api_key`](#method.query_sub_account_api_key).
472#[derive(Clone, Debug, Builder, Deserialize)]
473#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
474pub struct QuerySubAccountApiKeyParams {
475    /// Sub-account email
476    ///
477    /// This field is **required.
478    #[builder(setter(into))]
479    #[serde(rename = "email")]
480    pub email: String,
481    /// Specify an API Key for exact match
482    ///
483    /// This field is **optional.
484    #[builder(setter(into), default)]
485    #[serde(rename = "subAccountApiKey", default)]
486    pub sub_account_api_key: Option<String>,
487    /// Page number, default 1, minimum 1
488    ///
489    /// This field is **optional.
490    #[builder(setter(into), default)]
491    #[serde(rename = "page", default)]
492    pub page: Option<i64>,
493    /// Page size, default 30, maximum 100
494    ///
495    /// This field is **optional.
496    #[builder(setter(into), default)]
497    #[serde(rename = "size", default)]
498    pub size: Option<i64>,
499    ///
500    /// The `recv_window` parameter.
501    ///
502    /// This field is **optional.
503    #[builder(setter(into), default)]
504    #[serde(rename = "recvWindow", default)]
505    pub recv_window: Option<i64>,
506}
507
508impl QuerySubAccountApiKeyParams {
509    /// Create a builder for [`query_sub_account_api_key`].
510    ///
511    /// Required parameters:
512    ///
513    /// * `email` — Sub-account email
514    ///
515    #[must_use]
516    pub fn builder(email: String) -> QuerySubAccountApiKeyParamsBuilder {
517        QuerySubAccountApiKeyParamsBuilder::default().email(email)
518    }
519}
520
521#[async_trait]
522impl ApiManagementApi for ApiManagementApiClient {
523    async fn add_ip_restriction_for_sub_account_api_key(
524        &self,
525        params: AddIpRestrictionForSubAccountApiKeyParams,
526    ) -> anyhow::Result<RestApiResponse<models::AddIpRestrictionForSubAccountApiKeyResponse>> {
527        let AddIpRestrictionForSubAccountApiKeyParams {
528            email,
529            sub_account_api_key,
530            status,
531            ip_address,
532            recv_window,
533        } = params;
534
535        let mut query_params = BTreeMap::new();
536        let body_params = BTreeMap::new();
537
538        query_params.insert("email".to_string(), json!(email));
539
540        query_params.insert("subAccountApiKey".to_string(), json!(sub_account_api_key));
541
542        query_params.insert("status".to_string(), json!(status));
543
544        if let Some(rw) = ip_address {
545            query_params.insert("ipAddress".to_string(), json!(rw));
546        }
547
548        if let Some(rw) = recv_window {
549            query_params.insert("recvWindow".to_string(), json!(rw));
550        }
551
552        send_request::<models::AddIpRestrictionForSubAccountApiKeyResponse>(
553            &self.configuration,
554            "/sapi/v2/sub-account/subAccountApi/ipRestriction",
555            reqwest::Method::POST,
556            query_params,
557            body_params,
558            if HAS_TIME_UNIT {
559                self.configuration.time_unit
560            } else {
561                None
562            },
563            true,
564        )
565        .await
566    }
567
568    async fn create_sub_account_api_key(
569        &self,
570        params: CreateSubAccountApiKeyParams,
571    ) -> anyhow::Result<RestApiResponse<models::CreateSubAccountApiKeyResponse>> {
572        let CreateSubAccountApiKeyParams {
573            email,
574            api_name,
575            status,
576            can_trade,
577            can_margin_loan_repay,
578            can_futures_trade,
579            can_universal_transfer,
580            can_vanilla_options,
581            ip_address,
582            third_party_name,
583            public_key,
584            recv_window,
585        } = params;
586
587        let mut query_params = BTreeMap::new();
588        let body_params = BTreeMap::new();
589
590        query_params.insert("email".to_string(), json!(email));
591
592        query_params.insert("apiName".to_string(), json!(api_name));
593
594        query_params.insert("status".to_string(), json!(status));
595
596        if let Some(rw) = can_trade {
597            query_params.insert("canTrade".to_string(), json!(rw));
598        }
599
600        if let Some(rw) = can_margin_loan_repay {
601            query_params.insert("canMarginLoanRepay".to_string(), json!(rw));
602        }
603
604        if let Some(rw) = can_futures_trade {
605            query_params.insert("canFuturesTrade".to_string(), json!(rw));
606        }
607
608        if let Some(rw) = can_universal_transfer {
609            query_params.insert("canUniversalTransfer".to_string(), json!(rw));
610        }
611
612        if let Some(rw) = can_vanilla_options {
613            query_params.insert("canVanillaOptions".to_string(), json!(rw));
614        }
615
616        if let Some(rw) = ip_address {
617            query_params.insert("ipAddress".to_string(), json!(rw));
618        }
619
620        if let Some(rw) = third_party_name {
621            query_params.insert("thirdPartyName".to_string(), json!(rw));
622        }
623
624        if let Some(rw) = public_key {
625            query_params.insert("publicKey".to_string(), json!(rw));
626        }
627
628        if let Some(rw) = recv_window {
629            query_params.insert("recvWindow".to_string(), json!(rw));
630        }
631
632        send_request::<models::CreateSubAccountApiKeyResponse>(
633            &self.configuration,
634            "/sapi/v1/sub-account/subAccountApi",
635            reqwest::Method::POST,
636            query_params,
637            body_params,
638            if HAS_TIME_UNIT {
639                self.configuration.time_unit
640            } else {
641                None
642            },
643            true,
644        )
645        .await
646    }
647
648    async fn delete_ip_list_for_a_sub_account_api_key(
649        &self,
650        params: DeleteIpListForASubAccountApiKeyParams,
651    ) -> anyhow::Result<RestApiResponse<models::DeleteIpListForASubAccountApiKeyResponse>> {
652        let DeleteIpListForASubAccountApiKeyParams {
653            email,
654            sub_account_api_key,
655            ip_address,
656            recv_window,
657        } = params;
658
659        let mut query_params = BTreeMap::new();
660        let body_params = BTreeMap::new();
661
662        query_params.insert("email".to_string(), json!(email));
663
664        query_params.insert("subAccountApiKey".to_string(), json!(sub_account_api_key));
665
666        query_params.insert("ipAddress".to_string(), json!(ip_address));
667
668        if let Some(rw) = recv_window {
669            query_params.insert("recvWindow".to_string(), json!(rw));
670        }
671
672        send_request::<models::DeleteIpListForASubAccountApiKeyResponse>(
673            &self.configuration,
674            "/sapi/v1/sub-account/subAccountApi/ipRestriction/ipList",
675            reqwest::Method::DELETE,
676            query_params,
677            body_params,
678            if HAS_TIME_UNIT {
679                self.configuration.time_unit
680            } else {
681                None
682            },
683            true,
684        )
685        .await
686    }
687
688    async fn delete_sub_account_api_key(
689        &self,
690        params: DeleteSubAccountApiKeyParams,
691    ) -> anyhow::Result<RestApiResponse<serde_json::Value>> {
692        let DeleteSubAccountApiKeyParams {
693            email,
694            sub_account_api_key,
695            recv_window,
696        } = params;
697
698        let mut query_params = BTreeMap::new();
699        let body_params = BTreeMap::new();
700
701        query_params.insert("email".to_string(), json!(email));
702
703        query_params.insert("subAccountApiKey".to_string(), json!(sub_account_api_key));
704
705        if let Some(rw) = recv_window {
706            query_params.insert("recvWindow".to_string(), json!(rw));
707        }
708
709        send_request::<serde_json::Value>(
710            &self.configuration,
711            "/sapi/v1/sub-account/subAccountApi",
712            reqwest::Method::DELETE,
713            query_params,
714            body_params,
715            if HAS_TIME_UNIT {
716                self.configuration.time_unit
717            } else {
718                None
719            },
720            true,
721        )
722        .await
723    }
724
725    async fn get_ip_restriction_for_a_sub_account_api_key(
726        &self,
727        params: GetIpRestrictionForASubAccountApiKeyParams,
728    ) -> anyhow::Result<RestApiResponse<models::GetIpRestrictionForASubAccountApiKeyResponse>> {
729        let GetIpRestrictionForASubAccountApiKeyParams {
730            email,
731            sub_account_api_key,
732            recv_window,
733        } = params;
734
735        let mut query_params = BTreeMap::new();
736        let body_params = BTreeMap::new();
737
738        query_params.insert("email".to_string(), json!(email));
739
740        query_params.insert("subAccountApiKey".to_string(), json!(sub_account_api_key));
741
742        if let Some(rw) = recv_window {
743            query_params.insert("recvWindow".to_string(), json!(rw));
744        }
745
746        send_request::<models::GetIpRestrictionForASubAccountApiKeyResponse>(
747            &self.configuration,
748            "/sapi/v1/sub-account/subAccountApi/ipRestriction",
749            reqwest::Method::GET,
750            query_params,
751            body_params,
752            if HAS_TIME_UNIT {
753                self.configuration.time_unit
754            } else {
755                None
756            },
757            true,
758        )
759        .await
760    }
761
762    async fn modify_sub_account_api_key_permission(
763        &self,
764        params: ModifySubAccountApiKeyPermissionParams,
765    ) -> anyhow::Result<RestApiResponse<models::ModifySubAccountApiKeyPermissionResponse>> {
766        let ModifySubAccountApiKeyPermissionParams {
767            email,
768            sub_account_api_key,
769            can_trade,
770            can_margin_loan_repay,
771            can_futures_trade,
772            can_universal_transfer,
773            can_vanilla_options,
774            recv_window,
775        } = params;
776
777        let mut query_params = BTreeMap::new();
778        let body_params = BTreeMap::new();
779
780        query_params.insert("email".to_string(), json!(email));
781
782        query_params.insert("subAccountApiKey".to_string(), json!(sub_account_api_key));
783
784        if let Some(rw) = can_trade {
785            query_params.insert("canTrade".to_string(), json!(rw));
786        }
787
788        if let Some(rw) = can_margin_loan_repay {
789            query_params.insert("canMarginLoanRepay".to_string(), json!(rw));
790        }
791
792        if let Some(rw) = can_futures_trade {
793            query_params.insert("canFuturesTrade".to_string(), json!(rw));
794        }
795
796        if let Some(rw) = can_universal_transfer {
797            query_params.insert("canUniversalTransfer".to_string(), json!(rw));
798        }
799
800        if let Some(rw) = can_vanilla_options {
801            query_params.insert("canVanillaOptions".to_string(), json!(rw));
802        }
803
804        if let Some(rw) = recv_window {
805            query_params.insert("recvWindow".to_string(), json!(rw));
806        }
807
808        send_request::<models::ModifySubAccountApiKeyPermissionResponse>(
809            &self.configuration,
810            "/sapi/v1/sub-account/subAccountApiPermission",
811            reqwest::Method::POST,
812            query_params,
813            body_params,
814            if HAS_TIME_UNIT {
815                self.configuration.time_unit
816            } else {
817                None
818            },
819            true,
820        )
821        .await
822    }
823
824    async fn query_sub_account_api_key(
825        &self,
826        params: QuerySubAccountApiKeyParams,
827    ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountApiKeyResponse>> {
828        let QuerySubAccountApiKeyParams {
829            email,
830            sub_account_api_key,
831            page,
832            size,
833            recv_window,
834        } = params;
835
836        let mut query_params = BTreeMap::new();
837        let body_params = BTreeMap::new();
838
839        query_params.insert("email".to_string(), json!(email));
840
841        if let Some(rw) = sub_account_api_key {
842            query_params.insert("subAccountApiKey".to_string(), json!(rw));
843        }
844
845        if let Some(rw) = page {
846            query_params.insert("page".to_string(), json!(rw));
847        }
848
849        if let Some(rw) = size {
850            query_params.insert("size".to_string(), json!(rw));
851        }
852
853        if let Some(rw) = recv_window {
854            query_params.insert("recvWindow".to_string(), json!(rw));
855        }
856
857        send_request::<models::QuerySubAccountApiKeyResponse>(
858            &self.configuration,
859            "/sapi/v1/sub-account/subAccountApi",
860            reqwest::Method::GET,
861            query_params,
862            body_params,
863            if HAS_TIME_UNIT {
864                self.configuration.time_unit
865            } else {
866                None
867            },
868            true,
869        )
870        .await
871    }
872}
873
874#[cfg(all(test, feature = "sub_account"))]
875mod tests {
876    use super::*;
877    use crate::TOKIO_SHARED_RT;
878    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
879    use async_trait::async_trait;
880    use std::collections::HashMap;
881
882    struct DummyRestApiResponse<T> {
883        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
884        status: u16,
885        headers: HashMap<String, String>,
886        rate_limits: Option<Vec<RestApiRateLimit>>,
887    }
888
889    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
890        fn from(dummy: DummyRestApiResponse<T>) -> Self {
891            Self {
892                data_fn: dummy.inner,
893                status: dummy.status,
894                headers: dummy.headers,
895                rate_limits: dummy.rate_limits,
896            }
897        }
898    }
899
900    struct MockApiManagementApiClient {
901        force_error: bool,
902    }
903
904    #[async_trait]
905    impl ApiManagementApi for MockApiManagementApiClient {
906        async fn add_ip_restriction_for_sub_account_api_key(
907            &self,
908            _params: AddIpRestrictionForSubAccountApiKeyParams,
909        ) -> anyhow::Result<RestApiResponse<models::AddIpRestrictionForSubAccountApiKeyResponse>>
910        {
911            if self.force_error {
912                return Err(ConnectorError::ConnectorClientError {
913                    msg: "ResponseError".to_string(),
914                    code: None,
915                }
916                .into());
917            }
918
919            let resp_json: Value = serde_json::from_str(r#"{"status":"2","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
920            let dummy_response: models::AddIpRestrictionForSubAccountApiKeyResponse =
921                serde_json::from_value(resp_json.clone()).expect(
922                    "should parse into models::AddIpRestrictionForSubAccountApiKeyResponse",
923                );
924
925            let dummy = DummyRestApiResponse {
926                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
927                status: 200,
928                headers: HashMap::new(),
929                rate_limits: None,
930            };
931
932            Ok(dummy.into())
933        }
934
935        async fn create_sub_account_api_key(
936            &self,
937            _params: CreateSubAccountApiKeyParams,
938        ) -> anyhow::Result<RestApiResponse<models::CreateSubAccountApiKeyResponse>> {
939            if self.force_error {
940                return Err(ConnectorError::ConnectorClientError {
941                    msg: "ResponseError".to_string(),
942                    code: None,
943                }
944                .into());
945            }
946
947            let resp_json: Value = serde_json::from_str(r#"{"apiName":"myKey","apiKey":"vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A","secretKey":"NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":false,"canUniversalTransfer":false,"canVanillaOptions":false,"status":2,"ipList":["69.210.67.14"]}"#).unwrap_or_else(|_| serde_json::json!({}));
948            let dummy_response: models::CreateSubAccountApiKeyResponse =
949                serde_json::from_value(resp_json.clone())
950                    .expect("should parse into models::CreateSubAccountApiKeyResponse");
951
952            let dummy = DummyRestApiResponse {
953                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
954                status: 200,
955                headers: HashMap::new(),
956                rate_limits: None,
957            };
958
959            Ok(dummy.into())
960        }
961
962        async fn delete_ip_list_for_a_sub_account_api_key(
963            &self,
964            _params: DeleteIpListForASubAccountApiKeyParams,
965        ) -> anyhow::Result<RestApiResponse<models::DeleteIpListForASubAccountApiKeyResponse>>
966        {
967            if self.force_error {
968                return Err(ConnectorError::ConnectorClientError {
969                    msg: "ResponseError".to_string(),
970                    code: None,
971                }
972                .into());
973            }
974
975            let resp_json: Value = serde_json::from_str(r#"{"ipRestrict":"true","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
976            let dummy_response: models::DeleteIpListForASubAccountApiKeyResponse =
977                serde_json::from_value(resp_json.clone())
978                    .expect("should parse into models::DeleteIpListForASubAccountApiKeyResponse");
979
980            let dummy = DummyRestApiResponse {
981                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
982                status: 200,
983                headers: HashMap::new(),
984                rate_limits: None,
985            };
986
987            Ok(dummy.into())
988        }
989
990        async fn delete_sub_account_api_key(
991            &self,
992            _params: DeleteSubAccountApiKeyParams,
993        ) -> anyhow::Result<RestApiResponse<serde_json::Value>> {
994            if self.force_error {
995                return Err(ConnectorError::ConnectorClientError {
996                    msg: "ResponseError".to_string(),
997                    code: None,
998                }
999                .into());
1000            }
1001
1002            let resp_json: Value =
1003                serde_json::from_str(r"").unwrap_or_else(|_| serde_json::json!({}));
1004            let dummy_response: serde_json::Value = serde_json::from_value(resp_json.clone())
1005                .expect("should parse into serde_json::Value");
1006
1007            let dummy = DummyRestApiResponse {
1008                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1009                status: 200,
1010                headers: HashMap::new(),
1011                rate_limits: None,
1012            };
1013
1014            Ok(dummy.into())
1015        }
1016
1017        async fn get_ip_restriction_for_a_sub_account_api_key(
1018            &self,
1019            _params: GetIpRestrictionForASubAccountApiKeyParams,
1020        ) -> anyhow::Result<RestApiResponse<models::GetIpRestrictionForASubAccountApiKeyResponse>>
1021        {
1022            if self.force_error {
1023                return Err(ConnectorError::ConnectorClientError {
1024                    msg: "ResponseError".to_string(),
1025                    code: None,
1026                }
1027                .into());
1028            }
1029
1030            let resp_json: Value = serde_json::from_str(r#"{"ipRestrict":"true","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1031            let dummy_response: models::GetIpRestrictionForASubAccountApiKeyResponse =
1032                serde_json::from_value(resp_json.clone()).expect(
1033                    "should parse into models::GetIpRestrictionForASubAccountApiKeyResponse",
1034                );
1035
1036            let dummy = DummyRestApiResponse {
1037                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1038                status: 200,
1039                headers: HashMap::new(),
1040                rate_limits: None,
1041            };
1042
1043            Ok(dummy.into())
1044        }
1045
1046        async fn modify_sub_account_api_key_permission(
1047            &self,
1048            _params: ModifySubAccountApiKeyPermissionParams,
1049        ) -> anyhow::Result<RestApiResponse<models::ModifySubAccountApiKeyPermissionResponse>>
1050        {
1051            if self.force_error {
1052                return Err(ConnectorError::ConnectorClientError {
1053                    msg: "ResponseError".to_string(),
1054                    code: None,
1055                }
1056                .into());
1057            }
1058
1059            let resp_json: Value = serde_json::from_str(r#"{"apiName":"myKey","apikey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":true,"canUniversalTransfer":false,"canVanillaOptions":false,"timestamp":1640000000000}"#).unwrap_or_else(|_| serde_json::json!({}));
1060            let dummy_response: models::ModifySubAccountApiKeyPermissionResponse =
1061                serde_json::from_value(resp_json.clone())
1062                    .expect("should parse into models::ModifySubAccountApiKeyPermissionResponse");
1063
1064            let dummy = DummyRestApiResponse {
1065                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1066                status: 200,
1067                headers: HashMap::new(),
1068                rate_limits: None,
1069            };
1070
1071            Ok(dummy.into())
1072        }
1073
1074        async fn query_sub_account_api_key(
1075            &self,
1076            _params: QuerySubAccountApiKeyParams,
1077        ) -> anyhow::Result<RestApiResponse<models::QuerySubAccountApiKeyResponse>> {
1078            if self.force_error {
1079                return Err(ConnectorError::ConnectorClientError {
1080                    msg: "ResponseError".to_string(),
1081                    code: None,
1082                }
1083                .into());
1084            }
1085
1086            let resp_json: Value = serde_json::from_str(r#"{"total":1,"rows":[{"email":"123@test.com","apiName":"myKey","apikey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":false,"canUniversalTransfer":false,"canVanillaOptions":false,"timestamp":1640000000000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1087            let dummy_response: models::QuerySubAccountApiKeyResponse =
1088                serde_json::from_value(resp_json.clone())
1089                    .expect("should parse into models::QuerySubAccountApiKeyResponse");
1090
1091            let dummy = DummyRestApiResponse {
1092                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1093                status: 200,
1094                headers: HashMap::new(),
1095                rate_limits: None,
1096            };
1097
1098            Ok(dummy.into())
1099        }
1100    }
1101
1102    #[test]
1103    fn add_ip_restriction_for_sub_account_api_key_required_params_success() {
1104        TOKIO_SHARED_RT.block_on(async {
1105            let client = MockApiManagementApiClient { force_error: false };
1106
1107            let params = AddIpRestrictionForSubAccountApiKeyParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),1,).build().unwrap();
1108
1109            let resp_json: Value = serde_json::from_str(r#"{"status":"2","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1110            let expected_response : models::AddIpRestrictionForSubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AddIpRestrictionForSubAccountApiKeyResponse");
1111
1112            let resp = client.add_ip_restriction_for_sub_account_api_key(params).await.expect("Expected a response");
1113            let data_future = resp.data();
1114            let actual_response = data_future.await.unwrap();
1115            assert_eq!(actual_response, expected_response);
1116        });
1117    }
1118
1119    #[test]
1120    fn add_ip_restriction_for_sub_account_api_key_optional_params_success() {
1121        TOKIO_SHARED_RT.block_on(async {
1122            let client = MockApiManagementApiClient { force_error: false };
1123
1124            let params = AddIpRestrictionForSubAccountApiKeyParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),1,).ip_address("69.210.67.14".to_string()).recv_window(5000).build().unwrap();
1125
1126            let resp_json: Value = serde_json::from_str(r#"{"status":"2","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1127            let expected_response : models::AddIpRestrictionForSubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AddIpRestrictionForSubAccountApiKeyResponse");
1128
1129            let resp = client.add_ip_restriction_for_sub_account_api_key(params).await.expect("Expected a response");
1130            let data_future = resp.data();
1131            let actual_response = data_future.await.unwrap();
1132            assert_eq!(actual_response, expected_response);
1133        });
1134    }
1135
1136    #[test]
1137    fn add_ip_restriction_for_sub_account_api_key_response_error() {
1138        TOKIO_SHARED_RT.block_on(async {
1139            let client = MockApiManagementApiClient { force_error: true };
1140
1141            let params = AddIpRestrictionForSubAccountApiKeyParams::builder(
1142                "123@test.com".to_string(),
1143                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1144                1,
1145            )
1146            .build()
1147            .unwrap();
1148
1149            match client
1150                .add_ip_restriction_for_sub_account_api_key(params)
1151                .await
1152            {
1153                Ok(_) => panic!("Expected an error"),
1154                Err(err) => {
1155                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1156                }
1157            }
1158        });
1159    }
1160
1161    #[test]
1162    fn create_sub_account_api_key_required_params_success() {
1163        TOKIO_SHARED_RT.block_on(async {
1164            let client = MockApiManagementApiClient { force_error: false };
1165
1166            let params = CreateSubAccountApiKeyParams::builder("123@test.com".to_string(),"myKey".to_string(),2,).build().unwrap();
1167
1168            let resp_json: Value = serde_json::from_str(r#"{"apiName":"myKey","apiKey":"vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A","secretKey":"NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":false,"canUniversalTransfer":false,"canVanillaOptions":false,"status":2,"ipList":["69.210.67.14"]}"#).unwrap_or_else(|_| serde_json::json!({}));
1169            let expected_response : models::CreateSubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CreateSubAccountApiKeyResponse");
1170
1171            let resp = client.create_sub_account_api_key(params).await.expect("Expected a response");
1172            let data_future = resp.data();
1173            let actual_response = data_future.await.unwrap();
1174            assert_eq!(actual_response, expected_response);
1175        });
1176    }
1177
1178    #[test]
1179    fn create_sub_account_api_key_optional_params_success() {
1180        TOKIO_SHARED_RT.block_on(async {
1181            let client = MockApiManagementApiClient { force_error: false };
1182
1183            let params = CreateSubAccountApiKeyParams::builder("123@test.com".to_string(),"myKey".to_string(),2,).can_trade(true).can_margin_loan_repay(false).can_futures_trade(false).can_universal_transfer(false).can_vanilla_options(false).ip_address("69.210.67.14".to_string()).third_party_name("thirdParty".to_string()).public_key(String::new()).recv_window(5000).build().unwrap();
1184
1185            let resp_json: Value = serde_json::from_str(r#"{"apiName":"myKey","apiKey":"vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A","secretKey":"NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":false,"canUniversalTransfer":false,"canVanillaOptions":false,"status":2,"ipList":["69.210.67.14"]}"#).unwrap_or_else(|_| serde_json::json!({}));
1186            let expected_response : models::CreateSubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::CreateSubAccountApiKeyResponse");
1187
1188            let resp = client.create_sub_account_api_key(params).await.expect("Expected a response");
1189            let data_future = resp.data();
1190            let actual_response = data_future.await.unwrap();
1191            assert_eq!(actual_response, expected_response);
1192        });
1193    }
1194
1195    #[test]
1196    fn create_sub_account_api_key_response_error() {
1197        TOKIO_SHARED_RT.block_on(async {
1198            let client = MockApiManagementApiClient { force_error: true };
1199
1200            let params = CreateSubAccountApiKeyParams::builder(
1201                "123@test.com".to_string(),
1202                "myKey".to_string(),
1203                2,
1204            )
1205            .build()
1206            .unwrap();
1207
1208            match client.create_sub_account_api_key(params).await {
1209                Ok(_) => panic!("Expected an error"),
1210                Err(err) => {
1211                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1212                }
1213            }
1214        });
1215    }
1216
1217    #[test]
1218    fn delete_ip_list_for_a_sub_account_api_key_required_params_success() {
1219        TOKIO_SHARED_RT.block_on(async {
1220            let client = MockApiManagementApiClient { force_error: false };
1221
1222            let params = DeleteIpListForASubAccountApiKeyParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),"69.210.67.14".to_string(),).build().unwrap();
1223
1224            let resp_json: Value = serde_json::from_str(r#"{"ipRestrict":"true","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1225            let expected_response : models::DeleteIpListForASubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DeleteIpListForASubAccountApiKeyResponse");
1226
1227            let resp = client.delete_ip_list_for_a_sub_account_api_key(params).await.expect("Expected a response");
1228            let data_future = resp.data();
1229            let actual_response = data_future.await.unwrap();
1230            assert_eq!(actual_response, expected_response);
1231        });
1232    }
1233
1234    #[test]
1235    fn delete_ip_list_for_a_sub_account_api_key_optional_params_success() {
1236        TOKIO_SHARED_RT.block_on(async {
1237            let client = MockApiManagementApiClient { force_error: false };
1238
1239            let params = DeleteIpListForASubAccountApiKeyParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),"69.210.67.14".to_string(),).recv_window(5000).build().unwrap();
1240
1241            let resp_json: Value = serde_json::from_str(r#"{"ipRestrict":"true","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1242            let expected_response : models::DeleteIpListForASubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DeleteIpListForASubAccountApiKeyResponse");
1243
1244            let resp = client.delete_ip_list_for_a_sub_account_api_key(params).await.expect("Expected a response");
1245            let data_future = resp.data();
1246            let actual_response = data_future.await.unwrap();
1247            assert_eq!(actual_response, expected_response);
1248        });
1249    }
1250
1251    #[test]
1252    fn delete_ip_list_for_a_sub_account_api_key_response_error() {
1253        TOKIO_SHARED_RT.block_on(async {
1254            let client = MockApiManagementApiClient { force_error: true };
1255
1256            let params = DeleteIpListForASubAccountApiKeyParams::builder(
1257                "123@test.com".to_string(),
1258                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1259                "69.210.67.14".to_string(),
1260            )
1261            .build()
1262            .unwrap();
1263
1264            match client
1265                .delete_ip_list_for_a_sub_account_api_key(params)
1266                .await
1267            {
1268                Ok(_) => panic!("Expected an error"),
1269                Err(err) => {
1270                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1271                }
1272            }
1273        });
1274    }
1275
1276    #[test]
1277    fn delete_sub_account_api_key_required_params_success() {
1278        TOKIO_SHARED_RT.block_on(async {
1279            let client = MockApiManagementApiClient { force_error: false };
1280
1281            let params = DeleteSubAccountApiKeyParams::builder(
1282                "123@test.com".to_string(),
1283                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1284            )
1285            .build()
1286            .unwrap();
1287
1288            let resp_json: Value =
1289                serde_json::from_str(r"").unwrap_or_else(|_| serde_json::json!({}));
1290            let expected_response: serde_json::Value = serde_json::from_value(resp_json.clone())
1291                .expect("should parse into serde_json::Value");
1292
1293            let resp = client
1294                .delete_sub_account_api_key(params)
1295                .await
1296                .expect("Expected a response");
1297            let data_future = resp.data();
1298            let actual_response = data_future.await.unwrap();
1299            assert_eq!(actual_response, expected_response);
1300        });
1301    }
1302
1303    #[test]
1304    fn delete_sub_account_api_key_optional_params_success() {
1305        TOKIO_SHARED_RT.block_on(async {
1306            let client = MockApiManagementApiClient { force_error: false };
1307
1308            let params = DeleteSubAccountApiKeyParams::builder(
1309                "123@test.com".to_string(),
1310                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1311            )
1312            .recv_window(5000)
1313            .build()
1314            .unwrap();
1315
1316            let resp_json: Value =
1317                serde_json::from_str(r"").unwrap_or_else(|_| serde_json::json!({}));
1318            let expected_response: serde_json::Value = serde_json::from_value(resp_json.clone())
1319                .expect("should parse into serde_json::Value");
1320
1321            let resp = client
1322                .delete_sub_account_api_key(params)
1323                .await
1324                .expect("Expected a response");
1325            let data_future = resp.data();
1326            let actual_response = data_future.await.unwrap();
1327            assert_eq!(actual_response, expected_response);
1328        });
1329    }
1330
1331    #[test]
1332    fn delete_sub_account_api_key_response_error() {
1333        TOKIO_SHARED_RT.block_on(async {
1334            let client = MockApiManagementApiClient { force_error: true };
1335
1336            let params = DeleteSubAccountApiKeyParams::builder(
1337                "123@test.com".to_string(),
1338                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1339            )
1340            .build()
1341            .unwrap();
1342
1343            match client.delete_sub_account_api_key(params).await {
1344                Ok(_) => panic!("Expected an error"),
1345                Err(err) => {
1346                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1347                }
1348            }
1349        });
1350    }
1351
1352    #[test]
1353    fn get_ip_restriction_for_a_sub_account_api_key_required_params_success() {
1354        TOKIO_SHARED_RT.block_on(async {
1355            let client = MockApiManagementApiClient { force_error: false };
1356
1357            let params = GetIpRestrictionForASubAccountApiKeyParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),).build().unwrap();
1358
1359            let resp_json: Value = serde_json::from_str(r#"{"ipRestrict":"true","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1360            let expected_response : models::GetIpRestrictionForASubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetIpRestrictionForASubAccountApiKeyResponse");
1361
1362            let resp = client.get_ip_restriction_for_a_sub_account_api_key(params).await.expect("Expected a response");
1363            let data_future = resp.data();
1364            let actual_response = data_future.await.unwrap();
1365            assert_eq!(actual_response, expected_response);
1366        });
1367    }
1368
1369    #[test]
1370    fn get_ip_restriction_for_a_sub_account_api_key_optional_params_success() {
1371        TOKIO_SHARED_RT.block_on(async {
1372            let client = MockApiManagementApiClient { force_error: false };
1373
1374            let params = GetIpRestrictionForASubAccountApiKeyParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),).recv_window(5000).build().unwrap();
1375
1376            let resp_json: Value = serde_json::from_str(r#"{"ipRestrict":"true","ipList":["69.210.67.14"],"updateTime":1636371437000,"apiKey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf"}"#).unwrap_or_else(|_| serde_json::json!({}));
1377            let expected_response : models::GetIpRestrictionForASubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetIpRestrictionForASubAccountApiKeyResponse");
1378
1379            let resp = client.get_ip_restriction_for_a_sub_account_api_key(params).await.expect("Expected a response");
1380            let data_future = resp.data();
1381            let actual_response = data_future.await.unwrap();
1382            assert_eq!(actual_response, expected_response);
1383        });
1384    }
1385
1386    #[test]
1387    fn get_ip_restriction_for_a_sub_account_api_key_response_error() {
1388        TOKIO_SHARED_RT.block_on(async {
1389            let client = MockApiManagementApiClient { force_error: true };
1390
1391            let params = GetIpRestrictionForASubAccountApiKeyParams::builder(
1392                "123@test.com".to_string(),
1393                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1394            )
1395            .build()
1396            .unwrap();
1397
1398            match client
1399                .get_ip_restriction_for_a_sub_account_api_key(params)
1400                .await
1401            {
1402                Ok(_) => panic!("Expected an error"),
1403                Err(err) => {
1404                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1405                }
1406            }
1407        });
1408    }
1409
1410    #[test]
1411    fn modify_sub_account_api_key_permission_required_params_success() {
1412        TOKIO_SHARED_RT.block_on(async {
1413            let client = MockApiManagementApiClient { force_error: false };
1414
1415            let params = ModifySubAccountApiKeyPermissionParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),).build().unwrap();
1416
1417            let resp_json: Value = serde_json::from_str(r#"{"apiName":"myKey","apikey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":true,"canUniversalTransfer":false,"canVanillaOptions":false,"timestamp":1640000000000}"#).unwrap_or_else(|_| serde_json::json!({}));
1418            let expected_response : models::ModifySubAccountApiKeyPermissionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ModifySubAccountApiKeyPermissionResponse");
1419
1420            let resp = client.modify_sub_account_api_key_permission(params).await.expect("Expected a response");
1421            let data_future = resp.data();
1422            let actual_response = data_future.await.unwrap();
1423            assert_eq!(actual_response, expected_response);
1424        });
1425    }
1426
1427    #[test]
1428    fn modify_sub_account_api_key_permission_optional_params_success() {
1429        TOKIO_SHARED_RT.block_on(async {
1430            let client = MockApiManagementApiClient { force_error: false };
1431
1432            let params = ModifySubAccountApiKeyPermissionParams::builder("123@test.com".to_string(),"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),).can_trade(true).can_margin_loan_repay(false).can_futures_trade(true).can_universal_transfer(false).can_vanilla_options(false).recv_window(5000).build().unwrap();
1433
1434            let resp_json: Value = serde_json::from_str(r#"{"apiName":"myKey","apikey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":true,"canUniversalTransfer":false,"canVanillaOptions":false,"timestamp":1640000000000}"#).unwrap_or_else(|_| serde_json::json!({}));
1435            let expected_response : models::ModifySubAccountApiKeyPermissionResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::ModifySubAccountApiKeyPermissionResponse");
1436
1437            let resp = client.modify_sub_account_api_key_permission(params).await.expect("Expected a response");
1438            let data_future = resp.data();
1439            let actual_response = data_future.await.unwrap();
1440            assert_eq!(actual_response, expected_response);
1441        });
1442    }
1443
1444    #[test]
1445    fn modify_sub_account_api_key_permission_response_error() {
1446        TOKIO_SHARED_RT.block_on(async {
1447            let client = MockApiManagementApiClient { force_error: true };
1448
1449            let params = ModifySubAccountApiKeyPermissionParams::builder(
1450                "123@test.com".to_string(),
1451                "k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string(),
1452            )
1453            .build()
1454            .unwrap();
1455
1456            match client.modify_sub_account_api_key_permission(params).await {
1457                Ok(_) => panic!("Expected an error"),
1458                Err(err) => {
1459                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1460                }
1461            }
1462        });
1463    }
1464
1465    #[test]
1466    fn query_sub_account_api_key_required_params_success() {
1467        TOKIO_SHARED_RT.block_on(async {
1468            let client = MockApiManagementApiClient { force_error: false };
1469
1470            let params = QuerySubAccountApiKeyParams::builder("123@test.com".to_string(),).build().unwrap();
1471
1472            let resp_json: Value = serde_json::from_str(r#"{"total":1,"rows":[{"email":"123@test.com","apiName":"myKey","apikey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":false,"canUniversalTransfer":false,"canVanillaOptions":false,"timestamp":1640000000000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1473            let expected_response : models::QuerySubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountApiKeyResponse");
1474
1475            let resp = client.query_sub_account_api_key(params).await.expect("Expected a response");
1476            let data_future = resp.data();
1477            let actual_response = data_future.await.unwrap();
1478            assert_eq!(actual_response, expected_response);
1479        });
1480    }
1481
1482    #[test]
1483    fn query_sub_account_api_key_optional_params_success() {
1484        TOKIO_SHARED_RT.block_on(async {
1485            let client = MockApiManagementApiClient { force_error: false };
1486
1487            let params = QuerySubAccountApiKeyParams::builder("123@test.com".to_string(),).sub_account_api_key("k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf".to_string()).page(1).size(30).recv_window(5000).build().unwrap();
1488
1489            let resp_json: Value = serde_json::from_str(r#"{"total":1,"rows":[{"email":"123@test.com","apiName":"myKey","apikey":"k5V49ldtn4tszj6W3hystegdfvmGbqDzjmkCtpTvC0G74WhK7yd4rfCTo4lShf","canTrade":true,"canMarginLoanRepay":false,"canFuturesTrade":false,"canUniversalTransfer":false,"canVanillaOptions":false,"timestamp":1640000000000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
1490            let expected_response : models::QuerySubAccountApiKeyResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QuerySubAccountApiKeyResponse");
1491
1492            let resp = client.query_sub_account_api_key(params).await.expect("Expected a response");
1493            let data_future = resp.data();
1494            let actual_response = data_future.await.unwrap();
1495            assert_eq!(actual_response, expected_response);
1496        });
1497    }
1498
1499    #[test]
1500    fn query_sub_account_api_key_response_error() {
1501        TOKIO_SHARED_RT.block_on(async {
1502            let client = MockApiManagementApiClient { force_error: true };
1503
1504            let params = QuerySubAccountApiKeyParams::builder("123@test.com".to_string())
1505                .build()
1506                .unwrap();
1507
1508            match client.query_sub_account_api_key(params).await {
1509                Ok(_) => panic!("Expected an error"),
1510                Err(err) => {
1511                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1512                }
1513            }
1514        });
1515    }
1516}