Skip to main content

binance_sdk/simple_earn/rest_api/apis/
flexible_locked_api.rs

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