Skip to main content

binance_sdk/staking/rest_api/apis/
eth_staking_api.rs

1/*
2 * Binance Staking REST API
3 *
4 * OpenAPI Specification for the Binance Staking 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::staking::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait EthStakingApi: Send + Sync {
34    async fn eth_staking_account(
35        &self,
36        params: EthStakingAccountParams,
37    ) -> anyhow::Result<RestApiResponse<models::EthStakingAccountResponse>>;
38    async fn get_current_eth_staking_quota(
39        &self,
40        params: GetCurrentEthStakingQuotaParams,
41    ) -> anyhow::Result<RestApiResponse<models::GetCurrentEthStakingQuotaResponse>>;
42    async fn get_eth_redemption_history(
43        &self,
44        params: GetEthRedemptionHistoryParams,
45    ) -> anyhow::Result<RestApiResponse<models::GetEthRedemptionHistoryResponse>>;
46    async fn get_eth_staking_history(
47        &self,
48        params: GetEthStakingHistoryParams,
49    ) -> anyhow::Result<RestApiResponse<models::GetEthStakingHistoryResponse>>;
50    async fn get_wbeth_rate_history(
51        &self,
52        params: GetWbethRateHistoryParams,
53    ) -> anyhow::Result<RestApiResponse<models::GetWbethRateHistoryResponse>>;
54    async fn get_wbeth_rewards_history(
55        &self,
56        params: GetWbethRewardsHistoryParams,
57    ) -> anyhow::Result<RestApiResponse<models::GetWbethRewardsHistoryResponse>>;
58    async fn get_wbeth_unwrap_history(
59        &self,
60        params: GetWbethUnwrapHistoryParams,
61    ) -> anyhow::Result<RestApiResponse<models::GetWbethUnwrapHistoryResponse>>;
62    async fn get_wbeth_wrap_history(
63        &self,
64        params: GetWbethWrapHistoryParams,
65    ) -> anyhow::Result<RestApiResponse<models::GetWbethWrapHistoryResponse>>;
66    async fn redeem_eth(
67        &self,
68        params: RedeemEthParams,
69    ) -> anyhow::Result<RestApiResponse<models::RedeemEthResponse>>;
70    async fn subscribe_eth_staking(
71        &self,
72        params: SubscribeEthStakingParams,
73    ) -> anyhow::Result<RestApiResponse<models::SubscribeEthStakingResponse>>;
74    async fn wrap_beth(
75        &self,
76        params: WrapBethParams,
77    ) -> anyhow::Result<RestApiResponse<models::WrapBethResponse>>;
78}
79
80#[derive(Debug, Clone)]
81pub struct EthStakingApiClient {
82    configuration: ConfigurationRestApi,
83}
84
85impl EthStakingApiClient {
86    pub fn new(configuration: ConfigurationRestApi) -> Self {
87        Self { configuration }
88    }
89}
90
91/// Request parameters for the [`eth_staking_account`] operation.
92///
93/// This struct holds all of the inputs you can pass when calling
94/// [`eth_staking_account`](#method.eth_staking_account).
95#[derive(Clone, Debug, Builder, Default)]
96#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
97pub struct EthStakingAccountParams {
98    ///
99    /// The `recv_window` parameter.
100    ///
101    /// This field is **optional.
102    #[builder(setter(into), default)]
103    pub recv_window: Option<i64>,
104}
105
106impl EthStakingAccountParams {
107    /// Create a builder for [`eth_staking_account`].
108    ///
109    #[must_use]
110    pub fn builder() -> EthStakingAccountParamsBuilder {
111        EthStakingAccountParamsBuilder::default()
112    }
113}
114/// Request parameters for the [`get_current_eth_staking_quota`] operation.
115///
116/// This struct holds all of the inputs you can pass when calling
117/// [`get_current_eth_staking_quota`](#method.get_current_eth_staking_quota).
118#[derive(Clone, Debug, Builder, Default)]
119#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
120pub struct GetCurrentEthStakingQuotaParams {
121    ///
122    /// The `recv_window` parameter.
123    ///
124    /// This field is **optional.
125    #[builder(setter(into), default)]
126    pub recv_window: Option<i64>,
127}
128
129impl GetCurrentEthStakingQuotaParams {
130    /// Create a builder for [`get_current_eth_staking_quota`].
131    ///
132    #[must_use]
133    pub fn builder() -> GetCurrentEthStakingQuotaParamsBuilder {
134        GetCurrentEthStakingQuotaParamsBuilder::default()
135    }
136}
137/// Request parameters for the [`get_eth_redemption_history`] operation.
138///
139/// This struct holds all of the inputs you can pass when calling
140/// [`get_eth_redemption_history`](#method.get_eth_redemption_history).
141#[derive(Clone, Debug, Builder, Default)]
142#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
143pub struct GetEthRedemptionHistoryParams {
144    ///
145    /// The `redeem_id` parameter.
146    ///
147    /// This field is **optional.
148    #[builder(setter(into), default)]
149    pub redeem_id: Option<i64>,
150    ///
151    /// The `start_time` parameter.
152    ///
153    /// This field is **optional.
154    #[builder(setter(into), default)]
155    pub start_time: Option<i64>,
156    ///
157    /// The `end_time` parameter.
158    ///
159    /// This field is **optional.
160    #[builder(setter(into), default)]
161    pub end_time: Option<i64>,
162    /// Currently querying page. Start from 1. Default:1
163    ///
164    /// This field is **optional.
165    #[builder(setter(into), default)]
166    pub current: Option<i64>,
167    /// Default:10, Max:100
168    ///
169    /// This field is **optional.
170    #[builder(setter(into), default)]
171    pub size: Option<i64>,
172    ///
173    /// The `recv_window` parameter.
174    ///
175    /// This field is **optional.
176    #[builder(setter(into), default)]
177    pub recv_window: Option<i64>,
178}
179
180impl GetEthRedemptionHistoryParams {
181    /// Create a builder for [`get_eth_redemption_history`].
182    ///
183    #[must_use]
184    pub fn builder() -> GetEthRedemptionHistoryParamsBuilder {
185        GetEthRedemptionHistoryParamsBuilder::default()
186    }
187}
188/// Request parameters for the [`get_eth_staking_history`] operation.
189///
190/// This struct holds all of the inputs you can pass when calling
191/// [`get_eth_staking_history`](#method.get_eth_staking_history).
192#[derive(Clone, Debug, Builder, Default)]
193#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
194pub struct GetEthStakingHistoryParams {
195    ///
196    /// The `purchase_id` parameter.
197    ///
198    /// This field is **optional.
199    #[builder(setter(into), default)]
200    pub purchase_id: Option<i64>,
201    ///
202    /// The `start_time` parameter.
203    ///
204    /// This field is **optional.
205    #[builder(setter(into), default)]
206    pub start_time: Option<i64>,
207    ///
208    /// The `end_time` parameter.
209    ///
210    /// This field is **optional.
211    #[builder(setter(into), default)]
212    pub end_time: Option<i64>,
213    /// Currently querying page. Start from 1. Default:1
214    ///
215    /// This field is **optional.
216    #[builder(setter(into), default)]
217    pub current: Option<i64>,
218    /// Default:10, Max:100
219    ///
220    /// This field is **optional.
221    #[builder(setter(into), default)]
222    pub size: Option<i64>,
223    ///
224    /// The `recv_window` parameter.
225    ///
226    /// This field is **optional.
227    #[builder(setter(into), default)]
228    pub recv_window: Option<i64>,
229}
230
231impl GetEthStakingHistoryParams {
232    /// Create a builder for [`get_eth_staking_history`].
233    ///
234    #[must_use]
235    pub fn builder() -> GetEthStakingHistoryParamsBuilder {
236        GetEthStakingHistoryParamsBuilder::default()
237    }
238}
239/// Request parameters for the [`get_wbeth_rate_history`] operation.
240///
241/// This struct holds all of the inputs you can pass when calling
242/// [`get_wbeth_rate_history`](#method.get_wbeth_rate_history).
243#[derive(Clone, Debug, Builder, Default)]
244#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
245pub struct GetWbethRateHistoryParams {
246    ///
247    /// The `start_time` parameter.
248    ///
249    /// This field is **optional.
250    #[builder(setter(into), default)]
251    pub start_time: Option<i64>,
252    ///
253    /// The `end_time` parameter.
254    ///
255    /// This field is **optional.
256    #[builder(setter(into), default)]
257    pub end_time: Option<i64>,
258    /// Currently querying page. Start from 1. Default:1
259    ///
260    /// This field is **optional.
261    #[builder(setter(into), default)]
262    pub current: Option<i64>,
263    /// Default:10, Max:100
264    ///
265    /// This field is **optional.
266    #[builder(setter(into), default)]
267    pub size: Option<i64>,
268    ///
269    /// The `recv_window` parameter.
270    ///
271    /// This field is **optional.
272    #[builder(setter(into), default)]
273    pub recv_window: Option<i64>,
274}
275
276impl GetWbethRateHistoryParams {
277    /// Create a builder for [`get_wbeth_rate_history`].
278    ///
279    #[must_use]
280    pub fn builder() -> GetWbethRateHistoryParamsBuilder {
281        GetWbethRateHistoryParamsBuilder::default()
282    }
283}
284/// Request parameters for the [`get_wbeth_rewards_history`] operation.
285///
286/// This struct holds all of the inputs you can pass when calling
287/// [`get_wbeth_rewards_history`](#method.get_wbeth_rewards_history).
288#[derive(Clone, Debug, Builder, Default)]
289#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
290pub struct GetWbethRewardsHistoryParams {
291    ///
292    /// The `start_time` parameter.
293    ///
294    /// This field is **optional.
295    #[builder(setter(into), default)]
296    pub start_time: Option<i64>,
297    ///
298    /// The `end_time` parameter.
299    ///
300    /// This field is **optional.
301    #[builder(setter(into), default)]
302    pub end_time: Option<i64>,
303    /// Currently querying page. Start from 1. Default:1
304    ///
305    /// This field is **optional.
306    #[builder(setter(into), default)]
307    pub current: Option<i64>,
308    /// Default:10, Max:100
309    ///
310    /// This field is **optional.
311    #[builder(setter(into), default)]
312    pub size: Option<i64>,
313    ///
314    /// The `recv_window` parameter.
315    ///
316    /// This field is **optional.
317    #[builder(setter(into), default)]
318    pub recv_window: Option<i64>,
319}
320
321impl GetWbethRewardsHistoryParams {
322    /// Create a builder for [`get_wbeth_rewards_history`].
323    ///
324    #[must_use]
325    pub fn builder() -> GetWbethRewardsHistoryParamsBuilder {
326        GetWbethRewardsHistoryParamsBuilder::default()
327    }
328}
329/// Request parameters for the [`get_wbeth_unwrap_history`] operation.
330///
331/// This struct holds all of the inputs you can pass when calling
332/// [`get_wbeth_unwrap_history`](#method.get_wbeth_unwrap_history).
333#[derive(Clone, Debug, Builder, Default)]
334#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
335pub struct GetWbethUnwrapHistoryParams {
336    ///
337    /// The `start_time` parameter.
338    ///
339    /// This field is **optional.
340    #[builder(setter(into), default)]
341    pub start_time: Option<i64>,
342    ///
343    /// The `end_time` parameter.
344    ///
345    /// This field is **optional.
346    #[builder(setter(into), default)]
347    pub end_time: Option<i64>,
348    /// Currently querying page. Start from 1. Default:1
349    ///
350    /// This field is **optional.
351    #[builder(setter(into), default)]
352    pub current: Option<i64>,
353    /// Default:10, Max:100
354    ///
355    /// This field is **optional.
356    #[builder(setter(into), default)]
357    pub size: Option<i64>,
358    ///
359    /// The `recv_window` parameter.
360    ///
361    /// This field is **optional.
362    #[builder(setter(into), default)]
363    pub recv_window: Option<i64>,
364}
365
366impl GetWbethUnwrapHistoryParams {
367    /// Create a builder for [`get_wbeth_unwrap_history`].
368    ///
369    #[must_use]
370    pub fn builder() -> GetWbethUnwrapHistoryParamsBuilder {
371        GetWbethUnwrapHistoryParamsBuilder::default()
372    }
373}
374/// Request parameters for the [`get_wbeth_wrap_history`] operation.
375///
376/// This struct holds all of the inputs you can pass when calling
377/// [`get_wbeth_wrap_history`](#method.get_wbeth_wrap_history).
378#[derive(Clone, Debug, Builder, Default)]
379#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
380pub struct GetWbethWrapHistoryParams {
381    ///
382    /// The `start_time` parameter.
383    ///
384    /// This field is **optional.
385    #[builder(setter(into), default)]
386    pub start_time: Option<i64>,
387    ///
388    /// The `end_time` parameter.
389    ///
390    /// This field is **optional.
391    #[builder(setter(into), default)]
392    pub end_time: Option<i64>,
393    /// Currently querying page. Start from 1. Default:1
394    ///
395    /// This field is **optional.
396    #[builder(setter(into), default)]
397    pub current: Option<i64>,
398    /// Default:10, Max:100
399    ///
400    /// This field is **optional.
401    #[builder(setter(into), default)]
402    pub size: Option<i64>,
403    ///
404    /// The `recv_window` parameter.
405    ///
406    /// This field is **optional.
407    #[builder(setter(into), default)]
408    pub recv_window: Option<i64>,
409}
410
411impl GetWbethWrapHistoryParams {
412    /// Create a builder for [`get_wbeth_wrap_history`].
413    ///
414    #[must_use]
415    pub fn builder() -> GetWbethWrapHistoryParamsBuilder {
416        GetWbethWrapHistoryParamsBuilder::default()
417    }
418}
419/// Request parameters for the [`redeem_eth`] operation.
420///
421/// This struct holds all of the inputs you can pass when calling
422/// [`redeem_eth`](#method.redeem_eth).
423#[derive(Clone, Debug, Builder)]
424#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
425pub struct RedeemEthParams {
426    /// Amount in SOL.
427    ///
428    /// This field is **required.
429    #[builder(setter(into))]
430    pub amount: rust_decimal::Decimal,
431    /// WBETH or BETH, default to BETH
432    ///
433    /// This field is **optional.
434    #[builder(setter(into), default)]
435    pub asset: Option<String>,
436    ///
437    /// The `recv_window` parameter.
438    ///
439    /// This field is **optional.
440    #[builder(setter(into), default)]
441    pub recv_window: Option<i64>,
442}
443
444impl RedeemEthParams {
445    /// Create a builder for [`redeem_eth`].
446    ///
447    /// Required parameters:
448    ///
449    /// * `amount` — Amount in SOL.
450    ///
451    #[must_use]
452    pub fn builder(amount: rust_decimal::Decimal) -> RedeemEthParamsBuilder {
453        RedeemEthParamsBuilder::default().amount(amount)
454    }
455}
456/// Request parameters for the [`subscribe_eth_staking`] operation.
457///
458/// This struct holds all of the inputs you can pass when calling
459/// [`subscribe_eth_staking`](#method.subscribe_eth_staking).
460#[derive(Clone, Debug, Builder)]
461#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
462pub struct SubscribeEthStakingParams {
463    /// Amount in SOL.
464    ///
465    /// This field is **required.
466    #[builder(setter(into))]
467    pub amount: rust_decimal::Decimal,
468    ///
469    /// The `recv_window` parameter.
470    ///
471    /// This field is **optional.
472    #[builder(setter(into), default)]
473    pub recv_window: Option<i64>,
474}
475
476impl SubscribeEthStakingParams {
477    /// Create a builder for [`subscribe_eth_staking`].
478    ///
479    /// Required parameters:
480    ///
481    /// * `amount` — Amount in SOL.
482    ///
483    #[must_use]
484    pub fn builder(amount: rust_decimal::Decimal) -> SubscribeEthStakingParamsBuilder {
485        SubscribeEthStakingParamsBuilder::default().amount(amount)
486    }
487}
488/// Request parameters for the [`wrap_beth`] operation.
489///
490/// This struct holds all of the inputs you can pass when calling
491/// [`wrap_beth`](#method.wrap_beth).
492#[derive(Clone, Debug, Builder)]
493#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
494pub struct WrapBethParams {
495    /// Amount in SOL.
496    ///
497    /// This field is **required.
498    #[builder(setter(into))]
499    pub amount: rust_decimal::Decimal,
500    ///
501    /// The `recv_window` parameter.
502    ///
503    /// This field is **optional.
504    #[builder(setter(into), default)]
505    pub recv_window: Option<i64>,
506}
507
508impl WrapBethParams {
509    /// Create a builder for [`wrap_beth`].
510    ///
511    /// Required parameters:
512    ///
513    /// * `amount` — Amount in SOL.
514    ///
515    #[must_use]
516    pub fn builder(amount: rust_decimal::Decimal) -> WrapBethParamsBuilder {
517        WrapBethParamsBuilder::default().amount(amount)
518    }
519}
520
521#[async_trait]
522impl EthStakingApi for EthStakingApiClient {
523    async fn eth_staking_account(
524        &self,
525        params: EthStakingAccountParams,
526    ) -> anyhow::Result<RestApiResponse<models::EthStakingAccountResponse>> {
527        let EthStakingAccountParams { recv_window } = params;
528
529        let mut query_params = BTreeMap::new();
530        let body_params = BTreeMap::new();
531
532        if let Some(rw) = recv_window {
533            query_params.insert("recvWindow".to_string(), json!(rw));
534        }
535
536        send_request::<models::EthStakingAccountResponse>(
537            &self.configuration,
538            "/sapi/v2/eth-staking/account",
539            reqwest::Method::GET,
540            query_params,
541            body_params,
542            if HAS_TIME_UNIT {
543                self.configuration.time_unit
544            } else {
545                None
546            },
547            true,
548        )
549        .await
550    }
551
552    async fn get_current_eth_staking_quota(
553        &self,
554        params: GetCurrentEthStakingQuotaParams,
555    ) -> anyhow::Result<RestApiResponse<models::GetCurrentEthStakingQuotaResponse>> {
556        let GetCurrentEthStakingQuotaParams { recv_window } = params;
557
558        let mut query_params = BTreeMap::new();
559        let body_params = BTreeMap::new();
560
561        if let Some(rw) = recv_window {
562            query_params.insert("recvWindow".to_string(), json!(rw));
563        }
564
565        send_request::<models::GetCurrentEthStakingQuotaResponse>(
566            &self.configuration,
567            "/sapi/v1/eth-staking/eth/quota",
568            reqwest::Method::GET,
569            query_params,
570            body_params,
571            if HAS_TIME_UNIT {
572                self.configuration.time_unit
573            } else {
574                None
575            },
576            true,
577        )
578        .await
579    }
580
581    async fn get_eth_redemption_history(
582        &self,
583        params: GetEthRedemptionHistoryParams,
584    ) -> anyhow::Result<RestApiResponse<models::GetEthRedemptionHistoryResponse>> {
585        let GetEthRedemptionHistoryParams {
586            redeem_id,
587            start_time,
588            end_time,
589            current,
590            size,
591            recv_window,
592        } = params;
593
594        let mut query_params = BTreeMap::new();
595        let body_params = BTreeMap::new();
596
597        if let Some(rw) = redeem_id {
598            query_params.insert("redeemId".to_string(), json!(rw));
599        }
600
601        if let Some(rw) = start_time {
602            query_params.insert("startTime".to_string(), json!(rw));
603        }
604
605        if let Some(rw) = end_time {
606            query_params.insert("endTime".to_string(), json!(rw));
607        }
608
609        if let Some(rw) = current {
610            query_params.insert("current".to_string(), json!(rw));
611        }
612
613        if let Some(rw) = size {
614            query_params.insert("size".to_string(), json!(rw));
615        }
616
617        if let Some(rw) = recv_window {
618            query_params.insert("recvWindow".to_string(), json!(rw));
619        }
620
621        send_request::<models::GetEthRedemptionHistoryResponse>(
622            &self.configuration,
623            "/sapi/v1/eth-staking/eth/history/redemptionHistory",
624            reqwest::Method::GET,
625            query_params,
626            body_params,
627            if HAS_TIME_UNIT {
628                self.configuration.time_unit
629            } else {
630                None
631            },
632            true,
633        )
634        .await
635    }
636
637    async fn get_eth_staking_history(
638        &self,
639        params: GetEthStakingHistoryParams,
640    ) -> anyhow::Result<RestApiResponse<models::GetEthStakingHistoryResponse>> {
641        let GetEthStakingHistoryParams {
642            purchase_id,
643            start_time,
644            end_time,
645            current,
646            size,
647            recv_window,
648        } = params;
649
650        let mut query_params = BTreeMap::new();
651        let body_params = BTreeMap::new();
652
653        if let Some(rw) = purchase_id {
654            query_params.insert("purchaseId".to_string(), json!(rw));
655        }
656
657        if let Some(rw) = start_time {
658            query_params.insert("startTime".to_string(), json!(rw));
659        }
660
661        if let Some(rw) = end_time {
662            query_params.insert("endTime".to_string(), json!(rw));
663        }
664
665        if let Some(rw) = current {
666            query_params.insert("current".to_string(), json!(rw));
667        }
668
669        if let Some(rw) = size {
670            query_params.insert("size".to_string(), json!(rw));
671        }
672
673        if let Some(rw) = recv_window {
674            query_params.insert("recvWindow".to_string(), json!(rw));
675        }
676
677        send_request::<models::GetEthStakingHistoryResponse>(
678            &self.configuration,
679            "/sapi/v1/eth-staking/eth/history/stakingHistory",
680            reqwest::Method::GET,
681            query_params,
682            body_params,
683            if HAS_TIME_UNIT {
684                self.configuration.time_unit
685            } else {
686                None
687            },
688            true,
689        )
690        .await
691    }
692
693    async fn get_wbeth_rate_history(
694        &self,
695        params: GetWbethRateHistoryParams,
696    ) -> anyhow::Result<RestApiResponse<models::GetWbethRateHistoryResponse>> {
697        let GetWbethRateHistoryParams {
698            start_time,
699            end_time,
700            current,
701            size,
702            recv_window,
703        } = params;
704
705        let mut query_params = BTreeMap::new();
706        let body_params = BTreeMap::new();
707
708        if let Some(rw) = start_time {
709            query_params.insert("startTime".to_string(), json!(rw));
710        }
711
712        if let Some(rw) = end_time {
713            query_params.insert("endTime".to_string(), json!(rw));
714        }
715
716        if let Some(rw) = current {
717            query_params.insert("current".to_string(), json!(rw));
718        }
719
720        if let Some(rw) = size {
721            query_params.insert("size".to_string(), json!(rw));
722        }
723
724        if let Some(rw) = recv_window {
725            query_params.insert("recvWindow".to_string(), json!(rw));
726        }
727
728        send_request::<models::GetWbethRateHistoryResponse>(
729            &self.configuration,
730            "/sapi/v1/eth-staking/eth/history/rateHistory",
731            reqwest::Method::GET,
732            query_params,
733            body_params,
734            if HAS_TIME_UNIT {
735                self.configuration.time_unit
736            } else {
737                None
738            },
739            true,
740        )
741        .await
742    }
743
744    async fn get_wbeth_rewards_history(
745        &self,
746        params: GetWbethRewardsHistoryParams,
747    ) -> anyhow::Result<RestApiResponse<models::GetWbethRewardsHistoryResponse>> {
748        let GetWbethRewardsHistoryParams {
749            start_time,
750            end_time,
751            current,
752            size,
753            recv_window,
754        } = params;
755
756        let mut query_params = BTreeMap::new();
757        let body_params = BTreeMap::new();
758
759        if let Some(rw) = start_time {
760            query_params.insert("startTime".to_string(), json!(rw));
761        }
762
763        if let Some(rw) = end_time {
764            query_params.insert("endTime".to_string(), json!(rw));
765        }
766
767        if let Some(rw) = current {
768            query_params.insert("current".to_string(), json!(rw));
769        }
770
771        if let Some(rw) = size {
772            query_params.insert("size".to_string(), json!(rw));
773        }
774
775        if let Some(rw) = recv_window {
776            query_params.insert("recvWindow".to_string(), json!(rw));
777        }
778
779        send_request::<models::GetWbethRewardsHistoryResponse>(
780            &self.configuration,
781            "/sapi/v1/eth-staking/eth/history/wbethRewardsHistory",
782            reqwest::Method::GET,
783            query_params,
784            body_params,
785            if HAS_TIME_UNIT {
786                self.configuration.time_unit
787            } else {
788                None
789            },
790            true,
791        )
792        .await
793    }
794
795    async fn get_wbeth_unwrap_history(
796        &self,
797        params: GetWbethUnwrapHistoryParams,
798    ) -> anyhow::Result<RestApiResponse<models::GetWbethUnwrapHistoryResponse>> {
799        let GetWbethUnwrapHistoryParams {
800            start_time,
801            end_time,
802            current,
803            size,
804            recv_window,
805        } = params;
806
807        let mut query_params = BTreeMap::new();
808        let body_params = BTreeMap::new();
809
810        if let Some(rw) = start_time {
811            query_params.insert("startTime".to_string(), json!(rw));
812        }
813
814        if let Some(rw) = end_time {
815            query_params.insert("endTime".to_string(), json!(rw));
816        }
817
818        if let Some(rw) = current {
819            query_params.insert("current".to_string(), json!(rw));
820        }
821
822        if let Some(rw) = size {
823            query_params.insert("size".to_string(), json!(rw));
824        }
825
826        if let Some(rw) = recv_window {
827            query_params.insert("recvWindow".to_string(), json!(rw));
828        }
829
830        send_request::<models::GetWbethUnwrapHistoryResponse>(
831            &self.configuration,
832            "/sapi/v1/eth-staking/wbeth/history/unwrapHistory",
833            reqwest::Method::GET,
834            query_params,
835            body_params,
836            if HAS_TIME_UNIT {
837                self.configuration.time_unit
838            } else {
839                None
840            },
841            true,
842        )
843        .await
844    }
845
846    async fn get_wbeth_wrap_history(
847        &self,
848        params: GetWbethWrapHistoryParams,
849    ) -> anyhow::Result<RestApiResponse<models::GetWbethWrapHistoryResponse>> {
850        let GetWbethWrapHistoryParams {
851            start_time,
852            end_time,
853            current,
854            size,
855            recv_window,
856        } = params;
857
858        let mut query_params = BTreeMap::new();
859        let body_params = BTreeMap::new();
860
861        if let Some(rw) = start_time {
862            query_params.insert("startTime".to_string(), json!(rw));
863        }
864
865        if let Some(rw) = end_time {
866            query_params.insert("endTime".to_string(), json!(rw));
867        }
868
869        if let Some(rw) = current {
870            query_params.insert("current".to_string(), json!(rw));
871        }
872
873        if let Some(rw) = size {
874            query_params.insert("size".to_string(), json!(rw));
875        }
876
877        if let Some(rw) = recv_window {
878            query_params.insert("recvWindow".to_string(), json!(rw));
879        }
880
881        send_request::<models::GetWbethWrapHistoryResponse>(
882            &self.configuration,
883            "/sapi/v1/eth-staking/wbeth/history/wrapHistory",
884            reqwest::Method::GET,
885            query_params,
886            body_params,
887            if HAS_TIME_UNIT {
888                self.configuration.time_unit
889            } else {
890                None
891            },
892            true,
893        )
894        .await
895    }
896
897    async fn redeem_eth(
898        &self,
899        params: RedeemEthParams,
900    ) -> anyhow::Result<RestApiResponse<models::RedeemEthResponse>> {
901        let RedeemEthParams {
902            amount,
903            asset,
904            recv_window,
905        } = params;
906
907        let mut query_params = BTreeMap::new();
908        let body_params = BTreeMap::new();
909
910        query_params.insert("amount".to_string(), json!(amount));
911
912        if let Some(rw) = asset {
913            query_params.insert("asset".to_string(), json!(rw));
914        }
915
916        if let Some(rw) = recv_window {
917            query_params.insert("recvWindow".to_string(), json!(rw));
918        }
919
920        send_request::<models::RedeemEthResponse>(
921            &self.configuration,
922            "/sapi/v1/eth-staking/eth/redeem",
923            reqwest::Method::POST,
924            query_params,
925            body_params,
926            if HAS_TIME_UNIT {
927                self.configuration.time_unit
928            } else {
929                None
930            },
931            true,
932        )
933        .await
934    }
935
936    async fn subscribe_eth_staking(
937        &self,
938        params: SubscribeEthStakingParams,
939    ) -> anyhow::Result<RestApiResponse<models::SubscribeEthStakingResponse>> {
940        let SubscribeEthStakingParams {
941            amount,
942            recv_window,
943        } = params;
944
945        let mut query_params = BTreeMap::new();
946        let body_params = BTreeMap::new();
947
948        query_params.insert("amount".to_string(), json!(amount));
949
950        if let Some(rw) = recv_window {
951            query_params.insert("recvWindow".to_string(), json!(rw));
952        }
953
954        send_request::<models::SubscribeEthStakingResponse>(
955            &self.configuration,
956            "/sapi/v2/eth-staking/eth/stake",
957            reqwest::Method::POST,
958            query_params,
959            body_params,
960            if HAS_TIME_UNIT {
961                self.configuration.time_unit
962            } else {
963                None
964            },
965            true,
966        )
967        .await
968    }
969
970    async fn wrap_beth(
971        &self,
972        params: WrapBethParams,
973    ) -> anyhow::Result<RestApiResponse<models::WrapBethResponse>> {
974        let WrapBethParams {
975            amount,
976            recv_window,
977        } = params;
978
979        let mut query_params = BTreeMap::new();
980        let body_params = BTreeMap::new();
981
982        query_params.insert("amount".to_string(), json!(amount));
983
984        if let Some(rw) = recv_window {
985            query_params.insert("recvWindow".to_string(), json!(rw));
986        }
987
988        send_request::<models::WrapBethResponse>(
989            &self.configuration,
990            "/sapi/v1/eth-staking/wbeth/wrap",
991            reqwest::Method::POST,
992            query_params,
993            body_params,
994            if HAS_TIME_UNIT {
995                self.configuration.time_unit
996            } else {
997                None
998            },
999            true,
1000        )
1001        .await
1002    }
1003}
1004
1005#[cfg(all(test, feature = "staking"))]
1006mod tests {
1007    use super::*;
1008    use crate::TOKIO_SHARED_RT;
1009    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
1010    use async_trait::async_trait;
1011    use std::collections::HashMap;
1012
1013    struct DummyRestApiResponse<T> {
1014        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
1015        status: u16,
1016        headers: HashMap<String, String>,
1017        rate_limits: Option<Vec<RestApiRateLimit>>,
1018    }
1019
1020    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
1021        fn from(dummy: DummyRestApiResponse<T>) -> Self {
1022            Self {
1023                data_fn: dummy.inner,
1024                status: dummy.status,
1025                headers: dummy.headers,
1026                rate_limits: dummy.rate_limits,
1027            }
1028        }
1029    }
1030
1031    struct MockEthStakingApiClient {
1032        force_error: bool,
1033    }
1034
1035    #[async_trait]
1036    impl EthStakingApi for MockEthStakingApiClient {
1037        async fn eth_staking_account(
1038            &self,
1039            _params: EthStakingAccountParams,
1040        ) -> anyhow::Result<RestApiResponse<models::EthStakingAccountResponse>> {
1041            if self.force_error {
1042                return Err(ConnectorError::ConnectorClientError {
1043                    msg: "ResponseError".to_string(),
1044                    code: None,
1045                }
1046                .into());
1047            }
1048
1049            let resp_json: Value = serde_json::from_str(r#"{"holdingInETH":"1.22330928","holdings":{"wbethAmount":"1.10928781","bethAmount":"1.90002112"},"thirtyDaysProfitInETH":"0.22330928","profit":{"amountFromWBETH":"0.12330928","amountFromBETH":"0.1"}}"#).unwrap();
1050            let dummy_response: models::EthStakingAccountResponse =
1051                serde_json::from_value(resp_json.clone())
1052                    .expect("should parse into models::EthStakingAccountResponse");
1053
1054            let dummy = DummyRestApiResponse {
1055                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1056                status: 200,
1057                headers: HashMap::new(),
1058                rate_limits: None,
1059            };
1060
1061            Ok(dummy.into())
1062        }
1063
1064        async fn get_current_eth_staking_quota(
1065            &self,
1066            _params: GetCurrentEthStakingQuotaParams,
1067        ) -> anyhow::Result<RestApiResponse<models::GetCurrentEthStakingQuotaResponse>> {
1068            if self.force_error {
1069                return Err(ConnectorError::ConnectorClientError {
1070                    msg: "ResponseError".to_string(),
1071                    code: None,
1072                }
1073                .into());
1074            }
1075
1076            let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.00010000","minRedeemAmount":"0.00000001","redeemPeriod":20,"stakeable":true,"redeemable":true,"commissionFee":"0.05000000","calculating":false}"#).unwrap();
1077            let dummy_response: models::GetCurrentEthStakingQuotaResponse =
1078                serde_json::from_value(resp_json.clone())
1079                    .expect("should parse into models::GetCurrentEthStakingQuotaResponse");
1080
1081            let dummy = DummyRestApiResponse {
1082                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1083                status: 200,
1084                headers: HashMap::new(),
1085                rate_limits: None,
1086            };
1087
1088            Ok(dummy.into())
1089        }
1090
1091        async fn get_eth_redemption_history(
1092            &self,
1093            _params: GetEthRedemptionHistoryParams,
1094        ) -> anyhow::Result<RestApiResponse<models::GetEthRedemptionHistoryResponse>> {
1095            if self.force_error {
1096                return Err(ConnectorError::ConnectorClientError {
1097                    msg: "ResponseError".to_string(),
1098                    code: None,
1099                }
1100                .into());
1101            }
1102
1103            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"WBETH","amount":"21312.23223","distributeAsset":"ETH","distributeAmount":"21338.0699","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1104            let dummy_response: models::GetEthRedemptionHistoryResponse =
1105                serde_json::from_value(resp_json.clone())
1106                    .expect("should parse into models::GetEthRedemptionHistoryResponse");
1107
1108            let dummy = DummyRestApiResponse {
1109                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1110                status: 200,
1111                headers: HashMap::new(),
1112                rate_limits: None,
1113            };
1114
1115            Ok(dummy.into())
1116        }
1117
1118        async fn get_eth_staking_history(
1119            &self,
1120            _params: GetEthStakingHistoryParams,
1121        ) -> anyhow::Result<RestApiResponse<models::GetEthStakingHistoryResponse>> {
1122            if self.force_error {
1123                return Err(ConnectorError::ConnectorClientError {
1124                    msg: "ResponseError".to_string(),
1125                    code: None,
1126                }
1127                .into());
1128            }
1129
1130            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"ETH","amount":"21312.23223","distributeAsset":"WBETH","distributeAmount":"21286.42584","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1131            let dummy_response: models::GetEthStakingHistoryResponse =
1132                serde_json::from_value(resp_json.clone())
1133                    .expect("should parse into models::GetEthStakingHistoryResponse");
1134
1135            let dummy = DummyRestApiResponse {
1136                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1137                status: 200,
1138                headers: HashMap::new(),
1139                rate_limits: None,
1140            };
1141
1142            Ok(dummy.into())
1143        }
1144
1145        async fn get_wbeth_rate_history(
1146            &self,
1147            _params: GetWbethRateHistoryParams,
1148        ) -> anyhow::Result<RestApiResponse<models::GetWbethRateHistoryResponse>> {
1149            if self.force_error {
1150                return Err(ConnectorError::ConnectorClientError {
1151                    msg: "ResponseError".to_string(),
1152                    code: None,
1153                }
1154                .into());
1155            }
1156
1157            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.00121234","time":1577233578000}],"total":"1"}"#).unwrap();
1158            let dummy_response: models::GetWbethRateHistoryResponse =
1159                serde_json::from_value(resp_json.clone())
1160                    .expect("should parse into models::GetWbethRateHistoryResponse");
1161
1162            let dummy = DummyRestApiResponse {
1163                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1164                status: 200,
1165                headers: HashMap::new(),
1166                rate_limits: None,
1167            };
1168
1169            Ok(dummy.into())
1170        }
1171
1172        async fn get_wbeth_rewards_history(
1173            &self,
1174            _params: GetWbethRewardsHistoryParams,
1175        ) -> anyhow::Result<RestApiResponse<models::GetWbethRewardsHistoryResponse>> {
1176            if self.force_error {
1177                return Err(ConnectorError::ConnectorClientError {
1178                    msg: "ResponseError".to_string(),
1179                    code: None,
1180                }
1181                .into());
1182            }
1183
1184            let resp_json: Value = serde_json::from_str(r#"{"estRewardsInETH":"1.23230920","rows":[{"time":1575018510000,"amountInETH":"0.23223","holding":"2.3223","holdingInETH":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1185            let dummy_response: models::GetWbethRewardsHistoryResponse =
1186                serde_json::from_value(resp_json.clone())
1187                    .expect("should parse into models::GetWbethRewardsHistoryResponse");
1188
1189            let dummy = DummyRestApiResponse {
1190                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1191                status: 200,
1192                headers: HashMap::new(),
1193                rate_limits: None,
1194            };
1195
1196            Ok(dummy.into())
1197        }
1198
1199        async fn get_wbeth_unwrap_history(
1200            &self,
1201            _params: GetWbethUnwrapHistoryParams,
1202        ) -> anyhow::Result<RestApiResponse<models::GetWbethUnwrapHistoryResponse>> {
1203            if self.force_error {
1204                return Err(ConnectorError::ConnectorClientError {
1205                    msg: "ResponseError".to_string(),
1206                    code: None,
1207                }
1208                .into());
1209            }
1210
1211            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"WBETH","fromAmount":"21312.23223","toAsset":"BETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1212            let dummy_response: models::GetWbethUnwrapHistoryResponse =
1213                serde_json::from_value(resp_json.clone())
1214                    .expect("should parse into models::GetWbethUnwrapHistoryResponse");
1215
1216            let dummy = DummyRestApiResponse {
1217                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1218                status: 200,
1219                headers: HashMap::new(),
1220                rate_limits: None,
1221            };
1222
1223            Ok(dummy.into())
1224        }
1225
1226        async fn get_wbeth_wrap_history(
1227            &self,
1228            _params: GetWbethWrapHistoryParams,
1229        ) -> anyhow::Result<RestApiResponse<models::GetWbethWrapHistoryResponse>> {
1230            if self.force_error {
1231                return Err(ConnectorError::ConnectorClientError {
1232                    msg: "ResponseError".to_string(),
1233                    code: None,
1234                }
1235                .into());
1236            }
1237
1238            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"BETH","fromAmount":"21312.23223","toAsset":"WBETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1239            let dummy_response: models::GetWbethWrapHistoryResponse =
1240                serde_json::from_value(resp_json.clone())
1241                    .expect("should parse into models::GetWbethWrapHistoryResponse");
1242
1243            let dummy = DummyRestApiResponse {
1244                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1245                status: 200,
1246                headers: HashMap::new(),
1247                rate_limits: None,
1248            };
1249
1250            Ok(dummy.into())
1251        }
1252
1253        async fn redeem_eth(
1254            &self,
1255            _params: RedeemEthParams,
1256        ) -> anyhow::Result<RestApiResponse<models::RedeemEthResponse>> {
1257            if self.force_error {
1258                return Err(ConnectorError::ConnectorClientError {
1259                    msg: "ResponseError".to_string(),
1260                    code: None,
1261                }
1262                .into());
1263            }
1264
1265            let resp_json: Value = serde_json::from_str(r#"{"success":true,"ethAmount":"0.23092091","conversionRatio":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1266            let dummy_response: models::RedeemEthResponse =
1267                serde_json::from_value(resp_json.clone())
1268                    .expect("should parse into models::RedeemEthResponse");
1269
1270            let dummy = DummyRestApiResponse {
1271                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1272                status: 200,
1273                headers: HashMap::new(),
1274                rate_limits: None,
1275            };
1276
1277            Ok(dummy.into())
1278        }
1279
1280        async fn subscribe_eth_staking(
1281            &self,
1282            _params: SubscribeEthStakingParams,
1283        ) -> anyhow::Result<RestApiResponse<models::SubscribeEthStakingResponse>> {
1284            if self.force_error {
1285                return Err(ConnectorError::ConnectorClientError {
1286                    msg: "ResponseError".to_string(),
1287                    code: None,
1288                }
1289                .into());
1290            }
1291
1292            let resp_json: Value = serde_json::from_str(r#"{"success":true,"wbethAmount":"0.23092091","conversionRatio":"1.001212342342","purchaseId":1234567}"#).unwrap();
1293            let dummy_response: models::SubscribeEthStakingResponse =
1294                serde_json::from_value(resp_json.clone())
1295                    .expect("should parse into models::SubscribeEthStakingResponse");
1296
1297            let dummy = DummyRestApiResponse {
1298                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1299                status: 200,
1300                headers: HashMap::new(),
1301                rate_limits: None,
1302            };
1303
1304            Ok(dummy.into())
1305        }
1306
1307        async fn wrap_beth(
1308            &self,
1309            _params: WrapBethParams,
1310        ) -> anyhow::Result<RestApiResponse<models::WrapBethResponse>> {
1311            if self.force_error {
1312                return Err(ConnectorError::ConnectorClientError {
1313                    msg: "ResponseError".to_string(),
1314                    code: None,
1315                }
1316                .into());
1317            }
1318
1319            let resp_json: Value = serde_json::from_str(
1320                r#"{"success":true,"wbethAmount":"0.23092091","exchangeRate":"1.001212343432"}"#,
1321            )
1322            .unwrap();
1323            let dummy_response: models::WrapBethResponse =
1324                serde_json::from_value(resp_json.clone())
1325                    .expect("should parse into models::WrapBethResponse");
1326
1327            let dummy = DummyRestApiResponse {
1328                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
1329                status: 200,
1330                headers: HashMap::new(),
1331                rate_limits: None,
1332            };
1333
1334            Ok(dummy.into())
1335        }
1336    }
1337
1338    #[test]
1339    fn eth_staking_account_required_params_success() {
1340        TOKIO_SHARED_RT.block_on(async {
1341            let client = MockEthStakingApiClient { force_error: false };
1342
1343            let params = EthStakingAccountParams::builder().build().unwrap();
1344
1345            let resp_json: Value = serde_json::from_str(r#"{"holdingInETH":"1.22330928","holdings":{"wbethAmount":"1.10928781","bethAmount":"1.90002112"},"thirtyDaysProfitInETH":"0.22330928","profit":{"amountFromWBETH":"0.12330928","amountFromBETH":"0.1"}}"#).unwrap();
1346            let expected_response : models::EthStakingAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::EthStakingAccountResponse");
1347
1348            let resp = client.eth_staking_account(params).await.expect("Expected a response");
1349            let data_future = resp.data();
1350            let actual_response = data_future.await.unwrap();
1351            assert_eq!(actual_response, expected_response);
1352        });
1353    }
1354
1355    #[test]
1356    fn eth_staking_account_optional_params_success() {
1357        TOKIO_SHARED_RT.block_on(async {
1358            let client = MockEthStakingApiClient { force_error: false };
1359
1360            let params = EthStakingAccountParams::builder().recv_window(5000).build().unwrap();
1361
1362            let resp_json: Value = serde_json::from_str(r#"{"holdingInETH":"1.22330928","holdings":{"wbethAmount":"1.10928781","bethAmount":"1.90002112"},"thirtyDaysProfitInETH":"0.22330928","profit":{"amountFromWBETH":"0.12330928","amountFromBETH":"0.1"}}"#).unwrap();
1363            let expected_response : models::EthStakingAccountResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::EthStakingAccountResponse");
1364
1365            let resp = client.eth_staking_account(params).await.expect("Expected a response");
1366            let data_future = resp.data();
1367            let actual_response = data_future.await.unwrap();
1368            assert_eq!(actual_response, expected_response);
1369        });
1370    }
1371
1372    #[test]
1373    fn eth_staking_account_response_error() {
1374        TOKIO_SHARED_RT.block_on(async {
1375            let client = MockEthStakingApiClient { force_error: true };
1376
1377            let params = EthStakingAccountParams::builder().build().unwrap();
1378
1379            match client.eth_staking_account(params).await {
1380                Ok(_) => panic!("Expected an error"),
1381                Err(err) => {
1382                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1383                }
1384            }
1385        });
1386    }
1387
1388    #[test]
1389    fn get_current_eth_staking_quota_required_params_success() {
1390        TOKIO_SHARED_RT.block_on(async {
1391            let client = MockEthStakingApiClient { force_error: false };
1392
1393            let params = GetCurrentEthStakingQuotaParams::builder().build().unwrap();
1394
1395            let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.00010000","minRedeemAmount":"0.00000001","redeemPeriod":20,"stakeable":true,"redeemable":true,"commissionFee":"0.05000000","calculating":false}"#).unwrap();
1396            let expected_response : models::GetCurrentEthStakingQuotaResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCurrentEthStakingQuotaResponse");
1397
1398            let resp = client.get_current_eth_staking_quota(params).await.expect("Expected a response");
1399            let data_future = resp.data();
1400            let actual_response = data_future.await.unwrap();
1401            assert_eq!(actual_response, expected_response);
1402        });
1403    }
1404
1405    #[test]
1406    fn get_current_eth_staking_quota_optional_params_success() {
1407        TOKIO_SHARED_RT.block_on(async {
1408            let client = MockEthStakingApiClient { force_error: false };
1409
1410            let params = GetCurrentEthStakingQuotaParams::builder().recv_window(5000).build().unwrap();
1411
1412            let resp_json: Value = serde_json::from_str(r#"{"leftStakingPersonalQuota":"1000","leftRedemptionPersonalQuota":"1000","minStakeAmount":"0.00010000","minRedeemAmount":"0.00000001","redeemPeriod":20,"stakeable":true,"redeemable":true,"commissionFee":"0.05000000","calculating":false}"#).unwrap();
1413            let expected_response : models::GetCurrentEthStakingQuotaResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCurrentEthStakingQuotaResponse");
1414
1415            let resp = client.get_current_eth_staking_quota(params).await.expect("Expected a response");
1416            let data_future = resp.data();
1417            let actual_response = data_future.await.unwrap();
1418            assert_eq!(actual_response, expected_response);
1419        });
1420    }
1421
1422    #[test]
1423    fn get_current_eth_staking_quota_response_error() {
1424        TOKIO_SHARED_RT.block_on(async {
1425            let client = MockEthStakingApiClient { force_error: true };
1426
1427            let params = GetCurrentEthStakingQuotaParams::builder().build().unwrap();
1428
1429            match client.get_current_eth_staking_quota(params).await {
1430                Ok(_) => panic!("Expected an error"),
1431                Err(err) => {
1432                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1433                }
1434            }
1435        });
1436    }
1437
1438    #[test]
1439    fn get_eth_redemption_history_required_params_success() {
1440        TOKIO_SHARED_RT.block_on(async {
1441            let client = MockEthStakingApiClient { force_error: false };
1442
1443            let params = GetEthRedemptionHistoryParams::builder().build().unwrap();
1444
1445            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"WBETH","amount":"21312.23223","distributeAsset":"ETH","distributeAmount":"21338.0699","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1446            let expected_response : models::GetEthRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthRedemptionHistoryResponse");
1447
1448            let resp = client.get_eth_redemption_history(params).await.expect("Expected a response");
1449            let data_future = resp.data();
1450            let actual_response = data_future.await.unwrap();
1451            assert_eq!(actual_response, expected_response);
1452        });
1453    }
1454
1455    #[test]
1456    fn get_eth_redemption_history_optional_params_success() {
1457        TOKIO_SHARED_RT.block_on(async {
1458            let client = MockEthStakingApiClient { force_error: false };
1459
1460            let params = GetEthRedemptionHistoryParams::builder().redeem_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1461
1462            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"arrivalTime":1575018510000,"asset":"WBETH","amount":"21312.23223","distributeAsset":"ETH","distributeAmount":"21338.0699","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1463            let expected_response : models::GetEthRedemptionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthRedemptionHistoryResponse");
1464
1465            let resp = client.get_eth_redemption_history(params).await.expect("Expected a response");
1466            let data_future = resp.data();
1467            let actual_response = data_future.await.unwrap();
1468            assert_eq!(actual_response, expected_response);
1469        });
1470    }
1471
1472    #[test]
1473    fn get_eth_redemption_history_response_error() {
1474        TOKIO_SHARED_RT.block_on(async {
1475            let client = MockEthStakingApiClient { force_error: true };
1476
1477            let params = GetEthRedemptionHistoryParams::builder().build().unwrap();
1478
1479            match client.get_eth_redemption_history(params).await {
1480                Ok(_) => panic!("Expected an error"),
1481                Err(err) => {
1482                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1483                }
1484            }
1485        });
1486    }
1487
1488    #[test]
1489    fn get_eth_staking_history_required_params_success() {
1490        TOKIO_SHARED_RT.block_on(async {
1491            let client = MockEthStakingApiClient { force_error: false };
1492
1493            let params = GetEthStakingHistoryParams::builder().build().unwrap();
1494
1495            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"ETH","amount":"21312.23223","distributeAsset":"WBETH","distributeAmount":"21286.42584","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1496            let expected_response : models::GetEthStakingHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthStakingHistoryResponse");
1497
1498            let resp = client.get_eth_staking_history(params).await.expect("Expected a response");
1499            let data_future = resp.data();
1500            let actual_response = data_future.await.unwrap();
1501            assert_eq!(actual_response, expected_response);
1502        });
1503    }
1504
1505    #[test]
1506    fn get_eth_staking_history_optional_params_success() {
1507        TOKIO_SHARED_RT.block_on(async {
1508            let client = MockEthStakingApiClient { force_error: false };
1509
1510            let params = GetEthStakingHistoryParams::builder().purchase_id(1).start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1511
1512            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"asset":"ETH","amount":"21312.23223","distributeAsset":"WBETH","distributeAmount":"21286.42584","conversionRatio":"1.00121234","status":"SUCCESS"}],"total":1}"#).unwrap();
1513            let expected_response : models::GetEthStakingHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetEthStakingHistoryResponse");
1514
1515            let resp = client.get_eth_staking_history(params).await.expect("Expected a response");
1516            let data_future = resp.data();
1517            let actual_response = data_future.await.unwrap();
1518            assert_eq!(actual_response, expected_response);
1519        });
1520    }
1521
1522    #[test]
1523    fn get_eth_staking_history_response_error() {
1524        TOKIO_SHARED_RT.block_on(async {
1525            let client = MockEthStakingApiClient { force_error: true };
1526
1527            let params = GetEthStakingHistoryParams::builder().build().unwrap();
1528
1529            match client.get_eth_staking_history(params).await {
1530                Ok(_) => panic!("Expected an error"),
1531                Err(err) => {
1532                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1533                }
1534            }
1535        });
1536    }
1537
1538    #[test]
1539    fn get_wbeth_rate_history_required_params_success() {
1540        TOKIO_SHARED_RT.block_on(async {
1541            let client = MockEthStakingApiClient { force_error: false };
1542
1543            let params = GetWbethRateHistoryParams::builder().build().unwrap();
1544
1545            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.00121234","time":1577233578000}],"total":"1"}"#).unwrap();
1546            let expected_response : models::GetWbethRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRateHistoryResponse");
1547
1548            let resp = client.get_wbeth_rate_history(params).await.expect("Expected a response");
1549            let data_future = resp.data();
1550            let actual_response = data_future.await.unwrap();
1551            assert_eq!(actual_response, expected_response);
1552        });
1553    }
1554
1555    #[test]
1556    fn get_wbeth_rate_history_optional_params_success() {
1557        TOKIO_SHARED_RT.block_on(async {
1558            let client = MockEthStakingApiClient { force_error: false };
1559
1560            let params = GetWbethRateHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1561
1562            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"annualPercentageRate":"0.00006408","exchangeRate":"1.00121234","time":1577233578000}],"total":"1"}"#).unwrap();
1563            let expected_response : models::GetWbethRateHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRateHistoryResponse");
1564
1565            let resp = client.get_wbeth_rate_history(params).await.expect("Expected a response");
1566            let data_future = resp.data();
1567            let actual_response = data_future.await.unwrap();
1568            assert_eq!(actual_response, expected_response);
1569        });
1570    }
1571
1572    #[test]
1573    fn get_wbeth_rate_history_response_error() {
1574        TOKIO_SHARED_RT.block_on(async {
1575            let client = MockEthStakingApiClient { force_error: true };
1576
1577            let params = GetWbethRateHistoryParams::builder().build().unwrap();
1578
1579            match client.get_wbeth_rate_history(params).await {
1580                Ok(_) => panic!("Expected an error"),
1581                Err(err) => {
1582                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1583                }
1584            }
1585        });
1586    }
1587
1588    #[test]
1589    fn get_wbeth_rewards_history_required_params_success() {
1590        TOKIO_SHARED_RT.block_on(async {
1591            let client = MockEthStakingApiClient { force_error: false };
1592
1593            let params = GetWbethRewardsHistoryParams::builder().build().unwrap();
1594
1595            let resp_json: Value = serde_json::from_str(r#"{"estRewardsInETH":"1.23230920","rows":[{"time":1575018510000,"amountInETH":"0.23223","holding":"2.3223","holdingInETH":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1596            let expected_response : models::GetWbethRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRewardsHistoryResponse");
1597
1598            let resp = client.get_wbeth_rewards_history(params).await.expect("Expected a response");
1599            let data_future = resp.data();
1600            let actual_response = data_future.await.unwrap();
1601            assert_eq!(actual_response, expected_response);
1602        });
1603    }
1604
1605    #[test]
1606    fn get_wbeth_rewards_history_optional_params_success() {
1607        TOKIO_SHARED_RT.block_on(async {
1608            let client = MockEthStakingApiClient { force_error: false };
1609
1610            let params = GetWbethRewardsHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1611
1612            let resp_json: Value = serde_json::from_str(r#"{"estRewardsInETH":"1.23230920","rows":[{"time":1575018510000,"amountInETH":"0.23223","holding":"2.3223","holdingInETH":"2.4231","annualPercentageRate":"0.5"}],"total":1}"#).unwrap();
1613            let expected_response : models::GetWbethRewardsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethRewardsHistoryResponse");
1614
1615            let resp = client.get_wbeth_rewards_history(params).await.expect("Expected a response");
1616            let data_future = resp.data();
1617            let actual_response = data_future.await.unwrap();
1618            assert_eq!(actual_response, expected_response);
1619        });
1620    }
1621
1622    #[test]
1623    fn get_wbeth_rewards_history_response_error() {
1624        TOKIO_SHARED_RT.block_on(async {
1625            let client = MockEthStakingApiClient { force_error: true };
1626
1627            let params = GetWbethRewardsHistoryParams::builder().build().unwrap();
1628
1629            match client.get_wbeth_rewards_history(params).await {
1630                Ok(_) => panic!("Expected an error"),
1631                Err(err) => {
1632                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1633                }
1634            }
1635        });
1636    }
1637
1638    #[test]
1639    fn get_wbeth_unwrap_history_required_params_success() {
1640        TOKIO_SHARED_RT.block_on(async {
1641            let client = MockEthStakingApiClient { force_error: false };
1642
1643            let params = GetWbethUnwrapHistoryParams::builder().build().unwrap();
1644
1645            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"WBETH","fromAmount":"21312.23223","toAsset":"BETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1646            let expected_response : models::GetWbethUnwrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethUnwrapHistoryResponse");
1647
1648            let resp = client.get_wbeth_unwrap_history(params).await.expect("Expected a response");
1649            let data_future = resp.data();
1650            let actual_response = data_future.await.unwrap();
1651            assert_eq!(actual_response, expected_response);
1652        });
1653    }
1654
1655    #[test]
1656    fn get_wbeth_unwrap_history_optional_params_success() {
1657        TOKIO_SHARED_RT.block_on(async {
1658            let client = MockEthStakingApiClient { force_error: false };
1659
1660            let params = GetWbethUnwrapHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1661
1662            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"WBETH","fromAmount":"21312.23223","toAsset":"BETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1663            let expected_response : models::GetWbethUnwrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethUnwrapHistoryResponse");
1664
1665            let resp = client.get_wbeth_unwrap_history(params).await.expect("Expected a response");
1666            let data_future = resp.data();
1667            let actual_response = data_future.await.unwrap();
1668            assert_eq!(actual_response, expected_response);
1669        });
1670    }
1671
1672    #[test]
1673    fn get_wbeth_unwrap_history_response_error() {
1674        TOKIO_SHARED_RT.block_on(async {
1675            let client = MockEthStakingApiClient { force_error: true };
1676
1677            let params = GetWbethUnwrapHistoryParams::builder().build().unwrap();
1678
1679            match client.get_wbeth_unwrap_history(params).await {
1680                Ok(_) => panic!("Expected an error"),
1681                Err(err) => {
1682                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1683                }
1684            }
1685        });
1686    }
1687
1688    #[test]
1689    fn get_wbeth_wrap_history_required_params_success() {
1690        TOKIO_SHARED_RT.block_on(async {
1691            let client = MockEthStakingApiClient { force_error: false };
1692
1693            let params = GetWbethWrapHistoryParams::builder().build().unwrap();
1694
1695            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"BETH","fromAmount":"21312.23223","toAsset":"WBETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1696            let expected_response : models::GetWbethWrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethWrapHistoryResponse");
1697
1698            let resp = client.get_wbeth_wrap_history(params).await.expect("Expected a response");
1699            let data_future = resp.data();
1700            let actual_response = data_future.await.unwrap();
1701            assert_eq!(actual_response, expected_response);
1702        });
1703    }
1704
1705    #[test]
1706    fn get_wbeth_wrap_history_optional_params_success() {
1707        TOKIO_SHARED_RT.block_on(async {
1708            let client = MockEthStakingApiClient { force_error: false };
1709
1710            let params = GetWbethWrapHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).current(1).size(10).recv_window(5000).build().unwrap();
1711
1712            let resp_json: Value = serde_json::from_str(r#"{"rows":[{"time":1575018510000,"fromAsset":"BETH","fromAmount":"21312.23223","toAsset":"WBETH","toAmount":"21312.23223","exchangeRate":"1.01243253","status":"SUCCESS"}],"total":1}"#).unwrap();
1713            let expected_response : models::GetWbethWrapHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetWbethWrapHistoryResponse");
1714
1715            let resp = client.get_wbeth_wrap_history(params).await.expect("Expected a response");
1716            let data_future = resp.data();
1717            let actual_response = data_future.await.unwrap();
1718            assert_eq!(actual_response, expected_response);
1719        });
1720    }
1721
1722    #[test]
1723    fn get_wbeth_wrap_history_response_error() {
1724        TOKIO_SHARED_RT.block_on(async {
1725            let client = MockEthStakingApiClient { force_error: true };
1726
1727            let params = GetWbethWrapHistoryParams::builder().build().unwrap();
1728
1729            match client.get_wbeth_wrap_history(params).await {
1730                Ok(_) => panic!("Expected an error"),
1731                Err(err) => {
1732                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1733                }
1734            }
1735        });
1736    }
1737
1738    #[test]
1739    fn redeem_eth_required_params_success() {
1740        TOKIO_SHARED_RT.block_on(async {
1741            let client = MockEthStakingApiClient { force_error: false };
1742
1743            let params = RedeemEthParams::builder(dec!(1.0),).build().unwrap();
1744
1745            let resp_json: Value = serde_json::from_str(r#"{"success":true,"ethAmount":"0.23092091","conversionRatio":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1746            let expected_response : models::RedeemEthResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemEthResponse");
1747
1748            let resp = client.redeem_eth(params).await.expect("Expected a response");
1749            let data_future = resp.data();
1750            let actual_response = data_future.await.unwrap();
1751            assert_eq!(actual_response, expected_response);
1752        });
1753    }
1754
1755    #[test]
1756    fn redeem_eth_optional_params_success() {
1757        TOKIO_SHARED_RT.block_on(async {
1758            let client = MockEthStakingApiClient { force_error: false };
1759
1760            let params = RedeemEthParams::builder(dec!(1.0),).asset("BETH".to_string()).recv_window(5000).build().unwrap();
1761
1762            let resp_json: Value = serde_json::from_str(r#"{"success":true,"ethAmount":"0.23092091","conversionRatio":"1.00121234","arrivalTime":1575018510000,"redeemId":1234567}"#).unwrap();
1763            let expected_response : models::RedeemEthResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::RedeemEthResponse");
1764
1765            let resp = client.redeem_eth(params).await.expect("Expected a response");
1766            let data_future = resp.data();
1767            let actual_response = data_future.await.unwrap();
1768            assert_eq!(actual_response, expected_response);
1769        });
1770    }
1771
1772    #[test]
1773    fn redeem_eth_response_error() {
1774        TOKIO_SHARED_RT.block_on(async {
1775            let client = MockEthStakingApiClient { force_error: true };
1776
1777            let params = RedeemEthParams::builder(dec!(1.0)).build().unwrap();
1778
1779            match client.redeem_eth(params).await {
1780                Ok(_) => panic!("Expected an error"),
1781                Err(err) => {
1782                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1783                }
1784            }
1785        });
1786    }
1787
1788    #[test]
1789    fn subscribe_eth_staking_required_params_success() {
1790        TOKIO_SHARED_RT.block_on(async {
1791            let client = MockEthStakingApiClient { force_error: false };
1792
1793            let params = SubscribeEthStakingParams::builder(dec!(1.0),).build().unwrap();
1794
1795            let resp_json: Value = serde_json::from_str(r#"{"success":true,"wbethAmount":"0.23092091","conversionRatio":"1.001212342342","purchaseId":1234567}"#).unwrap();
1796            let expected_response : models::SubscribeEthStakingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SubscribeEthStakingResponse");
1797
1798            let resp = client.subscribe_eth_staking(params).await.expect("Expected a response");
1799            let data_future = resp.data();
1800            let actual_response = data_future.await.unwrap();
1801            assert_eq!(actual_response, expected_response);
1802        });
1803    }
1804
1805    #[test]
1806    fn subscribe_eth_staking_optional_params_success() {
1807        TOKIO_SHARED_RT.block_on(async {
1808            let client = MockEthStakingApiClient { force_error: false };
1809
1810            let params = SubscribeEthStakingParams::builder(dec!(1.0),).recv_window(5000).build().unwrap();
1811
1812            let resp_json: Value = serde_json::from_str(r#"{"success":true,"wbethAmount":"0.23092091","conversionRatio":"1.001212342342","purchaseId":1234567}"#).unwrap();
1813            let expected_response : models::SubscribeEthStakingResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::SubscribeEthStakingResponse");
1814
1815            let resp = client.subscribe_eth_staking(params).await.expect("Expected a response");
1816            let data_future = resp.data();
1817            let actual_response = data_future.await.unwrap();
1818            assert_eq!(actual_response, expected_response);
1819        });
1820    }
1821
1822    #[test]
1823    fn subscribe_eth_staking_response_error() {
1824        TOKIO_SHARED_RT.block_on(async {
1825            let client = MockEthStakingApiClient { force_error: true };
1826
1827            let params = SubscribeEthStakingParams::builder(dec!(1.0))
1828                .build()
1829                .unwrap();
1830
1831            match client.subscribe_eth_staking(params).await {
1832                Ok(_) => panic!("Expected an error"),
1833                Err(err) => {
1834                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1835                }
1836            }
1837        });
1838    }
1839
1840    #[test]
1841    fn wrap_beth_required_params_success() {
1842        TOKIO_SHARED_RT.block_on(async {
1843            let client = MockEthStakingApiClient { force_error: false };
1844
1845            let params = WrapBethParams::builder(dec!(1.0)).build().unwrap();
1846
1847            let resp_json: Value = serde_json::from_str(
1848                r#"{"success":true,"wbethAmount":"0.23092091","exchangeRate":"1.001212343432"}"#,
1849            )
1850            .unwrap();
1851            let expected_response: models::WrapBethResponse =
1852                serde_json::from_value(resp_json.clone())
1853                    .expect("should parse into models::WrapBethResponse");
1854
1855            let resp = client.wrap_beth(params).await.expect("Expected a response");
1856            let data_future = resp.data();
1857            let actual_response = data_future.await.unwrap();
1858            assert_eq!(actual_response, expected_response);
1859        });
1860    }
1861
1862    #[test]
1863    fn wrap_beth_optional_params_success() {
1864        TOKIO_SHARED_RT.block_on(async {
1865            let client = MockEthStakingApiClient { force_error: false };
1866
1867            let params = WrapBethParams::builder(dec!(1.0))
1868                .recv_window(5000)
1869                .build()
1870                .unwrap();
1871
1872            let resp_json: Value = serde_json::from_str(
1873                r#"{"success":true,"wbethAmount":"0.23092091","exchangeRate":"1.001212343432"}"#,
1874            )
1875            .unwrap();
1876            let expected_response: models::WrapBethResponse =
1877                serde_json::from_value(resp_json.clone())
1878                    .expect("should parse into models::WrapBethResponse");
1879
1880            let resp = client.wrap_beth(params).await.expect("Expected a response");
1881            let data_future = resp.data();
1882            let actual_response = data_future.await.unwrap();
1883            assert_eq!(actual_response, expected_response);
1884        });
1885    }
1886
1887    #[test]
1888    fn wrap_beth_response_error() {
1889        TOKIO_SHARED_RT.block_on(async {
1890            let client = MockEthStakingApiClient { force_error: true };
1891
1892            let params = WrapBethParams::builder(dec!(1.0)).build().unwrap();
1893
1894            match client.wrap_beth(params).await {
1895                Ok(_) => panic!("Expected an error"),
1896                Err(err) => {
1897                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1898                }
1899            }
1900        });
1901    }
1902}