Skip to main content

binance_sdk/nft/rest_api/apis/
nft_api.rs

1/*
2 * Binance NFT REST API
3 *
4 * OpenAPI Specification for the Binance NFT 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::nft::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait NftApi: Send + Sync {
34    async fn get_nft_asset(
35        &self,
36        params: GetNftAssetParams,
37    ) -> anyhow::Result<RestApiResponse<models::GetNftAssetResponse>>;
38    async fn get_nft_deposit_history(
39        &self,
40        params: GetNftDepositHistoryParams,
41    ) -> anyhow::Result<RestApiResponse<models::GetNftDepositHistoryResponse>>;
42    async fn get_nft_transaction_history(
43        &self,
44        params: GetNftTransactionHistoryParams,
45    ) -> anyhow::Result<RestApiResponse<models::GetNftTransactionHistoryResponse>>;
46    async fn get_nft_withdraw_history(
47        &self,
48        params: GetNftWithdrawHistoryParams,
49    ) -> anyhow::Result<RestApiResponse<models::GetNftWithdrawHistoryResponse>>;
50}
51
52#[derive(Debug, Clone)]
53pub struct NftApiClient {
54    configuration: ConfigurationRestApi,
55}
56
57impl NftApiClient {
58    pub fn new(configuration: ConfigurationRestApi) -> Self {
59        Self { configuration }
60    }
61}
62
63/// Request parameters for the [`get_nft_asset`] operation.
64///
65/// This struct holds all of the inputs you can pass when calling
66/// [`get_nft_asset`](#method.get_nft_asset).
67#[derive(Clone, Debug, Builder, Default)]
68#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
69pub struct GetNftAssetParams {
70    /// Default 50, Max 50
71    ///
72    /// This field is **optional.
73    #[builder(setter(into), default)]
74    pub limit: Option<i64>,
75    /// Default 1
76    ///
77    /// This field is **optional.
78    #[builder(setter(into), default)]
79    pub page: Option<i64>,
80    ///
81    /// The `recv_window` parameter.
82    ///
83    /// This field is **optional.
84    #[builder(setter(into), default)]
85    pub recv_window: Option<i64>,
86}
87
88impl GetNftAssetParams {
89    /// Create a builder for [`get_nft_asset`].
90    ///
91    #[must_use]
92    pub fn builder() -> GetNftAssetParamsBuilder {
93        GetNftAssetParamsBuilder::default()
94    }
95}
96/// Request parameters for the [`get_nft_deposit_history`] operation.
97///
98/// This struct holds all of the inputs you can pass when calling
99/// [`get_nft_deposit_history`](#method.get_nft_deposit_history).
100#[derive(Clone, Debug, Builder, Default)]
101#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
102pub struct GetNftDepositHistoryParams {
103    ///
104    /// The `start_time` parameter.
105    ///
106    /// This field is **optional.
107    #[builder(setter(into), default)]
108    pub start_time: Option<i64>,
109    ///
110    /// The `end_time` parameter.
111    ///
112    /// This field is **optional.
113    #[builder(setter(into), default)]
114    pub end_time: Option<i64>,
115    /// Default 50, Max 50
116    ///
117    /// This field is **optional.
118    #[builder(setter(into), default)]
119    pub limit: Option<i64>,
120    /// Default 1
121    ///
122    /// This field is **optional.
123    #[builder(setter(into), default)]
124    pub page: Option<i64>,
125    ///
126    /// The `recv_window` parameter.
127    ///
128    /// This field is **optional.
129    #[builder(setter(into), default)]
130    pub recv_window: Option<i64>,
131}
132
133impl GetNftDepositHistoryParams {
134    /// Create a builder for [`get_nft_deposit_history`].
135    ///
136    #[must_use]
137    pub fn builder() -> GetNftDepositHistoryParamsBuilder {
138        GetNftDepositHistoryParamsBuilder::default()
139    }
140}
141/// Request parameters for the [`get_nft_transaction_history`] operation.
142///
143/// This struct holds all of the inputs you can pass when calling
144/// [`get_nft_transaction_history`](#method.get_nft_transaction_history).
145#[derive(Clone, Debug, Builder)]
146#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
147pub struct GetNftTransactionHistoryParams {
148    /// 0: purchase order, 1: sell order, 2: royalty income, 3: primary market order, 4: mint fee
149    ///
150    /// This field is **required.
151    #[builder(setter(into))]
152    pub order_type: i64,
153    ///
154    /// The `start_time` parameter.
155    ///
156    /// This field is **optional.
157    #[builder(setter(into), default)]
158    pub start_time: Option<i64>,
159    ///
160    /// The `end_time` parameter.
161    ///
162    /// This field is **optional.
163    #[builder(setter(into), default)]
164    pub end_time: Option<i64>,
165    /// Default 50, Max 50
166    ///
167    /// This field is **optional.
168    #[builder(setter(into), default)]
169    pub limit: Option<i64>,
170    /// Default 1
171    ///
172    /// This field is **optional.
173    #[builder(setter(into), default)]
174    pub page: Option<i64>,
175    ///
176    /// The `recv_window` parameter.
177    ///
178    /// This field is **optional.
179    #[builder(setter(into), default)]
180    pub recv_window: Option<i64>,
181}
182
183impl GetNftTransactionHistoryParams {
184    /// Create a builder for [`get_nft_transaction_history`].
185    ///
186    /// Required parameters:
187    ///
188    /// * `order_type` — 0: purchase order, 1: sell order, 2: royalty income, 3: primary market order, 4: mint fee
189    ///
190    #[must_use]
191    pub fn builder(order_type: i64) -> GetNftTransactionHistoryParamsBuilder {
192        GetNftTransactionHistoryParamsBuilder::default().order_type(order_type)
193    }
194}
195/// Request parameters for the [`get_nft_withdraw_history`] operation.
196///
197/// This struct holds all of the inputs you can pass when calling
198/// [`get_nft_withdraw_history`](#method.get_nft_withdraw_history).
199#[derive(Clone, Debug, Builder, Default)]
200#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
201pub struct GetNftWithdrawHistoryParams {
202    ///
203    /// The `start_time` parameter.
204    ///
205    /// This field is **optional.
206    #[builder(setter(into), default)]
207    pub start_time: Option<i64>,
208    ///
209    /// The `end_time` parameter.
210    ///
211    /// This field is **optional.
212    #[builder(setter(into), default)]
213    pub end_time: Option<i64>,
214    /// Default 50, Max 50
215    ///
216    /// This field is **optional.
217    #[builder(setter(into), default)]
218    pub limit: Option<i64>,
219    /// Default 1
220    ///
221    /// This field is **optional.
222    #[builder(setter(into), default)]
223    pub page: Option<i64>,
224    ///
225    /// The `recv_window` parameter.
226    ///
227    /// This field is **optional.
228    #[builder(setter(into), default)]
229    pub recv_window: Option<i64>,
230}
231
232impl GetNftWithdrawHistoryParams {
233    /// Create a builder for [`get_nft_withdraw_history`].
234    ///
235    #[must_use]
236    pub fn builder() -> GetNftWithdrawHistoryParamsBuilder {
237        GetNftWithdrawHistoryParamsBuilder::default()
238    }
239}
240
241#[async_trait]
242impl NftApi for NftApiClient {
243    async fn get_nft_asset(
244        &self,
245        params: GetNftAssetParams,
246    ) -> anyhow::Result<RestApiResponse<models::GetNftAssetResponse>> {
247        let GetNftAssetParams {
248            limit,
249            page,
250            recv_window,
251        } = params;
252
253        let mut query_params = BTreeMap::new();
254        let body_params = BTreeMap::new();
255
256        if let Some(rw) = limit {
257            query_params.insert("limit".to_string(), json!(rw));
258        }
259
260        if let Some(rw) = page {
261            query_params.insert("page".to_string(), json!(rw));
262        }
263
264        if let Some(rw) = recv_window {
265            query_params.insert("recvWindow".to_string(), json!(rw));
266        }
267
268        send_request::<models::GetNftAssetResponse>(
269            &self.configuration,
270            "/sapi/v1/nft/user/getAsset",
271            reqwest::Method::GET,
272            query_params,
273            body_params,
274            if HAS_TIME_UNIT {
275                self.configuration.time_unit
276            } else {
277                None
278            },
279            true,
280        )
281        .await
282    }
283
284    async fn get_nft_deposit_history(
285        &self,
286        params: GetNftDepositHistoryParams,
287    ) -> anyhow::Result<RestApiResponse<models::GetNftDepositHistoryResponse>> {
288        let GetNftDepositHistoryParams {
289            start_time,
290            end_time,
291            limit,
292            page,
293            recv_window,
294        } = params;
295
296        let mut query_params = BTreeMap::new();
297        let body_params = BTreeMap::new();
298
299        if let Some(rw) = start_time {
300            query_params.insert("startTime".to_string(), json!(rw));
301        }
302
303        if let Some(rw) = end_time {
304            query_params.insert("endTime".to_string(), json!(rw));
305        }
306
307        if let Some(rw) = limit {
308            query_params.insert("limit".to_string(), json!(rw));
309        }
310
311        if let Some(rw) = page {
312            query_params.insert("page".to_string(), json!(rw));
313        }
314
315        if let Some(rw) = recv_window {
316            query_params.insert("recvWindow".to_string(), json!(rw));
317        }
318
319        send_request::<models::GetNftDepositHistoryResponse>(
320            &self.configuration,
321            "/sapi/v1/nft/history/deposit",
322            reqwest::Method::GET,
323            query_params,
324            body_params,
325            if HAS_TIME_UNIT {
326                self.configuration.time_unit
327            } else {
328                None
329            },
330            true,
331        )
332        .await
333    }
334
335    async fn get_nft_transaction_history(
336        &self,
337        params: GetNftTransactionHistoryParams,
338    ) -> anyhow::Result<RestApiResponse<models::GetNftTransactionHistoryResponse>> {
339        let GetNftTransactionHistoryParams {
340            order_type,
341            start_time,
342            end_time,
343            limit,
344            page,
345            recv_window,
346        } = params;
347
348        let mut query_params = BTreeMap::new();
349        let body_params = BTreeMap::new();
350
351        query_params.insert("orderType".to_string(), json!(order_type));
352
353        if let Some(rw) = start_time {
354            query_params.insert("startTime".to_string(), json!(rw));
355        }
356
357        if let Some(rw) = end_time {
358            query_params.insert("endTime".to_string(), json!(rw));
359        }
360
361        if let Some(rw) = limit {
362            query_params.insert("limit".to_string(), json!(rw));
363        }
364
365        if let Some(rw) = page {
366            query_params.insert("page".to_string(), json!(rw));
367        }
368
369        if let Some(rw) = recv_window {
370            query_params.insert("recvWindow".to_string(), json!(rw));
371        }
372
373        send_request::<models::GetNftTransactionHistoryResponse>(
374            &self.configuration,
375            "/sapi/v1/nft/history/transactions",
376            reqwest::Method::GET,
377            query_params,
378            body_params,
379            if HAS_TIME_UNIT {
380                self.configuration.time_unit
381            } else {
382                None
383            },
384            true,
385        )
386        .await
387    }
388
389    async fn get_nft_withdraw_history(
390        &self,
391        params: GetNftWithdrawHistoryParams,
392    ) -> anyhow::Result<RestApiResponse<models::GetNftWithdrawHistoryResponse>> {
393        let GetNftWithdrawHistoryParams {
394            start_time,
395            end_time,
396            limit,
397            page,
398            recv_window,
399        } = params;
400
401        let mut query_params = BTreeMap::new();
402        let body_params = BTreeMap::new();
403
404        if let Some(rw) = start_time {
405            query_params.insert("startTime".to_string(), json!(rw));
406        }
407
408        if let Some(rw) = end_time {
409            query_params.insert("endTime".to_string(), json!(rw));
410        }
411
412        if let Some(rw) = limit {
413            query_params.insert("limit".to_string(), json!(rw));
414        }
415
416        if let Some(rw) = page {
417            query_params.insert("page".to_string(), json!(rw));
418        }
419
420        if let Some(rw) = recv_window {
421            query_params.insert("recvWindow".to_string(), json!(rw));
422        }
423
424        send_request::<models::GetNftWithdrawHistoryResponse>(
425            &self.configuration,
426            "/sapi/v1/nft/history/withdraw",
427            reqwest::Method::GET,
428            query_params,
429            body_params,
430            if HAS_TIME_UNIT {
431                self.configuration.time_unit
432            } else {
433                None
434            },
435            true,
436        )
437        .await
438    }
439}
440
441#[cfg(all(test, feature = "nft"))]
442mod tests {
443    use super::*;
444    use crate::TOKIO_SHARED_RT;
445    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
446    use async_trait::async_trait;
447    use std::collections::HashMap;
448
449    struct DummyRestApiResponse<T> {
450        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
451        status: u16,
452        headers: HashMap<String, String>,
453        rate_limits: Option<Vec<RestApiRateLimit>>,
454    }
455
456    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
457        fn from(dummy: DummyRestApiResponse<T>) -> Self {
458            Self {
459                data_fn: dummy.inner,
460                status: dummy.status,
461                headers: dummy.headers,
462                rate_limits: dummy.rate_limits,
463            }
464        }
465    }
466
467    struct MockNftApiClient {
468        force_error: bool,
469    }
470
471    #[async_trait]
472    impl NftApi for MockNftApiClient {
473        async fn get_nft_asset(
474            &self,
475            _params: GetNftAssetParams,
476        ) -> anyhow::Result<RestApiResponse<models::GetNftAssetResponse>> {
477            if self.force_error {
478                return Err(ConnectorError::ConnectorClientError {
479                    msg: "ResponseError".to_string(),
480                    code: None,
481                }
482                .into());
483            }
484
485            let resp_json: Value = serde_json::from_str(r#"{"total":347,"list":[{"network":"BSC","contractAddress":"REGULAR11234567891779","tokenId":"100900000017"},{"network":"BSC","contractAddress":"SSMDQ8W59","tokenId":"200500000011"},{"network":"BSC","contractAddress":"SSMDQ8W59","tokenId":"200500000019"}]}"#).unwrap();
486            let dummy_response: models::GetNftAssetResponse =
487                serde_json::from_value(resp_json.clone())
488                    .expect("should parse into models::GetNftAssetResponse");
489
490            let dummy = DummyRestApiResponse {
491                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
492                status: 200,
493                headers: HashMap::new(),
494                rate_limits: None,
495            };
496
497            Ok(dummy.into())
498        }
499
500        async fn get_nft_deposit_history(
501            &self,
502            _params: GetNftDepositHistoryParams,
503        ) -> anyhow::Result<RestApiResponse<models::GetNftDepositHistoryResponse>> {
504            if self.force_error {
505                return Err(ConnectorError::ConnectorClientError {
506                    msg: "ResponseError".to_string(),
507                    code: None,
508                }
509                .into());
510            }
511
512            let resp_json: Value = serde_json::from_str(r#"{"total":2,"list":[{"network":"ETH","txID":null,"contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"10014","timestamp":1629986047000},{"network":"BSC","txID":null,"contractAdrress":"0x058451b463bab04f52c0799d55c4094f507acfa9","tokenId":"10016","timestamp":1630083581000}]}"#).unwrap();
513            let dummy_response: models::GetNftDepositHistoryResponse =
514                serde_json::from_value(resp_json.clone())
515                    .expect("should parse into models::GetNftDepositHistoryResponse");
516
517            let dummy = DummyRestApiResponse {
518                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
519                status: 200,
520                headers: HashMap::new(),
521                rate_limits: None,
522            };
523
524            Ok(dummy.into())
525        }
526
527        async fn get_nft_transaction_history(
528            &self,
529            _params: GetNftTransactionHistoryParams,
530        ) -> anyhow::Result<RestApiResponse<models::GetNftTransactionHistoryResponse>> {
531            if self.force_error {
532                return Err(ConnectorError::ConnectorClientError {
533                    msg: "ResponseError".to_string(),
534                    code: None,
535                }
536                .into());
537            }
538
539            let resp_json: Value = serde_json::from_str(r#"{"total":2,"list":[{"orderNo":"1_470502070600699904","tokens":[{"network":"BSC","tokenId":"216000000496","contractAddress":"MYSTERY_BOX0000087"}],"tradeTime":1626941236000,"tradeAmount":"19.60000000","tradeCurrency":"BNB"},{"orderNo":"1_488306442479116288","tokens":[{"network":"BSC","tokenId":"132900000007","contractAddress":"0xAf12111a592e408DAbC740849fcd5e68629D9fb6"}],"tradeTime":1631186130000,"tradeAmount":"192.00000000","tradeCurrency":"BNB"}]}"#).unwrap();
540            let dummy_response: models::GetNftTransactionHistoryResponse =
541                serde_json::from_value(resp_json.clone())
542                    .expect("should parse into models::GetNftTransactionHistoryResponse");
543
544            let dummy = DummyRestApiResponse {
545                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
546                status: 200,
547                headers: HashMap::new(),
548                rate_limits: None,
549            };
550
551            Ok(dummy.into())
552        }
553
554        async fn get_nft_withdraw_history(
555            &self,
556            _params: GetNftWithdrawHistoryParams,
557        ) -> anyhow::Result<RestApiResponse<models::GetNftWithdrawHistoryResponse>> {
558            if self.force_error {
559                return Err(ConnectorError::ConnectorClientError {
560                    msg: "ResponseError".to_string(),
561                    code: None,
562                }
563                .into());
564            }
565
566            let resp_json: Value = serde_json::from_str(r#"{"total":178,"list":[{"network":"ETH","txID":"0x2be5eed31d787fdb4880bc631c8e76bdfb6150e137f5cf1732e0416ea206f57f","contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"1000001247","timestamp":1633674433000,"fee":0.1,"feeAsset":"ETH"},{"network":"ETH","txID":"0x3b3aea5c0a4faccd6f306641e6deb9713ab229ac233be3be227f580311e4362a","contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"40000030","timestamp":1633677022000,"fee":0.1,"feeAsset":"ETH"}]}"#).unwrap();
567            let dummy_response: models::GetNftWithdrawHistoryResponse =
568                serde_json::from_value(resp_json.clone())
569                    .expect("should parse into models::GetNftWithdrawHistoryResponse");
570
571            let dummy = DummyRestApiResponse {
572                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
573                status: 200,
574                headers: HashMap::new(),
575                rate_limits: None,
576            };
577
578            Ok(dummy.into())
579        }
580    }
581
582    #[test]
583    fn get_nft_asset_required_params_success() {
584        TOKIO_SHARED_RT.block_on(async {
585            let client = MockNftApiClient { force_error: false };
586
587            let params = GetNftAssetParams::builder().build().unwrap();
588
589            let resp_json: Value = serde_json::from_str(r#"{"total":347,"list":[{"network":"BSC","contractAddress":"REGULAR11234567891779","tokenId":"100900000017"},{"network":"BSC","contractAddress":"SSMDQ8W59","tokenId":"200500000011"},{"network":"BSC","contractAddress":"SSMDQ8W59","tokenId":"200500000019"}]}"#).unwrap();
590            let expected_response : models::GetNftAssetResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftAssetResponse");
591
592            let resp = client.get_nft_asset(params).await.expect("Expected a response");
593            let data_future = resp.data();
594            let actual_response = data_future.await.unwrap();
595            assert_eq!(actual_response, expected_response);
596        });
597    }
598
599    #[test]
600    fn get_nft_asset_optional_params_success() {
601        TOKIO_SHARED_RT.block_on(async {
602            let client = MockNftApiClient { force_error: false };
603
604            let params = GetNftAssetParams::builder().limit(50).page(1).recv_window(5000).build().unwrap();
605
606            let resp_json: Value = serde_json::from_str(r#"{"total":347,"list":[{"network":"BSC","contractAddress":"REGULAR11234567891779","tokenId":"100900000017"},{"network":"BSC","contractAddress":"SSMDQ8W59","tokenId":"200500000011"},{"network":"BSC","contractAddress":"SSMDQ8W59","tokenId":"200500000019"}]}"#).unwrap();
607            let expected_response : models::GetNftAssetResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftAssetResponse");
608
609            let resp = client.get_nft_asset(params).await.expect("Expected a response");
610            let data_future = resp.data();
611            let actual_response = data_future.await.unwrap();
612            assert_eq!(actual_response, expected_response);
613        });
614    }
615
616    #[test]
617    fn get_nft_asset_response_error() {
618        TOKIO_SHARED_RT.block_on(async {
619            let client = MockNftApiClient { force_error: true };
620
621            let params = GetNftAssetParams::builder().build().unwrap();
622
623            match client.get_nft_asset(params).await {
624                Ok(_) => panic!("Expected an error"),
625                Err(err) => {
626                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
627                }
628            }
629        });
630    }
631
632    #[test]
633    fn get_nft_deposit_history_required_params_success() {
634        TOKIO_SHARED_RT.block_on(async {
635            let client = MockNftApiClient { force_error: false };
636
637            let params = GetNftDepositHistoryParams::builder().build().unwrap();
638
639            let resp_json: Value = serde_json::from_str(r#"{"total":2,"list":[{"network":"ETH","txID":null,"contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"10014","timestamp":1629986047000},{"network":"BSC","txID":null,"contractAdrress":"0x058451b463bab04f52c0799d55c4094f507acfa9","tokenId":"10016","timestamp":1630083581000}]}"#).unwrap();
640            let expected_response : models::GetNftDepositHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftDepositHistoryResponse");
641
642            let resp = client.get_nft_deposit_history(params).await.expect("Expected a response");
643            let data_future = resp.data();
644            let actual_response = data_future.await.unwrap();
645            assert_eq!(actual_response, expected_response);
646        });
647    }
648
649    #[test]
650    fn get_nft_deposit_history_optional_params_success() {
651        TOKIO_SHARED_RT.block_on(async {
652            let client = MockNftApiClient { force_error: false };
653
654            let params = GetNftDepositHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).limit(50).page(1).recv_window(5000).build().unwrap();
655
656            let resp_json: Value = serde_json::from_str(r#"{"total":2,"list":[{"network":"ETH","txID":null,"contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"10014","timestamp":1629986047000},{"network":"BSC","txID":null,"contractAdrress":"0x058451b463bab04f52c0799d55c4094f507acfa9","tokenId":"10016","timestamp":1630083581000}]}"#).unwrap();
657            let expected_response : models::GetNftDepositHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftDepositHistoryResponse");
658
659            let resp = client.get_nft_deposit_history(params).await.expect("Expected a response");
660            let data_future = resp.data();
661            let actual_response = data_future.await.unwrap();
662            assert_eq!(actual_response, expected_response);
663        });
664    }
665
666    #[test]
667    fn get_nft_deposit_history_response_error() {
668        TOKIO_SHARED_RT.block_on(async {
669            let client = MockNftApiClient { force_error: true };
670
671            let params = GetNftDepositHistoryParams::builder().build().unwrap();
672
673            match client.get_nft_deposit_history(params).await {
674                Ok(_) => panic!("Expected an error"),
675                Err(err) => {
676                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
677                }
678            }
679        });
680    }
681
682    #[test]
683    fn get_nft_transaction_history_required_params_success() {
684        TOKIO_SHARED_RT.block_on(async {
685            let client = MockNftApiClient { force_error: false };
686
687            let params = GetNftTransactionHistoryParams::builder(789,).build().unwrap();
688
689            let resp_json: Value = serde_json::from_str(r#"{"total":2,"list":[{"orderNo":"1_470502070600699904","tokens":[{"network":"BSC","tokenId":"216000000496","contractAddress":"MYSTERY_BOX0000087"}],"tradeTime":1626941236000,"tradeAmount":"19.60000000","tradeCurrency":"BNB"},{"orderNo":"1_488306442479116288","tokens":[{"network":"BSC","tokenId":"132900000007","contractAddress":"0xAf12111a592e408DAbC740849fcd5e68629D9fb6"}],"tradeTime":1631186130000,"tradeAmount":"192.00000000","tradeCurrency":"BNB"}]}"#).unwrap();
690            let expected_response : models::GetNftTransactionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftTransactionHistoryResponse");
691
692            let resp = client.get_nft_transaction_history(params).await.expect("Expected a response");
693            let data_future = resp.data();
694            let actual_response = data_future.await.unwrap();
695            assert_eq!(actual_response, expected_response);
696        });
697    }
698
699    #[test]
700    fn get_nft_transaction_history_optional_params_success() {
701        TOKIO_SHARED_RT.block_on(async {
702            let client = MockNftApiClient { force_error: false };
703
704            let params = GetNftTransactionHistoryParams::builder(789,).start_time(1623319461670).end_time(1641782889000).limit(50).page(1).recv_window(5000).build().unwrap();
705
706            let resp_json: Value = serde_json::from_str(r#"{"total":2,"list":[{"orderNo":"1_470502070600699904","tokens":[{"network":"BSC","tokenId":"216000000496","contractAddress":"MYSTERY_BOX0000087"}],"tradeTime":1626941236000,"tradeAmount":"19.60000000","tradeCurrency":"BNB"},{"orderNo":"1_488306442479116288","tokens":[{"network":"BSC","tokenId":"132900000007","contractAddress":"0xAf12111a592e408DAbC740849fcd5e68629D9fb6"}],"tradeTime":1631186130000,"tradeAmount":"192.00000000","tradeCurrency":"BNB"}]}"#).unwrap();
707            let expected_response : models::GetNftTransactionHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftTransactionHistoryResponse");
708
709            let resp = client.get_nft_transaction_history(params).await.expect("Expected a response");
710            let data_future = resp.data();
711            let actual_response = data_future.await.unwrap();
712            assert_eq!(actual_response, expected_response);
713        });
714    }
715
716    #[test]
717    fn get_nft_transaction_history_response_error() {
718        TOKIO_SHARED_RT.block_on(async {
719            let client = MockNftApiClient { force_error: true };
720
721            let params = GetNftTransactionHistoryParams::builder(789)
722                .build()
723                .unwrap();
724
725            match client.get_nft_transaction_history(params).await {
726                Ok(_) => panic!("Expected an error"),
727                Err(err) => {
728                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
729                }
730            }
731        });
732    }
733
734    #[test]
735    fn get_nft_withdraw_history_required_params_success() {
736        TOKIO_SHARED_RT.block_on(async {
737            let client = MockNftApiClient { force_error: false };
738
739            let params = GetNftWithdrawHistoryParams::builder().build().unwrap();
740
741            let resp_json: Value = serde_json::from_str(r#"{"total":178,"list":[{"network":"ETH","txID":"0x2be5eed31d787fdb4880bc631c8e76bdfb6150e137f5cf1732e0416ea206f57f","contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"1000001247","timestamp":1633674433000,"fee":0.1,"feeAsset":"ETH"},{"network":"ETH","txID":"0x3b3aea5c0a4faccd6f306641e6deb9713ab229ac233be3be227f580311e4362a","contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"40000030","timestamp":1633677022000,"fee":0.1,"feeAsset":"ETH"}]}"#).unwrap();
742            let expected_response : models::GetNftWithdrawHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftWithdrawHistoryResponse");
743
744            let resp = client.get_nft_withdraw_history(params).await.expect("Expected a response");
745            let data_future = resp.data();
746            let actual_response = data_future.await.unwrap();
747            assert_eq!(actual_response, expected_response);
748        });
749    }
750
751    #[test]
752    fn get_nft_withdraw_history_optional_params_success() {
753        TOKIO_SHARED_RT.block_on(async {
754            let client = MockNftApiClient { force_error: false };
755
756            let params = GetNftWithdrawHistoryParams::builder().start_time(1623319461670).end_time(1641782889000).limit(50).page(1).recv_window(5000).build().unwrap();
757
758            let resp_json: Value = serde_json::from_str(r#"{"total":178,"list":[{"network":"ETH","txID":"0x2be5eed31d787fdb4880bc631c8e76bdfb6150e137f5cf1732e0416ea206f57f","contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"1000001247","timestamp":1633674433000,"fee":0.1,"feeAsset":"ETH"},{"network":"ETH","txID":"0x3b3aea5c0a4faccd6f306641e6deb9713ab229ac233be3be227f580311e4362a","contractAdrress":"0xe507c961ee127d4439977a61af39c34eafee0dc6","tokenId":"40000030","timestamp":1633677022000,"fee":0.1,"feeAsset":"ETH"}]}"#).unwrap();
759            let expected_response : models::GetNftWithdrawHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetNftWithdrawHistoryResponse");
760
761            let resp = client.get_nft_withdraw_history(params).await.expect("Expected a response");
762            let data_future = resp.data();
763            let actual_response = data_future.await.unwrap();
764            assert_eq!(actual_response, expected_response);
765        });
766    }
767
768    #[test]
769    fn get_nft_withdraw_history_response_error() {
770        TOKIO_SHARED_RT.block_on(async {
771            let client = MockNftApiClient { force_error: true };
772
773            let params = GetNftWithdrawHistoryParams::builder().build().unwrap();
774
775            match client.get_nft_withdraw_history(params).await {
776                Ok(_) => panic!("Expected an error"),
777                Err(err) => {
778                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
779                }
780            }
781        });
782    }
783}