1#![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::wallet::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait AssetApi: Send + Sync {
34 async fn asset_detail(
35 &self,
36 params: AssetDetailParams,
37 ) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>>;
38 async fn asset_dividend_record(
39 &self,
40 params: AssetDividendRecordParams,
41 ) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>>;
42 async fn dust_convert(
43 &self,
44 params: DustConvertParams,
45 ) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>>;
46 async fn dust_convertible_assets(
47 &self,
48 params: DustConvertibleAssetsParams,
49 ) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>>;
50 async fn dust_transfer(
51 &self,
52 params: DustTransferParams,
53 ) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>>;
54 async fn dustlog(
55 &self,
56 params: DustlogParams,
57 ) -> anyhow::Result<RestApiResponse<models::DustlogResponse>>;
58 async fn funding_wallet(
59 &self,
60 params: FundingWalletParams,
61 ) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>>;
62 async fn get_assets_that_can_be_converted_into_bnb(
63 &self,
64 params: GetAssetsThatCanBeConvertedIntoBnbParams,
65 ) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>>;
66 async fn get_cloud_mining_payment_and_refund_history(
67 &self,
68 params: GetCloudMiningPaymentAndRefundHistoryParams,
69 ) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>;
70 async fn get_open_symbol_list(
71 &self,
72 ) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>>;
73 async fn get_spot_asset_tags(
74 &self,
75 params: GetSpotAssetTagsParams,
76 ) -> anyhow::Result<RestApiResponse<Vec<models::GetSpotAssetTagsResponseInner>>>;
77 async fn query_user_delegation_history(
78 &self,
79 params: QueryUserDelegationHistoryParams,
80 ) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>>;
81 async fn query_user_universal_transfer_history(
82 &self,
83 params: QueryUserUniversalTransferHistoryParams,
84 ) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>>;
85 async fn query_user_wallet_balance(
86 &self,
87 params: QueryUserWalletBalanceParams,
88 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>>;
89 async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
90 &self,
91 params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
92 ) -> anyhow::Result<RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>>;
93 async fn trade_fee(
94 &self,
95 params: TradeFeeParams,
96 ) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>>;
97 async fn user_asset(
98 &self,
99 params: UserAssetParams,
100 ) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>>;
101 async fn user_universal_transfer(
102 &self,
103 params: UserUniversalTransferParams,
104 ) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>>;
105}
106
107#[derive(Debug, Clone)]
108pub struct AssetApiClient {
109 configuration: ConfigurationRestApi,
110}
111
112impl AssetApiClient {
113 pub fn new(configuration: ConfigurationRestApi) -> Self {
114 Self { configuration }
115 }
116}
117
118#[allow(non_camel_case_types)]
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub enum DustTransferAccountTypeEnum {
121 #[serde(rename = "SPOT")]
122 Spot,
123 #[serde(rename = "MARGIN")]
124 Margin,
125}
126
127impl DustTransferAccountTypeEnum {
128 #[must_use]
129 pub fn as_str(&self) -> &'static str {
130 match self {
131 Self::Spot => "SPOT",
132 Self::Margin => "MARGIN",
133 }
134 }
135}
136
137impl std::str::FromStr for DustTransferAccountTypeEnum {
138 type Err = Box<dyn std::error::Error + Send + Sync>;
139
140 fn from_str(s: &str) -> Result<Self, Self::Err> {
141 match s {
142 "SPOT" => Ok(Self::Spot),
143 "MARGIN" => Ok(Self::Margin),
144 other => Err(format!("invalid DustTransferAccountTypeEnum: {}", other).into()),
145 }
146 }
147}
148
149#[allow(non_camel_case_types)]
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub enum DustlogAccountTypeEnum {
152 #[serde(rename = "SPOT")]
153 Spot,
154 #[serde(rename = "MARGIN")]
155 Margin,
156}
157
158impl DustlogAccountTypeEnum {
159 #[must_use]
160 pub fn as_str(&self) -> &'static str {
161 match self {
162 Self::Spot => "SPOT",
163 Self::Margin => "MARGIN",
164 }
165 }
166}
167
168impl std::str::FromStr for DustlogAccountTypeEnum {
169 type Err = Box<dyn std::error::Error + Send + Sync>;
170
171 fn from_str(s: &str) -> Result<Self, Self::Err> {
172 match s {
173 "SPOT" => Ok(Self::Spot),
174 "MARGIN" => Ok(Self::Margin),
175 other => Err(format!("invalid DustlogAccountTypeEnum: {}", other).into()),
176 }
177 }
178}
179
180#[allow(non_camel_case_types)]
181#[derive(Debug, Clone, Serialize, Deserialize)]
182pub enum GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
183 #[serde(rename = "SPOT")]
184 Spot,
185 #[serde(rename = "MARGIN")]
186 Margin,
187}
188
189impl GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
190 #[must_use]
191 pub fn as_str(&self) -> &'static str {
192 match self {
193 Self::Spot => "SPOT",
194 Self::Margin => "MARGIN",
195 }
196 }
197}
198
199impl std::str::FromStr for GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
200 type Err = Box<dyn std::error::Error + Send + Sync>;
201
202 fn from_str(s: &str) -> Result<Self, Self::Err> {
203 match s {
204 "SPOT" => Ok(Self::Spot),
205 "MARGIN" => Ok(Self::Margin),
206 other => Err(format!(
207 "invalid GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum: {}",
208 other
209 )
210 .into()),
211 }
212 }
213}
214
215#[allow(non_camel_case_types)]
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub enum QueryUserDelegationHistoryTypeEnum {
218 #[serde(rename = "DELEGATE")]
219 Delegate,
220 #[serde(rename = "UNDELEGATE")]
221 Undelegate,
222}
223
224impl QueryUserDelegationHistoryTypeEnum {
225 #[must_use]
226 pub fn as_str(&self) -> &'static str {
227 match self {
228 Self::Delegate => "DELEGATE",
229 Self::Undelegate => "UNDELEGATE",
230 }
231 }
232}
233
234impl std::str::FromStr for QueryUserDelegationHistoryTypeEnum {
235 type Err = Box<dyn std::error::Error + Send + Sync>;
236
237 fn from_str(s: &str) -> Result<Self, Self::Err> {
238 match s {
239 "DELEGATE" => Ok(Self::Delegate),
240 "UNDELEGATE" => Ok(Self::Undelegate),
241 other => Err(format!("invalid QueryUserDelegationHistoryTypeEnum: {}", other).into()),
242 }
243 }
244}
245
246#[allow(non_camel_case_types)]
247#[derive(Debug, Clone, Serialize, Deserialize)]
248pub enum QueryUserUniversalTransferHistoryFromSymbolEnum {
249 #[serde(rename = "ISOLATEDMARGIN_MARGIN")]
250 IsolatedmarginMargin,
251 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
252 IsolatedmarginIsolatedmargin,
253}
254
255impl QueryUserUniversalTransferHistoryFromSymbolEnum {
256 #[must_use]
257 pub fn as_str(&self) -> &'static str {
258 match self {
259 Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
260 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
261 }
262 }
263}
264
265impl std::str::FromStr for QueryUserUniversalTransferHistoryFromSymbolEnum {
266 type Err = Box<dyn std::error::Error + Send + Sync>;
267
268 fn from_str(s: &str) -> Result<Self, Self::Err> {
269 match s {
270 "ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
271 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
272 other => Err(format!(
273 "invalid QueryUserUniversalTransferHistoryFromSymbolEnum: {}",
274 other
275 )
276 .into()),
277 }
278 }
279}
280
281#[allow(non_camel_case_types)]
282#[derive(Debug, Clone, Serialize, Deserialize)]
283pub enum QueryUserUniversalTransferHistoryToSymbolEnum {
284 #[serde(rename = "MARGIN_ISOLATEDMARGIN")]
285 MarginIsolatedmargin,
286 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
287 IsolatedmarginIsolatedmargin,
288}
289
290impl QueryUserUniversalTransferHistoryToSymbolEnum {
291 #[must_use]
292 pub fn as_str(&self) -> &'static str {
293 match self {
294 Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
295 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
296 }
297 }
298}
299
300impl std::str::FromStr for QueryUserUniversalTransferHistoryToSymbolEnum {
301 type Err = Box<dyn std::error::Error + Send + Sync>;
302
303 fn from_str(s: &str) -> Result<Self, Self::Err> {
304 match s {
305 "MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
306 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
307 other => Err(format!(
308 "invalid QueryUserUniversalTransferHistoryToSymbolEnum: {}",
309 other
310 )
311 .into()),
312 }
313 }
314}
315
316#[allow(non_camel_case_types)]
317#[derive(Debug, Clone, Serialize, Deserialize)]
318pub enum UserUniversalTransferTypeEnum {
319 #[serde(rename = "MAIN_UMFUTURE")]
320 MainUmfuture,
321 #[serde(rename = "MAIN_CMFUTURE")]
322 MainCmfuture,
323 #[serde(rename = "MAIN_MARGIN")]
324 MainMargin,
325 #[serde(rename = "UMFUTURE_MAIN")]
326 UmfutureMain,
327 #[serde(rename = "UMFUTURE_MARGIN")]
328 UmfutureMargin,
329 #[serde(rename = "CMFUTURE_MAIN")]
330 CmfutureMain,
331 #[serde(rename = "CMFUTURE_MARGIN")]
332 CmfutureMargin,
333 #[serde(rename = "MARGIN_MAIN")]
334 MarginMain,
335 #[serde(rename = "MARGIN_UMFUTURE")]
336 MarginUmfuture,
337 #[serde(rename = "MARGIN_CMFUTURE")]
338 MarginCmfuture,
339 #[serde(rename = "ISOLATEDMARGIN_MARGIN")]
340 IsolatedmarginMargin,
341 #[serde(rename = "MARGIN_ISOLATEDMARGIN")]
342 MarginIsolatedmargin,
343 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
344 IsolatedmarginIsolatedmargin,
345 #[serde(rename = "MAIN_FUNDING")]
346 MainFunding,
347 #[serde(rename = "FUNDING_MAIN")]
348 FundingMain,
349 #[serde(rename = "FUNDING_UMFUTURE")]
350 FundingUmfuture,
351 #[serde(rename = "UMFUTURE_FUNDING")]
352 UmfutureFunding,
353 #[serde(rename = "MARGIN_FUNDING")]
354 MarginFunding,
355 #[serde(rename = "FUNDING_MARGIN")]
356 FundingMargin,
357 #[serde(rename = "FUNDING_CMFUTURE")]
358 FundingCmfuture,
359 #[serde(rename = "CMFUTURE_FUNDING")]
360 CmfutureFunding,
361 #[serde(rename = "MAIN_OPTION")]
362 MainOption,
363 #[serde(rename = "OPTION_MAIN")]
364 OptionMain,
365 #[serde(rename = "UMFUTURE_OPTION")]
366 UmfutureOption,
367 #[serde(rename = "OPTION_UMFUTURE")]
368 OptionUmfuture,
369 #[serde(rename = "MARGIN_OPTION")]
370 MarginOption,
371 #[serde(rename = "OPTION_MARGIN")]
372 OptionMargin,
373 #[serde(rename = "FUNDING_OPTION")]
374 FundingOption,
375 #[serde(rename = "OPTION_FUNDING")]
376 OptionFunding,
377 #[serde(rename = "MAIN_PORTFOLIO_MARGIN")]
378 MainPortfolioMargin,
379 #[serde(rename = "PORTFOLIO_MARGIN_MAIN")]
380 PortfolioMarginMain,
381}
382
383impl UserUniversalTransferTypeEnum {
384 #[must_use]
385 pub fn as_str(&self) -> &'static str {
386 match self {
387 Self::MainUmfuture => "MAIN_UMFUTURE",
388 Self::MainCmfuture => "MAIN_CMFUTURE",
389 Self::MainMargin => "MAIN_MARGIN",
390 Self::UmfutureMain => "UMFUTURE_MAIN",
391 Self::UmfutureMargin => "UMFUTURE_MARGIN",
392 Self::CmfutureMain => "CMFUTURE_MAIN",
393 Self::CmfutureMargin => "CMFUTURE_MARGIN",
394 Self::MarginMain => "MARGIN_MAIN",
395 Self::MarginUmfuture => "MARGIN_UMFUTURE",
396 Self::MarginCmfuture => "MARGIN_CMFUTURE",
397 Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
398 Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
399 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
400 Self::MainFunding => "MAIN_FUNDING",
401 Self::FundingMain => "FUNDING_MAIN",
402 Self::FundingUmfuture => "FUNDING_UMFUTURE",
403 Self::UmfutureFunding => "UMFUTURE_FUNDING",
404 Self::MarginFunding => "MARGIN_FUNDING",
405 Self::FundingMargin => "FUNDING_MARGIN",
406 Self::FundingCmfuture => "FUNDING_CMFUTURE",
407 Self::CmfutureFunding => "CMFUTURE_FUNDING",
408 Self::MainOption => "MAIN_OPTION",
409 Self::OptionMain => "OPTION_MAIN",
410 Self::UmfutureOption => "UMFUTURE_OPTION",
411 Self::OptionUmfuture => "OPTION_UMFUTURE",
412 Self::MarginOption => "MARGIN_OPTION",
413 Self::OptionMargin => "OPTION_MARGIN",
414 Self::FundingOption => "FUNDING_OPTION",
415 Self::OptionFunding => "OPTION_FUNDING",
416 Self::MainPortfolioMargin => "MAIN_PORTFOLIO_MARGIN",
417 Self::PortfolioMarginMain => "PORTFOLIO_MARGIN_MAIN",
418 }
419 }
420}
421
422impl std::str::FromStr for UserUniversalTransferTypeEnum {
423 type Err = Box<dyn std::error::Error + Send + Sync>;
424
425 fn from_str(s: &str) -> Result<Self, Self::Err> {
426 match s {
427 "MAIN_UMFUTURE" => Ok(Self::MainUmfuture),
428 "MAIN_CMFUTURE" => Ok(Self::MainCmfuture),
429 "MAIN_MARGIN" => Ok(Self::MainMargin),
430 "UMFUTURE_MAIN" => Ok(Self::UmfutureMain),
431 "UMFUTURE_MARGIN" => Ok(Self::UmfutureMargin),
432 "CMFUTURE_MAIN" => Ok(Self::CmfutureMain),
433 "CMFUTURE_MARGIN" => Ok(Self::CmfutureMargin),
434 "MARGIN_MAIN" => Ok(Self::MarginMain),
435 "MARGIN_UMFUTURE" => Ok(Self::MarginUmfuture),
436 "MARGIN_CMFUTURE" => Ok(Self::MarginCmfuture),
437 "ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
438 "MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
439 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
440 "MAIN_FUNDING" => Ok(Self::MainFunding),
441 "FUNDING_MAIN" => Ok(Self::FundingMain),
442 "FUNDING_UMFUTURE" => Ok(Self::FundingUmfuture),
443 "UMFUTURE_FUNDING" => Ok(Self::UmfutureFunding),
444 "MARGIN_FUNDING" => Ok(Self::MarginFunding),
445 "FUNDING_MARGIN" => Ok(Self::FundingMargin),
446 "FUNDING_CMFUTURE" => Ok(Self::FundingCmfuture),
447 "CMFUTURE_FUNDING" => Ok(Self::CmfutureFunding),
448 "MAIN_OPTION" => Ok(Self::MainOption),
449 "OPTION_MAIN" => Ok(Self::OptionMain),
450 "UMFUTURE_OPTION" => Ok(Self::UmfutureOption),
451 "OPTION_UMFUTURE" => Ok(Self::OptionUmfuture),
452 "MARGIN_OPTION" => Ok(Self::MarginOption),
453 "OPTION_MARGIN" => Ok(Self::OptionMargin),
454 "FUNDING_OPTION" => Ok(Self::FundingOption),
455 "OPTION_FUNDING" => Ok(Self::OptionFunding),
456 "MAIN_PORTFOLIO_MARGIN" => Ok(Self::MainPortfolioMargin),
457 "PORTFOLIO_MARGIN_MAIN" => Ok(Self::PortfolioMarginMain),
458 other => Err(format!("invalid UserUniversalTransferTypeEnum: {}", other).into()),
459 }
460 }
461}
462
463#[allow(non_camel_case_types)]
464#[derive(Debug, Clone, Serialize, Deserialize)]
465pub enum UserUniversalTransferFromSymbolEnum {
466 #[serde(rename = "ISOLATEDMARGIN_MARGIN")]
467 IsolatedmarginMargin,
468 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
469 IsolatedmarginIsolatedmargin,
470}
471
472impl UserUniversalTransferFromSymbolEnum {
473 #[must_use]
474 pub fn as_str(&self) -> &'static str {
475 match self {
476 Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
477 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
478 }
479 }
480}
481
482impl std::str::FromStr for UserUniversalTransferFromSymbolEnum {
483 type Err = Box<dyn std::error::Error + Send + Sync>;
484
485 fn from_str(s: &str) -> Result<Self, Self::Err> {
486 match s {
487 "ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
488 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
489 other => Err(format!("invalid UserUniversalTransferFromSymbolEnum: {}", other).into()),
490 }
491 }
492}
493
494#[allow(non_camel_case_types)]
495#[derive(Debug, Clone, Serialize, Deserialize)]
496pub enum UserUniversalTransferToSymbolEnum {
497 #[serde(rename = "MARGIN_ISOLATEDMARGIN")]
498 MarginIsolatedmargin,
499 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
500 IsolatedmarginIsolatedmargin,
501}
502
503impl UserUniversalTransferToSymbolEnum {
504 #[must_use]
505 pub fn as_str(&self) -> &'static str {
506 match self {
507 Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
508 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
509 }
510 }
511}
512
513impl std::str::FromStr for UserUniversalTransferToSymbolEnum {
514 type Err = Box<dyn std::error::Error + Send + Sync>;
515
516 fn from_str(s: &str) -> Result<Self, Self::Err> {
517 match s {
518 "MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
519 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
520 other => Err(format!("invalid UserUniversalTransferToSymbolEnum: {}", other).into()),
521 }
522 }
523}
524
525#[derive(Clone, Debug, Builder, Deserialize, Default)]
530#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
531pub struct AssetDetailParams {
532 #[builder(setter(into), default)]
537 #[serde(rename = "asset", default)]
538 pub asset: Option<String>,
539 #[builder(setter(into), default)]
544 #[serde(rename = "recvWindow", default)]
545 pub recv_window: Option<i64>,
546}
547
548impl AssetDetailParams {
549 #[must_use]
552 pub fn builder() -> AssetDetailParamsBuilder {
553 AssetDetailParamsBuilder::default()
554 }
555}
556#[derive(Clone, Debug, Builder, Deserialize, Default)]
561#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
562pub struct AssetDividendRecordParams {
563 #[builder(setter(into), default)]
568 #[serde(rename = "asset", default)]
569 pub asset: Option<String>,
570 #[builder(setter(into), default)]
575 #[serde(rename = "startTime", default)]
576 pub start_time: Option<i64>,
577 #[builder(setter(into), default)]
582 #[serde(rename = "endTime", default)]
583 pub end_time: Option<i64>,
584 #[builder(setter(into), default)]
589 #[serde(rename = "limit", default)]
590 pub limit: Option<i64>,
591 #[builder(setter(into), default)]
596 #[serde(rename = "recvWindow", default)]
597 pub recv_window: Option<i64>,
598}
599
600impl AssetDividendRecordParams {
601 #[must_use]
604 pub fn builder() -> AssetDividendRecordParamsBuilder {
605 AssetDividendRecordParamsBuilder::default()
606 }
607}
608#[derive(Clone, Debug, Builder, Deserialize)]
613#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
614pub struct DustConvertParams {
615 #[builder(setter(into))]
620 #[serde(rename = "asset")]
621 pub asset: String,
622 #[builder(setter(into), default)]
626 #[serde(rename = "accountType", default)]
627 pub account_type: Option<String>,
628 #[builder(setter(into), default)]
632 #[serde(rename = "clientId", default)]
633 pub client_id: Option<String>,
634 #[builder(setter(into), default)]
639 #[serde(rename = "targetAsset", default)]
640 pub target_asset: Option<String>,
641 #[builder(setter(into), default)]
646 #[serde(rename = "thirdPartyClientId", default)]
647 pub third_party_client_id: Option<String>,
648 #[builder(setter(into), default)]
653 #[serde(rename = "dustQuotaAssetToTargetAssetPrice", default)]
654 pub dust_quota_asset_to_target_asset_price: Option<rust_decimal::Decimal>,
655}
656
657impl DustConvertParams {
658 #[must_use]
665 pub fn builder(asset: String) -> DustConvertParamsBuilder {
666 DustConvertParamsBuilder::default().asset(asset)
667 }
668}
669#[derive(Clone, Debug, Builder, Deserialize)]
674#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
675pub struct DustConvertibleAssetsParams {
676 #[builder(setter(into))]
681 #[serde(rename = "targetAsset")]
682 pub target_asset: String,
683 #[builder(setter(into), default)]
687 #[serde(rename = "accountType", default)]
688 pub account_type: Option<String>,
689 #[builder(setter(into), default)]
694 #[serde(rename = "dustQuotaAssetToTargetAssetPrice", default)]
695 pub dust_quota_asset_to_target_asset_price: Option<rust_decimal::Decimal>,
696}
697
698impl DustConvertibleAssetsParams {
699 #[must_use]
706 pub fn builder(target_asset: String) -> DustConvertibleAssetsParamsBuilder {
707 DustConvertibleAssetsParamsBuilder::default().target_asset(target_asset)
708 }
709}
710#[derive(Clone, Debug, Builder, Deserialize)]
715#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
716pub struct DustTransferParams {
717 #[builder(setter(into))]
721 #[serde(rename = "asset")]
722 pub asset: String,
723 #[builder(setter(into), default)]
728 #[serde(rename = "accountType", default)]
729 pub account_type: Option<DustTransferAccountTypeEnum>,
730 #[builder(setter(into), default)]
735 #[serde(rename = "recvWindow", default)]
736 pub recv_window: Option<i64>,
737}
738
739impl DustTransferParams {
740 #[must_use]
747 pub fn builder(asset: String) -> DustTransferParamsBuilder {
748 DustTransferParamsBuilder::default().asset(asset)
749 }
750}
751#[derive(Clone, Debug, Builder, Deserialize, Default)]
756#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
757pub struct DustlogParams {
758 #[builder(setter(into), default)]
763 #[serde(rename = "accountType", default)]
764 pub account_type: Option<DustlogAccountTypeEnum>,
765 #[builder(setter(into), default)]
770 #[serde(rename = "startTime", default)]
771 pub start_time: Option<i64>,
772 #[builder(setter(into), default)]
777 #[serde(rename = "endTime", default)]
778 pub end_time: Option<i64>,
779 #[builder(setter(into), default)]
784 #[serde(rename = "recvWindow", default)]
785 pub recv_window: Option<i64>,
786}
787
788impl DustlogParams {
789 #[must_use]
792 pub fn builder() -> DustlogParamsBuilder {
793 DustlogParamsBuilder::default()
794 }
795}
796#[derive(Clone, Debug, Builder, Deserialize, Default)]
801#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
802pub struct FundingWalletParams {
803 #[builder(setter(into), default)]
808 #[serde(rename = "asset", default)]
809 pub asset: Option<String>,
810 #[builder(setter(into), default)]
815 #[serde(rename = "needBtcValuation", default)]
816 pub need_btc_valuation: Option<bool>,
817 #[builder(setter(into), default)]
822 #[serde(rename = "recvWindow", default)]
823 pub recv_window: Option<i64>,
824}
825
826impl FundingWalletParams {
827 #[must_use]
830 pub fn builder() -> FundingWalletParamsBuilder {
831 FundingWalletParamsBuilder::default()
832 }
833}
834#[derive(Clone, Debug, Builder, Deserialize, Default)]
839#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
840pub struct GetAssetsThatCanBeConvertedIntoBnbParams {
841 #[builder(setter(into), default)]
846 #[serde(rename = "accountType", default)]
847 pub account_type: Option<GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum>,
848 #[builder(setter(into), default)]
853 #[serde(rename = "recvWindow", default)]
854 pub recv_window: Option<i64>,
855}
856
857impl GetAssetsThatCanBeConvertedIntoBnbParams {
858 #[must_use]
861 pub fn builder() -> GetAssetsThatCanBeConvertedIntoBnbParamsBuilder {
862 GetAssetsThatCanBeConvertedIntoBnbParamsBuilder::default()
863 }
864}
865#[derive(Clone, Debug, Builder, Deserialize)]
870#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
871pub struct GetCloudMiningPaymentAndRefundHistoryParams {
872 #[builder(setter(into))]
876 #[serde(rename = "startTime")]
877 pub start_time: i64,
878 #[builder(setter(into))]
882 #[serde(rename = "endTime")]
883 pub end_time: i64,
884 #[builder(setter(into), default)]
888 #[serde(rename = "tranId", default)]
889 pub tran_id: Option<i64>,
890 #[builder(setter(into), default)]
894 #[serde(rename = "clientTranId", default)]
895 pub client_tran_id: Option<String>,
896 #[builder(setter(into), default)]
900 #[serde(rename = "asset", default)]
901 pub asset: Option<String>,
902 #[builder(setter(into), default)]
907 #[serde(rename = "current", default)]
908 pub current: Option<i64>,
909 #[builder(setter(into), default)]
914 #[serde(rename = "size", default)]
915 pub size: Option<i64>,
916}
917
918impl GetCloudMiningPaymentAndRefundHistoryParams {
919 #[must_use]
927 pub fn builder(
928 start_time: i64,
929 end_time: i64,
930 ) -> GetCloudMiningPaymentAndRefundHistoryParamsBuilder {
931 GetCloudMiningPaymentAndRefundHistoryParamsBuilder::default()
932 .start_time(start_time)
933 .end_time(end_time)
934 }
935}
936#[derive(Clone, Debug, Builder, Deserialize, Default)]
941#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
942pub struct GetSpotAssetTagsParams {
943 #[builder(setter(into), default)]
947 #[serde(rename = "tag", default)]
948 pub tag: Option<String>,
949}
950
951impl GetSpotAssetTagsParams {
952 #[must_use]
955 pub fn builder() -> GetSpotAssetTagsParamsBuilder {
956 GetSpotAssetTagsParamsBuilder::default()
957 }
958}
959#[derive(Clone, Debug, Builder, Deserialize)]
964#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
965pub struct QueryUserDelegationHistoryParams {
966 #[builder(setter(into))]
971 #[serde(rename = "email")]
972 pub email: String,
973 #[builder(setter(into))]
978 #[serde(rename = "startTime")]
979 pub start_time: i64,
980 #[builder(setter(into))]
985 #[serde(rename = "endTime")]
986 pub end_time: i64,
987 #[builder(setter(into), default)]
992 #[serde(rename = "type", default)]
993 pub r#type: Option<QueryUserDelegationHistoryTypeEnum>,
994 #[builder(setter(into), default)]
999 #[serde(rename = "asset", default)]
1000 pub asset: Option<String>,
1001 #[builder(setter(into), default)]
1006 #[serde(rename = "current", default)]
1007 pub current: Option<i64>,
1008 #[builder(setter(into), default)]
1013 #[serde(rename = "size", default)]
1014 pub size: Option<i64>,
1015 #[builder(setter(into), default)]
1020 #[serde(rename = "recvWindow", default)]
1021 pub recv_window: Option<i64>,
1022}
1023
1024impl QueryUserDelegationHistoryParams {
1025 #[must_use]
1034 pub fn builder(
1035 email: String,
1036 start_time: i64,
1037 end_time: i64,
1038 ) -> QueryUserDelegationHistoryParamsBuilder {
1039 QueryUserDelegationHistoryParamsBuilder::default()
1040 .email(email)
1041 .start_time(start_time)
1042 .end_time(end_time)
1043 }
1044}
1045#[derive(Clone, Debug, Builder, Deserialize)]
1050#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1051pub struct QueryUserUniversalTransferHistoryParams {
1052 #[builder(setter(into))]
1057 #[serde(rename = "type")]
1058 pub r#type: String,
1059 #[builder(setter(into), default)]
1064 #[serde(rename = "startTime", default)]
1065 pub start_time: Option<i64>,
1066 #[builder(setter(into), default)]
1071 #[serde(rename = "endTime", default)]
1072 pub end_time: Option<i64>,
1073 #[builder(setter(into), default)]
1078 #[serde(rename = "current", default)]
1079 pub current: Option<i64>,
1080 #[builder(setter(into), default)]
1085 #[serde(rename = "size", default)]
1086 pub size: Option<i64>,
1087 #[builder(setter(into), default)]
1092 #[serde(rename = "fromSymbol", default)]
1093 pub from_symbol: Option<QueryUserUniversalTransferHistoryFromSymbolEnum>,
1094 #[builder(setter(into), default)]
1099 #[serde(rename = "toSymbol", default)]
1100 pub to_symbol: Option<QueryUserUniversalTransferHistoryToSymbolEnum>,
1101 #[builder(setter(into), default)]
1106 #[serde(rename = "recvWindow", default)]
1107 pub recv_window: Option<i64>,
1108}
1109
1110impl QueryUserUniversalTransferHistoryParams {
1111 #[must_use]
1118 pub fn builder(r#type: String) -> QueryUserUniversalTransferHistoryParamsBuilder {
1119 QueryUserUniversalTransferHistoryParamsBuilder::default().r#type(r#type)
1120 }
1121}
1122#[derive(Clone, Debug, Builder, Deserialize, Default)]
1127#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1128pub struct QueryUserWalletBalanceParams {
1129 #[builder(setter(into), default)]
1134 #[serde(rename = "quoteAsset", default)]
1135 pub quote_asset: Option<String>,
1136 #[builder(setter(into), default)]
1141 #[serde(rename = "needBalanceDetail", default)]
1142 pub need_balance_detail: Option<bool>,
1143 #[builder(setter(into), default)]
1148 #[serde(rename = "recvWindow", default)]
1149 pub recv_window: Option<i64>,
1150}
1151
1152impl QueryUserWalletBalanceParams {
1153 #[must_use]
1156 pub fn builder() -> QueryUserWalletBalanceParamsBuilder {
1157 QueryUserWalletBalanceParamsBuilder::default()
1158 }
1159}
1160#[derive(Clone, Debug, Builder, Deserialize, Default)]
1165#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1166pub struct ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
1167 #[builder(setter(into), default)]
1171 #[serde(rename = "spotBNBBurn", default)]
1172 pub spot_bnb_burn: Option<String>,
1173 #[builder(setter(into), default)]
1177 #[serde(rename = "interestBNBBurn", default)]
1178 pub interest_bnb_burn: Option<String>,
1179 #[builder(setter(into), default)]
1184 #[serde(rename = "recvWindow", default)]
1185 pub recv_window: Option<i64>,
1186}
1187
1188impl ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
1189 #[must_use]
1192 pub fn builder() -> ToggleBnbBurnOnSpotTradeAndMarginInterestParamsBuilder {
1193 ToggleBnbBurnOnSpotTradeAndMarginInterestParamsBuilder::default()
1194 }
1195}
1196#[derive(Clone, Debug, Builder, Deserialize, Default)]
1201#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1202pub struct TradeFeeParams {
1203 #[builder(setter(into), default)]
1208 #[serde(rename = "symbol", default)]
1209 pub symbol: Option<String>,
1210 #[builder(setter(into), default)]
1215 #[serde(rename = "recvWindow", default)]
1216 pub recv_window: Option<i64>,
1217}
1218
1219impl TradeFeeParams {
1220 #[must_use]
1223 pub fn builder() -> TradeFeeParamsBuilder {
1224 TradeFeeParamsBuilder::default()
1225 }
1226}
1227#[derive(Clone, Debug, Builder, Deserialize, Default)]
1232#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1233pub struct UserAssetParams {
1234 #[builder(setter(into), default)]
1238 #[serde(rename = "asset", default)]
1239 pub asset: Option<String>,
1240 #[builder(setter(into), default)]
1244 #[serde(rename = "needBtcValuation", default)]
1245 pub need_btc_valuation: Option<bool>,
1246 #[builder(setter(into), default)]
1251 #[serde(rename = "recvWindow", default)]
1252 pub recv_window: Option<i64>,
1253}
1254
1255impl UserAssetParams {
1256 #[must_use]
1259 pub fn builder() -> UserAssetParamsBuilder {
1260 UserAssetParamsBuilder::default()
1261 }
1262}
1263#[derive(Clone, Debug, Builder, Deserialize)]
1268#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1269pub struct UserUniversalTransferParams {
1270 #[builder(setter(into))]
1275 #[serde(rename = "type")]
1276 pub r#type: UserUniversalTransferTypeEnum,
1277 #[builder(setter(into))]
1282 #[serde(rename = "asset")]
1283 pub asset: String,
1284 #[builder(setter(into))]
1289 #[serde(rename = "amount")]
1290 pub amount: rust_decimal::Decimal,
1291 #[builder(setter(into), default)]
1296 #[serde(rename = "fromSymbol", default)]
1297 pub from_symbol: Option<UserUniversalTransferFromSymbolEnum>,
1298 #[builder(setter(into), default)]
1303 #[serde(rename = "toSymbol", default)]
1304 pub to_symbol: Option<UserUniversalTransferToSymbolEnum>,
1305 #[builder(setter(into), default)]
1310 #[serde(rename = "recvWindow", default)]
1311 pub recv_window: Option<i64>,
1312}
1313
1314impl UserUniversalTransferParams {
1315 #[must_use]
1324 pub fn builder(
1325 r#type: UserUniversalTransferTypeEnum,
1326 asset: String,
1327 amount: rust_decimal::Decimal,
1328 ) -> UserUniversalTransferParamsBuilder {
1329 UserUniversalTransferParamsBuilder::default()
1330 .r#type(r#type)
1331 .asset(asset)
1332 .amount(amount)
1333 }
1334}
1335
1336#[async_trait]
1337impl AssetApi for AssetApiClient {
1338 async fn asset_detail(
1339 &self,
1340 params: AssetDetailParams,
1341 ) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>> {
1342 let AssetDetailParams { asset, recv_window } = params;
1343
1344 let mut query_params = BTreeMap::new();
1345 let body_params = BTreeMap::new();
1346
1347 if let Some(rw) = asset {
1348 query_params.insert("asset".to_string(), json!(rw));
1349 }
1350
1351 if let Some(rw) = recv_window {
1352 query_params.insert("recvWindow".to_string(), json!(rw));
1353 }
1354
1355 send_request::<models::AssetDetailResponse>(
1356 &self.configuration,
1357 "/sapi/v1/asset/assetDetail",
1358 reqwest::Method::GET,
1359 query_params,
1360 body_params,
1361 if HAS_TIME_UNIT {
1362 self.configuration.time_unit
1363 } else {
1364 None
1365 },
1366 true,
1367 )
1368 .await
1369 }
1370
1371 async fn asset_dividend_record(
1372 &self,
1373 params: AssetDividendRecordParams,
1374 ) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>> {
1375 let AssetDividendRecordParams {
1376 asset,
1377 start_time,
1378 end_time,
1379 limit,
1380 recv_window,
1381 } = params;
1382
1383 let mut query_params = BTreeMap::new();
1384 let body_params = BTreeMap::new();
1385
1386 if let Some(rw) = asset {
1387 query_params.insert("asset".to_string(), json!(rw));
1388 }
1389
1390 if let Some(rw) = start_time {
1391 query_params.insert("startTime".to_string(), json!(rw));
1392 }
1393
1394 if let Some(rw) = end_time {
1395 query_params.insert("endTime".to_string(), json!(rw));
1396 }
1397
1398 if let Some(rw) = limit {
1399 query_params.insert("limit".to_string(), json!(rw));
1400 }
1401
1402 if let Some(rw) = recv_window {
1403 query_params.insert("recvWindow".to_string(), json!(rw));
1404 }
1405
1406 send_request::<models::AssetDividendRecordResponse>(
1407 &self.configuration,
1408 "/sapi/v1/asset/assetDividend",
1409 reqwest::Method::GET,
1410 query_params,
1411 body_params,
1412 if HAS_TIME_UNIT {
1413 self.configuration.time_unit
1414 } else {
1415 None
1416 },
1417 true,
1418 )
1419 .await
1420 }
1421
1422 async fn dust_convert(
1423 &self,
1424 params: DustConvertParams,
1425 ) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>> {
1426 let DustConvertParams {
1427 asset,
1428 account_type,
1429 client_id,
1430 target_asset,
1431 third_party_client_id,
1432 dust_quota_asset_to_target_asset_price,
1433 } = params;
1434
1435 let mut query_params = BTreeMap::new();
1436 let body_params = BTreeMap::new();
1437
1438 query_params.insert("asset".to_string(), json!(asset));
1439
1440 if let Some(rw) = account_type {
1441 query_params.insert("accountType".to_string(), json!(rw));
1442 }
1443
1444 if let Some(rw) = client_id {
1445 query_params.insert("clientId".to_string(), json!(rw));
1446 }
1447
1448 if let Some(rw) = target_asset {
1449 query_params.insert("targetAsset".to_string(), json!(rw));
1450 }
1451
1452 if let Some(rw) = third_party_client_id {
1453 query_params.insert("thirdPartyClientId".to_string(), json!(rw));
1454 }
1455
1456 if let Some(rw) = dust_quota_asset_to_target_asset_price {
1457 query_params.insert("dustQuotaAssetToTargetAssetPrice".to_string(), json!(rw));
1458 }
1459
1460 send_request::<models::DustConvertResponse>(
1461 &self.configuration,
1462 "/sapi/v1/asset/dust-convert/convert",
1463 reqwest::Method::POST,
1464 query_params,
1465 body_params,
1466 if HAS_TIME_UNIT {
1467 self.configuration.time_unit
1468 } else {
1469 None
1470 },
1471 true,
1472 )
1473 .await
1474 }
1475
1476 async fn dust_convertible_assets(
1477 &self,
1478 params: DustConvertibleAssetsParams,
1479 ) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>> {
1480 let DustConvertibleAssetsParams {
1481 target_asset,
1482 account_type,
1483 dust_quota_asset_to_target_asset_price,
1484 } = params;
1485
1486 let mut query_params = BTreeMap::new();
1487 let body_params = BTreeMap::new();
1488
1489 if let Some(rw) = account_type {
1490 query_params.insert("accountType".to_string(), json!(rw));
1491 }
1492
1493 query_params.insert("targetAsset".to_string(), json!(target_asset));
1494
1495 if let Some(rw) = dust_quota_asset_to_target_asset_price {
1496 query_params.insert("dustQuotaAssetToTargetAssetPrice".to_string(), json!(rw));
1497 }
1498
1499 send_request::<models::DustConvertibleAssetsResponse>(
1500 &self.configuration,
1501 "/sapi/v1/asset/dust-convert/query-convertible-assets",
1502 reqwest::Method::POST,
1503 query_params,
1504 body_params,
1505 if HAS_TIME_UNIT {
1506 self.configuration.time_unit
1507 } else {
1508 None
1509 },
1510 true,
1511 )
1512 .await
1513 }
1514
1515 async fn dust_transfer(
1516 &self,
1517 params: DustTransferParams,
1518 ) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>> {
1519 let DustTransferParams {
1520 asset,
1521 account_type,
1522 recv_window,
1523 } = params;
1524
1525 let mut query_params = BTreeMap::new();
1526 let body_params = BTreeMap::new();
1527
1528 query_params.insert("asset".to_string(), json!(asset));
1529
1530 if let Some(rw) = account_type {
1531 query_params.insert("accountType".to_string(), json!(rw));
1532 }
1533
1534 if let Some(rw) = recv_window {
1535 query_params.insert("recvWindow".to_string(), json!(rw));
1536 }
1537
1538 send_request::<models::DustTransferResponse>(
1539 &self.configuration,
1540 "/sapi/v1/asset/dust",
1541 reqwest::Method::POST,
1542 query_params,
1543 body_params,
1544 if HAS_TIME_UNIT {
1545 self.configuration.time_unit
1546 } else {
1547 None
1548 },
1549 true,
1550 )
1551 .await
1552 }
1553
1554 async fn dustlog(
1555 &self,
1556 params: DustlogParams,
1557 ) -> anyhow::Result<RestApiResponse<models::DustlogResponse>> {
1558 let DustlogParams {
1559 account_type,
1560 start_time,
1561 end_time,
1562 recv_window,
1563 } = params;
1564
1565 let mut query_params = BTreeMap::new();
1566 let body_params = BTreeMap::new();
1567
1568 if let Some(rw) = account_type {
1569 query_params.insert("accountType".to_string(), json!(rw));
1570 }
1571
1572 if let Some(rw) = start_time {
1573 query_params.insert("startTime".to_string(), json!(rw));
1574 }
1575
1576 if let Some(rw) = end_time {
1577 query_params.insert("endTime".to_string(), json!(rw));
1578 }
1579
1580 if let Some(rw) = recv_window {
1581 query_params.insert("recvWindow".to_string(), json!(rw));
1582 }
1583
1584 send_request::<models::DustlogResponse>(
1585 &self.configuration,
1586 "/sapi/v1/asset/dribblet",
1587 reqwest::Method::GET,
1588 query_params,
1589 body_params,
1590 if HAS_TIME_UNIT {
1591 self.configuration.time_unit
1592 } else {
1593 None
1594 },
1595 true,
1596 )
1597 .await
1598 }
1599
1600 async fn funding_wallet(
1601 &self,
1602 params: FundingWalletParams,
1603 ) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>> {
1604 let FundingWalletParams {
1605 asset,
1606 need_btc_valuation,
1607 recv_window,
1608 } = params;
1609
1610 let mut query_params = BTreeMap::new();
1611 let body_params = BTreeMap::new();
1612
1613 if let Some(rw) = asset {
1614 query_params.insert("asset".to_string(), json!(rw));
1615 }
1616
1617 if let Some(rw) = need_btc_valuation {
1618 query_params.insert("needBtcValuation".to_string(), json!(rw));
1619 }
1620
1621 if let Some(rw) = recv_window {
1622 query_params.insert("recvWindow".to_string(), json!(rw));
1623 }
1624
1625 send_request::<Vec<models::FundingWalletResponseInner>>(
1626 &self.configuration,
1627 "/sapi/v1/asset/get-funding-asset",
1628 reqwest::Method::POST,
1629 query_params,
1630 body_params,
1631 if HAS_TIME_UNIT {
1632 self.configuration.time_unit
1633 } else {
1634 None
1635 },
1636 true,
1637 )
1638 .await
1639 }
1640
1641 async fn get_assets_that_can_be_converted_into_bnb(
1642 &self,
1643 params: GetAssetsThatCanBeConvertedIntoBnbParams,
1644 ) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>> {
1645 let GetAssetsThatCanBeConvertedIntoBnbParams {
1646 account_type,
1647 recv_window,
1648 } = params;
1649
1650 let mut query_params = BTreeMap::new();
1651 let body_params = BTreeMap::new();
1652
1653 if let Some(rw) = account_type {
1654 query_params.insert("accountType".to_string(), json!(rw));
1655 }
1656
1657 if let Some(rw) = recv_window {
1658 query_params.insert("recvWindow".to_string(), json!(rw));
1659 }
1660
1661 send_request::<models::GetAssetsThatCanBeConvertedIntoBnbResponse>(
1662 &self.configuration,
1663 "/sapi/v1/asset/dust-btc",
1664 reqwest::Method::POST,
1665 query_params,
1666 body_params,
1667 if HAS_TIME_UNIT {
1668 self.configuration.time_unit
1669 } else {
1670 None
1671 },
1672 true,
1673 )
1674 .await
1675 }
1676
1677 async fn get_cloud_mining_payment_and_refund_history(
1678 &self,
1679 params: GetCloudMiningPaymentAndRefundHistoryParams,
1680 ) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>
1681 {
1682 let GetCloudMiningPaymentAndRefundHistoryParams {
1683 start_time,
1684 end_time,
1685 tran_id,
1686 client_tran_id,
1687 asset,
1688 current,
1689 size,
1690 } = params;
1691
1692 let mut query_params = BTreeMap::new();
1693 let body_params = BTreeMap::new();
1694
1695 if let Some(rw) = tran_id {
1696 query_params.insert("tranId".to_string(), json!(rw));
1697 }
1698
1699 if let Some(rw) = client_tran_id {
1700 query_params.insert("clientTranId".to_string(), json!(rw));
1701 }
1702
1703 if let Some(rw) = asset {
1704 query_params.insert("asset".to_string(), json!(rw));
1705 }
1706
1707 query_params.insert("startTime".to_string(), json!(start_time));
1708
1709 query_params.insert("endTime".to_string(), json!(end_time));
1710
1711 if let Some(rw) = current {
1712 query_params.insert("current".to_string(), json!(rw));
1713 }
1714
1715 if let Some(rw) = size {
1716 query_params.insert("size".to_string(), json!(rw));
1717 }
1718
1719 send_request::<models::GetCloudMiningPaymentAndRefundHistoryResponse>(
1720 &self.configuration,
1721 "/sapi/v1/asset/ledger-transfer/cloud-mining/queryByPage",
1722 reqwest::Method::GET,
1723 query_params,
1724 body_params,
1725 if HAS_TIME_UNIT {
1726 self.configuration.time_unit
1727 } else {
1728 None
1729 },
1730 true,
1731 )
1732 .await
1733 }
1734
1735 async fn get_open_symbol_list(
1736 &self,
1737 ) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>> {
1738 let query_params = BTreeMap::new();
1739 let body_params = BTreeMap::new();
1740
1741 send_request::<Vec<models::GetOpenSymbolListResponseInner>>(
1742 &self.configuration,
1743 "/sapi/v1/spot/open-symbol-list",
1744 reqwest::Method::GET,
1745 query_params,
1746 body_params,
1747 if HAS_TIME_UNIT {
1748 self.configuration.time_unit
1749 } else {
1750 None
1751 },
1752 false,
1753 )
1754 .await
1755 }
1756
1757 async fn get_spot_asset_tags(
1758 &self,
1759 params: GetSpotAssetTagsParams,
1760 ) -> anyhow::Result<RestApiResponse<Vec<models::GetSpotAssetTagsResponseInner>>> {
1761 let GetSpotAssetTagsParams { tag } = params;
1762
1763 let mut query_params = BTreeMap::new();
1764 let body_params = BTreeMap::new();
1765
1766 if let Some(rw) = tag {
1767 query_params.insert("tag".to_string(), json!(rw));
1768 }
1769
1770 send_request::<Vec<models::GetSpotAssetTagsResponseInner>>(
1771 &self.configuration,
1772 "/sapi/v1/spot/asset/tags",
1773 reqwest::Method::GET,
1774 query_params,
1775 body_params,
1776 if HAS_TIME_UNIT {
1777 self.configuration.time_unit
1778 } else {
1779 None
1780 },
1781 false,
1782 )
1783 .await
1784 }
1785
1786 async fn query_user_delegation_history(
1787 &self,
1788 params: QueryUserDelegationHistoryParams,
1789 ) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>> {
1790 let QueryUserDelegationHistoryParams {
1791 email,
1792 start_time,
1793 end_time,
1794 r#type,
1795 asset,
1796 current,
1797 size,
1798 recv_window,
1799 } = params;
1800
1801 let mut query_params = BTreeMap::new();
1802 let body_params = BTreeMap::new();
1803
1804 query_params.insert("email".to_string(), json!(email));
1805
1806 query_params.insert("startTime".to_string(), json!(start_time));
1807
1808 query_params.insert("endTime".to_string(), json!(end_time));
1809
1810 if let Some(rw) = r#type {
1811 query_params.insert("type".to_string(), json!(rw));
1812 }
1813
1814 if let Some(rw) = asset {
1815 query_params.insert("asset".to_string(), json!(rw));
1816 }
1817
1818 if let Some(rw) = current {
1819 query_params.insert("current".to_string(), json!(rw));
1820 }
1821
1822 if let Some(rw) = size {
1823 query_params.insert("size".to_string(), json!(rw));
1824 }
1825
1826 if let Some(rw) = recv_window {
1827 query_params.insert("recvWindow".to_string(), json!(rw));
1828 }
1829
1830 send_request::<models::QueryUserDelegationHistoryResponse>(
1831 &self.configuration,
1832 "/sapi/v1/asset/custody/transfer-history",
1833 reqwest::Method::GET,
1834 query_params,
1835 body_params,
1836 if HAS_TIME_UNIT {
1837 self.configuration.time_unit
1838 } else {
1839 None
1840 },
1841 true,
1842 )
1843 .await
1844 }
1845
1846 async fn query_user_universal_transfer_history(
1847 &self,
1848 params: QueryUserUniversalTransferHistoryParams,
1849 ) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>> {
1850 let QueryUserUniversalTransferHistoryParams {
1851 r#type,
1852 start_time,
1853 end_time,
1854 current,
1855 size,
1856 from_symbol,
1857 to_symbol,
1858 recv_window,
1859 } = params;
1860
1861 let mut query_params = BTreeMap::new();
1862 let body_params = BTreeMap::new();
1863
1864 query_params.insert("type".to_string(), json!(r#type));
1865
1866 if let Some(rw) = start_time {
1867 query_params.insert("startTime".to_string(), json!(rw));
1868 }
1869
1870 if let Some(rw) = end_time {
1871 query_params.insert("endTime".to_string(), json!(rw));
1872 }
1873
1874 if let Some(rw) = current {
1875 query_params.insert("current".to_string(), json!(rw));
1876 }
1877
1878 if let Some(rw) = size {
1879 query_params.insert("size".to_string(), json!(rw));
1880 }
1881
1882 if let Some(rw) = from_symbol {
1883 query_params.insert("fromSymbol".to_string(), json!(rw));
1884 }
1885
1886 if let Some(rw) = to_symbol {
1887 query_params.insert("toSymbol".to_string(), json!(rw));
1888 }
1889
1890 if let Some(rw) = recv_window {
1891 query_params.insert("recvWindow".to_string(), json!(rw));
1892 }
1893
1894 send_request::<models::QueryUserUniversalTransferHistoryResponse>(
1895 &self.configuration,
1896 "/sapi/v1/asset/transfer",
1897 reqwest::Method::GET,
1898 query_params,
1899 body_params,
1900 if HAS_TIME_UNIT {
1901 self.configuration.time_unit
1902 } else {
1903 None
1904 },
1905 true,
1906 )
1907 .await
1908 }
1909
1910 async fn query_user_wallet_balance(
1911 &self,
1912 params: QueryUserWalletBalanceParams,
1913 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>> {
1914 let QueryUserWalletBalanceParams {
1915 quote_asset,
1916 need_balance_detail,
1917 recv_window,
1918 } = params;
1919
1920 let mut query_params = BTreeMap::new();
1921 let body_params = BTreeMap::new();
1922
1923 if let Some(rw) = quote_asset {
1924 query_params.insert("quoteAsset".to_string(), json!(rw));
1925 }
1926
1927 if let Some(rw) = need_balance_detail {
1928 query_params.insert("needBalanceDetail".to_string(), json!(rw));
1929 }
1930
1931 if let Some(rw) = recv_window {
1932 query_params.insert("recvWindow".to_string(), json!(rw));
1933 }
1934
1935 send_request::<Vec<models::QueryUserWalletBalanceResponseInner>>(
1936 &self.configuration,
1937 "/sapi/v1/asset/wallet/balance",
1938 reqwest::Method::GET,
1939 query_params,
1940 body_params,
1941 if HAS_TIME_UNIT {
1942 self.configuration.time_unit
1943 } else {
1944 None
1945 },
1946 true,
1947 )
1948 .await
1949 }
1950
1951 async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
1952 &self,
1953 params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
1954 ) -> anyhow::Result<RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>>
1955 {
1956 let ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
1957 spot_bnb_burn,
1958 interest_bnb_burn,
1959 recv_window,
1960 } = params;
1961
1962 let mut query_params = BTreeMap::new();
1963 let body_params = BTreeMap::new();
1964
1965 if let Some(rw) = spot_bnb_burn {
1966 query_params.insert("spotBNBBurn".to_string(), json!(rw));
1967 }
1968
1969 if let Some(rw) = interest_bnb_burn {
1970 query_params.insert("interestBNBBurn".to_string(), json!(rw));
1971 }
1972
1973 if let Some(rw) = recv_window {
1974 query_params.insert("recvWindow".to_string(), json!(rw));
1975 }
1976
1977 send_request::<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>(
1978 &self.configuration,
1979 "/sapi/v1/bnbBurn",
1980 reqwest::Method::POST,
1981 query_params,
1982 body_params,
1983 if HAS_TIME_UNIT {
1984 self.configuration.time_unit
1985 } else {
1986 None
1987 },
1988 true,
1989 )
1990 .await
1991 }
1992
1993 async fn trade_fee(
1994 &self,
1995 params: TradeFeeParams,
1996 ) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>> {
1997 let TradeFeeParams {
1998 symbol,
1999 recv_window,
2000 } = params;
2001
2002 let mut query_params = BTreeMap::new();
2003 let body_params = BTreeMap::new();
2004
2005 if let Some(rw) = symbol {
2006 query_params.insert("symbol".to_string(), json!(rw));
2007 }
2008
2009 if let Some(rw) = recv_window {
2010 query_params.insert("recvWindow".to_string(), json!(rw));
2011 }
2012
2013 send_request::<Vec<models::TradeFeeResponseInner>>(
2014 &self.configuration,
2015 "/sapi/v1/asset/tradeFee",
2016 reqwest::Method::GET,
2017 query_params,
2018 body_params,
2019 if HAS_TIME_UNIT {
2020 self.configuration.time_unit
2021 } else {
2022 None
2023 },
2024 true,
2025 )
2026 .await
2027 }
2028
2029 async fn user_asset(
2030 &self,
2031 params: UserAssetParams,
2032 ) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>> {
2033 let UserAssetParams {
2034 asset,
2035 need_btc_valuation,
2036 recv_window,
2037 } = params;
2038
2039 let mut query_params = BTreeMap::new();
2040 let body_params = BTreeMap::new();
2041
2042 if let Some(rw) = asset {
2043 query_params.insert("asset".to_string(), json!(rw));
2044 }
2045
2046 if let Some(rw) = need_btc_valuation {
2047 query_params.insert("needBtcValuation".to_string(), json!(rw));
2048 }
2049
2050 if let Some(rw) = recv_window {
2051 query_params.insert("recvWindow".to_string(), json!(rw));
2052 }
2053
2054 send_request::<Vec<models::UserAssetResponseInner>>(
2055 &self.configuration,
2056 "/sapi/v3/asset/getUserAsset",
2057 reqwest::Method::POST,
2058 query_params,
2059 body_params,
2060 if HAS_TIME_UNIT {
2061 self.configuration.time_unit
2062 } else {
2063 None
2064 },
2065 true,
2066 )
2067 .await
2068 }
2069
2070 async fn user_universal_transfer(
2071 &self,
2072 params: UserUniversalTransferParams,
2073 ) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>> {
2074 let UserUniversalTransferParams {
2075 r#type,
2076 asset,
2077 amount,
2078 from_symbol,
2079 to_symbol,
2080 recv_window,
2081 } = params;
2082
2083 let mut query_params = BTreeMap::new();
2084 let body_params = BTreeMap::new();
2085
2086 query_params.insert("type".to_string(), json!(r#type));
2087
2088 query_params.insert("asset".to_string(), json!(asset));
2089
2090 query_params.insert("amount".to_string(), json!(amount));
2091
2092 if let Some(rw) = from_symbol {
2093 query_params.insert("fromSymbol".to_string(), json!(rw));
2094 }
2095
2096 if let Some(rw) = to_symbol {
2097 query_params.insert("toSymbol".to_string(), json!(rw));
2098 }
2099
2100 if let Some(rw) = recv_window {
2101 query_params.insert("recvWindow".to_string(), json!(rw));
2102 }
2103
2104 send_request::<models::UserUniversalTransferResponse>(
2105 &self.configuration,
2106 "/sapi/v1/asset/transfer",
2107 reqwest::Method::POST,
2108 query_params,
2109 body_params,
2110 if HAS_TIME_UNIT {
2111 self.configuration.time_unit
2112 } else {
2113 None
2114 },
2115 true,
2116 )
2117 .await
2118 }
2119}
2120
2121#[cfg(all(test, feature = "wallet"))]
2122mod tests {
2123 use super::*;
2124 use crate::TOKIO_SHARED_RT;
2125 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
2126 use async_trait::async_trait;
2127 use std::collections::HashMap;
2128
2129 struct DummyRestApiResponse<T> {
2130 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
2131 status: u16,
2132 headers: HashMap<String, String>,
2133 rate_limits: Option<Vec<RestApiRateLimit>>,
2134 }
2135
2136 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
2137 fn from(dummy: DummyRestApiResponse<T>) -> Self {
2138 Self {
2139 data_fn: dummy.inner,
2140 status: dummy.status,
2141 headers: dummy.headers,
2142 rate_limits: dummy.rate_limits,
2143 }
2144 }
2145 }
2146
2147 struct MockAssetApiClient {
2148 force_error: bool,
2149 }
2150
2151 #[async_trait]
2152 impl AssetApi for MockAssetApiClient {
2153 async fn asset_detail(
2154 &self,
2155 _params: AssetDetailParams,
2156 ) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>> {
2157 if self.force_error {
2158 return Err(ConnectorError::ConnectorClientError {
2159 msg: "ResponseError".to_string(),
2160 code: None,
2161 }
2162 .into());
2163 }
2164
2165 let resp_json: Value = serde_json::from_str(r#"{"CTR":{"minWithdrawAmount":"70.00000000","depositStatus":false,"withdrawFee":35,"withdrawStatus":true,"depositTip":"Delisted, Deposit Suspended"},"SKY":{"minWithdrawAmount":"0.02000000","depositStatus":true,"withdrawFee":0.01,"withdrawStatus":true}}"#).unwrap_or_else(|_| serde_json::json!({}));
2166 let dummy_response: models::AssetDetailResponse =
2167 serde_json::from_value(resp_json.clone())
2168 .expect("should parse into models::AssetDetailResponse");
2169
2170 let dummy = DummyRestApiResponse {
2171 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2172 status: 200,
2173 headers: HashMap::new(),
2174 rate_limits: None,
2175 };
2176
2177 Ok(dummy.into())
2178 }
2179
2180 async fn asset_dividend_record(
2181 &self,
2182 _params: AssetDividendRecordParams,
2183 ) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>> {
2184 if self.force_error {
2185 return Err(ConnectorError::ConnectorClientError {
2186 msg: "ResponseError".to_string(),
2187 code: None,
2188 }
2189 .into());
2190 }
2191
2192 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"id":1637366104,"amount":"10.00000000","asset":"BHFT","divTime":1563189166000,"enInfo":"BHFT distribution","tranId":2968885920,"direction":1}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2193 let dummy_response: models::AssetDividendRecordResponse =
2194 serde_json::from_value(resp_json.clone())
2195 .expect("should parse into models::AssetDividendRecordResponse");
2196
2197 let dummy = DummyRestApiResponse {
2198 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2199 status: 200,
2200 headers: HashMap::new(),
2201 rate_limits: None,
2202 };
2203
2204 Ok(dummy.into())
2205 }
2206
2207 async fn dust_convert(
2208 &self,
2209 _params: DustConvertParams,
2210 ) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>> {
2211 if self.force_error {
2212 return Err(ConnectorError::ConnectorClientError {
2213 msg: "ResponseError".to_string(),
2214 code: None,
2215 }
2216 .into());
2217 }
2218
2219 let resp_json: Value = serde_json::from_str(r#"{"totalTransfered":"3.5971223","totalServiceCharge":"0.0794964","transferResult":[{"tranId":2987331510,"fromAsset":"USDT","amount":"1","transferedAmount":"3.5971223","serviceChargeAmount":"0.0794964","operateTime":1765212029749}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2220 let dummy_response: models::DustConvertResponse =
2221 serde_json::from_value(resp_json.clone())
2222 .expect("should parse into models::DustConvertResponse");
2223
2224 let dummy = DummyRestApiResponse {
2225 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2226 status: 200,
2227 headers: HashMap::new(),
2228 rate_limits: None,
2229 };
2230
2231 Ok(dummy.into())
2232 }
2233
2234 async fn dust_convertible_assets(
2235 &self,
2236 _params: DustConvertibleAssetsParams,
2237 ) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>> {
2238 if self.force_error {
2239 return Err(ConnectorError::ConnectorClientError {
2240 msg: "ResponseError".to_string(),
2241 code: None,
2242 }
2243 .into());
2244 }
2245
2246 let resp_json: Value = serde_json::from_str(r#"{"dribbletPercentage":"0.02","totalTransferQuotaAssetAmount":"0.7899968","totalTransferTargetAssetAmount":"0.7899968","dribbletBase":"10","details":[{"asset":"AR","assetFullName":"AR","amountFree":"0.00856","exchange":"0.00073616","toQuotaAssetAmount":"0.036808","toTargetAssetAmount":"0.036808","toTargetAssetOffExchange":"0.03607184"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2247 let dummy_response: models::DustConvertibleAssetsResponse =
2248 serde_json::from_value(resp_json.clone())
2249 .expect("should parse into models::DustConvertibleAssetsResponse");
2250
2251 let dummy = DummyRestApiResponse {
2252 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2253 status: 200,
2254 headers: HashMap::new(),
2255 rate_limits: None,
2256 };
2257
2258 Ok(dummy.into())
2259 }
2260
2261 async fn dust_transfer(
2262 &self,
2263 _params: DustTransferParams,
2264 ) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>> {
2265 if self.force_error {
2266 return Err(ConnectorError::ConnectorClientError {
2267 msg: "ResponseError".to_string(),
2268 code: None,
2269 }
2270 .into());
2271 }
2272
2273 let resp_json: Value = serde_json::from_str(r#"{"totalServiceCharge":"0.02102542","totalTransfered":"1.05127099","transferResult":[{"amount":"0.03000000","fromAsset":"ETH","operateTime":1563368549307,"serviceChargeAmount":"0.00500000","tranId":2970932918,"transferedAmount":"0.25000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2274 let dummy_response: models::DustTransferResponse =
2275 serde_json::from_value(resp_json.clone())
2276 .expect("should parse into models::DustTransferResponse");
2277
2278 let dummy = DummyRestApiResponse {
2279 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2280 status: 200,
2281 headers: HashMap::new(),
2282 rate_limits: None,
2283 };
2284
2285 Ok(dummy.into())
2286 }
2287
2288 async fn dustlog(
2289 &self,
2290 _params: DustlogParams,
2291 ) -> anyhow::Result<RestApiResponse<models::DustlogResponse>> {
2292 if self.force_error {
2293 return Err(ConnectorError::ConnectorClientError {
2294 msg: "ResponseError".to_string(),
2295 code: None,
2296 }
2297 .into());
2298 }
2299
2300 let resp_json: Value = serde_json::from_str(r#"{"total":8,"userAssetDribblets":[{"operateTime":1615985535000,"totalTransferedAmount":"0.00132256","totalServiceChargeAmount":"0.00002699","transId":45178372831,"userAssetDribbletDetails":[{"transId":4359321,"serviceChargeAmount":"0.000009","amount":"0.0009","operateTime":1615985535000,"transferedAmount":"0.000441","fromAsset":"USDT","targetAsset":"BNB"}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2301 let dummy_response: models::DustlogResponse = serde_json::from_value(resp_json.clone())
2302 .expect("should parse into models::DustlogResponse");
2303
2304 let dummy = DummyRestApiResponse {
2305 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2306 status: 200,
2307 headers: HashMap::new(),
2308 rate_limits: None,
2309 };
2310
2311 Ok(dummy.into())
2312 }
2313
2314 async fn funding_wallet(
2315 &self,
2316 _params: FundingWalletParams,
2317 ) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>> {
2318 if self.force_error {
2319 return Err(ConnectorError::ConnectorClientError {
2320 msg: "ResponseError".to_string(),
2321 code: None,
2322 }
2323 .into());
2324 }
2325
2326 let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","free":"1","locked":"0","freeze":"0","withdrawing":"0","btcValuation":"0.00000091"}]"#).unwrap_or_else(|_| serde_json::json!({}));
2327 let dummy_response: Vec<models::FundingWalletResponseInner> =
2328 serde_json::from_value(resp_json.clone())
2329 .expect("should parse into Vec<models::FundingWalletResponseInner>");
2330
2331 let dummy = DummyRestApiResponse {
2332 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2333 status: 200,
2334 headers: HashMap::new(),
2335 rate_limits: None,
2336 };
2337
2338 Ok(dummy.into())
2339 }
2340
2341 async fn get_assets_that_can_be_converted_into_bnb(
2342 &self,
2343 _params: GetAssetsThatCanBeConvertedIntoBnbParams,
2344 ) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>>
2345 {
2346 if self.force_error {
2347 return Err(ConnectorError::ConnectorClientError {
2348 msg: "ResponseError".to_string(),
2349 code: None,
2350 }
2351 .into());
2352 }
2353
2354 let resp_json: Value = serde_json::from_str(r#"{"details":[{"asset":"ADA","assetFullName":"ADA","amountFree":"6.21","toBTC":"0.00016848","toBNB":"0.01777302","toBNBOffExchange":"0.01741756","exchange":"0.00035546"}],"totalTransferBtc":"0.00016848","totalTransferBNB":"0.01777302","dribbletPercentage":"0.02"}"#).unwrap_or_else(|_| serde_json::json!({}));
2355 let dummy_response: models::GetAssetsThatCanBeConvertedIntoBnbResponse =
2356 serde_json::from_value(resp_json.clone())
2357 .expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
2358
2359 let dummy = DummyRestApiResponse {
2360 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2361 status: 200,
2362 headers: HashMap::new(),
2363 rate_limits: None,
2364 };
2365
2366 Ok(dummy.into())
2367 }
2368
2369 async fn get_cloud_mining_payment_and_refund_history(
2370 &self,
2371 _params: GetCloudMiningPaymentAndRefundHistoryParams,
2372 ) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>
2373 {
2374 if self.force_error {
2375 return Err(ConnectorError::ConnectorClientError {
2376 msg: "ResponseError".to_string(),
2377 code: None,
2378 }
2379 .into());
2380 }
2381
2382 let resp_json: Value = serde_json::from_str(r#"{"total":5,"rows":[{"createTime":1667880112000,"tranId":121230610120,"type":248,"asset":"USDT","amount":"25.0068","status":"S"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2383 let dummy_response: models::GetCloudMiningPaymentAndRefundHistoryResponse =
2384 serde_json::from_value(resp_json.clone()).expect(
2385 "should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse",
2386 );
2387
2388 let dummy = DummyRestApiResponse {
2389 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2390 status: 200,
2391 headers: HashMap::new(),
2392 rate_limits: None,
2393 };
2394
2395 Ok(dummy.into())
2396 }
2397
2398 async fn get_open_symbol_list(
2399 &self,
2400 ) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>> {
2401 if self.force_error {
2402 return Err(ConnectorError::ConnectorClientError {
2403 msg: "ResponseError".to_string(),
2404 code: None,
2405 }
2406 .into());
2407 }
2408
2409 let resp_json: Value =
2410 serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
2411 .unwrap_or_else(|_| serde_json::json!({}));
2412 let dummy_response: Vec<models::GetOpenSymbolListResponseInner> =
2413 serde_json::from_value(resp_json.clone())
2414 .expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
2415
2416 let dummy = DummyRestApiResponse {
2417 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2418 status: 200,
2419 headers: HashMap::new(),
2420 rate_limits: None,
2421 };
2422
2423 Ok(dummy.into())
2424 }
2425
2426 async fn get_spot_asset_tags(
2427 &self,
2428 _params: GetSpotAssetTagsParams,
2429 ) -> anyhow::Result<RestApiResponse<Vec<models::GetSpotAssetTagsResponseInner>>> {
2430 if self.force_error {
2431 return Err(ConnectorError::ConnectorClientError {
2432 msg: "ResponseError".to_string(),
2433 code: None,
2434 }
2435 .into());
2436 }
2437
2438 let resp_json: Value = serde_json::from_str(r#"[{"assetCode":"BNB","assetName":"BNB","trading":true,"tags":["Layer1_Layer2","BSC"]}]"#).unwrap_or_else(|_| serde_json::json!({}));
2439 let dummy_response: Vec<models::GetSpotAssetTagsResponseInner> =
2440 serde_json::from_value(resp_json.clone())
2441 .expect("should parse into Vec<models::GetSpotAssetTagsResponseInner>");
2442
2443 let dummy = DummyRestApiResponse {
2444 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2445 status: 200,
2446 headers: HashMap::new(),
2447 rate_limits: None,
2448 };
2449
2450 Ok(dummy.into())
2451 }
2452
2453 async fn query_user_delegation_history(
2454 &self,
2455 _params: QueryUserDelegationHistoryParams,
2456 ) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>> {
2457 if self.force_error {
2458 return Err(ConnectorError::ConnectorClientError {
2459 msg: "ResponseError".to_string(),
2460 code: None,
2461 }
2462 .into());
2463 }
2464
2465 let resp_json: Value = serde_json::from_str(r#"{"total":3316,"rows":[{"clientTranId":"293915932290879488","transferType":"Undelegate","asset":"ETH","amount":"1","time":1695205406000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2466 let dummy_response: models::QueryUserDelegationHistoryResponse =
2467 serde_json::from_value(resp_json.clone())
2468 .expect("should parse into models::QueryUserDelegationHistoryResponse");
2469
2470 let dummy = DummyRestApiResponse {
2471 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2472 status: 200,
2473 headers: HashMap::new(),
2474 rate_limits: None,
2475 };
2476
2477 Ok(dummy.into())
2478 }
2479
2480 async fn query_user_universal_transfer_history(
2481 &self,
2482 _params: QueryUserUniversalTransferHistoryParams,
2483 ) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>>
2484 {
2485 if self.force_error {
2486 return Err(ConnectorError::ConnectorClientError {
2487 msg: "ResponseError".to_string(),
2488 code: None,
2489 }
2490 .into());
2491 }
2492
2493 let resp_json: Value = serde_json::from_str(r#"{"total":2,"rows":[{"asset":"USDT","amount":"1","type":"MAIN_UMFUTURE","status":"CONFIRMED","tranId":11415955596,"timestamp":1544433328000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2494 let dummy_response: models::QueryUserUniversalTransferHistoryResponse =
2495 serde_json::from_value(resp_json.clone())
2496 .expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
2497
2498 let dummy = DummyRestApiResponse {
2499 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2500 status: 200,
2501 headers: HashMap::new(),
2502 rate_limits: None,
2503 };
2504
2505 Ok(dummy.into())
2506 }
2507
2508 async fn query_user_wallet_balance(
2509 &self,
2510 _params: QueryUserWalletBalanceParams,
2511 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>>
2512 {
2513 if self.force_error {
2514 return Err(ConnectorError::ConnectorClientError {
2515 msg: "ResponseError".to_string(),
2516 code: None,
2517 }
2518 .into());
2519 }
2520
2521 let resp_json: Value = serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot","assetBalances":[{"asset":"USDT","assetName":"TetherUS","free":"6.238383","locked":"0","freeze":"0","withdrawing":"0","btcValuation":"6.238383"}]}]"#).unwrap_or_else(|_| serde_json::json!({}));
2522 let dummy_response: Vec<models::QueryUserWalletBalanceResponseInner> =
2523 serde_json::from_value(resp_json.clone())
2524 .expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
2525
2526 let dummy = DummyRestApiResponse {
2527 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2528 status: 200,
2529 headers: HashMap::new(),
2530 rate_limits: None,
2531 };
2532
2533 Ok(dummy.into())
2534 }
2535
2536 async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
2537 &self,
2538 _params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
2539 ) -> anyhow::Result<
2540 RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>,
2541 > {
2542 if self.force_error {
2543 return Err(ConnectorError::ConnectorClientError {
2544 msg: "ResponseError".to_string(),
2545 code: None,
2546 }
2547 .into());
2548 }
2549
2550 let resp_json: Value =
2551 serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
2552 .unwrap_or_else(|_| serde_json::json!({}));
2553 let dummy_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
2554 serde_json::from_value(resp_json.clone()).expect(
2555 "should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
2556 );
2557
2558 let dummy = DummyRestApiResponse {
2559 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2560 status: 200,
2561 headers: HashMap::new(),
2562 rate_limits: None,
2563 };
2564
2565 Ok(dummy.into())
2566 }
2567
2568 async fn trade_fee(
2569 &self,
2570 _params: TradeFeeParams,
2571 ) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>> {
2572 if self.force_error {
2573 return Err(ConnectorError::ConnectorClientError {
2574 msg: "ResponseError".to_string(),
2575 code: None,
2576 }
2577 .into());
2578 }
2579
2580 let resp_json: Value = serde_json::from_str(
2581 r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
2582 )
2583 .unwrap_or_else(|_| serde_json::json!({}));
2584 let dummy_response: Vec<models::TradeFeeResponseInner> =
2585 serde_json::from_value(resp_json.clone())
2586 .expect("should parse into Vec<models::TradeFeeResponseInner>");
2587
2588 let dummy = DummyRestApiResponse {
2589 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2590 status: 200,
2591 headers: HashMap::new(),
2592 rate_limits: None,
2593 };
2594
2595 Ok(dummy.into())
2596 }
2597
2598 async fn user_asset(
2599 &self,
2600 _params: UserAssetParams,
2601 ) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>> {
2602 if self.force_error {
2603 return Err(ConnectorError::ConnectorClientError {
2604 msg: "ResponseError".to_string(),
2605 code: None,
2606 }
2607 .into());
2608 }
2609
2610 let resp_json: Value = serde_json::from_str(r#"[{"asset":"AVAX","free":"1","locked":"0","freeze":"0","withdrawing":"0","ipoable":"0","btcValuation":"0"}]"#).unwrap_or_else(|_| serde_json::json!({}));
2611 let dummy_response: Vec<models::UserAssetResponseInner> =
2612 serde_json::from_value(resp_json.clone())
2613 .expect("should parse into Vec<models::UserAssetResponseInner>");
2614
2615 let dummy = DummyRestApiResponse {
2616 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2617 status: 200,
2618 headers: HashMap::new(),
2619 rate_limits: None,
2620 };
2621
2622 Ok(dummy.into())
2623 }
2624
2625 async fn user_universal_transfer(
2626 &self,
2627 _params: UserUniversalTransferParams,
2628 ) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>> {
2629 if self.force_error {
2630 return Err(ConnectorError::ConnectorClientError {
2631 msg: "ResponseError".to_string(),
2632 code: None,
2633 }
2634 .into());
2635 }
2636
2637 let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
2638 .unwrap_or_else(|_| serde_json::json!({}));
2639 let dummy_response: models::UserUniversalTransferResponse =
2640 serde_json::from_value(resp_json.clone())
2641 .expect("should parse into models::UserUniversalTransferResponse");
2642
2643 let dummy = DummyRestApiResponse {
2644 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2645 status: 200,
2646 headers: HashMap::new(),
2647 rate_limits: None,
2648 };
2649
2650 Ok(dummy.into())
2651 }
2652 }
2653
2654 #[test]
2655 fn asset_detail_required_params_success() {
2656 TOKIO_SHARED_RT.block_on(async {
2657 let client = MockAssetApiClient { force_error: false };
2658
2659 let params = AssetDetailParams::builder().build().unwrap();
2660
2661 let resp_json: Value = serde_json::from_str(r#"{"CTR":{"minWithdrawAmount":"70.00000000","depositStatus":false,"withdrawFee":35,"withdrawStatus":true,"depositTip":"Delisted, Deposit Suspended"},"SKY":{"minWithdrawAmount":"0.02000000","depositStatus":true,"withdrawFee":0.01,"withdrawStatus":true}}"#).unwrap_or_else(|_| serde_json::json!({}));
2662 let expected_response : models::AssetDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDetailResponse");
2663
2664 let resp = client.asset_detail(params).await.expect("Expected a response");
2665 let data_future = resp.data();
2666 let actual_response = data_future.await.unwrap();
2667 assert_eq!(actual_response, expected_response);
2668 });
2669 }
2670
2671 #[test]
2672 fn asset_detail_optional_params_success() {
2673 TOKIO_SHARED_RT.block_on(async {
2674 let client = MockAssetApiClient { force_error: false };
2675
2676 let params = AssetDetailParams::builder().asset("BTC".to_string()).recv_window(5000).build().unwrap();
2677
2678 let resp_json: Value = serde_json::from_str(r#"{"CTR":{"minWithdrawAmount":"70.00000000","depositStatus":false,"withdrawFee":35,"withdrawStatus":true,"depositTip":"Delisted, Deposit Suspended"},"SKY":{"minWithdrawAmount":"0.02000000","depositStatus":true,"withdrawFee":0.01,"withdrawStatus":true}}"#).unwrap_or_else(|_| serde_json::json!({}));
2679 let expected_response : models::AssetDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDetailResponse");
2680
2681 let resp = client.asset_detail(params).await.expect("Expected a response");
2682 let data_future = resp.data();
2683 let actual_response = data_future.await.unwrap();
2684 assert_eq!(actual_response, expected_response);
2685 });
2686 }
2687
2688 #[test]
2689 fn asset_detail_response_error() {
2690 TOKIO_SHARED_RT.block_on(async {
2691 let client = MockAssetApiClient { force_error: true };
2692
2693 let params = AssetDetailParams::builder().build().unwrap();
2694
2695 match client.asset_detail(params).await {
2696 Ok(_) => panic!("Expected an error"),
2697 Err(err) => {
2698 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2699 }
2700 }
2701 });
2702 }
2703
2704 #[test]
2705 fn asset_dividend_record_required_params_success() {
2706 TOKIO_SHARED_RT.block_on(async {
2707 let client = MockAssetApiClient { force_error: false };
2708
2709 let params = AssetDividendRecordParams::builder().build().unwrap();
2710
2711 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"id":1637366104,"amount":"10.00000000","asset":"BHFT","divTime":1563189166000,"enInfo":"BHFT distribution","tranId":2968885920,"direction":1}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2712 let expected_response : models::AssetDividendRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDividendRecordResponse");
2713
2714 let resp = client.asset_dividend_record(params).await.expect("Expected a response");
2715 let data_future = resp.data();
2716 let actual_response = data_future.await.unwrap();
2717 assert_eq!(actual_response, expected_response);
2718 });
2719 }
2720
2721 #[test]
2722 fn asset_dividend_record_optional_params_success() {
2723 TOKIO_SHARED_RT.block_on(async {
2724 let client = MockAssetApiClient { force_error: false };
2725
2726 let params = AssetDividendRecordParams::builder().asset("BTC".to_string()).start_time(1623319461670).end_time(1641782889000).limit(20).recv_window(5000).build().unwrap();
2727
2728 let resp_json: Value = serde_json::from_str(r#"{"rows":[{"id":1637366104,"amount":"10.00000000","asset":"BHFT","divTime":1563189166000,"enInfo":"BHFT distribution","tranId":2968885920,"direction":1}],"total":2}"#).unwrap_or_else(|_| serde_json::json!({}));
2729 let expected_response : models::AssetDividendRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDividendRecordResponse");
2730
2731 let resp = client.asset_dividend_record(params).await.expect("Expected a response");
2732 let data_future = resp.data();
2733 let actual_response = data_future.await.unwrap();
2734 assert_eq!(actual_response, expected_response);
2735 });
2736 }
2737
2738 #[test]
2739 fn asset_dividend_record_response_error() {
2740 TOKIO_SHARED_RT.block_on(async {
2741 let client = MockAssetApiClient { force_error: true };
2742
2743 let params = AssetDividendRecordParams::builder().build().unwrap();
2744
2745 match client.asset_dividend_record(params).await {
2746 Ok(_) => panic!("Expected an error"),
2747 Err(err) => {
2748 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2749 }
2750 }
2751 });
2752 }
2753
2754 #[test]
2755 fn dust_convert_required_params_success() {
2756 TOKIO_SHARED_RT.block_on(async {
2757 let client = MockAssetApiClient { force_error: false };
2758
2759 let params = DustConvertParams::builder("USDT".to_string(),).build().unwrap();
2760
2761 let resp_json: Value = serde_json::from_str(r#"{"totalTransfered":"3.5971223","totalServiceCharge":"0.0794964","transferResult":[{"tranId":2987331510,"fromAsset":"USDT","amount":"1","transferedAmount":"3.5971223","serviceChargeAmount":"0.0794964","operateTime":1765212029749}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2762 let expected_response : models::DustConvertResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertResponse");
2763
2764 let resp = client.dust_convert(params).await.expect("Expected a response");
2765 let data_future = resp.data();
2766 let actual_response = data_future.await.unwrap();
2767 assert_eq!(actual_response, expected_response);
2768 });
2769 }
2770
2771 #[test]
2772 fn dust_convert_optional_params_success() {
2773 TOKIO_SHARED_RT.block_on(async {
2774 let client = MockAssetApiClient { force_error: false };
2775
2776 let params = DustConvertParams::builder("USDT".to_string(),).account_type("SPOT".to_string()).client_id("1".to_string()).target_asset("BTC".to_string()).third_party_client_id("1".to_string()).dust_quota_asset_to_target_asset_price(dec!(1.0)).build().unwrap();
2777
2778 let resp_json: Value = serde_json::from_str(r#"{"totalTransfered":"3.5971223","totalServiceCharge":"0.0794964","transferResult":[{"tranId":2987331510,"fromAsset":"USDT","amount":"1","transferedAmount":"3.5971223","serviceChargeAmount":"0.0794964","operateTime":1765212029749}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2779 let expected_response : models::DustConvertResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertResponse");
2780
2781 let resp = client.dust_convert(params).await.expect("Expected a response");
2782 let data_future = resp.data();
2783 let actual_response = data_future.await.unwrap();
2784 assert_eq!(actual_response, expected_response);
2785 });
2786 }
2787
2788 #[test]
2789 fn dust_convert_response_error() {
2790 TOKIO_SHARED_RT.block_on(async {
2791 let client = MockAssetApiClient { force_error: true };
2792
2793 let params = DustConvertParams::builder("USDT".to_string())
2794 .build()
2795 .unwrap();
2796
2797 match client.dust_convert(params).await {
2798 Ok(_) => panic!("Expected an error"),
2799 Err(err) => {
2800 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2801 }
2802 }
2803 });
2804 }
2805
2806 #[test]
2807 fn dust_convertible_assets_required_params_success() {
2808 TOKIO_SHARED_RT.block_on(async {
2809 let client = MockAssetApiClient { force_error: false };
2810
2811 let params = DustConvertibleAssetsParams::builder("BTC".to_string(),).build().unwrap();
2812
2813 let resp_json: Value = serde_json::from_str(r#"{"dribbletPercentage":"0.02","totalTransferQuotaAssetAmount":"0.7899968","totalTransferTargetAssetAmount":"0.7899968","dribbletBase":"10","details":[{"asset":"AR","assetFullName":"AR","amountFree":"0.00856","exchange":"0.00073616","toQuotaAssetAmount":"0.036808","toTargetAssetAmount":"0.036808","toTargetAssetOffExchange":"0.03607184"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2814 let expected_response : models::DustConvertibleAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertibleAssetsResponse");
2815
2816 let resp = client.dust_convertible_assets(params).await.expect("Expected a response");
2817 let data_future = resp.data();
2818 let actual_response = data_future.await.unwrap();
2819 assert_eq!(actual_response, expected_response);
2820 });
2821 }
2822
2823 #[test]
2824 fn dust_convertible_assets_optional_params_success() {
2825 TOKIO_SHARED_RT.block_on(async {
2826 let client = MockAssetApiClient { force_error: false };
2827
2828 let params = DustConvertibleAssetsParams::builder("BTC".to_string(),).account_type("SPOT".to_string()).dust_quota_asset_to_target_asset_price(dec!(1.0)).build().unwrap();
2829
2830 let resp_json: Value = serde_json::from_str(r#"{"dribbletPercentage":"0.02","totalTransferQuotaAssetAmount":"0.7899968","totalTransferTargetAssetAmount":"0.7899968","dribbletBase":"10","details":[{"asset":"AR","assetFullName":"AR","amountFree":"0.00856","exchange":"0.00073616","toQuotaAssetAmount":"0.036808","toTargetAssetAmount":"0.036808","toTargetAssetOffExchange":"0.03607184"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2831 let expected_response : models::DustConvertibleAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertibleAssetsResponse");
2832
2833 let resp = client.dust_convertible_assets(params).await.expect("Expected a response");
2834 let data_future = resp.data();
2835 let actual_response = data_future.await.unwrap();
2836 assert_eq!(actual_response, expected_response);
2837 });
2838 }
2839
2840 #[test]
2841 fn dust_convertible_assets_response_error() {
2842 TOKIO_SHARED_RT.block_on(async {
2843 let client = MockAssetApiClient { force_error: true };
2844
2845 let params = DustConvertibleAssetsParams::builder("BTC".to_string())
2846 .build()
2847 .unwrap();
2848
2849 match client.dust_convertible_assets(params).await {
2850 Ok(_) => panic!("Expected an error"),
2851 Err(err) => {
2852 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2853 }
2854 }
2855 });
2856 }
2857
2858 #[test]
2859 fn dust_transfer_required_params_success() {
2860 TOKIO_SHARED_RT.block_on(async {
2861 let client = MockAssetApiClient { force_error: false };
2862
2863 let params = DustTransferParams::builder("BTC".to_string(),).build().unwrap();
2864
2865 let resp_json: Value = serde_json::from_str(r#"{"totalServiceCharge":"0.02102542","totalTransfered":"1.05127099","transferResult":[{"amount":"0.03000000","fromAsset":"ETH","operateTime":1563368549307,"serviceChargeAmount":"0.00500000","tranId":2970932918,"transferedAmount":"0.25000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2866 let expected_response : models::DustTransferResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustTransferResponse");
2867
2868 let resp = client.dust_transfer(params).await.expect("Expected a response");
2869 let data_future = resp.data();
2870 let actual_response = data_future.await.unwrap();
2871 assert_eq!(actual_response, expected_response);
2872 });
2873 }
2874
2875 #[test]
2876 fn dust_transfer_optional_params_success() {
2877 TOKIO_SHARED_RT.block_on(async {
2878 let client = MockAssetApiClient { force_error: false };
2879
2880 let params = DustTransferParams::builder("BTC".to_string(),).account_type(DustTransferAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
2881
2882 let resp_json: Value = serde_json::from_str(r#"{"totalServiceCharge":"0.02102542","totalTransfered":"1.05127099","transferResult":[{"amount":"0.03000000","fromAsset":"ETH","operateTime":1563368549307,"serviceChargeAmount":"0.00500000","tranId":2970932918,"transferedAmount":"0.25000000"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2883 let expected_response : models::DustTransferResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustTransferResponse");
2884
2885 let resp = client.dust_transfer(params).await.expect("Expected a response");
2886 let data_future = resp.data();
2887 let actual_response = data_future.await.unwrap();
2888 assert_eq!(actual_response, expected_response);
2889 });
2890 }
2891
2892 #[test]
2893 fn dust_transfer_response_error() {
2894 TOKIO_SHARED_RT.block_on(async {
2895 let client = MockAssetApiClient { force_error: true };
2896
2897 let params = DustTransferParams::builder("BTC".to_string())
2898 .build()
2899 .unwrap();
2900
2901 match client.dust_transfer(params).await {
2902 Ok(_) => panic!("Expected an error"),
2903 Err(err) => {
2904 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2905 }
2906 }
2907 });
2908 }
2909
2910 #[test]
2911 fn dustlog_required_params_success() {
2912 TOKIO_SHARED_RT.block_on(async {
2913 let client = MockAssetApiClient { force_error: false };
2914
2915 let params = DustlogParams::builder().build().unwrap();
2916
2917 let resp_json: Value = serde_json::from_str(r#"{"total":8,"userAssetDribblets":[{"operateTime":1615985535000,"totalTransferedAmount":"0.00132256","totalServiceChargeAmount":"0.00002699","transId":45178372831,"userAssetDribbletDetails":[{"transId":4359321,"serviceChargeAmount":"0.000009","amount":"0.0009","operateTime":1615985535000,"transferedAmount":"0.000441","fromAsset":"USDT","targetAsset":"BNB"}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2918 let expected_response : models::DustlogResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustlogResponse");
2919
2920 let resp = client.dustlog(params).await.expect("Expected a response");
2921 let data_future = resp.data();
2922 let actual_response = data_future.await.unwrap();
2923 assert_eq!(actual_response, expected_response);
2924 });
2925 }
2926
2927 #[test]
2928 fn dustlog_optional_params_success() {
2929 TOKIO_SHARED_RT.block_on(async {
2930 let client = MockAssetApiClient { force_error: false };
2931
2932 let params = DustlogParams::builder().account_type(DustlogAccountTypeEnum::Spot).start_time(1623319461670).end_time(1641782889000).recv_window(5000).build().unwrap();
2933
2934 let resp_json: Value = serde_json::from_str(r#"{"total":8,"userAssetDribblets":[{"operateTime":1615985535000,"totalTransferedAmount":"0.00132256","totalServiceChargeAmount":"0.00002699","transId":45178372831,"userAssetDribbletDetails":[{"transId":4359321,"serviceChargeAmount":"0.000009","amount":"0.0009","operateTime":1615985535000,"transferedAmount":"0.000441","fromAsset":"USDT","targetAsset":"BNB"}]}]}"#).unwrap_or_else(|_| serde_json::json!({}));
2935 let expected_response : models::DustlogResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustlogResponse");
2936
2937 let resp = client.dustlog(params).await.expect("Expected a response");
2938 let data_future = resp.data();
2939 let actual_response = data_future.await.unwrap();
2940 assert_eq!(actual_response, expected_response);
2941 });
2942 }
2943
2944 #[test]
2945 fn dustlog_response_error() {
2946 TOKIO_SHARED_RT.block_on(async {
2947 let client = MockAssetApiClient { force_error: true };
2948
2949 let params = DustlogParams::builder().build().unwrap();
2950
2951 match client.dustlog(params).await {
2952 Ok(_) => panic!("Expected an error"),
2953 Err(err) => {
2954 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2955 }
2956 }
2957 });
2958 }
2959
2960 #[test]
2961 fn funding_wallet_required_params_success() {
2962 TOKIO_SHARED_RT.block_on(async {
2963 let client = MockAssetApiClient { force_error: false };
2964
2965 let params = FundingWalletParams::builder().build().unwrap();
2966
2967 let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","free":"1","locked":"0","freeze":"0","withdrawing":"0","btcValuation":"0.00000091"}]"#).unwrap_or_else(|_| serde_json::json!({}));
2968 let expected_response : Vec<models::FundingWalletResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::FundingWalletResponseInner>");
2969
2970 let resp = client.funding_wallet(params).await.expect("Expected a response");
2971 let data_future = resp.data();
2972 let actual_response = data_future.await.unwrap();
2973 assert_eq!(actual_response, expected_response);
2974 });
2975 }
2976
2977 #[test]
2978 fn funding_wallet_optional_params_success() {
2979 TOKIO_SHARED_RT.block_on(async {
2980 let client = MockAssetApiClient { force_error: false };
2981
2982 let params = FundingWalletParams::builder().asset("BTC".to_string()).need_btc_valuation(true).recv_window(5000).build().unwrap();
2983
2984 let resp_json: Value = serde_json::from_str(r#"[{"asset":"USDT","free":"1","locked":"0","freeze":"0","withdrawing":"0","btcValuation":"0.00000091"}]"#).unwrap_or_else(|_| serde_json::json!({}));
2985 let expected_response : Vec<models::FundingWalletResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::FundingWalletResponseInner>");
2986
2987 let resp = client.funding_wallet(params).await.expect("Expected a response");
2988 let data_future = resp.data();
2989 let actual_response = data_future.await.unwrap();
2990 assert_eq!(actual_response, expected_response);
2991 });
2992 }
2993
2994 #[test]
2995 fn funding_wallet_response_error() {
2996 TOKIO_SHARED_RT.block_on(async {
2997 let client = MockAssetApiClient { force_error: true };
2998
2999 let params = FundingWalletParams::builder().build().unwrap();
3000
3001 match client.funding_wallet(params).await {
3002 Ok(_) => panic!("Expected an error"),
3003 Err(err) => {
3004 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3005 }
3006 }
3007 });
3008 }
3009
3010 #[test]
3011 fn get_assets_that_can_be_converted_into_bnb_required_params_success() {
3012 TOKIO_SHARED_RT.block_on(async {
3013 let client = MockAssetApiClient { force_error: false };
3014
3015 let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder().build().unwrap();
3016
3017 let resp_json: Value = serde_json::from_str(r#"{"details":[{"asset":"ADA","assetFullName":"ADA","amountFree":"6.21","toBTC":"0.00016848","toBNB":"0.01777302","toBNBOffExchange":"0.01741756","exchange":"0.00035546"}],"totalTransferBtc":"0.00016848","totalTransferBNB":"0.01777302","dribbletPercentage":"0.02"}"#).unwrap_or_else(|_| serde_json::json!({}));
3018 let expected_response : models::GetAssetsThatCanBeConvertedIntoBnbResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
3019
3020 let resp = client.get_assets_that_can_be_converted_into_bnb(params).await.expect("Expected a response");
3021 let data_future = resp.data();
3022 let actual_response = data_future.await.unwrap();
3023 assert_eq!(actual_response, expected_response);
3024 });
3025 }
3026
3027 #[test]
3028 fn get_assets_that_can_be_converted_into_bnb_optional_params_success() {
3029 TOKIO_SHARED_RT.block_on(async {
3030 let client = MockAssetApiClient { force_error: false };
3031
3032 let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder().account_type(GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
3033
3034 let resp_json: Value = serde_json::from_str(r#"{"details":[{"asset":"ADA","assetFullName":"ADA","amountFree":"6.21","toBTC":"0.00016848","toBNB":"0.01777302","toBNBOffExchange":"0.01741756","exchange":"0.00035546"}],"totalTransferBtc":"0.00016848","totalTransferBNB":"0.01777302","dribbletPercentage":"0.02"}"#).unwrap_or_else(|_| serde_json::json!({}));
3035 let expected_response : models::GetAssetsThatCanBeConvertedIntoBnbResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
3036
3037 let resp = client.get_assets_that_can_be_converted_into_bnb(params).await.expect("Expected a response");
3038 let data_future = resp.data();
3039 let actual_response = data_future.await.unwrap();
3040 assert_eq!(actual_response, expected_response);
3041 });
3042 }
3043
3044 #[test]
3045 fn get_assets_that_can_be_converted_into_bnb_response_error() {
3046 TOKIO_SHARED_RT.block_on(async {
3047 let client = MockAssetApiClient { force_error: true };
3048
3049 let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder()
3050 .build()
3051 .unwrap();
3052
3053 match client
3054 .get_assets_that_can_be_converted_into_bnb(params)
3055 .await
3056 {
3057 Ok(_) => panic!("Expected an error"),
3058 Err(err) => {
3059 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3060 }
3061 }
3062 });
3063 }
3064
3065 #[test]
3066 fn get_cloud_mining_payment_and_refund_history_required_params_success() {
3067 TOKIO_SHARED_RT.block_on(async {
3068 let client = MockAssetApiClient { force_error: false };
3069
3070 let params = GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670,1641782889000,).build().unwrap();
3071
3072 let resp_json: Value = serde_json::from_str(r#"{"total":5,"rows":[{"createTime":1667880112000,"tranId":121230610120,"type":248,"asset":"USDT","amount":"25.0068","status":"S"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3073 let expected_response : models::GetCloudMiningPaymentAndRefundHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse");
3074
3075 let resp = client.get_cloud_mining_payment_and_refund_history(params).await.expect("Expected a response");
3076 let data_future = resp.data();
3077 let actual_response = data_future.await.unwrap();
3078 assert_eq!(actual_response, expected_response);
3079 });
3080 }
3081
3082 #[test]
3083 fn get_cloud_mining_payment_and_refund_history_optional_params_success() {
3084 TOKIO_SHARED_RT.block_on(async {
3085 let client = MockAssetApiClient { force_error: false };
3086
3087 let params = GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670,1641782889000,).tran_id(1).client_tran_id("1".to_string()).asset("BTC".to_string()).current(1).size(10).build().unwrap();
3088
3089 let resp_json: Value = serde_json::from_str(r#"{"total":5,"rows":[{"createTime":1667880112000,"tranId":121230610120,"type":248,"asset":"USDT","amount":"25.0068","status":"S"}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3090 let expected_response : models::GetCloudMiningPaymentAndRefundHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse");
3091
3092 let resp = client.get_cloud_mining_payment_and_refund_history(params).await.expect("Expected a response");
3093 let data_future = resp.data();
3094 let actual_response = data_future.await.unwrap();
3095 assert_eq!(actual_response, expected_response);
3096 });
3097 }
3098
3099 #[test]
3100 fn get_cloud_mining_payment_and_refund_history_response_error() {
3101 TOKIO_SHARED_RT.block_on(async {
3102 let client = MockAssetApiClient { force_error: true };
3103
3104 let params =
3105 GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670, 1641782889000)
3106 .build()
3107 .unwrap();
3108
3109 match client
3110 .get_cloud_mining_payment_and_refund_history(params)
3111 .await
3112 {
3113 Ok(_) => panic!("Expected an error"),
3114 Err(err) => {
3115 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3116 }
3117 }
3118 });
3119 }
3120
3121 #[test]
3122 fn get_open_symbol_list_required_params_success() {
3123 TOKIO_SHARED_RT.block_on(async {
3124 let client = MockAssetApiClient { force_error: false };
3125
3126 let resp_json: Value =
3127 serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
3128 .unwrap_or_else(|_| serde_json::json!({}));
3129 let expected_response: Vec<models::GetOpenSymbolListResponseInner> =
3130 serde_json::from_value(resp_json.clone())
3131 .expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
3132
3133 let resp = client
3134 .get_open_symbol_list()
3135 .await
3136 .expect("Expected a response");
3137 let data_future = resp.data();
3138 let actual_response = data_future.await.unwrap();
3139 assert_eq!(actual_response, expected_response);
3140 });
3141 }
3142
3143 #[test]
3144 fn get_open_symbol_list_optional_params_success() {
3145 TOKIO_SHARED_RT.block_on(async {
3146 let client = MockAssetApiClient { force_error: false };
3147
3148 let resp_json: Value =
3149 serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
3150 .unwrap_or_else(|_| serde_json::json!({}));
3151 let expected_response: Vec<models::GetOpenSymbolListResponseInner> =
3152 serde_json::from_value(resp_json.clone())
3153 .expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
3154
3155 let resp = client
3156 .get_open_symbol_list()
3157 .await
3158 .expect("Expected a response");
3159 let data_future = resp.data();
3160 let actual_response = data_future.await.unwrap();
3161 assert_eq!(actual_response, expected_response);
3162 });
3163 }
3164
3165 #[test]
3166 fn get_open_symbol_list_response_error() {
3167 TOKIO_SHARED_RT.block_on(async {
3168 let client = MockAssetApiClient { force_error: true };
3169
3170 match client.get_open_symbol_list().await {
3171 Ok(_) => panic!("Expected an error"),
3172 Err(err) => {
3173 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3174 }
3175 }
3176 });
3177 }
3178
3179 #[test]
3180 fn get_spot_asset_tags_required_params_success() {
3181 TOKIO_SHARED_RT.block_on(async {
3182 let client = MockAssetApiClient { force_error: false };
3183
3184 let params = GetSpotAssetTagsParams::builder().build().unwrap();
3185
3186 let resp_json: Value = serde_json::from_str(r#"[{"assetCode":"BNB","assetName":"BNB","trading":true,"tags":["Layer1_Layer2","BSC"]}]"#).unwrap_or_else(|_| serde_json::json!({}));
3187 let expected_response : Vec<models::GetSpotAssetTagsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSpotAssetTagsResponseInner>");
3188
3189 let resp = client.get_spot_asset_tags(params).await.expect("Expected a response");
3190 let data_future = resp.data();
3191 let actual_response = data_future.await.unwrap();
3192 assert_eq!(actual_response, expected_response);
3193 });
3194 }
3195
3196 #[test]
3197 fn get_spot_asset_tags_optional_params_success() {
3198 TOKIO_SHARED_RT.block_on(async {
3199 let client = MockAssetApiClient { force_error: false };
3200
3201 let params = GetSpotAssetTagsParams::builder().tag("Layer1_Layer2,BSC".to_string()).build().unwrap();
3202
3203 let resp_json: Value = serde_json::from_str(r#"[{"assetCode":"BNB","assetName":"BNB","trading":true,"tags":["Layer1_Layer2","BSC"]}]"#).unwrap_or_else(|_| serde_json::json!({}));
3204 let expected_response : Vec<models::GetSpotAssetTagsResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetSpotAssetTagsResponseInner>");
3205
3206 let resp = client.get_spot_asset_tags(params).await.expect("Expected a response");
3207 let data_future = resp.data();
3208 let actual_response = data_future.await.unwrap();
3209 assert_eq!(actual_response, expected_response);
3210 });
3211 }
3212
3213 #[test]
3214 fn get_spot_asset_tags_response_error() {
3215 TOKIO_SHARED_RT.block_on(async {
3216 let client = MockAssetApiClient { force_error: true };
3217
3218 let params = GetSpotAssetTagsParams::builder().build().unwrap();
3219
3220 match client.get_spot_asset_tags(params).await {
3221 Ok(_) => panic!("Expected an error"),
3222 Err(err) => {
3223 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3224 }
3225 }
3226 });
3227 }
3228
3229 #[test]
3230 fn query_user_delegation_history_required_params_success() {
3231 TOKIO_SHARED_RT.block_on(async {
3232 let client = MockAssetApiClient { force_error: false };
3233
3234 let params = QueryUserDelegationHistoryParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,).build().unwrap();
3235
3236 let resp_json: Value = serde_json::from_str(r#"{"total":3316,"rows":[{"clientTranId":"293915932290879488","transferType":"Undelegate","asset":"ETH","amount":"1","time":1695205406000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3237 let expected_response : models::QueryUserDelegationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserDelegationHistoryResponse");
3238
3239 let resp = client.query_user_delegation_history(params).await.expect("Expected a response");
3240 let data_future = resp.data();
3241 let actual_response = data_future.await.unwrap();
3242 assert_eq!(actual_response, expected_response);
3243 });
3244 }
3245
3246 #[test]
3247 fn query_user_delegation_history_optional_params_success() {
3248 TOKIO_SHARED_RT.block_on(async {
3249 let client = MockAssetApiClient { force_error: false };
3250
3251 let params = QueryUserDelegationHistoryParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,).r#type(QueryUserDelegationHistoryTypeEnum::Delegate).asset("BTC".to_string()).current(1).size(10).recv_window(5000).build().unwrap();
3252
3253 let resp_json: Value = serde_json::from_str(r#"{"total":3316,"rows":[{"clientTranId":"293915932290879488","transferType":"Undelegate","asset":"ETH","amount":"1","time":1695205406000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3254 let expected_response : models::QueryUserDelegationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserDelegationHistoryResponse");
3255
3256 let resp = client.query_user_delegation_history(params).await.expect("Expected a response");
3257 let data_future = resp.data();
3258 let actual_response = data_future.await.unwrap();
3259 assert_eq!(actual_response, expected_response);
3260 });
3261 }
3262
3263 #[test]
3264 fn query_user_delegation_history_response_error() {
3265 TOKIO_SHARED_RT.block_on(async {
3266 let client = MockAssetApiClient { force_error: true };
3267
3268 let params = QueryUserDelegationHistoryParams::builder(
3269 "abc@test.com".to_string(),
3270 1623319461670,
3271 1641782889000,
3272 )
3273 .build()
3274 .unwrap();
3275
3276 match client.query_user_delegation_history(params).await {
3277 Ok(_) => panic!("Expected an error"),
3278 Err(err) => {
3279 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3280 }
3281 }
3282 });
3283 }
3284
3285 #[test]
3286 fn query_user_universal_transfer_history_required_params_success() {
3287 TOKIO_SHARED_RT.block_on(async {
3288 let client = MockAssetApiClient { force_error: false };
3289
3290 let params = QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string(),).build().unwrap();
3291
3292 let resp_json: Value = serde_json::from_str(r#"{"total":2,"rows":[{"asset":"USDT","amount":"1","type":"MAIN_UMFUTURE","status":"CONFIRMED","tranId":11415955596,"timestamp":1544433328000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3293 let expected_response : models::QueryUserUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
3294
3295 let resp = client.query_user_universal_transfer_history(params).await.expect("Expected a response");
3296 let data_future = resp.data();
3297 let actual_response = data_future.await.unwrap();
3298 assert_eq!(actual_response, expected_response);
3299 });
3300 }
3301
3302 #[test]
3303 fn query_user_universal_transfer_history_optional_params_success() {
3304 TOKIO_SHARED_RT.block_on(async {
3305 let client = MockAssetApiClient { force_error: false };
3306
3307 let params = QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string(),).start_time(1623319461670).end_time(1641782889000).current(1).size(10).from_symbol(QueryUserUniversalTransferHistoryFromSymbolEnum::IsolatedmarginMargin).to_symbol(QueryUserUniversalTransferHistoryToSymbolEnum::MarginIsolatedmargin).recv_window(5000).build().unwrap();
3308
3309 let resp_json: Value = serde_json::from_str(r#"{"total":2,"rows":[{"asset":"USDT","amount":"1","type":"MAIN_UMFUTURE","status":"CONFIRMED","tranId":11415955596,"timestamp":1544433328000}]}"#).unwrap_or_else(|_| serde_json::json!({}));
3310 let expected_response : models::QueryUserUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
3311
3312 let resp = client.query_user_universal_transfer_history(params).await.expect("Expected a response");
3313 let data_future = resp.data();
3314 let actual_response = data_future.await.unwrap();
3315 assert_eq!(actual_response, expected_response);
3316 });
3317 }
3318
3319 #[test]
3320 fn query_user_universal_transfer_history_response_error() {
3321 TOKIO_SHARED_RT.block_on(async {
3322 let client = MockAssetApiClient { force_error: true };
3323
3324 let params =
3325 QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string())
3326 .build()
3327 .unwrap();
3328
3329 match client.query_user_universal_transfer_history(params).await {
3330 Ok(_) => panic!("Expected an error"),
3331 Err(err) => {
3332 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3333 }
3334 }
3335 });
3336 }
3337
3338 #[test]
3339 fn query_user_wallet_balance_required_params_success() {
3340 TOKIO_SHARED_RT.block_on(async {
3341 let client = MockAssetApiClient { force_error: false };
3342
3343 let params = QueryUserWalletBalanceParams::builder().build().unwrap();
3344
3345 let resp_json: Value = serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot","assetBalances":[{"asset":"USDT","assetName":"TetherUS","free":"6.238383","locked":"0","freeze":"0","withdrawing":"0","btcValuation":"6.238383"}]}]"#).unwrap_or_else(|_| serde_json::json!({}));
3346 let expected_response : Vec<models::QueryUserWalletBalanceResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
3347
3348 let resp = client.query_user_wallet_balance(params).await.expect("Expected a response");
3349 let data_future = resp.data();
3350 let actual_response = data_future.await.unwrap();
3351 assert_eq!(actual_response, expected_response);
3352 });
3353 }
3354
3355 #[test]
3356 fn query_user_wallet_balance_optional_params_success() {
3357 TOKIO_SHARED_RT.block_on(async {
3358 let client = MockAssetApiClient { force_error: false };
3359
3360 let params = QueryUserWalletBalanceParams::builder().quote_asset("BTC".to_string()).need_balance_detail(false).recv_window(5000).build().unwrap();
3361
3362 let resp_json: Value = serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot","assetBalances":[{"asset":"USDT","assetName":"TetherUS","free":"6.238383","locked":"0","freeze":"0","withdrawing":"0","btcValuation":"6.238383"}]}]"#).unwrap_or_else(|_| serde_json::json!({}));
3363 let expected_response : Vec<models::QueryUserWalletBalanceResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
3364
3365 let resp = client.query_user_wallet_balance(params).await.expect("Expected a response");
3366 let data_future = resp.data();
3367 let actual_response = data_future.await.unwrap();
3368 assert_eq!(actual_response, expected_response);
3369 });
3370 }
3371
3372 #[test]
3373 fn query_user_wallet_balance_response_error() {
3374 TOKIO_SHARED_RT.block_on(async {
3375 let client = MockAssetApiClient { force_error: true };
3376
3377 let params = QueryUserWalletBalanceParams::builder().build().unwrap();
3378
3379 match client.query_user_wallet_balance(params).await {
3380 Ok(_) => panic!("Expected an error"),
3381 Err(err) => {
3382 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3383 }
3384 }
3385 });
3386 }
3387
3388 #[test]
3389 fn toggle_bnb_burn_on_spot_trade_and_margin_interest_required_params_success() {
3390 TOKIO_SHARED_RT.block_on(async {
3391 let client = MockAssetApiClient { force_error: false };
3392
3393 let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
3394 .build()
3395 .unwrap();
3396
3397 let resp_json: Value =
3398 serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
3399 .unwrap_or_else(|_| serde_json::json!({}));
3400 let expected_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
3401 serde_json::from_value(resp_json.clone()).expect(
3402 "should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
3403 );
3404
3405 let resp = client
3406 .toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
3407 .await
3408 .expect("Expected a response");
3409 let data_future = resp.data();
3410 let actual_response = data_future.await.unwrap();
3411 assert_eq!(actual_response, expected_response);
3412 });
3413 }
3414
3415 #[test]
3416 fn toggle_bnb_burn_on_spot_trade_and_margin_interest_optional_params_success() {
3417 TOKIO_SHARED_RT.block_on(async {
3418 let client = MockAssetApiClient { force_error: false };
3419
3420 let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
3421 .spot_bnb_burn("true".to_string())
3422 .interest_bnb_burn("true".to_string())
3423 .recv_window(5000)
3424 .build()
3425 .unwrap();
3426
3427 let resp_json: Value =
3428 serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
3429 .unwrap_or_else(|_| serde_json::json!({}));
3430 let expected_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
3431 serde_json::from_value(resp_json.clone()).expect(
3432 "should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
3433 );
3434
3435 let resp = client
3436 .toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
3437 .await
3438 .expect("Expected a response");
3439 let data_future = resp.data();
3440 let actual_response = data_future.await.unwrap();
3441 assert_eq!(actual_response, expected_response);
3442 });
3443 }
3444
3445 #[test]
3446 fn toggle_bnb_burn_on_spot_trade_and_margin_interest_response_error() {
3447 TOKIO_SHARED_RT.block_on(async {
3448 let client = MockAssetApiClient { force_error: true };
3449
3450 let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
3451 .build()
3452 .unwrap();
3453
3454 match client
3455 .toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
3456 .await
3457 {
3458 Ok(_) => panic!("Expected an error"),
3459 Err(err) => {
3460 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3461 }
3462 }
3463 });
3464 }
3465
3466 #[test]
3467 fn trade_fee_required_params_success() {
3468 TOKIO_SHARED_RT.block_on(async {
3469 let client = MockAssetApiClient { force_error: false };
3470
3471 let params = TradeFeeParams::builder().build().unwrap();
3472
3473 let resp_json: Value = serde_json::from_str(
3474 r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
3475 )
3476 .unwrap_or_else(|_| serde_json::json!({}));
3477 let expected_response: Vec<models::TradeFeeResponseInner> =
3478 serde_json::from_value(resp_json.clone())
3479 .expect("should parse into Vec<models::TradeFeeResponseInner>");
3480
3481 let resp = client.trade_fee(params).await.expect("Expected a response");
3482 let data_future = resp.data();
3483 let actual_response = data_future.await.unwrap();
3484 assert_eq!(actual_response, expected_response);
3485 });
3486 }
3487
3488 #[test]
3489 fn trade_fee_optional_params_success() {
3490 TOKIO_SHARED_RT.block_on(async {
3491 let client = MockAssetApiClient { force_error: false };
3492
3493 let params = TradeFeeParams::builder()
3494 .symbol("ADABNB".to_string())
3495 .recv_window(5000)
3496 .build()
3497 .unwrap();
3498
3499 let resp_json: Value = serde_json::from_str(
3500 r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
3501 )
3502 .unwrap_or_else(|_| serde_json::json!({}));
3503 let expected_response: Vec<models::TradeFeeResponseInner> =
3504 serde_json::from_value(resp_json.clone())
3505 .expect("should parse into Vec<models::TradeFeeResponseInner>");
3506
3507 let resp = client.trade_fee(params).await.expect("Expected a response");
3508 let data_future = resp.data();
3509 let actual_response = data_future.await.unwrap();
3510 assert_eq!(actual_response, expected_response);
3511 });
3512 }
3513
3514 #[test]
3515 fn trade_fee_response_error() {
3516 TOKIO_SHARED_RT.block_on(async {
3517 let client = MockAssetApiClient { force_error: true };
3518
3519 let params = TradeFeeParams::builder().build().unwrap();
3520
3521 match client.trade_fee(params).await {
3522 Ok(_) => panic!("Expected an error"),
3523 Err(err) => {
3524 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3525 }
3526 }
3527 });
3528 }
3529
3530 #[test]
3531 fn user_asset_required_params_success() {
3532 TOKIO_SHARED_RT.block_on(async {
3533 let client = MockAssetApiClient { force_error: false };
3534
3535 let params = UserAssetParams::builder().build().unwrap();
3536
3537 let resp_json: Value = serde_json::from_str(r#"[{"asset":"AVAX","free":"1","locked":"0","freeze":"0","withdrawing":"0","ipoable":"0","btcValuation":"0"}]"#).unwrap_or_else(|_| serde_json::json!({}));
3538 let expected_response : Vec<models::UserAssetResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UserAssetResponseInner>");
3539
3540 let resp = client.user_asset(params).await.expect("Expected a response");
3541 let data_future = resp.data();
3542 let actual_response = data_future.await.unwrap();
3543 assert_eq!(actual_response, expected_response);
3544 });
3545 }
3546
3547 #[test]
3548 fn user_asset_optional_params_success() {
3549 TOKIO_SHARED_RT.block_on(async {
3550 let client = MockAssetApiClient { force_error: false };
3551
3552 let params = UserAssetParams::builder().asset("BTC".to_string()).need_btc_valuation(true).recv_window(5000).build().unwrap();
3553
3554 let resp_json: Value = serde_json::from_str(r#"[{"asset":"AVAX","free":"1","locked":"0","freeze":"0","withdrawing":"0","ipoable":"0","btcValuation":"0"}]"#).unwrap_or_else(|_| serde_json::json!({}));
3555 let expected_response : Vec<models::UserAssetResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UserAssetResponseInner>");
3556
3557 let resp = client.user_asset(params).await.expect("Expected a response");
3558 let data_future = resp.data();
3559 let actual_response = data_future.await.unwrap();
3560 assert_eq!(actual_response, expected_response);
3561 });
3562 }
3563
3564 #[test]
3565 fn user_asset_response_error() {
3566 TOKIO_SHARED_RT.block_on(async {
3567 let client = MockAssetApiClient { force_error: true };
3568
3569 let params = UserAssetParams::builder().build().unwrap();
3570
3571 match client.user_asset(params).await {
3572 Ok(_) => panic!("Expected an error"),
3573 Err(err) => {
3574 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3575 }
3576 }
3577 });
3578 }
3579
3580 #[test]
3581 fn user_universal_transfer_required_params_success() {
3582 TOKIO_SHARED_RT.block_on(async {
3583 let client = MockAssetApiClient { force_error: false };
3584
3585 let params = UserUniversalTransferParams::builder(
3586 UserUniversalTransferTypeEnum::MainUmfuture,
3587 "BTC".to_string(),
3588 dec!(1.0),
3589 )
3590 .build()
3591 .unwrap();
3592
3593 let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
3594 .unwrap_or_else(|_| serde_json::json!({}));
3595 let expected_response: models::UserUniversalTransferResponse =
3596 serde_json::from_value(resp_json.clone())
3597 .expect("should parse into models::UserUniversalTransferResponse");
3598
3599 let resp = client
3600 .user_universal_transfer(params)
3601 .await
3602 .expect("Expected a response");
3603 let data_future = resp.data();
3604 let actual_response = data_future.await.unwrap();
3605 assert_eq!(actual_response, expected_response);
3606 });
3607 }
3608
3609 #[test]
3610 fn user_universal_transfer_optional_params_success() {
3611 TOKIO_SHARED_RT.block_on(async {
3612 let client = MockAssetApiClient { force_error: false };
3613
3614 let params = UserUniversalTransferParams::builder(
3615 UserUniversalTransferTypeEnum::MainUmfuture,
3616 "BTC".to_string(),
3617 dec!(1.0),
3618 )
3619 .from_symbol(UserUniversalTransferFromSymbolEnum::IsolatedmarginMargin)
3620 .to_symbol(UserUniversalTransferToSymbolEnum::MarginIsolatedmargin)
3621 .recv_window(5000)
3622 .build()
3623 .unwrap();
3624
3625 let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
3626 .unwrap_or_else(|_| serde_json::json!({}));
3627 let expected_response: models::UserUniversalTransferResponse =
3628 serde_json::from_value(resp_json.clone())
3629 .expect("should parse into models::UserUniversalTransferResponse");
3630
3631 let resp = client
3632 .user_universal_transfer(params)
3633 .await
3634 .expect("Expected a response");
3635 let data_future = resp.data();
3636 let actual_response = data_future.await.unwrap();
3637 assert_eq!(actual_response, expected_response);
3638 });
3639 }
3640
3641 #[test]
3642 fn user_universal_transfer_response_error() {
3643 TOKIO_SHARED_RT.block_on(async {
3644 let client = MockAssetApiClient { force_error: true };
3645
3646 let params = UserUniversalTransferParams::builder(
3647 UserUniversalTransferTypeEnum::MainUmfuture,
3648 "BTC".to_string(),
3649 dec!(1.0),
3650 )
3651 .build()
3652 .unwrap();
3653
3654 match client.user_universal_transfer(params).await {
3655 Ok(_) => panic!("Expected an error"),
3656 Err(err) => {
3657 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3658 }
3659 }
3660 });
3661 }
3662}