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 query_user_delegation_history(
74 &self,
75 params: QueryUserDelegationHistoryParams,
76 ) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>>;
77 async fn query_user_universal_transfer_history(
78 &self,
79 params: QueryUserUniversalTransferHistoryParams,
80 ) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>>;
81 async fn query_user_wallet_balance(
82 &self,
83 params: QueryUserWalletBalanceParams,
84 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>>;
85 async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
86 &self,
87 params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
88 ) -> anyhow::Result<RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>>;
89 async fn trade_fee(
90 &self,
91 params: TradeFeeParams,
92 ) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>>;
93 async fn user_asset(
94 &self,
95 params: UserAssetParams,
96 ) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>>;
97 async fn user_universal_transfer(
98 &self,
99 params: UserUniversalTransferParams,
100 ) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>>;
101}
102
103#[derive(Debug, Clone)]
104pub struct AssetApiClient {
105 configuration: ConfigurationRestApi,
106}
107
108impl AssetApiClient {
109 pub fn new(configuration: ConfigurationRestApi) -> Self {
110 Self { configuration }
111 }
112}
113
114#[allow(non_camel_case_types)]
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub enum DustTransferAccountTypeEnum {
117 #[serde(rename = "SPOT")]
118 Spot,
119 #[serde(rename = "MARGIN")]
120 Margin,
121}
122
123impl DustTransferAccountTypeEnum {
124 #[must_use]
125 pub fn as_str(&self) -> &'static str {
126 match self {
127 Self::Spot => "SPOT",
128 Self::Margin => "MARGIN",
129 }
130 }
131}
132
133impl std::str::FromStr for DustTransferAccountTypeEnum {
134 type Err = Box<dyn std::error::Error + Send + Sync>;
135
136 fn from_str(s: &str) -> Result<Self, Self::Err> {
137 match s {
138 "SPOT" => Ok(Self::Spot),
139 "MARGIN" => Ok(Self::Margin),
140 other => Err(format!("invalid DustTransferAccountTypeEnum: {}", other).into()),
141 }
142 }
143}
144
145#[allow(non_camel_case_types)]
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub enum DustlogAccountTypeEnum {
148 #[serde(rename = "SPOT")]
149 Spot,
150 #[serde(rename = "MARGIN")]
151 Margin,
152}
153
154impl DustlogAccountTypeEnum {
155 #[must_use]
156 pub fn as_str(&self) -> &'static str {
157 match self {
158 Self::Spot => "SPOT",
159 Self::Margin => "MARGIN",
160 }
161 }
162}
163
164impl std::str::FromStr for DustlogAccountTypeEnum {
165 type Err = Box<dyn std::error::Error + Send + Sync>;
166
167 fn from_str(s: &str) -> Result<Self, Self::Err> {
168 match s {
169 "SPOT" => Ok(Self::Spot),
170 "MARGIN" => Ok(Self::Margin),
171 other => Err(format!("invalid DustlogAccountTypeEnum: {}", other).into()),
172 }
173 }
174}
175
176#[allow(non_camel_case_types)]
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub enum GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
179 #[serde(rename = "SPOT")]
180 Spot,
181 #[serde(rename = "MARGIN")]
182 Margin,
183}
184
185impl GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
186 #[must_use]
187 pub fn as_str(&self) -> &'static str {
188 match self {
189 Self::Spot => "SPOT",
190 Self::Margin => "MARGIN",
191 }
192 }
193}
194
195impl std::str::FromStr for GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
196 type Err = Box<dyn std::error::Error + Send + Sync>;
197
198 fn from_str(s: &str) -> Result<Self, Self::Err> {
199 match s {
200 "SPOT" => Ok(Self::Spot),
201 "MARGIN" => Ok(Self::Margin),
202 other => Err(format!(
203 "invalid GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum: {}",
204 other
205 )
206 .into()),
207 }
208 }
209}
210
211#[allow(non_camel_case_types)]
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub enum QueryUserDelegationHistoryTypeEnum {
214 #[serde(rename = "DELEGATE")]
215 Delegate,
216 #[serde(rename = "UNDELEGATE")]
217 Undelegate,
218}
219
220impl QueryUserDelegationHistoryTypeEnum {
221 #[must_use]
222 pub fn as_str(&self) -> &'static str {
223 match self {
224 Self::Delegate => "DELEGATE",
225 Self::Undelegate => "UNDELEGATE",
226 }
227 }
228}
229
230impl std::str::FromStr for QueryUserDelegationHistoryTypeEnum {
231 type Err = Box<dyn std::error::Error + Send + Sync>;
232
233 fn from_str(s: &str) -> Result<Self, Self::Err> {
234 match s {
235 "DELEGATE" => Ok(Self::Delegate),
236 "UNDELEGATE" => Ok(Self::Undelegate),
237 other => Err(format!("invalid QueryUserDelegationHistoryTypeEnum: {}", other).into()),
238 }
239 }
240}
241
242#[allow(non_camel_case_types)]
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub enum QueryUserUniversalTransferHistoryFromSymbolEnum {
245 #[serde(rename = "ISOLATEDMARGIN_MARGIN")]
246 IsolatedmarginMargin,
247 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
248 IsolatedmarginIsolatedmargin,
249}
250
251impl QueryUserUniversalTransferHistoryFromSymbolEnum {
252 #[must_use]
253 pub fn as_str(&self) -> &'static str {
254 match self {
255 Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
256 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
257 }
258 }
259}
260
261impl std::str::FromStr for QueryUserUniversalTransferHistoryFromSymbolEnum {
262 type Err = Box<dyn std::error::Error + Send + Sync>;
263
264 fn from_str(s: &str) -> Result<Self, Self::Err> {
265 match s {
266 "ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
267 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
268 other => Err(format!(
269 "invalid QueryUserUniversalTransferHistoryFromSymbolEnum: {}",
270 other
271 )
272 .into()),
273 }
274 }
275}
276
277#[allow(non_camel_case_types)]
278#[derive(Debug, Clone, Serialize, Deserialize)]
279pub enum QueryUserUniversalTransferHistoryToSymbolEnum {
280 #[serde(rename = "MARGIN_ISOLATEDMARGIN")]
281 MarginIsolatedmargin,
282 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
283 IsolatedmarginIsolatedmargin,
284}
285
286impl QueryUserUniversalTransferHistoryToSymbolEnum {
287 #[must_use]
288 pub fn as_str(&self) -> &'static str {
289 match self {
290 Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
291 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
292 }
293 }
294}
295
296impl std::str::FromStr for QueryUserUniversalTransferHistoryToSymbolEnum {
297 type Err = Box<dyn std::error::Error + Send + Sync>;
298
299 fn from_str(s: &str) -> Result<Self, Self::Err> {
300 match s {
301 "MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
302 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
303 other => Err(format!(
304 "invalid QueryUserUniversalTransferHistoryToSymbolEnum: {}",
305 other
306 )
307 .into()),
308 }
309 }
310}
311
312#[allow(non_camel_case_types)]
313#[derive(Debug, Clone, Serialize, Deserialize)]
314pub enum UserUniversalTransferTypeEnum {
315 #[serde(rename = "MAIN_UMFUTURE")]
316 MainUmfuture,
317 #[serde(rename = "MAIN_CMFUTURE")]
318 MainCmfuture,
319 #[serde(rename = "MAIN_MARGIN")]
320 MainMargin,
321 #[serde(rename = "UMFUTURE_MAIN")]
322 UmfutureMain,
323 #[serde(rename = "UMFUTURE_MARGIN")]
324 UmfutureMargin,
325 #[serde(rename = "CMFUTURE_MAIN")]
326 CmfutureMain,
327 #[serde(rename = "CMFUTURE_MARGIN")]
328 CmfutureMargin,
329 #[serde(rename = "MARGIN_MAIN")]
330 MarginMain,
331 #[serde(rename = "MARGIN_UMFUTURE")]
332 MarginUmfuture,
333 #[serde(rename = "MARGIN_CMFUTURE")]
334 MarginCmfuture,
335 #[serde(rename = "ISOLATEDMARGIN_MARGIN")]
336 IsolatedmarginMargin,
337 #[serde(rename = "MARGIN_ISOLATEDMARGIN")]
338 MarginIsolatedmargin,
339 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
340 IsolatedmarginIsolatedmargin,
341 #[serde(rename = "MAIN_FUNDING")]
342 MainFunding,
343 #[serde(rename = "FUNDING_MAIN")]
344 FundingMain,
345 #[serde(rename = "FUNDING_UMFUTURE")]
346 FundingUmfuture,
347 #[serde(rename = "UMFUTURE_FUNDING")]
348 UmfutureFunding,
349 #[serde(rename = "MARGIN_FUNDING")]
350 MarginFunding,
351 #[serde(rename = "FUNDING_MARGIN")]
352 FundingMargin,
353 #[serde(rename = "FUNDING_CMFUTURE")]
354 FundingCmfuture,
355 #[serde(rename = "CMFUTURE_FUNDING")]
356 CmfutureFunding,
357 #[serde(rename = "MAIN_OPTION")]
358 MainOption,
359 #[serde(rename = "OPTION_MAIN")]
360 OptionMain,
361 #[serde(rename = "UMFUTURE_OPTION")]
362 UmfutureOption,
363 #[serde(rename = "OPTION_UMFUTURE")]
364 OptionUmfuture,
365 #[serde(rename = "MARGIN_OPTION")]
366 MarginOption,
367 #[serde(rename = "OPTION_MARGIN")]
368 OptionMargin,
369 #[serde(rename = "FUNDING_OPTION")]
370 FundingOption,
371 #[serde(rename = "OPTION_FUNDING")]
372 OptionFunding,
373 #[serde(rename = "MAIN_PORTFOLIO_MARGIN")]
374 MainPortfolioMargin,
375 #[serde(rename = "PORTFOLIO_MARGIN_MAIN")]
376 PortfolioMarginMain,
377}
378
379impl UserUniversalTransferTypeEnum {
380 #[must_use]
381 pub fn as_str(&self) -> &'static str {
382 match self {
383 Self::MainUmfuture => "MAIN_UMFUTURE",
384 Self::MainCmfuture => "MAIN_CMFUTURE",
385 Self::MainMargin => "MAIN_MARGIN",
386 Self::UmfutureMain => "UMFUTURE_MAIN",
387 Self::UmfutureMargin => "UMFUTURE_MARGIN",
388 Self::CmfutureMain => "CMFUTURE_MAIN",
389 Self::CmfutureMargin => "CMFUTURE_MARGIN",
390 Self::MarginMain => "MARGIN_MAIN",
391 Self::MarginUmfuture => "MARGIN_UMFUTURE",
392 Self::MarginCmfuture => "MARGIN_CMFUTURE",
393 Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
394 Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
395 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
396 Self::MainFunding => "MAIN_FUNDING",
397 Self::FundingMain => "FUNDING_MAIN",
398 Self::FundingUmfuture => "FUNDING_UMFUTURE",
399 Self::UmfutureFunding => "UMFUTURE_FUNDING",
400 Self::MarginFunding => "MARGIN_FUNDING",
401 Self::FundingMargin => "FUNDING_MARGIN",
402 Self::FundingCmfuture => "FUNDING_CMFUTURE",
403 Self::CmfutureFunding => "CMFUTURE_FUNDING",
404 Self::MainOption => "MAIN_OPTION",
405 Self::OptionMain => "OPTION_MAIN",
406 Self::UmfutureOption => "UMFUTURE_OPTION",
407 Self::OptionUmfuture => "OPTION_UMFUTURE",
408 Self::MarginOption => "MARGIN_OPTION",
409 Self::OptionMargin => "OPTION_MARGIN",
410 Self::FundingOption => "FUNDING_OPTION",
411 Self::OptionFunding => "OPTION_FUNDING",
412 Self::MainPortfolioMargin => "MAIN_PORTFOLIO_MARGIN",
413 Self::PortfolioMarginMain => "PORTFOLIO_MARGIN_MAIN",
414 }
415 }
416}
417
418impl std::str::FromStr for UserUniversalTransferTypeEnum {
419 type Err = Box<dyn std::error::Error + Send + Sync>;
420
421 fn from_str(s: &str) -> Result<Self, Self::Err> {
422 match s {
423 "MAIN_UMFUTURE" => Ok(Self::MainUmfuture),
424 "MAIN_CMFUTURE" => Ok(Self::MainCmfuture),
425 "MAIN_MARGIN" => Ok(Self::MainMargin),
426 "UMFUTURE_MAIN" => Ok(Self::UmfutureMain),
427 "UMFUTURE_MARGIN" => Ok(Self::UmfutureMargin),
428 "CMFUTURE_MAIN" => Ok(Self::CmfutureMain),
429 "CMFUTURE_MARGIN" => Ok(Self::CmfutureMargin),
430 "MARGIN_MAIN" => Ok(Self::MarginMain),
431 "MARGIN_UMFUTURE" => Ok(Self::MarginUmfuture),
432 "MARGIN_CMFUTURE" => Ok(Self::MarginCmfuture),
433 "ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
434 "MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
435 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
436 "MAIN_FUNDING" => Ok(Self::MainFunding),
437 "FUNDING_MAIN" => Ok(Self::FundingMain),
438 "FUNDING_UMFUTURE" => Ok(Self::FundingUmfuture),
439 "UMFUTURE_FUNDING" => Ok(Self::UmfutureFunding),
440 "MARGIN_FUNDING" => Ok(Self::MarginFunding),
441 "FUNDING_MARGIN" => Ok(Self::FundingMargin),
442 "FUNDING_CMFUTURE" => Ok(Self::FundingCmfuture),
443 "CMFUTURE_FUNDING" => Ok(Self::CmfutureFunding),
444 "MAIN_OPTION" => Ok(Self::MainOption),
445 "OPTION_MAIN" => Ok(Self::OptionMain),
446 "UMFUTURE_OPTION" => Ok(Self::UmfutureOption),
447 "OPTION_UMFUTURE" => Ok(Self::OptionUmfuture),
448 "MARGIN_OPTION" => Ok(Self::MarginOption),
449 "OPTION_MARGIN" => Ok(Self::OptionMargin),
450 "FUNDING_OPTION" => Ok(Self::FundingOption),
451 "OPTION_FUNDING" => Ok(Self::OptionFunding),
452 "MAIN_PORTFOLIO_MARGIN" => Ok(Self::MainPortfolioMargin),
453 "PORTFOLIO_MARGIN_MAIN" => Ok(Self::PortfolioMarginMain),
454 other => Err(format!("invalid UserUniversalTransferTypeEnum: {}", other).into()),
455 }
456 }
457}
458
459#[allow(non_camel_case_types)]
460#[derive(Debug, Clone, Serialize, Deserialize)]
461pub enum UserUniversalTransferFromSymbolEnum {
462 #[serde(rename = "ISOLATEDMARGIN_MARGIN")]
463 IsolatedmarginMargin,
464 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
465 IsolatedmarginIsolatedmargin,
466}
467
468impl UserUniversalTransferFromSymbolEnum {
469 #[must_use]
470 pub fn as_str(&self) -> &'static str {
471 match self {
472 Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
473 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
474 }
475 }
476}
477
478impl std::str::FromStr for UserUniversalTransferFromSymbolEnum {
479 type Err = Box<dyn std::error::Error + Send + Sync>;
480
481 fn from_str(s: &str) -> Result<Self, Self::Err> {
482 match s {
483 "ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
484 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
485 other => Err(format!("invalid UserUniversalTransferFromSymbolEnum: {}", other).into()),
486 }
487 }
488}
489
490#[allow(non_camel_case_types)]
491#[derive(Debug, Clone, Serialize, Deserialize)]
492pub enum UserUniversalTransferToSymbolEnum {
493 #[serde(rename = "MARGIN_ISOLATEDMARGIN")]
494 MarginIsolatedmargin,
495 #[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
496 IsolatedmarginIsolatedmargin,
497}
498
499impl UserUniversalTransferToSymbolEnum {
500 #[must_use]
501 pub fn as_str(&self) -> &'static str {
502 match self {
503 Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
504 Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
505 }
506 }
507}
508
509impl std::str::FromStr for UserUniversalTransferToSymbolEnum {
510 type Err = Box<dyn std::error::Error + Send + Sync>;
511
512 fn from_str(s: &str) -> Result<Self, Self::Err> {
513 match s {
514 "MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
515 "ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
516 other => Err(format!("invalid UserUniversalTransferToSymbolEnum: {}", other).into()),
517 }
518 }
519}
520
521#[derive(Clone, Debug, Builder, Deserialize, Default)]
526#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
527pub struct AssetDetailParams {
528 #[builder(setter(into), default)]
533 #[serde(rename = "asset", default)]
534 pub asset: Option<String>,
535 #[builder(setter(into), default)]
540 #[serde(rename = "recvWindow", default)]
541 pub recv_window: Option<i64>,
542}
543
544impl AssetDetailParams {
545 #[must_use]
548 pub fn builder() -> AssetDetailParamsBuilder {
549 AssetDetailParamsBuilder::default()
550 }
551}
552#[derive(Clone, Debug, Builder, Deserialize, Default)]
557#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
558pub struct AssetDividendRecordParams {
559 #[builder(setter(into), default)]
564 #[serde(rename = "asset", default)]
565 pub asset: Option<String>,
566 #[builder(setter(into), default)]
571 #[serde(rename = "startTime", default)]
572 pub start_time: Option<i64>,
573 #[builder(setter(into), default)]
578 #[serde(rename = "endTime", default)]
579 pub end_time: Option<i64>,
580 #[builder(setter(into), default)]
585 #[serde(rename = "limit", default)]
586 pub limit: Option<i64>,
587 #[builder(setter(into), default)]
592 #[serde(rename = "recvWindow", default)]
593 pub recv_window: Option<i64>,
594}
595
596impl AssetDividendRecordParams {
597 #[must_use]
600 pub fn builder() -> AssetDividendRecordParamsBuilder {
601 AssetDividendRecordParamsBuilder::default()
602 }
603}
604#[derive(Clone, Debug, Builder, Deserialize)]
609#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
610pub struct DustConvertParams {
611 #[builder(setter(into))]
616 #[serde(rename = "asset")]
617 pub asset: String,
618 #[builder(setter(into), default)]
622 #[serde(rename = "accountType", default)]
623 pub account_type: Option<String>,
624 #[builder(setter(into), default)]
628 #[serde(rename = "clientId", default)]
629 pub client_id: Option<String>,
630 #[builder(setter(into), default)]
635 #[serde(rename = "targetAsset", default)]
636 pub target_asset: Option<String>,
637 #[builder(setter(into), default)]
642 #[serde(rename = "thirdPartyClientId", default)]
643 pub third_party_client_id: Option<String>,
644 #[builder(setter(into), default)]
649 #[serde(rename = "dustQuotaAssetToTargetAssetPrice", default)]
650 pub dust_quota_asset_to_target_asset_price: Option<rust_decimal::Decimal>,
651}
652
653impl DustConvertParams {
654 #[must_use]
661 pub fn builder(asset: String) -> DustConvertParamsBuilder {
662 DustConvertParamsBuilder::default().asset(asset)
663 }
664}
665#[derive(Clone, Debug, Builder, Deserialize)]
670#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
671pub struct DustConvertibleAssetsParams {
672 #[builder(setter(into))]
677 #[serde(rename = "targetAsset")]
678 pub target_asset: String,
679 #[builder(setter(into), default)]
683 #[serde(rename = "accountType", default)]
684 pub account_type: Option<String>,
685 #[builder(setter(into), default)]
690 #[serde(rename = "dustQuotaAssetToTargetAssetPrice", default)]
691 pub dust_quota_asset_to_target_asset_price: Option<rust_decimal::Decimal>,
692}
693
694impl DustConvertibleAssetsParams {
695 #[must_use]
702 pub fn builder(target_asset: String) -> DustConvertibleAssetsParamsBuilder {
703 DustConvertibleAssetsParamsBuilder::default().target_asset(target_asset)
704 }
705}
706#[derive(Clone, Debug, Builder, Deserialize)]
711#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
712pub struct DustTransferParams {
713 #[builder(setter(into))]
717 #[serde(rename = "asset")]
718 pub asset: String,
719 #[builder(setter(into), default)]
724 #[serde(rename = "accountType", default)]
725 pub account_type: Option<DustTransferAccountTypeEnum>,
726 #[builder(setter(into), default)]
731 #[serde(rename = "recvWindow", default)]
732 pub recv_window: Option<i64>,
733}
734
735impl DustTransferParams {
736 #[must_use]
743 pub fn builder(asset: String) -> DustTransferParamsBuilder {
744 DustTransferParamsBuilder::default().asset(asset)
745 }
746}
747#[derive(Clone, Debug, Builder, Deserialize, Default)]
752#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
753pub struct DustlogParams {
754 #[builder(setter(into), default)]
759 #[serde(rename = "accountType", default)]
760 pub account_type: Option<DustlogAccountTypeEnum>,
761 #[builder(setter(into), default)]
766 #[serde(rename = "startTime", default)]
767 pub start_time: Option<i64>,
768 #[builder(setter(into), default)]
773 #[serde(rename = "endTime", default)]
774 pub end_time: Option<i64>,
775 #[builder(setter(into), default)]
780 #[serde(rename = "recvWindow", default)]
781 pub recv_window: Option<i64>,
782}
783
784impl DustlogParams {
785 #[must_use]
788 pub fn builder() -> DustlogParamsBuilder {
789 DustlogParamsBuilder::default()
790 }
791}
792#[derive(Clone, Debug, Builder, Deserialize, Default)]
797#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
798pub struct FundingWalletParams {
799 #[builder(setter(into), default)]
804 #[serde(rename = "asset", default)]
805 pub asset: Option<String>,
806 #[builder(setter(into), default)]
811 #[serde(rename = "needBtcValuation", default)]
812 pub need_btc_valuation: Option<bool>,
813 #[builder(setter(into), default)]
818 #[serde(rename = "recvWindow", default)]
819 pub recv_window: Option<i64>,
820}
821
822impl FundingWalletParams {
823 #[must_use]
826 pub fn builder() -> FundingWalletParamsBuilder {
827 FundingWalletParamsBuilder::default()
828 }
829}
830#[derive(Clone, Debug, Builder, Deserialize, Default)]
835#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
836pub struct GetAssetsThatCanBeConvertedIntoBnbParams {
837 #[builder(setter(into), default)]
842 #[serde(rename = "accountType", default)]
843 pub account_type: Option<GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum>,
844 #[builder(setter(into), default)]
849 #[serde(rename = "recvWindow", default)]
850 pub recv_window: Option<i64>,
851}
852
853impl GetAssetsThatCanBeConvertedIntoBnbParams {
854 #[must_use]
857 pub fn builder() -> GetAssetsThatCanBeConvertedIntoBnbParamsBuilder {
858 GetAssetsThatCanBeConvertedIntoBnbParamsBuilder::default()
859 }
860}
861#[derive(Clone, Debug, Builder, Deserialize)]
866#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
867pub struct GetCloudMiningPaymentAndRefundHistoryParams {
868 #[builder(setter(into))]
872 #[serde(rename = "startTime")]
873 pub start_time: i64,
874 #[builder(setter(into))]
878 #[serde(rename = "endTime")]
879 pub end_time: i64,
880 #[builder(setter(into), default)]
884 #[serde(rename = "tranId", default)]
885 pub tran_id: Option<i64>,
886 #[builder(setter(into), default)]
890 #[serde(rename = "clientTranId", default)]
891 pub client_tran_id: Option<String>,
892 #[builder(setter(into), default)]
896 #[serde(rename = "asset", default)]
897 pub asset: Option<String>,
898 #[builder(setter(into), default)]
903 #[serde(rename = "current", default)]
904 pub current: Option<i64>,
905 #[builder(setter(into), default)]
910 #[serde(rename = "size", default)]
911 pub size: Option<i64>,
912}
913
914impl GetCloudMiningPaymentAndRefundHistoryParams {
915 #[must_use]
923 pub fn builder(
924 start_time: i64,
925 end_time: i64,
926 ) -> GetCloudMiningPaymentAndRefundHistoryParamsBuilder {
927 GetCloudMiningPaymentAndRefundHistoryParamsBuilder::default()
928 .start_time(start_time)
929 .end_time(end_time)
930 }
931}
932#[derive(Clone, Debug, Builder, Deserialize)]
937#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
938pub struct QueryUserDelegationHistoryParams {
939 #[builder(setter(into))]
944 #[serde(rename = "email")]
945 pub email: String,
946 #[builder(setter(into))]
951 #[serde(rename = "startTime")]
952 pub start_time: i64,
953 #[builder(setter(into))]
958 #[serde(rename = "endTime")]
959 pub end_time: i64,
960 #[builder(setter(into), default)]
965 #[serde(rename = "type", default)]
966 pub r#type: Option<QueryUserDelegationHistoryTypeEnum>,
967 #[builder(setter(into), default)]
972 #[serde(rename = "asset", default)]
973 pub asset: Option<String>,
974 #[builder(setter(into), default)]
979 #[serde(rename = "current", default)]
980 pub current: Option<i64>,
981 #[builder(setter(into), default)]
986 #[serde(rename = "size", default)]
987 pub size: Option<i64>,
988 #[builder(setter(into), default)]
993 #[serde(rename = "recvWindow", default)]
994 pub recv_window: Option<i64>,
995}
996
997impl QueryUserDelegationHistoryParams {
998 #[must_use]
1007 pub fn builder(
1008 email: String,
1009 start_time: i64,
1010 end_time: i64,
1011 ) -> QueryUserDelegationHistoryParamsBuilder {
1012 QueryUserDelegationHistoryParamsBuilder::default()
1013 .email(email)
1014 .start_time(start_time)
1015 .end_time(end_time)
1016 }
1017}
1018#[derive(Clone, Debug, Builder, Deserialize)]
1023#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1024pub struct QueryUserUniversalTransferHistoryParams {
1025 #[builder(setter(into))]
1030 #[serde(rename = "type")]
1031 pub r#type: String,
1032 #[builder(setter(into), default)]
1037 #[serde(rename = "startTime", default)]
1038 pub start_time: Option<i64>,
1039 #[builder(setter(into), default)]
1044 #[serde(rename = "endTime", default)]
1045 pub end_time: Option<i64>,
1046 #[builder(setter(into), default)]
1051 #[serde(rename = "current", default)]
1052 pub current: Option<i64>,
1053 #[builder(setter(into), default)]
1058 #[serde(rename = "size", default)]
1059 pub size: Option<i64>,
1060 #[builder(setter(into), default)]
1065 #[serde(rename = "fromSymbol", default)]
1066 pub from_symbol: Option<QueryUserUniversalTransferHistoryFromSymbolEnum>,
1067 #[builder(setter(into), default)]
1072 #[serde(rename = "toSymbol", default)]
1073 pub to_symbol: Option<QueryUserUniversalTransferHistoryToSymbolEnum>,
1074 #[builder(setter(into), default)]
1079 #[serde(rename = "recvWindow", default)]
1080 pub recv_window: Option<i64>,
1081}
1082
1083impl QueryUserUniversalTransferHistoryParams {
1084 #[must_use]
1091 pub fn builder(r#type: String) -> QueryUserUniversalTransferHistoryParamsBuilder {
1092 QueryUserUniversalTransferHistoryParamsBuilder::default().r#type(r#type)
1093 }
1094}
1095#[derive(Clone, Debug, Builder, Deserialize, Default)]
1100#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1101pub struct QueryUserWalletBalanceParams {
1102 #[builder(setter(into), default)]
1107 #[serde(rename = "quoteAsset", default)]
1108 pub quote_asset: Option<String>,
1109 #[builder(setter(into), default)]
1114 #[serde(rename = "recvWindow", default)]
1115 pub recv_window: Option<i64>,
1116}
1117
1118impl QueryUserWalletBalanceParams {
1119 #[must_use]
1122 pub fn builder() -> QueryUserWalletBalanceParamsBuilder {
1123 QueryUserWalletBalanceParamsBuilder::default()
1124 }
1125}
1126#[derive(Clone, Debug, Builder, Deserialize, Default)]
1131#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1132pub struct ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
1133 #[builder(setter(into), default)]
1137 #[serde(rename = "spotBNBBurn", default)]
1138 pub spot_bnb_burn: Option<String>,
1139 #[builder(setter(into), default)]
1143 #[serde(rename = "interestBNBBurn", default)]
1144 pub interest_bnb_burn: Option<String>,
1145 #[builder(setter(into), default)]
1150 #[serde(rename = "recvWindow", default)]
1151 pub recv_window: Option<i64>,
1152}
1153
1154impl ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
1155 #[must_use]
1158 pub fn builder() -> ToggleBnbBurnOnSpotTradeAndMarginInterestParamsBuilder {
1159 ToggleBnbBurnOnSpotTradeAndMarginInterestParamsBuilder::default()
1160 }
1161}
1162#[derive(Clone, Debug, Builder, Deserialize, Default)]
1167#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1168pub struct TradeFeeParams {
1169 #[builder(setter(into), default)]
1174 #[serde(rename = "symbol", default)]
1175 pub symbol: Option<String>,
1176 #[builder(setter(into), default)]
1181 #[serde(rename = "recvWindow", default)]
1182 pub recv_window: Option<i64>,
1183}
1184
1185impl TradeFeeParams {
1186 #[must_use]
1189 pub fn builder() -> TradeFeeParamsBuilder {
1190 TradeFeeParamsBuilder::default()
1191 }
1192}
1193#[derive(Clone, Debug, Builder, Deserialize, Default)]
1198#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1199pub struct UserAssetParams {
1200 #[builder(setter(into), default)]
1204 #[serde(rename = "asset", default)]
1205 pub asset: Option<String>,
1206 #[builder(setter(into), default)]
1210 #[serde(rename = "needBtcValuation", default)]
1211 pub need_btc_valuation: Option<bool>,
1212 #[builder(setter(into), default)]
1217 #[serde(rename = "recvWindow", default)]
1218 pub recv_window: Option<i64>,
1219}
1220
1221impl UserAssetParams {
1222 #[must_use]
1225 pub fn builder() -> UserAssetParamsBuilder {
1226 UserAssetParamsBuilder::default()
1227 }
1228}
1229#[derive(Clone, Debug, Builder, Deserialize)]
1234#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
1235pub struct UserUniversalTransferParams {
1236 #[builder(setter(into))]
1241 #[serde(rename = "type")]
1242 pub r#type: UserUniversalTransferTypeEnum,
1243 #[builder(setter(into))]
1248 #[serde(rename = "asset")]
1249 pub asset: String,
1250 #[builder(setter(into))]
1255 #[serde(rename = "amount")]
1256 pub amount: rust_decimal::Decimal,
1257 #[builder(setter(into), default)]
1262 #[serde(rename = "fromSymbol", default)]
1263 pub from_symbol: Option<UserUniversalTransferFromSymbolEnum>,
1264 #[builder(setter(into), default)]
1269 #[serde(rename = "toSymbol", default)]
1270 pub to_symbol: Option<UserUniversalTransferToSymbolEnum>,
1271 #[builder(setter(into), default)]
1276 #[serde(rename = "recvWindow", default)]
1277 pub recv_window: Option<i64>,
1278}
1279
1280impl UserUniversalTransferParams {
1281 #[must_use]
1290 pub fn builder(
1291 r#type: UserUniversalTransferTypeEnum,
1292 asset: String,
1293 amount: rust_decimal::Decimal,
1294 ) -> UserUniversalTransferParamsBuilder {
1295 UserUniversalTransferParamsBuilder::default()
1296 .r#type(r#type)
1297 .asset(asset)
1298 .amount(amount)
1299 }
1300}
1301
1302#[async_trait]
1303impl AssetApi for AssetApiClient {
1304 async fn asset_detail(
1305 &self,
1306 params: AssetDetailParams,
1307 ) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>> {
1308 let AssetDetailParams { asset, recv_window } = params;
1309
1310 let mut query_params = BTreeMap::new();
1311 let body_params = BTreeMap::new();
1312
1313 if let Some(rw) = asset {
1314 query_params.insert("asset".to_string(), json!(rw));
1315 }
1316
1317 if let Some(rw) = recv_window {
1318 query_params.insert("recvWindow".to_string(), json!(rw));
1319 }
1320
1321 send_request::<models::AssetDetailResponse>(
1322 &self.configuration,
1323 "/sapi/v1/asset/assetDetail",
1324 reqwest::Method::GET,
1325 query_params,
1326 body_params,
1327 if HAS_TIME_UNIT {
1328 self.configuration.time_unit
1329 } else {
1330 None
1331 },
1332 true,
1333 )
1334 .await
1335 }
1336
1337 async fn asset_dividend_record(
1338 &self,
1339 params: AssetDividendRecordParams,
1340 ) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>> {
1341 let AssetDividendRecordParams {
1342 asset,
1343 start_time,
1344 end_time,
1345 limit,
1346 recv_window,
1347 } = params;
1348
1349 let mut query_params = BTreeMap::new();
1350 let body_params = BTreeMap::new();
1351
1352 if let Some(rw) = asset {
1353 query_params.insert("asset".to_string(), json!(rw));
1354 }
1355
1356 if let Some(rw) = start_time {
1357 query_params.insert("startTime".to_string(), json!(rw));
1358 }
1359
1360 if let Some(rw) = end_time {
1361 query_params.insert("endTime".to_string(), json!(rw));
1362 }
1363
1364 if let Some(rw) = limit {
1365 query_params.insert("limit".to_string(), json!(rw));
1366 }
1367
1368 if let Some(rw) = recv_window {
1369 query_params.insert("recvWindow".to_string(), json!(rw));
1370 }
1371
1372 send_request::<models::AssetDividendRecordResponse>(
1373 &self.configuration,
1374 "/sapi/v1/asset/assetDividend",
1375 reqwest::Method::GET,
1376 query_params,
1377 body_params,
1378 if HAS_TIME_UNIT {
1379 self.configuration.time_unit
1380 } else {
1381 None
1382 },
1383 true,
1384 )
1385 .await
1386 }
1387
1388 async fn dust_convert(
1389 &self,
1390 params: DustConvertParams,
1391 ) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>> {
1392 let DustConvertParams {
1393 asset,
1394 account_type,
1395 client_id,
1396 target_asset,
1397 third_party_client_id,
1398 dust_quota_asset_to_target_asset_price,
1399 } = params;
1400
1401 let mut query_params = BTreeMap::new();
1402 let body_params = BTreeMap::new();
1403
1404 query_params.insert("asset".to_string(), json!(asset));
1405
1406 if let Some(rw) = account_type {
1407 query_params.insert("accountType".to_string(), json!(rw));
1408 }
1409
1410 if let Some(rw) = client_id {
1411 query_params.insert("clientId".to_string(), json!(rw));
1412 }
1413
1414 if let Some(rw) = target_asset {
1415 query_params.insert("targetAsset".to_string(), json!(rw));
1416 }
1417
1418 if let Some(rw) = third_party_client_id {
1419 query_params.insert("thirdPartyClientId".to_string(), json!(rw));
1420 }
1421
1422 if let Some(rw) = dust_quota_asset_to_target_asset_price {
1423 query_params.insert("dustQuotaAssetToTargetAssetPrice".to_string(), json!(rw));
1424 }
1425
1426 send_request::<models::DustConvertResponse>(
1427 &self.configuration,
1428 "/sapi/v1/asset/dust-convert/convert",
1429 reqwest::Method::POST,
1430 query_params,
1431 body_params,
1432 if HAS_TIME_UNIT {
1433 self.configuration.time_unit
1434 } else {
1435 None
1436 },
1437 true,
1438 )
1439 .await
1440 }
1441
1442 async fn dust_convertible_assets(
1443 &self,
1444 params: DustConvertibleAssetsParams,
1445 ) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>> {
1446 let DustConvertibleAssetsParams {
1447 target_asset,
1448 account_type,
1449 dust_quota_asset_to_target_asset_price,
1450 } = params;
1451
1452 let mut query_params = BTreeMap::new();
1453 let body_params = BTreeMap::new();
1454
1455 if let Some(rw) = account_type {
1456 query_params.insert("accountType".to_string(), json!(rw));
1457 }
1458
1459 query_params.insert("targetAsset".to_string(), json!(target_asset));
1460
1461 if let Some(rw) = dust_quota_asset_to_target_asset_price {
1462 query_params.insert("dustQuotaAssetToTargetAssetPrice".to_string(), json!(rw));
1463 }
1464
1465 send_request::<models::DustConvertibleAssetsResponse>(
1466 &self.configuration,
1467 "/sapi/v1/asset/dust-convert/query-convertible-assets",
1468 reqwest::Method::POST,
1469 query_params,
1470 body_params,
1471 if HAS_TIME_UNIT {
1472 self.configuration.time_unit
1473 } else {
1474 None
1475 },
1476 true,
1477 )
1478 .await
1479 }
1480
1481 async fn dust_transfer(
1482 &self,
1483 params: DustTransferParams,
1484 ) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>> {
1485 let DustTransferParams {
1486 asset,
1487 account_type,
1488 recv_window,
1489 } = params;
1490
1491 let mut query_params = BTreeMap::new();
1492 let body_params = BTreeMap::new();
1493
1494 query_params.insert("asset".to_string(), json!(asset));
1495
1496 if let Some(rw) = account_type {
1497 query_params.insert("accountType".to_string(), json!(rw));
1498 }
1499
1500 if let Some(rw) = recv_window {
1501 query_params.insert("recvWindow".to_string(), json!(rw));
1502 }
1503
1504 send_request::<models::DustTransferResponse>(
1505 &self.configuration,
1506 "/sapi/v1/asset/dust",
1507 reqwest::Method::POST,
1508 query_params,
1509 body_params,
1510 if HAS_TIME_UNIT {
1511 self.configuration.time_unit
1512 } else {
1513 None
1514 },
1515 true,
1516 )
1517 .await
1518 }
1519
1520 async fn dustlog(
1521 &self,
1522 params: DustlogParams,
1523 ) -> anyhow::Result<RestApiResponse<models::DustlogResponse>> {
1524 let DustlogParams {
1525 account_type,
1526 start_time,
1527 end_time,
1528 recv_window,
1529 } = params;
1530
1531 let mut query_params = BTreeMap::new();
1532 let body_params = BTreeMap::new();
1533
1534 if let Some(rw) = account_type {
1535 query_params.insert("accountType".to_string(), json!(rw));
1536 }
1537
1538 if let Some(rw) = start_time {
1539 query_params.insert("startTime".to_string(), json!(rw));
1540 }
1541
1542 if let Some(rw) = end_time {
1543 query_params.insert("endTime".to_string(), json!(rw));
1544 }
1545
1546 if let Some(rw) = recv_window {
1547 query_params.insert("recvWindow".to_string(), json!(rw));
1548 }
1549
1550 send_request::<models::DustlogResponse>(
1551 &self.configuration,
1552 "/sapi/v1/asset/dribblet",
1553 reqwest::Method::GET,
1554 query_params,
1555 body_params,
1556 if HAS_TIME_UNIT {
1557 self.configuration.time_unit
1558 } else {
1559 None
1560 },
1561 true,
1562 )
1563 .await
1564 }
1565
1566 async fn funding_wallet(
1567 &self,
1568 params: FundingWalletParams,
1569 ) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>> {
1570 let FundingWalletParams {
1571 asset,
1572 need_btc_valuation,
1573 recv_window,
1574 } = params;
1575
1576 let mut query_params = BTreeMap::new();
1577 let body_params = BTreeMap::new();
1578
1579 if let Some(rw) = asset {
1580 query_params.insert("asset".to_string(), json!(rw));
1581 }
1582
1583 if let Some(rw) = need_btc_valuation {
1584 query_params.insert("needBtcValuation".to_string(), json!(rw));
1585 }
1586
1587 if let Some(rw) = recv_window {
1588 query_params.insert("recvWindow".to_string(), json!(rw));
1589 }
1590
1591 send_request::<Vec<models::FundingWalletResponseInner>>(
1592 &self.configuration,
1593 "/sapi/v1/asset/get-funding-asset",
1594 reqwest::Method::POST,
1595 query_params,
1596 body_params,
1597 if HAS_TIME_UNIT {
1598 self.configuration.time_unit
1599 } else {
1600 None
1601 },
1602 true,
1603 )
1604 .await
1605 }
1606
1607 async fn get_assets_that_can_be_converted_into_bnb(
1608 &self,
1609 params: GetAssetsThatCanBeConvertedIntoBnbParams,
1610 ) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>> {
1611 let GetAssetsThatCanBeConvertedIntoBnbParams {
1612 account_type,
1613 recv_window,
1614 } = params;
1615
1616 let mut query_params = BTreeMap::new();
1617 let body_params = BTreeMap::new();
1618
1619 if let Some(rw) = account_type {
1620 query_params.insert("accountType".to_string(), json!(rw));
1621 }
1622
1623 if let Some(rw) = recv_window {
1624 query_params.insert("recvWindow".to_string(), json!(rw));
1625 }
1626
1627 send_request::<models::GetAssetsThatCanBeConvertedIntoBnbResponse>(
1628 &self.configuration,
1629 "/sapi/v1/asset/dust-btc",
1630 reqwest::Method::POST,
1631 query_params,
1632 body_params,
1633 if HAS_TIME_UNIT {
1634 self.configuration.time_unit
1635 } else {
1636 None
1637 },
1638 true,
1639 )
1640 .await
1641 }
1642
1643 async fn get_cloud_mining_payment_and_refund_history(
1644 &self,
1645 params: GetCloudMiningPaymentAndRefundHistoryParams,
1646 ) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>
1647 {
1648 let GetCloudMiningPaymentAndRefundHistoryParams {
1649 start_time,
1650 end_time,
1651 tran_id,
1652 client_tran_id,
1653 asset,
1654 current,
1655 size,
1656 } = params;
1657
1658 let mut query_params = BTreeMap::new();
1659 let body_params = BTreeMap::new();
1660
1661 if let Some(rw) = tran_id {
1662 query_params.insert("tranId".to_string(), json!(rw));
1663 }
1664
1665 if let Some(rw) = client_tran_id {
1666 query_params.insert("clientTranId".to_string(), json!(rw));
1667 }
1668
1669 if let Some(rw) = asset {
1670 query_params.insert("asset".to_string(), json!(rw));
1671 }
1672
1673 query_params.insert("startTime".to_string(), json!(start_time));
1674
1675 query_params.insert("endTime".to_string(), json!(end_time));
1676
1677 if let Some(rw) = current {
1678 query_params.insert("current".to_string(), json!(rw));
1679 }
1680
1681 if let Some(rw) = size {
1682 query_params.insert("size".to_string(), json!(rw));
1683 }
1684
1685 send_request::<models::GetCloudMiningPaymentAndRefundHistoryResponse>(
1686 &self.configuration,
1687 "/sapi/v1/asset/ledger-transfer/cloud-mining/queryByPage",
1688 reqwest::Method::GET,
1689 query_params,
1690 body_params,
1691 if HAS_TIME_UNIT {
1692 self.configuration.time_unit
1693 } else {
1694 None
1695 },
1696 true,
1697 )
1698 .await
1699 }
1700
1701 async fn get_open_symbol_list(
1702 &self,
1703 ) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>> {
1704 let query_params = BTreeMap::new();
1705 let body_params = BTreeMap::new();
1706
1707 send_request::<Vec<models::GetOpenSymbolListResponseInner>>(
1708 &self.configuration,
1709 "/sapi/v1/spot/open-symbol-list",
1710 reqwest::Method::GET,
1711 query_params,
1712 body_params,
1713 if HAS_TIME_UNIT {
1714 self.configuration.time_unit
1715 } else {
1716 None
1717 },
1718 false,
1719 )
1720 .await
1721 }
1722
1723 async fn query_user_delegation_history(
1724 &self,
1725 params: QueryUserDelegationHistoryParams,
1726 ) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>> {
1727 let QueryUserDelegationHistoryParams {
1728 email,
1729 start_time,
1730 end_time,
1731 r#type,
1732 asset,
1733 current,
1734 size,
1735 recv_window,
1736 } = params;
1737
1738 let mut query_params = BTreeMap::new();
1739 let body_params = BTreeMap::new();
1740
1741 query_params.insert("email".to_string(), json!(email));
1742
1743 query_params.insert("startTime".to_string(), json!(start_time));
1744
1745 query_params.insert("endTime".to_string(), json!(end_time));
1746
1747 if let Some(rw) = r#type {
1748 query_params.insert("type".to_string(), json!(rw));
1749 }
1750
1751 if let Some(rw) = asset {
1752 query_params.insert("asset".to_string(), json!(rw));
1753 }
1754
1755 if let Some(rw) = current {
1756 query_params.insert("current".to_string(), json!(rw));
1757 }
1758
1759 if let Some(rw) = size {
1760 query_params.insert("size".to_string(), json!(rw));
1761 }
1762
1763 if let Some(rw) = recv_window {
1764 query_params.insert("recvWindow".to_string(), json!(rw));
1765 }
1766
1767 send_request::<models::QueryUserDelegationHistoryResponse>(
1768 &self.configuration,
1769 "/sapi/v1/asset/custody/transfer-history",
1770 reqwest::Method::GET,
1771 query_params,
1772 body_params,
1773 if HAS_TIME_UNIT {
1774 self.configuration.time_unit
1775 } else {
1776 None
1777 },
1778 true,
1779 )
1780 .await
1781 }
1782
1783 async fn query_user_universal_transfer_history(
1784 &self,
1785 params: QueryUserUniversalTransferHistoryParams,
1786 ) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>> {
1787 let QueryUserUniversalTransferHistoryParams {
1788 r#type,
1789 start_time,
1790 end_time,
1791 current,
1792 size,
1793 from_symbol,
1794 to_symbol,
1795 recv_window,
1796 } = params;
1797
1798 let mut query_params = BTreeMap::new();
1799 let body_params = BTreeMap::new();
1800
1801 query_params.insert("type".to_string(), json!(r#type));
1802
1803 if let Some(rw) = start_time {
1804 query_params.insert("startTime".to_string(), json!(rw));
1805 }
1806
1807 if let Some(rw) = end_time {
1808 query_params.insert("endTime".to_string(), json!(rw));
1809 }
1810
1811 if let Some(rw) = current {
1812 query_params.insert("current".to_string(), json!(rw));
1813 }
1814
1815 if let Some(rw) = size {
1816 query_params.insert("size".to_string(), json!(rw));
1817 }
1818
1819 if let Some(rw) = from_symbol {
1820 query_params.insert("fromSymbol".to_string(), json!(rw));
1821 }
1822
1823 if let Some(rw) = to_symbol {
1824 query_params.insert("toSymbol".to_string(), json!(rw));
1825 }
1826
1827 if let Some(rw) = recv_window {
1828 query_params.insert("recvWindow".to_string(), json!(rw));
1829 }
1830
1831 send_request::<models::QueryUserUniversalTransferHistoryResponse>(
1832 &self.configuration,
1833 "/sapi/v1/asset/transfer",
1834 reqwest::Method::GET,
1835 query_params,
1836 body_params,
1837 if HAS_TIME_UNIT {
1838 self.configuration.time_unit
1839 } else {
1840 None
1841 },
1842 true,
1843 )
1844 .await
1845 }
1846
1847 async fn query_user_wallet_balance(
1848 &self,
1849 params: QueryUserWalletBalanceParams,
1850 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>> {
1851 let QueryUserWalletBalanceParams {
1852 quote_asset,
1853 recv_window,
1854 } = params;
1855
1856 let mut query_params = BTreeMap::new();
1857 let body_params = BTreeMap::new();
1858
1859 if let Some(rw) = quote_asset {
1860 query_params.insert("quoteAsset".to_string(), json!(rw));
1861 }
1862
1863 if let Some(rw) = recv_window {
1864 query_params.insert("recvWindow".to_string(), json!(rw));
1865 }
1866
1867 send_request::<Vec<models::QueryUserWalletBalanceResponseInner>>(
1868 &self.configuration,
1869 "/sapi/v1/asset/wallet/balance",
1870 reqwest::Method::GET,
1871 query_params,
1872 body_params,
1873 if HAS_TIME_UNIT {
1874 self.configuration.time_unit
1875 } else {
1876 None
1877 },
1878 true,
1879 )
1880 .await
1881 }
1882
1883 async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
1884 &self,
1885 params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
1886 ) -> anyhow::Result<RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>>
1887 {
1888 let ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
1889 spot_bnb_burn,
1890 interest_bnb_burn,
1891 recv_window,
1892 } = params;
1893
1894 let mut query_params = BTreeMap::new();
1895 let body_params = BTreeMap::new();
1896
1897 if let Some(rw) = spot_bnb_burn {
1898 query_params.insert("spotBNBBurn".to_string(), json!(rw));
1899 }
1900
1901 if let Some(rw) = interest_bnb_burn {
1902 query_params.insert("interestBNBBurn".to_string(), json!(rw));
1903 }
1904
1905 if let Some(rw) = recv_window {
1906 query_params.insert("recvWindow".to_string(), json!(rw));
1907 }
1908
1909 send_request::<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>(
1910 &self.configuration,
1911 "/sapi/v1/bnbBurn",
1912 reqwest::Method::POST,
1913 query_params,
1914 body_params,
1915 if HAS_TIME_UNIT {
1916 self.configuration.time_unit
1917 } else {
1918 None
1919 },
1920 true,
1921 )
1922 .await
1923 }
1924
1925 async fn trade_fee(
1926 &self,
1927 params: TradeFeeParams,
1928 ) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>> {
1929 let TradeFeeParams {
1930 symbol,
1931 recv_window,
1932 } = params;
1933
1934 let mut query_params = BTreeMap::new();
1935 let body_params = BTreeMap::new();
1936
1937 if let Some(rw) = symbol {
1938 query_params.insert("symbol".to_string(), json!(rw));
1939 }
1940
1941 if let Some(rw) = recv_window {
1942 query_params.insert("recvWindow".to_string(), json!(rw));
1943 }
1944
1945 send_request::<Vec<models::TradeFeeResponseInner>>(
1946 &self.configuration,
1947 "/sapi/v1/asset/tradeFee",
1948 reqwest::Method::GET,
1949 query_params,
1950 body_params,
1951 if HAS_TIME_UNIT {
1952 self.configuration.time_unit
1953 } else {
1954 None
1955 },
1956 true,
1957 )
1958 .await
1959 }
1960
1961 async fn user_asset(
1962 &self,
1963 params: UserAssetParams,
1964 ) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>> {
1965 let UserAssetParams {
1966 asset,
1967 need_btc_valuation,
1968 recv_window,
1969 } = params;
1970
1971 let mut query_params = BTreeMap::new();
1972 let body_params = BTreeMap::new();
1973
1974 if let Some(rw) = asset {
1975 query_params.insert("asset".to_string(), json!(rw));
1976 }
1977
1978 if let Some(rw) = need_btc_valuation {
1979 query_params.insert("needBtcValuation".to_string(), json!(rw));
1980 }
1981
1982 if let Some(rw) = recv_window {
1983 query_params.insert("recvWindow".to_string(), json!(rw));
1984 }
1985
1986 send_request::<Vec<models::UserAssetResponseInner>>(
1987 &self.configuration,
1988 "/sapi/v3/asset/getUserAsset",
1989 reqwest::Method::POST,
1990 query_params,
1991 body_params,
1992 if HAS_TIME_UNIT {
1993 self.configuration.time_unit
1994 } else {
1995 None
1996 },
1997 true,
1998 )
1999 .await
2000 }
2001
2002 async fn user_universal_transfer(
2003 &self,
2004 params: UserUniversalTransferParams,
2005 ) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>> {
2006 let UserUniversalTransferParams {
2007 r#type,
2008 asset,
2009 amount,
2010 from_symbol,
2011 to_symbol,
2012 recv_window,
2013 } = params;
2014
2015 let mut query_params = BTreeMap::new();
2016 let body_params = BTreeMap::new();
2017
2018 query_params.insert("type".to_string(), json!(r#type));
2019
2020 query_params.insert("asset".to_string(), json!(asset));
2021
2022 query_params.insert("amount".to_string(), json!(amount));
2023
2024 if let Some(rw) = from_symbol {
2025 query_params.insert("fromSymbol".to_string(), json!(rw));
2026 }
2027
2028 if let Some(rw) = to_symbol {
2029 query_params.insert("toSymbol".to_string(), json!(rw));
2030 }
2031
2032 if let Some(rw) = recv_window {
2033 query_params.insert("recvWindow".to_string(), json!(rw));
2034 }
2035
2036 send_request::<models::UserUniversalTransferResponse>(
2037 &self.configuration,
2038 "/sapi/v1/asset/transfer",
2039 reqwest::Method::POST,
2040 query_params,
2041 body_params,
2042 if HAS_TIME_UNIT {
2043 self.configuration.time_unit
2044 } else {
2045 None
2046 },
2047 true,
2048 )
2049 .await
2050 }
2051}
2052
2053#[cfg(all(test, feature = "wallet"))]
2054mod tests {
2055 use super::*;
2056 use crate::TOKIO_SHARED_RT;
2057 use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
2058 use async_trait::async_trait;
2059 use std::collections::HashMap;
2060
2061 struct DummyRestApiResponse<T> {
2062 inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
2063 status: u16,
2064 headers: HashMap<String, String>,
2065 rate_limits: Option<Vec<RestApiRateLimit>>,
2066 }
2067
2068 impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
2069 fn from(dummy: DummyRestApiResponse<T>) -> Self {
2070 Self {
2071 data_fn: dummy.inner,
2072 status: dummy.status,
2073 headers: dummy.headers,
2074 rate_limits: dummy.rate_limits,
2075 }
2076 }
2077 }
2078
2079 struct MockAssetApiClient {
2080 force_error: bool,
2081 }
2082
2083 #[async_trait]
2084 impl AssetApi for MockAssetApiClient {
2085 async fn asset_detail(
2086 &self,
2087 _params: AssetDetailParams,
2088 ) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>> {
2089 if self.force_error {
2090 return Err(ConnectorError::ConnectorClientError {
2091 msg: "ResponseError".to_string(),
2092 code: None,
2093 }
2094 .into());
2095 }
2096
2097 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!({}));
2098 let dummy_response: models::AssetDetailResponse =
2099 serde_json::from_value(resp_json.clone())
2100 .expect("should parse into models::AssetDetailResponse");
2101
2102 let dummy = DummyRestApiResponse {
2103 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2104 status: 200,
2105 headers: HashMap::new(),
2106 rate_limits: None,
2107 };
2108
2109 Ok(dummy.into())
2110 }
2111
2112 async fn asset_dividend_record(
2113 &self,
2114 _params: AssetDividendRecordParams,
2115 ) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>> {
2116 if self.force_error {
2117 return Err(ConnectorError::ConnectorClientError {
2118 msg: "ResponseError".to_string(),
2119 code: None,
2120 }
2121 .into());
2122 }
2123
2124 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!({}));
2125 let dummy_response: models::AssetDividendRecordResponse =
2126 serde_json::from_value(resp_json.clone())
2127 .expect("should parse into models::AssetDividendRecordResponse");
2128
2129 let dummy = DummyRestApiResponse {
2130 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2131 status: 200,
2132 headers: HashMap::new(),
2133 rate_limits: None,
2134 };
2135
2136 Ok(dummy.into())
2137 }
2138
2139 async fn dust_convert(
2140 &self,
2141 _params: DustConvertParams,
2142 ) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>> {
2143 if self.force_error {
2144 return Err(ConnectorError::ConnectorClientError {
2145 msg: "ResponseError".to_string(),
2146 code: None,
2147 }
2148 .into());
2149 }
2150
2151 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!({}));
2152 let dummy_response: models::DustConvertResponse =
2153 serde_json::from_value(resp_json.clone())
2154 .expect("should parse into models::DustConvertResponse");
2155
2156 let dummy = DummyRestApiResponse {
2157 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2158 status: 200,
2159 headers: HashMap::new(),
2160 rate_limits: None,
2161 };
2162
2163 Ok(dummy.into())
2164 }
2165
2166 async fn dust_convertible_assets(
2167 &self,
2168 _params: DustConvertibleAssetsParams,
2169 ) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>> {
2170 if self.force_error {
2171 return Err(ConnectorError::ConnectorClientError {
2172 msg: "ResponseError".to_string(),
2173 code: None,
2174 }
2175 .into());
2176 }
2177
2178 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!({}));
2179 let dummy_response: models::DustConvertibleAssetsResponse =
2180 serde_json::from_value(resp_json.clone())
2181 .expect("should parse into models::DustConvertibleAssetsResponse");
2182
2183 let dummy = DummyRestApiResponse {
2184 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2185 status: 200,
2186 headers: HashMap::new(),
2187 rate_limits: None,
2188 };
2189
2190 Ok(dummy.into())
2191 }
2192
2193 async fn dust_transfer(
2194 &self,
2195 _params: DustTransferParams,
2196 ) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>> {
2197 if self.force_error {
2198 return Err(ConnectorError::ConnectorClientError {
2199 msg: "ResponseError".to_string(),
2200 code: None,
2201 }
2202 .into());
2203 }
2204
2205 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!({}));
2206 let dummy_response: models::DustTransferResponse =
2207 serde_json::from_value(resp_json.clone())
2208 .expect("should parse into models::DustTransferResponse");
2209
2210 let dummy = DummyRestApiResponse {
2211 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2212 status: 200,
2213 headers: HashMap::new(),
2214 rate_limits: None,
2215 };
2216
2217 Ok(dummy.into())
2218 }
2219
2220 async fn dustlog(
2221 &self,
2222 _params: DustlogParams,
2223 ) -> anyhow::Result<RestApiResponse<models::DustlogResponse>> {
2224 if self.force_error {
2225 return Err(ConnectorError::ConnectorClientError {
2226 msg: "ResponseError".to_string(),
2227 code: None,
2228 }
2229 .into());
2230 }
2231
2232 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!({}));
2233 let dummy_response: models::DustlogResponse = serde_json::from_value(resp_json.clone())
2234 .expect("should parse into models::DustlogResponse");
2235
2236 let dummy = DummyRestApiResponse {
2237 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2238 status: 200,
2239 headers: HashMap::new(),
2240 rate_limits: None,
2241 };
2242
2243 Ok(dummy.into())
2244 }
2245
2246 async fn funding_wallet(
2247 &self,
2248 _params: FundingWalletParams,
2249 ) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>> {
2250 if self.force_error {
2251 return Err(ConnectorError::ConnectorClientError {
2252 msg: "ResponseError".to_string(),
2253 code: None,
2254 }
2255 .into());
2256 }
2257
2258 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!({}));
2259 let dummy_response: Vec<models::FundingWalletResponseInner> =
2260 serde_json::from_value(resp_json.clone())
2261 .expect("should parse into Vec<models::FundingWalletResponseInner>");
2262
2263 let dummy = DummyRestApiResponse {
2264 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2265 status: 200,
2266 headers: HashMap::new(),
2267 rate_limits: None,
2268 };
2269
2270 Ok(dummy.into())
2271 }
2272
2273 async fn get_assets_that_can_be_converted_into_bnb(
2274 &self,
2275 _params: GetAssetsThatCanBeConvertedIntoBnbParams,
2276 ) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>>
2277 {
2278 if self.force_error {
2279 return Err(ConnectorError::ConnectorClientError {
2280 msg: "ResponseError".to_string(),
2281 code: None,
2282 }
2283 .into());
2284 }
2285
2286 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!({}));
2287 let dummy_response: models::GetAssetsThatCanBeConvertedIntoBnbResponse =
2288 serde_json::from_value(resp_json.clone())
2289 .expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
2290
2291 let dummy = DummyRestApiResponse {
2292 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2293 status: 200,
2294 headers: HashMap::new(),
2295 rate_limits: None,
2296 };
2297
2298 Ok(dummy.into())
2299 }
2300
2301 async fn get_cloud_mining_payment_and_refund_history(
2302 &self,
2303 _params: GetCloudMiningPaymentAndRefundHistoryParams,
2304 ) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>
2305 {
2306 if self.force_error {
2307 return Err(ConnectorError::ConnectorClientError {
2308 msg: "ResponseError".to_string(),
2309 code: None,
2310 }
2311 .into());
2312 }
2313
2314 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!({}));
2315 let dummy_response: models::GetCloudMiningPaymentAndRefundHistoryResponse =
2316 serde_json::from_value(resp_json.clone()).expect(
2317 "should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse",
2318 );
2319
2320 let dummy = DummyRestApiResponse {
2321 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2322 status: 200,
2323 headers: HashMap::new(),
2324 rate_limits: None,
2325 };
2326
2327 Ok(dummy.into())
2328 }
2329
2330 async fn get_open_symbol_list(
2331 &self,
2332 ) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>> {
2333 if self.force_error {
2334 return Err(ConnectorError::ConnectorClientError {
2335 msg: "ResponseError".to_string(),
2336 code: None,
2337 }
2338 .into());
2339 }
2340
2341 let resp_json: Value =
2342 serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
2343 .unwrap_or_else(|_| serde_json::json!({}));
2344 let dummy_response: Vec<models::GetOpenSymbolListResponseInner> =
2345 serde_json::from_value(resp_json.clone())
2346 .expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
2347
2348 let dummy = DummyRestApiResponse {
2349 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2350 status: 200,
2351 headers: HashMap::new(),
2352 rate_limits: None,
2353 };
2354
2355 Ok(dummy.into())
2356 }
2357
2358 async fn query_user_delegation_history(
2359 &self,
2360 _params: QueryUserDelegationHistoryParams,
2361 ) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>> {
2362 if self.force_error {
2363 return Err(ConnectorError::ConnectorClientError {
2364 msg: "ResponseError".to_string(),
2365 code: None,
2366 }
2367 .into());
2368 }
2369
2370 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!({}));
2371 let dummy_response: models::QueryUserDelegationHistoryResponse =
2372 serde_json::from_value(resp_json.clone())
2373 .expect("should parse into models::QueryUserDelegationHistoryResponse");
2374
2375 let dummy = DummyRestApiResponse {
2376 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2377 status: 200,
2378 headers: HashMap::new(),
2379 rate_limits: None,
2380 };
2381
2382 Ok(dummy.into())
2383 }
2384
2385 async fn query_user_universal_transfer_history(
2386 &self,
2387 _params: QueryUserUniversalTransferHistoryParams,
2388 ) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>>
2389 {
2390 if self.force_error {
2391 return Err(ConnectorError::ConnectorClientError {
2392 msg: "ResponseError".to_string(),
2393 code: None,
2394 }
2395 .into());
2396 }
2397
2398 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!({}));
2399 let dummy_response: models::QueryUserUniversalTransferHistoryResponse =
2400 serde_json::from_value(resp_json.clone())
2401 .expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
2402
2403 let dummy = DummyRestApiResponse {
2404 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2405 status: 200,
2406 headers: HashMap::new(),
2407 rate_limits: None,
2408 };
2409
2410 Ok(dummy.into())
2411 }
2412
2413 async fn query_user_wallet_balance(
2414 &self,
2415 _params: QueryUserWalletBalanceParams,
2416 ) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>>
2417 {
2418 if self.force_error {
2419 return Err(ConnectorError::ConnectorClientError {
2420 msg: "ResponseError".to_string(),
2421 code: None,
2422 }
2423 .into());
2424 }
2425
2426 let resp_json: Value =
2427 serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot"}]"#)
2428 .unwrap_or_else(|_| serde_json::json!({}));
2429 let dummy_response: Vec<models::QueryUserWalletBalanceResponseInner> =
2430 serde_json::from_value(resp_json.clone())
2431 .expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
2432
2433 let dummy = DummyRestApiResponse {
2434 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2435 status: 200,
2436 headers: HashMap::new(),
2437 rate_limits: None,
2438 };
2439
2440 Ok(dummy.into())
2441 }
2442
2443 async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
2444 &self,
2445 _params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
2446 ) -> anyhow::Result<
2447 RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>,
2448 > {
2449 if self.force_error {
2450 return Err(ConnectorError::ConnectorClientError {
2451 msg: "ResponseError".to_string(),
2452 code: None,
2453 }
2454 .into());
2455 }
2456
2457 let resp_json: Value =
2458 serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
2459 .unwrap_or_else(|_| serde_json::json!({}));
2460 let dummy_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
2461 serde_json::from_value(resp_json.clone()).expect(
2462 "should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
2463 );
2464
2465 let dummy = DummyRestApiResponse {
2466 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2467 status: 200,
2468 headers: HashMap::new(),
2469 rate_limits: None,
2470 };
2471
2472 Ok(dummy.into())
2473 }
2474
2475 async fn trade_fee(
2476 &self,
2477 _params: TradeFeeParams,
2478 ) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>> {
2479 if self.force_error {
2480 return Err(ConnectorError::ConnectorClientError {
2481 msg: "ResponseError".to_string(),
2482 code: None,
2483 }
2484 .into());
2485 }
2486
2487 let resp_json: Value = serde_json::from_str(
2488 r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
2489 )
2490 .unwrap_or_else(|_| serde_json::json!({}));
2491 let dummy_response: Vec<models::TradeFeeResponseInner> =
2492 serde_json::from_value(resp_json.clone())
2493 .expect("should parse into Vec<models::TradeFeeResponseInner>");
2494
2495 let dummy = DummyRestApiResponse {
2496 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2497 status: 200,
2498 headers: HashMap::new(),
2499 rate_limits: None,
2500 };
2501
2502 Ok(dummy.into())
2503 }
2504
2505 async fn user_asset(
2506 &self,
2507 _params: UserAssetParams,
2508 ) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>> {
2509 if self.force_error {
2510 return Err(ConnectorError::ConnectorClientError {
2511 msg: "ResponseError".to_string(),
2512 code: None,
2513 }
2514 .into());
2515 }
2516
2517 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!({}));
2518 let dummy_response: Vec<models::UserAssetResponseInner> =
2519 serde_json::from_value(resp_json.clone())
2520 .expect("should parse into Vec<models::UserAssetResponseInner>");
2521
2522 let dummy = DummyRestApiResponse {
2523 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2524 status: 200,
2525 headers: HashMap::new(),
2526 rate_limits: None,
2527 };
2528
2529 Ok(dummy.into())
2530 }
2531
2532 async fn user_universal_transfer(
2533 &self,
2534 _params: UserUniversalTransferParams,
2535 ) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>> {
2536 if self.force_error {
2537 return Err(ConnectorError::ConnectorClientError {
2538 msg: "ResponseError".to_string(),
2539 code: None,
2540 }
2541 .into());
2542 }
2543
2544 let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
2545 .unwrap_or_else(|_| serde_json::json!({}));
2546 let dummy_response: models::UserUniversalTransferResponse =
2547 serde_json::from_value(resp_json.clone())
2548 .expect("should parse into models::UserUniversalTransferResponse");
2549
2550 let dummy = DummyRestApiResponse {
2551 inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
2552 status: 200,
2553 headers: HashMap::new(),
2554 rate_limits: None,
2555 };
2556
2557 Ok(dummy.into())
2558 }
2559 }
2560
2561 #[test]
2562 fn asset_detail_required_params_success() {
2563 TOKIO_SHARED_RT.block_on(async {
2564 let client = MockAssetApiClient { force_error: false };
2565
2566 let params = AssetDetailParams::builder().build().unwrap();
2567
2568 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!({}));
2569 let expected_response : models::AssetDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDetailResponse");
2570
2571 let resp = client.asset_detail(params).await.expect("Expected a response");
2572 let data_future = resp.data();
2573 let actual_response = data_future.await.unwrap();
2574 assert_eq!(actual_response, expected_response);
2575 });
2576 }
2577
2578 #[test]
2579 fn asset_detail_optional_params_success() {
2580 TOKIO_SHARED_RT.block_on(async {
2581 let client = MockAssetApiClient { force_error: false };
2582
2583 let params = AssetDetailParams::builder().asset("BTC".to_string()).recv_window(5000).build().unwrap();
2584
2585 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!({}));
2586 let expected_response : models::AssetDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDetailResponse");
2587
2588 let resp = client.asset_detail(params).await.expect("Expected a response");
2589 let data_future = resp.data();
2590 let actual_response = data_future.await.unwrap();
2591 assert_eq!(actual_response, expected_response);
2592 });
2593 }
2594
2595 #[test]
2596 fn asset_detail_response_error() {
2597 TOKIO_SHARED_RT.block_on(async {
2598 let client = MockAssetApiClient { force_error: true };
2599
2600 let params = AssetDetailParams::builder().build().unwrap();
2601
2602 match client.asset_detail(params).await {
2603 Ok(_) => panic!("Expected an error"),
2604 Err(err) => {
2605 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2606 }
2607 }
2608 });
2609 }
2610
2611 #[test]
2612 fn asset_dividend_record_required_params_success() {
2613 TOKIO_SHARED_RT.block_on(async {
2614 let client = MockAssetApiClient { force_error: false };
2615
2616 let params = AssetDividendRecordParams::builder().build().unwrap();
2617
2618 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!({}));
2619 let expected_response : models::AssetDividendRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDividendRecordResponse");
2620
2621 let resp = client.asset_dividend_record(params).await.expect("Expected a response");
2622 let data_future = resp.data();
2623 let actual_response = data_future.await.unwrap();
2624 assert_eq!(actual_response, expected_response);
2625 });
2626 }
2627
2628 #[test]
2629 fn asset_dividend_record_optional_params_success() {
2630 TOKIO_SHARED_RT.block_on(async {
2631 let client = MockAssetApiClient { force_error: false };
2632
2633 let params = AssetDividendRecordParams::builder().asset("BTC".to_string()).start_time(1623319461670).end_time(1641782889000).limit(20).recv_window(5000).build().unwrap();
2634
2635 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!({}));
2636 let expected_response : models::AssetDividendRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDividendRecordResponse");
2637
2638 let resp = client.asset_dividend_record(params).await.expect("Expected a response");
2639 let data_future = resp.data();
2640 let actual_response = data_future.await.unwrap();
2641 assert_eq!(actual_response, expected_response);
2642 });
2643 }
2644
2645 #[test]
2646 fn asset_dividend_record_response_error() {
2647 TOKIO_SHARED_RT.block_on(async {
2648 let client = MockAssetApiClient { force_error: true };
2649
2650 let params = AssetDividendRecordParams::builder().build().unwrap();
2651
2652 match client.asset_dividend_record(params).await {
2653 Ok(_) => panic!("Expected an error"),
2654 Err(err) => {
2655 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2656 }
2657 }
2658 });
2659 }
2660
2661 #[test]
2662 fn dust_convert_required_params_success() {
2663 TOKIO_SHARED_RT.block_on(async {
2664 let client = MockAssetApiClient { force_error: false };
2665
2666 let params = DustConvertParams::builder("USDT".to_string(),).build().unwrap();
2667
2668 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!({}));
2669 let expected_response : models::DustConvertResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertResponse");
2670
2671 let resp = client.dust_convert(params).await.expect("Expected a response");
2672 let data_future = resp.data();
2673 let actual_response = data_future.await.unwrap();
2674 assert_eq!(actual_response, expected_response);
2675 });
2676 }
2677
2678 #[test]
2679 fn dust_convert_optional_params_success() {
2680 TOKIO_SHARED_RT.block_on(async {
2681 let client = MockAssetApiClient { force_error: false };
2682
2683 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();
2684
2685 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!({}));
2686 let expected_response : models::DustConvertResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertResponse");
2687
2688 let resp = client.dust_convert(params).await.expect("Expected a response");
2689 let data_future = resp.data();
2690 let actual_response = data_future.await.unwrap();
2691 assert_eq!(actual_response, expected_response);
2692 });
2693 }
2694
2695 #[test]
2696 fn dust_convert_response_error() {
2697 TOKIO_SHARED_RT.block_on(async {
2698 let client = MockAssetApiClient { force_error: true };
2699
2700 let params = DustConvertParams::builder("USDT".to_string())
2701 .build()
2702 .unwrap();
2703
2704 match client.dust_convert(params).await {
2705 Ok(_) => panic!("Expected an error"),
2706 Err(err) => {
2707 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2708 }
2709 }
2710 });
2711 }
2712
2713 #[test]
2714 fn dust_convertible_assets_required_params_success() {
2715 TOKIO_SHARED_RT.block_on(async {
2716 let client = MockAssetApiClient { force_error: false };
2717
2718 let params = DustConvertibleAssetsParams::builder("BTC".to_string(),).build().unwrap();
2719
2720 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!({}));
2721 let expected_response : models::DustConvertibleAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertibleAssetsResponse");
2722
2723 let resp = client.dust_convertible_assets(params).await.expect("Expected a response");
2724 let data_future = resp.data();
2725 let actual_response = data_future.await.unwrap();
2726 assert_eq!(actual_response, expected_response);
2727 });
2728 }
2729
2730 #[test]
2731 fn dust_convertible_assets_optional_params_success() {
2732 TOKIO_SHARED_RT.block_on(async {
2733 let client = MockAssetApiClient { force_error: false };
2734
2735 let params = DustConvertibleAssetsParams::builder("BTC".to_string(),).account_type("SPOT".to_string()).dust_quota_asset_to_target_asset_price(dec!(1.0)).build().unwrap();
2736
2737 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!({}));
2738 let expected_response : models::DustConvertibleAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertibleAssetsResponse");
2739
2740 let resp = client.dust_convertible_assets(params).await.expect("Expected a response");
2741 let data_future = resp.data();
2742 let actual_response = data_future.await.unwrap();
2743 assert_eq!(actual_response, expected_response);
2744 });
2745 }
2746
2747 #[test]
2748 fn dust_convertible_assets_response_error() {
2749 TOKIO_SHARED_RT.block_on(async {
2750 let client = MockAssetApiClient { force_error: true };
2751
2752 let params = DustConvertibleAssetsParams::builder("BTC".to_string())
2753 .build()
2754 .unwrap();
2755
2756 match client.dust_convertible_assets(params).await {
2757 Ok(_) => panic!("Expected an error"),
2758 Err(err) => {
2759 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2760 }
2761 }
2762 });
2763 }
2764
2765 #[test]
2766 fn dust_transfer_required_params_success() {
2767 TOKIO_SHARED_RT.block_on(async {
2768 let client = MockAssetApiClient { force_error: false };
2769
2770 let params = DustTransferParams::builder("BTC".to_string(),).build().unwrap();
2771
2772 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!({}));
2773 let expected_response : models::DustTransferResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustTransferResponse");
2774
2775 let resp = client.dust_transfer(params).await.expect("Expected a response");
2776 let data_future = resp.data();
2777 let actual_response = data_future.await.unwrap();
2778 assert_eq!(actual_response, expected_response);
2779 });
2780 }
2781
2782 #[test]
2783 fn dust_transfer_optional_params_success() {
2784 TOKIO_SHARED_RT.block_on(async {
2785 let client = MockAssetApiClient { force_error: false };
2786
2787 let params = DustTransferParams::builder("BTC".to_string(),).account_type(DustTransferAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
2788
2789 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!({}));
2790 let expected_response : models::DustTransferResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustTransferResponse");
2791
2792 let resp = client.dust_transfer(params).await.expect("Expected a response");
2793 let data_future = resp.data();
2794 let actual_response = data_future.await.unwrap();
2795 assert_eq!(actual_response, expected_response);
2796 });
2797 }
2798
2799 #[test]
2800 fn dust_transfer_response_error() {
2801 TOKIO_SHARED_RT.block_on(async {
2802 let client = MockAssetApiClient { force_error: true };
2803
2804 let params = DustTransferParams::builder("BTC".to_string())
2805 .build()
2806 .unwrap();
2807
2808 match client.dust_transfer(params).await {
2809 Ok(_) => panic!("Expected an error"),
2810 Err(err) => {
2811 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2812 }
2813 }
2814 });
2815 }
2816
2817 #[test]
2818 fn dustlog_required_params_success() {
2819 TOKIO_SHARED_RT.block_on(async {
2820 let client = MockAssetApiClient { force_error: false };
2821
2822 let params = DustlogParams::builder().build().unwrap();
2823
2824 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!({}));
2825 let expected_response : models::DustlogResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustlogResponse");
2826
2827 let resp = client.dustlog(params).await.expect("Expected a response");
2828 let data_future = resp.data();
2829 let actual_response = data_future.await.unwrap();
2830 assert_eq!(actual_response, expected_response);
2831 });
2832 }
2833
2834 #[test]
2835 fn dustlog_optional_params_success() {
2836 TOKIO_SHARED_RT.block_on(async {
2837 let client = MockAssetApiClient { force_error: false };
2838
2839 let params = DustlogParams::builder().account_type(DustlogAccountTypeEnum::Spot).start_time(1623319461670).end_time(1641782889000).recv_window(5000).build().unwrap();
2840
2841 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!({}));
2842 let expected_response : models::DustlogResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustlogResponse");
2843
2844 let resp = client.dustlog(params).await.expect("Expected a response");
2845 let data_future = resp.data();
2846 let actual_response = data_future.await.unwrap();
2847 assert_eq!(actual_response, expected_response);
2848 });
2849 }
2850
2851 #[test]
2852 fn dustlog_response_error() {
2853 TOKIO_SHARED_RT.block_on(async {
2854 let client = MockAssetApiClient { force_error: true };
2855
2856 let params = DustlogParams::builder().build().unwrap();
2857
2858 match client.dustlog(params).await {
2859 Ok(_) => panic!("Expected an error"),
2860 Err(err) => {
2861 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2862 }
2863 }
2864 });
2865 }
2866
2867 #[test]
2868 fn funding_wallet_required_params_success() {
2869 TOKIO_SHARED_RT.block_on(async {
2870 let client = MockAssetApiClient { force_error: false };
2871
2872 let params = FundingWalletParams::builder().build().unwrap();
2873
2874 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!({}));
2875 let expected_response : Vec<models::FundingWalletResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::FundingWalletResponseInner>");
2876
2877 let resp = client.funding_wallet(params).await.expect("Expected a response");
2878 let data_future = resp.data();
2879 let actual_response = data_future.await.unwrap();
2880 assert_eq!(actual_response, expected_response);
2881 });
2882 }
2883
2884 #[test]
2885 fn funding_wallet_optional_params_success() {
2886 TOKIO_SHARED_RT.block_on(async {
2887 let client = MockAssetApiClient { force_error: false };
2888
2889 let params = FundingWalletParams::builder().asset("BTC".to_string()).need_btc_valuation(true).recv_window(5000).build().unwrap();
2890
2891 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!({}));
2892 let expected_response : Vec<models::FundingWalletResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::FundingWalletResponseInner>");
2893
2894 let resp = client.funding_wallet(params).await.expect("Expected a response");
2895 let data_future = resp.data();
2896 let actual_response = data_future.await.unwrap();
2897 assert_eq!(actual_response, expected_response);
2898 });
2899 }
2900
2901 #[test]
2902 fn funding_wallet_response_error() {
2903 TOKIO_SHARED_RT.block_on(async {
2904 let client = MockAssetApiClient { force_error: true };
2905
2906 let params = FundingWalletParams::builder().build().unwrap();
2907
2908 match client.funding_wallet(params).await {
2909 Ok(_) => panic!("Expected an error"),
2910 Err(err) => {
2911 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2912 }
2913 }
2914 });
2915 }
2916
2917 #[test]
2918 fn get_assets_that_can_be_converted_into_bnb_required_params_success() {
2919 TOKIO_SHARED_RT.block_on(async {
2920 let client = MockAssetApiClient { force_error: false };
2921
2922 let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder().build().unwrap();
2923
2924 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!({}));
2925 let expected_response : models::GetAssetsThatCanBeConvertedIntoBnbResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
2926
2927 let resp = client.get_assets_that_can_be_converted_into_bnb(params).await.expect("Expected a response");
2928 let data_future = resp.data();
2929 let actual_response = data_future.await.unwrap();
2930 assert_eq!(actual_response, expected_response);
2931 });
2932 }
2933
2934 #[test]
2935 fn get_assets_that_can_be_converted_into_bnb_optional_params_success() {
2936 TOKIO_SHARED_RT.block_on(async {
2937 let client = MockAssetApiClient { force_error: false };
2938
2939 let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder().account_type(GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
2940
2941 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!({}));
2942 let expected_response : models::GetAssetsThatCanBeConvertedIntoBnbResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
2943
2944 let resp = client.get_assets_that_can_be_converted_into_bnb(params).await.expect("Expected a response");
2945 let data_future = resp.data();
2946 let actual_response = data_future.await.unwrap();
2947 assert_eq!(actual_response, expected_response);
2948 });
2949 }
2950
2951 #[test]
2952 fn get_assets_that_can_be_converted_into_bnb_response_error() {
2953 TOKIO_SHARED_RT.block_on(async {
2954 let client = MockAssetApiClient { force_error: true };
2955
2956 let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder()
2957 .build()
2958 .unwrap();
2959
2960 match client
2961 .get_assets_that_can_be_converted_into_bnb(params)
2962 .await
2963 {
2964 Ok(_) => panic!("Expected an error"),
2965 Err(err) => {
2966 assert_eq!(err.to_string(), "Connector client error: ResponseError");
2967 }
2968 }
2969 });
2970 }
2971
2972 #[test]
2973 fn get_cloud_mining_payment_and_refund_history_required_params_success() {
2974 TOKIO_SHARED_RT.block_on(async {
2975 let client = MockAssetApiClient { force_error: false };
2976
2977 let params = GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670,1641782889000,).build().unwrap();
2978
2979 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!({}));
2980 let expected_response : models::GetCloudMiningPaymentAndRefundHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse");
2981
2982 let resp = client.get_cloud_mining_payment_and_refund_history(params).await.expect("Expected a response");
2983 let data_future = resp.data();
2984 let actual_response = data_future.await.unwrap();
2985 assert_eq!(actual_response, expected_response);
2986 });
2987 }
2988
2989 #[test]
2990 fn get_cloud_mining_payment_and_refund_history_optional_params_success() {
2991 TOKIO_SHARED_RT.block_on(async {
2992 let client = MockAssetApiClient { force_error: false };
2993
2994 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();
2995
2996 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!({}));
2997 let expected_response : models::GetCloudMiningPaymentAndRefundHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse");
2998
2999 let resp = client.get_cloud_mining_payment_and_refund_history(params).await.expect("Expected a response");
3000 let data_future = resp.data();
3001 let actual_response = data_future.await.unwrap();
3002 assert_eq!(actual_response, expected_response);
3003 });
3004 }
3005
3006 #[test]
3007 fn get_cloud_mining_payment_and_refund_history_response_error() {
3008 TOKIO_SHARED_RT.block_on(async {
3009 let client = MockAssetApiClient { force_error: true };
3010
3011 let params =
3012 GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670, 1641782889000)
3013 .build()
3014 .unwrap();
3015
3016 match client
3017 .get_cloud_mining_payment_and_refund_history(params)
3018 .await
3019 {
3020 Ok(_) => panic!("Expected an error"),
3021 Err(err) => {
3022 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3023 }
3024 }
3025 });
3026 }
3027
3028 #[test]
3029 fn get_open_symbol_list_required_params_success() {
3030 TOKIO_SHARED_RT.block_on(async {
3031 let client = MockAssetApiClient { force_error: false };
3032
3033 let resp_json: Value =
3034 serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
3035 .unwrap_or_else(|_| serde_json::json!({}));
3036 let expected_response: Vec<models::GetOpenSymbolListResponseInner> =
3037 serde_json::from_value(resp_json.clone())
3038 .expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
3039
3040 let resp = client
3041 .get_open_symbol_list()
3042 .await
3043 .expect("Expected a response");
3044 let data_future = resp.data();
3045 let actual_response = data_future.await.unwrap();
3046 assert_eq!(actual_response, expected_response);
3047 });
3048 }
3049
3050 #[test]
3051 fn get_open_symbol_list_optional_params_success() {
3052 TOKIO_SHARED_RT.block_on(async {
3053 let client = MockAssetApiClient { force_error: false };
3054
3055 let resp_json: Value =
3056 serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
3057 .unwrap_or_else(|_| serde_json::json!({}));
3058 let expected_response: Vec<models::GetOpenSymbolListResponseInner> =
3059 serde_json::from_value(resp_json.clone())
3060 .expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
3061
3062 let resp = client
3063 .get_open_symbol_list()
3064 .await
3065 .expect("Expected a response");
3066 let data_future = resp.data();
3067 let actual_response = data_future.await.unwrap();
3068 assert_eq!(actual_response, expected_response);
3069 });
3070 }
3071
3072 #[test]
3073 fn get_open_symbol_list_response_error() {
3074 TOKIO_SHARED_RT.block_on(async {
3075 let client = MockAssetApiClient { force_error: true };
3076
3077 match client.get_open_symbol_list().await {
3078 Ok(_) => panic!("Expected an error"),
3079 Err(err) => {
3080 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3081 }
3082 }
3083 });
3084 }
3085
3086 #[test]
3087 fn query_user_delegation_history_required_params_success() {
3088 TOKIO_SHARED_RT.block_on(async {
3089 let client = MockAssetApiClient { force_error: false };
3090
3091 let params = QueryUserDelegationHistoryParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,).build().unwrap();
3092
3093 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!({}));
3094 let expected_response : models::QueryUserDelegationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserDelegationHistoryResponse");
3095
3096 let resp = client.query_user_delegation_history(params).await.expect("Expected a response");
3097 let data_future = resp.data();
3098 let actual_response = data_future.await.unwrap();
3099 assert_eq!(actual_response, expected_response);
3100 });
3101 }
3102
3103 #[test]
3104 fn query_user_delegation_history_optional_params_success() {
3105 TOKIO_SHARED_RT.block_on(async {
3106 let client = MockAssetApiClient { force_error: false };
3107
3108 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();
3109
3110 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!({}));
3111 let expected_response : models::QueryUserDelegationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserDelegationHistoryResponse");
3112
3113 let resp = client.query_user_delegation_history(params).await.expect("Expected a response");
3114 let data_future = resp.data();
3115 let actual_response = data_future.await.unwrap();
3116 assert_eq!(actual_response, expected_response);
3117 });
3118 }
3119
3120 #[test]
3121 fn query_user_delegation_history_response_error() {
3122 TOKIO_SHARED_RT.block_on(async {
3123 let client = MockAssetApiClient { force_error: true };
3124
3125 let params = QueryUserDelegationHistoryParams::builder(
3126 "abc@test.com".to_string(),
3127 1623319461670,
3128 1641782889000,
3129 )
3130 .build()
3131 .unwrap();
3132
3133 match client.query_user_delegation_history(params).await {
3134 Ok(_) => panic!("Expected an error"),
3135 Err(err) => {
3136 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3137 }
3138 }
3139 });
3140 }
3141
3142 #[test]
3143 fn query_user_universal_transfer_history_required_params_success() {
3144 TOKIO_SHARED_RT.block_on(async {
3145 let client = MockAssetApiClient { force_error: false };
3146
3147 let params = QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string(),).build().unwrap();
3148
3149 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!({}));
3150 let expected_response : models::QueryUserUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
3151
3152 let resp = client.query_user_universal_transfer_history(params).await.expect("Expected a response");
3153 let data_future = resp.data();
3154 let actual_response = data_future.await.unwrap();
3155 assert_eq!(actual_response, expected_response);
3156 });
3157 }
3158
3159 #[test]
3160 fn query_user_universal_transfer_history_optional_params_success() {
3161 TOKIO_SHARED_RT.block_on(async {
3162 let client = MockAssetApiClient { force_error: false };
3163
3164 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();
3165
3166 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!({}));
3167 let expected_response : models::QueryUserUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
3168
3169 let resp = client.query_user_universal_transfer_history(params).await.expect("Expected a response");
3170 let data_future = resp.data();
3171 let actual_response = data_future.await.unwrap();
3172 assert_eq!(actual_response, expected_response);
3173 });
3174 }
3175
3176 #[test]
3177 fn query_user_universal_transfer_history_response_error() {
3178 TOKIO_SHARED_RT.block_on(async {
3179 let client = MockAssetApiClient { force_error: true };
3180
3181 let params =
3182 QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string())
3183 .build()
3184 .unwrap();
3185
3186 match client.query_user_universal_transfer_history(params).await {
3187 Ok(_) => panic!("Expected an error"),
3188 Err(err) => {
3189 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3190 }
3191 }
3192 });
3193 }
3194
3195 #[test]
3196 fn query_user_wallet_balance_required_params_success() {
3197 TOKIO_SHARED_RT.block_on(async {
3198 let client = MockAssetApiClient { force_error: false };
3199
3200 let params = QueryUserWalletBalanceParams::builder().build().unwrap();
3201
3202 let resp_json: Value =
3203 serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot"}]"#)
3204 .unwrap_or_else(|_| serde_json::json!({}));
3205 let expected_response: Vec<models::QueryUserWalletBalanceResponseInner> =
3206 serde_json::from_value(resp_json.clone())
3207 .expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
3208
3209 let resp = client
3210 .query_user_wallet_balance(params)
3211 .await
3212 .expect("Expected a response");
3213 let data_future = resp.data();
3214 let actual_response = data_future.await.unwrap();
3215 assert_eq!(actual_response, expected_response);
3216 });
3217 }
3218
3219 #[test]
3220 fn query_user_wallet_balance_optional_params_success() {
3221 TOKIO_SHARED_RT.block_on(async {
3222 let client = MockAssetApiClient { force_error: false };
3223
3224 let params = QueryUserWalletBalanceParams::builder()
3225 .quote_asset("BTC".to_string())
3226 .recv_window(5000)
3227 .build()
3228 .unwrap();
3229
3230 let resp_json: Value =
3231 serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot"}]"#)
3232 .unwrap_or_else(|_| serde_json::json!({}));
3233 let expected_response: Vec<models::QueryUserWalletBalanceResponseInner> =
3234 serde_json::from_value(resp_json.clone())
3235 .expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
3236
3237 let resp = client
3238 .query_user_wallet_balance(params)
3239 .await
3240 .expect("Expected a response");
3241 let data_future = resp.data();
3242 let actual_response = data_future.await.unwrap();
3243 assert_eq!(actual_response, expected_response);
3244 });
3245 }
3246
3247 #[test]
3248 fn query_user_wallet_balance_response_error() {
3249 TOKIO_SHARED_RT.block_on(async {
3250 let client = MockAssetApiClient { force_error: true };
3251
3252 let params = QueryUserWalletBalanceParams::builder().build().unwrap();
3253
3254 match client.query_user_wallet_balance(params).await {
3255 Ok(_) => panic!("Expected an error"),
3256 Err(err) => {
3257 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3258 }
3259 }
3260 });
3261 }
3262
3263 #[test]
3264 fn toggle_bnb_burn_on_spot_trade_and_margin_interest_required_params_success() {
3265 TOKIO_SHARED_RT.block_on(async {
3266 let client = MockAssetApiClient { force_error: false };
3267
3268 let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
3269 .build()
3270 .unwrap();
3271
3272 let resp_json: Value =
3273 serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
3274 .unwrap_or_else(|_| serde_json::json!({}));
3275 let expected_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
3276 serde_json::from_value(resp_json.clone()).expect(
3277 "should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
3278 );
3279
3280 let resp = client
3281 .toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
3282 .await
3283 .expect("Expected a response");
3284 let data_future = resp.data();
3285 let actual_response = data_future.await.unwrap();
3286 assert_eq!(actual_response, expected_response);
3287 });
3288 }
3289
3290 #[test]
3291 fn toggle_bnb_burn_on_spot_trade_and_margin_interest_optional_params_success() {
3292 TOKIO_SHARED_RT.block_on(async {
3293 let client = MockAssetApiClient { force_error: false };
3294
3295 let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
3296 .spot_bnb_burn("true".to_string())
3297 .interest_bnb_burn("true".to_string())
3298 .recv_window(5000)
3299 .build()
3300 .unwrap();
3301
3302 let resp_json: Value =
3303 serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
3304 .unwrap_or_else(|_| serde_json::json!({}));
3305 let expected_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
3306 serde_json::from_value(resp_json.clone()).expect(
3307 "should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
3308 );
3309
3310 let resp = client
3311 .toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
3312 .await
3313 .expect("Expected a response");
3314 let data_future = resp.data();
3315 let actual_response = data_future.await.unwrap();
3316 assert_eq!(actual_response, expected_response);
3317 });
3318 }
3319
3320 #[test]
3321 fn toggle_bnb_burn_on_spot_trade_and_margin_interest_response_error() {
3322 TOKIO_SHARED_RT.block_on(async {
3323 let client = MockAssetApiClient { force_error: true };
3324
3325 let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
3326 .build()
3327 .unwrap();
3328
3329 match client
3330 .toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
3331 .await
3332 {
3333 Ok(_) => panic!("Expected an error"),
3334 Err(err) => {
3335 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3336 }
3337 }
3338 });
3339 }
3340
3341 #[test]
3342 fn trade_fee_required_params_success() {
3343 TOKIO_SHARED_RT.block_on(async {
3344 let client = MockAssetApiClient { force_error: false };
3345
3346 let params = TradeFeeParams::builder().build().unwrap();
3347
3348 let resp_json: Value = serde_json::from_str(
3349 r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
3350 )
3351 .unwrap_or_else(|_| serde_json::json!({}));
3352 let expected_response: Vec<models::TradeFeeResponseInner> =
3353 serde_json::from_value(resp_json.clone())
3354 .expect("should parse into Vec<models::TradeFeeResponseInner>");
3355
3356 let resp = client.trade_fee(params).await.expect("Expected a response");
3357 let data_future = resp.data();
3358 let actual_response = data_future.await.unwrap();
3359 assert_eq!(actual_response, expected_response);
3360 });
3361 }
3362
3363 #[test]
3364 fn trade_fee_optional_params_success() {
3365 TOKIO_SHARED_RT.block_on(async {
3366 let client = MockAssetApiClient { force_error: false };
3367
3368 let params = TradeFeeParams::builder()
3369 .symbol("ADABNB".to_string())
3370 .recv_window(5000)
3371 .build()
3372 .unwrap();
3373
3374 let resp_json: Value = serde_json::from_str(
3375 r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
3376 )
3377 .unwrap_or_else(|_| serde_json::json!({}));
3378 let expected_response: Vec<models::TradeFeeResponseInner> =
3379 serde_json::from_value(resp_json.clone())
3380 .expect("should parse into Vec<models::TradeFeeResponseInner>");
3381
3382 let resp = client.trade_fee(params).await.expect("Expected a response");
3383 let data_future = resp.data();
3384 let actual_response = data_future.await.unwrap();
3385 assert_eq!(actual_response, expected_response);
3386 });
3387 }
3388
3389 #[test]
3390 fn trade_fee_response_error() {
3391 TOKIO_SHARED_RT.block_on(async {
3392 let client = MockAssetApiClient { force_error: true };
3393
3394 let params = TradeFeeParams::builder().build().unwrap();
3395
3396 match client.trade_fee(params).await {
3397 Ok(_) => panic!("Expected an error"),
3398 Err(err) => {
3399 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3400 }
3401 }
3402 });
3403 }
3404
3405 #[test]
3406 fn user_asset_required_params_success() {
3407 TOKIO_SHARED_RT.block_on(async {
3408 let client = MockAssetApiClient { force_error: false };
3409
3410 let params = UserAssetParams::builder().build().unwrap();
3411
3412 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!({}));
3413 let expected_response : Vec<models::UserAssetResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UserAssetResponseInner>");
3414
3415 let resp = client.user_asset(params).await.expect("Expected a response");
3416 let data_future = resp.data();
3417 let actual_response = data_future.await.unwrap();
3418 assert_eq!(actual_response, expected_response);
3419 });
3420 }
3421
3422 #[test]
3423 fn user_asset_optional_params_success() {
3424 TOKIO_SHARED_RT.block_on(async {
3425 let client = MockAssetApiClient { force_error: false };
3426
3427 let params = UserAssetParams::builder().asset("BTC".to_string()).need_btc_valuation(true).recv_window(5000).build().unwrap();
3428
3429 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!({}));
3430 let expected_response : Vec<models::UserAssetResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UserAssetResponseInner>");
3431
3432 let resp = client.user_asset(params).await.expect("Expected a response");
3433 let data_future = resp.data();
3434 let actual_response = data_future.await.unwrap();
3435 assert_eq!(actual_response, expected_response);
3436 });
3437 }
3438
3439 #[test]
3440 fn user_asset_response_error() {
3441 TOKIO_SHARED_RT.block_on(async {
3442 let client = MockAssetApiClient { force_error: true };
3443
3444 let params = UserAssetParams::builder().build().unwrap();
3445
3446 match client.user_asset(params).await {
3447 Ok(_) => panic!("Expected an error"),
3448 Err(err) => {
3449 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3450 }
3451 }
3452 });
3453 }
3454
3455 #[test]
3456 fn user_universal_transfer_required_params_success() {
3457 TOKIO_SHARED_RT.block_on(async {
3458 let client = MockAssetApiClient { force_error: false };
3459
3460 let params = UserUniversalTransferParams::builder(
3461 UserUniversalTransferTypeEnum::MainUmfuture,
3462 "BTC".to_string(),
3463 dec!(1.0),
3464 )
3465 .build()
3466 .unwrap();
3467
3468 let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
3469 .unwrap_or_else(|_| serde_json::json!({}));
3470 let expected_response: models::UserUniversalTransferResponse =
3471 serde_json::from_value(resp_json.clone())
3472 .expect("should parse into models::UserUniversalTransferResponse");
3473
3474 let resp = client
3475 .user_universal_transfer(params)
3476 .await
3477 .expect("Expected a response");
3478 let data_future = resp.data();
3479 let actual_response = data_future.await.unwrap();
3480 assert_eq!(actual_response, expected_response);
3481 });
3482 }
3483
3484 #[test]
3485 fn user_universal_transfer_optional_params_success() {
3486 TOKIO_SHARED_RT.block_on(async {
3487 let client = MockAssetApiClient { force_error: false };
3488
3489 let params = UserUniversalTransferParams::builder(
3490 UserUniversalTransferTypeEnum::MainUmfuture,
3491 "BTC".to_string(),
3492 dec!(1.0),
3493 )
3494 .from_symbol(UserUniversalTransferFromSymbolEnum::IsolatedmarginMargin)
3495 .to_symbol(UserUniversalTransferToSymbolEnum::MarginIsolatedmargin)
3496 .recv_window(5000)
3497 .build()
3498 .unwrap();
3499
3500 let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
3501 .unwrap_or_else(|_| serde_json::json!({}));
3502 let expected_response: models::UserUniversalTransferResponse =
3503 serde_json::from_value(resp_json.clone())
3504 .expect("should parse into models::UserUniversalTransferResponse");
3505
3506 let resp = client
3507 .user_universal_transfer(params)
3508 .await
3509 .expect("Expected a response");
3510 let data_future = resp.data();
3511 let actual_response = data_future.await.unwrap();
3512 assert_eq!(actual_response, expected_response);
3513 });
3514 }
3515
3516 #[test]
3517 fn user_universal_transfer_response_error() {
3518 TOKIO_SHARED_RT.block_on(async {
3519 let client = MockAssetApiClient { force_error: true };
3520
3521 let params = UserUniversalTransferParams::builder(
3522 UserUniversalTransferTypeEnum::MainUmfuture,
3523 "BTC".to_string(),
3524 dec!(1.0),
3525 )
3526 .build()
3527 .unwrap();
3528
3529 match client.user_universal_transfer(params).await {
3530 Ok(_) => panic!("Expected an error"),
3531 Err(err) => {
3532 assert_eq!(err.to_string(), "Connector client error: ResponseError");
3533 }
3534 }
3535 });
3536 }
3537}