#![allow(unused_imports)]
use async_trait::async_trait;
use derive_builder::Builder;
use reqwest;
use rust_decimal::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::collections::BTreeMap;
use crate::common::{
config::ConfigurationRestApi,
models::{ParamBuildError, RestApiResponse},
utils::send_request,
};
use crate::wallet::rest_api::models;
const HAS_TIME_UNIT: bool = false;
#[async_trait]
pub trait AssetApi: Send + Sync {
async fn asset_detail(
&self,
params: AssetDetailParams,
) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>>;
async fn asset_dividend_record(
&self,
params: AssetDividendRecordParams,
) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>>;
async fn dust_convert(
&self,
params: DustConvertParams,
) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>>;
async fn dust_convertible_assets(
&self,
params: DustConvertibleAssetsParams,
) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>>;
async fn dust_transfer(
&self,
params: DustTransferParams,
) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>>;
async fn dustlog(
&self,
params: DustlogParams,
) -> anyhow::Result<RestApiResponse<models::DustlogResponse>>;
async fn funding_wallet(
&self,
params: FundingWalletParams,
) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>>;
async fn get_assets_that_can_be_converted_into_bnb(
&self,
params: GetAssetsThatCanBeConvertedIntoBnbParams,
) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>>;
async fn get_cloud_mining_payment_and_refund_history(
&self,
params: GetCloudMiningPaymentAndRefundHistoryParams,
) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>;
async fn get_open_symbol_list(
&self,
) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>>;
async fn query_user_delegation_history(
&self,
params: QueryUserDelegationHistoryParams,
) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>>;
async fn query_user_universal_transfer_history(
&self,
params: QueryUserUniversalTransferHistoryParams,
) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>>;
async fn query_user_wallet_balance(
&self,
params: QueryUserWalletBalanceParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>>;
async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
&self,
params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
) -> anyhow::Result<RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>>;
async fn trade_fee(
&self,
params: TradeFeeParams,
) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>>;
async fn user_asset(
&self,
params: UserAssetParams,
) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>>;
async fn user_universal_transfer(
&self,
params: UserUniversalTransferParams,
) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>>;
}
#[derive(Debug, Clone)]
pub struct AssetApiClient {
configuration: ConfigurationRestApi,
}
impl AssetApiClient {
pub fn new(configuration: ConfigurationRestApi) -> Self {
Self { configuration }
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DustTransferAccountTypeEnum {
#[serde(rename = "SPOT")]
Spot,
#[serde(rename = "MARGIN")]
Margin,
}
impl DustTransferAccountTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Spot => "SPOT",
Self::Margin => "MARGIN",
}
}
}
impl std::str::FromStr for DustTransferAccountTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SPOT" => Ok(Self::Spot),
"MARGIN" => Ok(Self::Margin),
other => Err(format!("invalid DustTransferAccountTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DustlogAccountTypeEnum {
#[serde(rename = "SPOT")]
Spot,
#[serde(rename = "MARGIN")]
Margin,
}
impl DustlogAccountTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Spot => "SPOT",
Self::Margin => "MARGIN",
}
}
}
impl std::str::FromStr for DustlogAccountTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SPOT" => Ok(Self::Spot),
"MARGIN" => Ok(Self::Margin),
other => Err(format!("invalid DustlogAccountTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
#[serde(rename = "SPOT")]
Spot,
#[serde(rename = "MARGIN")]
Margin,
}
impl GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Spot => "SPOT",
Self::Margin => "MARGIN",
}
}
}
impl std::str::FromStr for GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SPOT" => Ok(Self::Spot),
"MARGIN" => Ok(Self::Margin),
other => Err(format!(
"invalid GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum: {}",
other
)
.into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum QueryUserDelegationHistoryTypeEnum {
#[serde(rename = "DELEGATE")]
Delegate,
#[serde(rename = "UNDELEGATE")]
Undelegate,
}
impl QueryUserDelegationHistoryTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Delegate => "DELEGATE",
Self::Undelegate => "UNDELEGATE",
}
}
}
impl std::str::FromStr for QueryUserDelegationHistoryTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"DELEGATE" => Ok(Self::Delegate),
"UNDELEGATE" => Ok(Self::Undelegate),
other => Err(format!("invalid QueryUserDelegationHistoryTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum QueryUserUniversalTransferHistoryFromSymbolEnum {
#[serde(rename = "ISOLATEDMARGIN_MARGIN")]
IsolatedmarginMargin,
#[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
IsolatedmarginIsolatedmargin,
}
impl QueryUserUniversalTransferHistoryFromSymbolEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
}
}
}
impl std::str::FromStr for QueryUserUniversalTransferHistoryFromSymbolEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
"ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
other => Err(format!(
"invalid QueryUserUniversalTransferHistoryFromSymbolEnum: {}",
other
)
.into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum QueryUserUniversalTransferHistoryToSymbolEnum {
#[serde(rename = "MARGIN_ISOLATEDMARGIN")]
MarginIsolatedmargin,
#[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
IsolatedmarginIsolatedmargin,
}
impl QueryUserUniversalTransferHistoryToSymbolEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
}
}
}
impl std::str::FromStr for QueryUserUniversalTransferHistoryToSymbolEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
"ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
other => Err(format!(
"invalid QueryUserUniversalTransferHistoryToSymbolEnum: {}",
other
)
.into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UserUniversalTransferTypeEnum {
#[serde(rename = "MAIN_UMFUTURE")]
MainUmfuture,
#[serde(rename = "MAIN_CMFUTURE")]
MainCmfuture,
#[serde(rename = "MAIN_MARGIN")]
MainMargin,
#[serde(rename = "UMFUTURE_MAIN")]
UmfutureMain,
#[serde(rename = "UMFUTURE_MARGIN")]
UmfutureMargin,
#[serde(rename = "CMFUTURE_MAIN")]
CmfutureMain,
#[serde(rename = "CMFUTURE_MARGIN")]
CmfutureMargin,
#[serde(rename = "MARGIN_MAIN")]
MarginMain,
#[serde(rename = "MARGIN_UMFUTURE")]
MarginUmfuture,
#[serde(rename = "MARGIN_CMFUTURE")]
MarginCmfuture,
#[serde(rename = "ISOLATEDMARGIN_MARGIN")]
IsolatedmarginMargin,
#[serde(rename = "MARGIN_ISOLATEDMARGIN")]
MarginIsolatedmargin,
#[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
IsolatedmarginIsolatedmargin,
#[serde(rename = "MAIN_FUNDING")]
MainFunding,
#[serde(rename = "FUNDING_MAIN")]
FundingMain,
#[serde(rename = "FUNDING_UMFUTURE")]
FundingUmfuture,
#[serde(rename = "UMFUTURE_FUNDING")]
UmfutureFunding,
#[serde(rename = "MARGIN_FUNDING")]
MarginFunding,
#[serde(rename = "FUNDING_MARGIN")]
FundingMargin,
#[serde(rename = "FUNDING_CMFUTURE")]
FundingCmfuture,
#[serde(rename = "CMFUTURE_FUNDING")]
CmfutureFunding,
#[serde(rename = "MAIN_OPTION")]
MainOption,
#[serde(rename = "OPTION_MAIN")]
OptionMain,
#[serde(rename = "UMFUTURE_OPTION")]
UmfutureOption,
#[serde(rename = "OPTION_UMFUTURE")]
OptionUmfuture,
#[serde(rename = "MARGIN_OPTION")]
MarginOption,
#[serde(rename = "OPTION_MARGIN")]
OptionMargin,
#[serde(rename = "FUNDING_OPTION")]
FundingOption,
#[serde(rename = "OPTION_FUNDING")]
OptionFunding,
#[serde(rename = "MAIN_PORTFOLIO_MARGIN")]
MainPortfolioMargin,
#[serde(rename = "PORTFOLIO_MARGIN_MAIN")]
PortfolioMarginMain,
}
impl UserUniversalTransferTypeEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MainUmfuture => "MAIN_UMFUTURE",
Self::MainCmfuture => "MAIN_CMFUTURE",
Self::MainMargin => "MAIN_MARGIN",
Self::UmfutureMain => "UMFUTURE_MAIN",
Self::UmfutureMargin => "UMFUTURE_MARGIN",
Self::CmfutureMain => "CMFUTURE_MAIN",
Self::CmfutureMargin => "CMFUTURE_MARGIN",
Self::MarginMain => "MARGIN_MAIN",
Self::MarginUmfuture => "MARGIN_UMFUTURE",
Self::MarginCmfuture => "MARGIN_CMFUTURE",
Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
Self::MainFunding => "MAIN_FUNDING",
Self::FundingMain => "FUNDING_MAIN",
Self::FundingUmfuture => "FUNDING_UMFUTURE",
Self::UmfutureFunding => "UMFUTURE_FUNDING",
Self::MarginFunding => "MARGIN_FUNDING",
Self::FundingMargin => "FUNDING_MARGIN",
Self::FundingCmfuture => "FUNDING_CMFUTURE",
Self::CmfutureFunding => "CMFUTURE_FUNDING",
Self::MainOption => "MAIN_OPTION",
Self::OptionMain => "OPTION_MAIN",
Self::UmfutureOption => "UMFUTURE_OPTION",
Self::OptionUmfuture => "OPTION_UMFUTURE",
Self::MarginOption => "MARGIN_OPTION",
Self::OptionMargin => "OPTION_MARGIN",
Self::FundingOption => "FUNDING_OPTION",
Self::OptionFunding => "OPTION_FUNDING",
Self::MainPortfolioMargin => "MAIN_PORTFOLIO_MARGIN",
Self::PortfolioMarginMain => "PORTFOLIO_MARGIN_MAIN",
}
}
}
impl std::str::FromStr for UserUniversalTransferTypeEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"MAIN_UMFUTURE" => Ok(Self::MainUmfuture),
"MAIN_CMFUTURE" => Ok(Self::MainCmfuture),
"MAIN_MARGIN" => Ok(Self::MainMargin),
"UMFUTURE_MAIN" => Ok(Self::UmfutureMain),
"UMFUTURE_MARGIN" => Ok(Self::UmfutureMargin),
"CMFUTURE_MAIN" => Ok(Self::CmfutureMain),
"CMFUTURE_MARGIN" => Ok(Self::CmfutureMargin),
"MARGIN_MAIN" => Ok(Self::MarginMain),
"MARGIN_UMFUTURE" => Ok(Self::MarginUmfuture),
"MARGIN_CMFUTURE" => Ok(Self::MarginCmfuture),
"ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
"MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
"ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
"MAIN_FUNDING" => Ok(Self::MainFunding),
"FUNDING_MAIN" => Ok(Self::FundingMain),
"FUNDING_UMFUTURE" => Ok(Self::FundingUmfuture),
"UMFUTURE_FUNDING" => Ok(Self::UmfutureFunding),
"MARGIN_FUNDING" => Ok(Self::MarginFunding),
"FUNDING_MARGIN" => Ok(Self::FundingMargin),
"FUNDING_CMFUTURE" => Ok(Self::FundingCmfuture),
"CMFUTURE_FUNDING" => Ok(Self::CmfutureFunding),
"MAIN_OPTION" => Ok(Self::MainOption),
"OPTION_MAIN" => Ok(Self::OptionMain),
"UMFUTURE_OPTION" => Ok(Self::UmfutureOption),
"OPTION_UMFUTURE" => Ok(Self::OptionUmfuture),
"MARGIN_OPTION" => Ok(Self::MarginOption),
"OPTION_MARGIN" => Ok(Self::OptionMargin),
"FUNDING_OPTION" => Ok(Self::FundingOption),
"OPTION_FUNDING" => Ok(Self::OptionFunding),
"MAIN_PORTFOLIO_MARGIN" => Ok(Self::MainPortfolioMargin),
"PORTFOLIO_MARGIN_MAIN" => Ok(Self::PortfolioMarginMain),
other => Err(format!("invalid UserUniversalTransferTypeEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UserUniversalTransferFromSymbolEnum {
#[serde(rename = "ISOLATEDMARGIN_MARGIN")]
IsolatedmarginMargin,
#[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
IsolatedmarginIsolatedmargin,
}
impl UserUniversalTransferFromSymbolEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::IsolatedmarginMargin => "ISOLATEDMARGIN_MARGIN",
Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
}
}
}
impl std::str::FromStr for UserUniversalTransferFromSymbolEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ISOLATEDMARGIN_MARGIN" => Ok(Self::IsolatedmarginMargin),
"ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
other => Err(format!("invalid UserUniversalTransferFromSymbolEnum: {}", other).into()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UserUniversalTransferToSymbolEnum {
#[serde(rename = "MARGIN_ISOLATEDMARGIN")]
MarginIsolatedmargin,
#[serde(rename = "ISOLATEDMARGIN_ISOLATEDMARGIN")]
IsolatedmarginIsolatedmargin,
}
impl UserUniversalTransferToSymbolEnum {
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::MarginIsolatedmargin => "MARGIN_ISOLATEDMARGIN",
Self::IsolatedmarginIsolatedmargin => "ISOLATEDMARGIN_ISOLATEDMARGIN",
}
}
}
impl std::str::FromStr for UserUniversalTransferToSymbolEnum {
type Err = Box<dyn std::error::Error + Send + Sync>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"MARGIN_ISOLATEDMARGIN" => Ok(Self::MarginIsolatedmargin),
"ISOLATEDMARGIN_ISOLATEDMARGIN" => Ok(Self::IsolatedmarginIsolatedmargin),
other => Err(format!("invalid UserUniversalTransferToSymbolEnum: {}", other).into()),
}
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AssetDetailParams {
#[builder(setter(into), default)]
#[serde(rename = "asset", default)]
pub asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl AssetDetailParams {
#[must_use]
pub fn builder() -> AssetDetailParamsBuilder {
AssetDetailParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct AssetDividendRecordParams {
#[builder(setter(into), default)]
#[serde(rename = "asset", default)]
pub asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "startTime", default)]
pub start_time: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "endTime", default)]
pub end_time: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "limit", default)]
pub limit: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl AssetDividendRecordParams {
#[must_use]
pub fn builder() -> AssetDividendRecordParamsBuilder {
AssetDividendRecordParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct DustConvertParams {
#[builder(setter(into))]
#[serde(rename = "asset")]
pub asset: String,
#[builder(setter(into), default)]
#[serde(rename = "accountType", default)]
pub account_type: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "clientId", default)]
pub client_id: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "targetAsset", default)]
pub target_asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "thirdPartyClientId", default)]
pub third_party_client_id: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "dustQuotaAssetToTargetAssetPrice", default)]
pub dust_quota_asset_to_target_asset_price: Option<rust_decimal::Decimal>,
}
impl DustConvertParams {
#[must_use]
pub fn builder(asset: String) -> DustConvertParamsBuilder {
DustConvertParamsBuilder::default().asset(asset)
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct DustConvertibleAssetsParams {
#[builder(setter(into))]
#[serde(rename = "targetAsset")]
pub target_asset: String,
#[builder(setter(into), default)]
#[serde(rename = "accountType", default)]
pub account_type: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "dustQuotaAssetToTargetAssetPrice", default)]
pub dust_quota_asset_to_target_asset_price: Option<rust_decimal::Decimal>,
}
impl DustConvertibleAssetsParams {
#[must_use]
pub fn builder(target_asset: String) -> DustConvertibleAssetsParamsBuilder {
DustConvertibleAssetsParamsBuilder::default().target_asset(target_asset)
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct DustTransferParams {
#[builder(setter(into))]
#[serde(rename = "asset")]
pub asset: String,
#[builder(setter(into), default)]
#[serde(rename = "accountType", default)]
pub account_type: Option<DustTransferAccountTypeEnum>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl DustTransferParams {
#[must_use]
pub fn builder(asset: String) -> DustTransferParamsBuilder {
DustTransferParamsBuilder::default().asset(asset)
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct DustlogParams {
#[builder(setter(into), default)]
#[serde(rename = "accountType", default)]
pub account_type: Option<DustlogAccountTypeEnum>,
#[builder(setter(into), default)]
#[serde(rename = "startTime", default)]
pub start_time: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "endTime", default)]
pub end_time: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl DustlogParams {
#[must_use]
pub fn builder() -> DustlogParamsBuilder {
DustlogParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct FundingWalletParams {
#[builder(setter(into), default)]
#[serde(rename = "asset", default)]
pub asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "needBtcValuation", default)]
pub need_btc_valuation: Option<bool>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl FundingWalletParams {
#[must_use]
pub fn builder() -> FundingWalletParamsBuilder {
FundingWalletParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetAssetsThatCanBeConvertedIntoBnbParams {
#[builder(setter(into), default)]
#[serde(rename = "accountType", default)]
pub account_type: Option<GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl GetAssetsThatCanBeConvertedIntoBnbParams {
#[must_use]
pub fn builder() -> GetAssetsThatCanBeConvertedIntoBnbParamsBuilder {
GetAssetsThatCanBeConvertedIntoBnbParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct GetCloudMiningPaymentAndRefundHistoryParams {
#[builder(setter(into))]
#[serde(rename = "startTime")]
pub start_time: i64,
#[builder(setter(into))]
#[serde(rename = "endTime")]
pub end_time: i64,
#[builder(setter(into), default)]
#[serde(rename = "tranId", default)]
pub tran_id: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "clientTranId", default)]
pub client_tran_id: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "asset", default)]
pub asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "current", default)]
pub current: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "size", default)]
pub size: Option<i64>,
}
impl GetCloudMiningPaymentAndRefundHistoryParams {
#[must_use]
pub fn builder(
start_time: i64,
end_time: i64,
) -> GetCloudMiningPaymentAndRefundHistoryParamsBuilder {
GetCloudMiningPaymentAndRefundHistoryParamsBuilder::default()
.start_time(start_time)
.end_time(end_time)
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryUserDelegationHistoryParams {
#[builder(setter(into))]
#[serde(rename = "email")]
pub email: String,
#[builder(setter(into))]
#[serde(rename = "startTime")]
pub start_time: i64,
#[builder(setter(into))]
#[serde(rename = "endTime")]
pub end_time: i64,
#[builder(setter(into), default)]
#[serde(rename = "type", default)]
pub r#type: Option<QueryUserDelegationHistoryTypeEnum>,
#[builder(setter(into), default)]
#[serde(rename = "asset", default)]
pub asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "current", default)]
pub current: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "size", default)]
pub size: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl QueryUserDelegationHistoryParams {
#[must_use]
pub fn builder(
email: String,
start_time: i64,
end_time: i64,
) -> QueryUserDelegationHistoryParamsBuilder {
QueryUserDelegationHistoryParamsBuilder::default()
.email(email)
.start_time(start_time)
.end_time(end_time)
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryUserUniversalTransferHistoryParams {
#[builder(setter(into))]
#[serde(rename = "type")]
pub r#type: String,
#[builder(setter(into), default)]
#[serde(rename = "startTime", default)]
pub start_time: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "endTime", default)]
pub end_time: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "current", default)]
pub current: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "size", default)]
pub size: Option<i64>,
#[builder(setter(into), default)]
#[serde(rename = "fromSymbol", default)]
pub from_symbol: Option<QueryUserUniversalTransferHistoryFromSymbolEnum>,
#[builder(setter(into), default)]
#[serde(rename = "toSymbol", default)]
pub to_symbol: Option<QueryUserUniversalTransferHistoryToSymbolEnum>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl QueryUserUniversalTransferHistoryParams {
#[must_use]
pub fn builder(r#type: String) -> QueryUserUniversalTransferHistoryParamsBuilder {
QueryUserUniversalTransferHistoryParamsBuilder::default().r#type(r#type)
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct QueryUserWalletBalanceParams {
#[builder(setter(into), default)]
#[serde(rename = "quoteAsset", default)]
pub quote_asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl QueryUserWalletBalanceParams {
#[must_use]
pub fn builder() -> QueryUserWalletBalanceParamsBuilder {
QueryUserWalletBalanceParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
#[builder(setter(into), default)]
#[serde(rename = "spotBNBBurn", default)]
pub spot_bnb_burn: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "interestBNBBurn", default)]
pub interest_bnb_burn: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
#[must_use]
pub fn builder() -> ToggleBnbBurnOnSpotTradeAndMarginInterestParamsBuilder {
ToggleBnbBurnOnSpotTradeAndMarginInterestParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct TradeFeeParams {
#[builder(setter(into), default)]
#[serde(rename = "symbol", default)]
pub symbol: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl TradeFeeParams {
#[must_use]
pub fn builder() -> TradeFeeParamsBuilder {
TradeFeeParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize, Default)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct UserAssetParams {
#[builder(setter(into), default)]
#[serde(rename = "asset", default)]
pub asset: Option<String>,
#[builder(setter(into), default)]
#[serde(rename = "needBtcValuation", default)]
pub need_btc_valuation: Option<bool>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl UserAssetParams {
#[must_use]
pub fn builder() -> UserAssetParamsBuilder {
UserAssetParamsBuilder::default()
}
}
#[derive(Clone, Debug, Builder, Deserialize)]
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
pub struct UserUniversalTransferParams {
#[builder(setter(into))]
#[serde(rename = "type")]
pub r#type: UserUniversalTransferTypeEnum,
#[builder(setter(into))]
#[serde(rename = "asset")]
pub asset: String,
#[builder(setter(into))]
#[serde(rename = "amount")]
pub amount: rust_decimal::Decimal,
#[builder(setter(into), default)]
#[serde(rename = "fromSymbol", default)]
pub from_symbol: Option<UserUniversalTransferFromSymbolEnum>,
#[builder(setter(into), default)]
#[serde(rename = "toSymbol", default)]
pub to_symbol: Option<UserUniversalTransferToSymbolEnum>,
#[builder(setter(into), default)]
#[serde(rename = "recvWindow", default)]
pub recv_window: Option<i64>,
}
impl UserUniversalTransferParams {
#[must_use]
pub fn builder(
r#type: UserUniversalTransferTypeEnum,
asset: String,
amount: rust_decimal::Decimal,
) -> UserUniversalTransferParamsBuilder {
UserUniversalTransferParamsBuilder::default()
.r#type(r#type)
.asset(asset)
.amount(amount)
}
}
#[async_trait]
impl AssetApi for AssetApiClient {
async fn asset_detail(
&self,
params: AssetDetailParams,
) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>> {
let AssetDetailParams { asset, recv_window } = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = asset {
query_params.insert("asset".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::AssetDetailResponse>(
&self.configuration,
"/sapi/v1/asset/assetDetail",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn asset_dividend_record(
&self,
params: AssetDividendRecordParams,
) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>> {
let AssetDividendRecordParams {
asset,
start_time,
end_time,
limit,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = asset {
query_params.insert("asset".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = limit {
query_params.insert("limit".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::AssetDividendRecordResponse>(
&self.configuration,
"/sapi/v1/asset/assetDividend",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn dust_convert(
&self,
params: DustConvertParams,
) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>> {
let DustConvertParams {
asset,
account_type,
client_id,
target_asset,
third_party_client_id,
dust_quota_asset_to_target_asset_price,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("asset".to_string(), json!(asset));
if let Some(rw) = account_type {
query_params.insert("accountType".to_string(), json!(rw));
}
if let Some(rw) = client_id {
query_params.insert("clientId".to_string(), json!(rw));
}
if let Some(rw) = target_asset {
query_params.insert("targetAsset".to_string(), json!(rw));
}
if let Some(rw) = third_party_client_id {
query_params.insert("thirdPartyClientId".to_string(), json!(rw));
}
if let Some(rw) = dust_quota_asset_to_target_asset_price {
query_params.insert("dustQuotaAssetToTargetAssetPrice".to_string(), json!(rw));
}
send_request::<models::DustConvertResponse>(
&self.configuration,
"/sapi/v1/asset/dust-convert/convert",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn dust_convertible_assets(
&self,
params: DustConvertibleAssetsParams,
) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>> {
let DustConvertibleAssetsParams {
target_asset,
account_type,
dust_quota_asset_to_target_asset_price,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = account_type {
query_params.insert("accountType".to_string(), json!(rw));
}
query_params.insert("targetAsset".to_string(), json!(target_asset));
if let Some(rw) = dust_quota_asset_to_target_asset_price {
query_params.insert("dustQuotaAssetToTargetAssetPrice".to_string(), json!(rw));
}
send_request::<models::DustConvertibleAssetsResponse>(
&self.configuration,
"/sapi/v1/asset/dust-convert/query-convertible-assets",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn dust_transfer(
&self,
params: DustTransferParams,
) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>> {
let DustTransferParams {
asset,
account_type,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("asset".to_string(), json!(asset));
if let Some(rw) = account_type {
query_params.insert("accountType".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::DustTransferResponse>(
&self.configuration,
"/sapi/v1/asset/dust",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn dustlog(
&self,
params: DustlogParams,
) -> anyhow::Result<RestApiResponse<models::DustlogResponse>> {
let DustlogParams {
account_type,
start_time,
end_time,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = account_type {
query_params.insert("accountType".to_string(), json!(rw));
}
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::DustlogResponse>(
&self.configuration,
"/sapi/v1/asset/dribblet",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn funding_wallet(
&self,
params: FundingWalletParams,
) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>> {
let FundingWalletParams {
asset,
need_btc_valuation,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = asset {
query_params.insert("asset".to_string(), json!(rw));
}
if let Some(rw) = need_btc_valuation {
query_params.insert("needBtcValuation".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::FundingWalletResponseInner>>(
&self.configuration,
"/sapi/v1/asset/get-funding-asset",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_assets_that_can_be_converted_into_bnb(
&self,
params: GetAssetsThatCanBeConvertedIntoBnbParams,
) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>> {
let GetAssetsThatCanBeConvertedIntoBnbParams {
account_type,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = account_type {
query_params.insert("accountType".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::GetAssetsThatCanBeConvertedIntoBnbResponse>(
&self.configuration,
"/sapi/v1/asset/dust-btc",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_cloud_mining_payment_and_refund_history(
&self,
params: GetCloudMiningPaymentAndRefundHistoryParams,
) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>
{
let GetCloudMiningPaymentAndRefundHistoryParams {
start_time,
end_time,
tran_id,
client_tran_id,
asset,
current,
size,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = tran_id {
query_params.insert("tranId".to_string(), json!(rw));
}
if let Some(rw) = client_tran_id {
query_params.insert("clientTranId".to_string(), json!(rw));
}
if let Some(rw) = asset {
query_params.insert("asset".to_string(), json!(rw));
}
query_params.insert("startTime".to_string(), json!(start_time));
query_params.insert("endTime".to_string(), json!(end_time));
if let Some(rw) = current {
query_params.insert("current".to_string(), json!(rw));
}
if let Some(rw) = size {
query_params.insert("size".to_string(), json!(rw));
}
send_request::<models::GetCloudMiningPaymentAndRefundHistoryResponse>(
&self.configuration,
"/sapi/v1/asset/ledger-transfer/cloud-mining/queryByPage",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn get_open_symbol_list(
&self,
) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>> {
let query_params = BTreeMap::new();
let body_params = BTreeMap::new();
send_request::<Vec<models::GetOpenSymbolListResponseInner>>(
&self.configuration,
"/sapi/v1/spot/open-symbol-list",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
false,
)
.await
}
async fn query_user_delegation_history(
&self,
params: QueryUserDelegationHistoryParams,
) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>> {
let QueryUserDelegationHistoryParams {
email,
start_time,
end_time,
r#type,
asset,
current,
size,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("email".to_string(), json!(email));
query_params.insert("startTime".to_string(), json!(start_time));
query_params.insert("endTime".to_string(), json!(end_time));
if let Some(rw) = r#type {
query_params.insert("type".to_string(), json!(rw));
}
if let Some(rw) = asset {
query_params.insert("asset".to_string(), json!(rw));
}
if let Some(rw) = current {
query_params.insert("current".to_string(), json!(rw));
}
if let Some(rw) = size {
query_params.insert("size".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryUserDelegationHistoryResponse>(
&self.configuration,
"/sapi/v1/asset/custody/transfer-history",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_user_universal_transfer_history(
&self,
params: QueryUserUniversalTransferHistoryParams,
) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>> {
let QueryUserUniversalTransferHistoryParams {
r#type,
start_time,
end_time,
current,
size,
from_symbol,
to_symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("type".to_string(), json!(r#type));
if let Some(rw) = start_time {
query_params.insert("startTime".to_string(), json!(rw));
}
if let Some(rw) = end_time {
query_params.insert("endTime".to_string(), json!(rw));
}
if let Some(rw) = current {
query_params.insert("current".to_string(), json!(rw));
}
if let Some(rw) = size {
query_params.insert("size".to_string(), json!(rw));
}
if let Some(rw) = from_symbol {
query_params.insert("fromSymbol".to_string(), json!(rw));
}
if let Some(rw) = to_symbol {
query_params.insert("toSymbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::QueryUserUniversalTransferHistoryResponse>(
&self.configuration,
"/sapi/v1/asset/transfer",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn query_user_wallet_balance(
&self,
params: QueryUserWalletBalanceParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>> {
let QueryUserWalletBalanceParams {
quote_asset,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = quote_asset {
query_params.insert("quoteAsset".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::QueryUserWalletBalanceResponseInner>>(
&self.configuration,
"/sapi/v1/asset/wallet/balance",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
&self,
params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
) -> anyhow::Result<RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>>
{
let ToggleBnbBurnOnSpotTradeAndMarginInterestParams {
spot_bnb_burn,
interest_bnb_burn,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = spot_bnb_burn {
query_params.insert("spotBNBBurn".to_string(), json!(rw));
}
if let Some(rw) = interest_bnb_burn {
query_params.insert("interestBNBBurn".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>(
&self.configuration,
"/sapi/v1/bnbBurn",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn trade_fee(
&self,
params: TradeFeeParams,
) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>> {
let TradeFeeParams {
symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = symbol {
query_params.insert("symbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::TradeFeeResponseInner>>(
&self.configuration,
"/sapi/v1/asset/tradeFee",
reqwest::Method::GET,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn user_asset(
&self,
params: UserAssetParams,
) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>> {
let UserAssetParams {
asset,
need_btc_valuation,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
if let Some(rw) = asset {
query_params.insert("asset".to_string(), json!(rw));
}
if let Some(rw) = need_btc_valuation {
query_params.insert("needBtcValuation".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<Vec<models::UserAssetResponseInner>>(
&self.configuration,
"/sapi/v3/asset/getUserAsset",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
async fn user_universal_transfer(
&self,
params: UserUniversalTransferParams,
) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>> {
let UserUniversalTransferParams {
r#type,
asset,
amount,
from_symbol,
to_symbol,
recv_window,
} = params;
let mut query_params = BTreeMap::new();
let body_params = BTreeMap::new();
query_params.insert("type".to_string(), json!(r#type));
query_params.insert("asset".to_string(), json!(asset));
query_params.insert("amount".to_string(), json!(amount));
if let Some(rw) = from_symbol {
query_params.insert("fromSymbol".to_string(), json!(rw));
}
if let Some(rw) = to_symbol {
query_params.insert("toSymbol".to_string(), json!(rw));
}
if let Some(rw) = recv_window {
query_params.insert("recvWindow".to_string(), json!(rw));
}
send_request::<models::UserUniversalTransferResponse>(
&self.configuration,
"/sapi/v1/asset/transfer",
reqwest::Method::POST,
query_params,
body_params,
if HAS_TIME_UNIT {
self.configuration.time_unit
} else {
None
},
true,
)
.await
}
}
#[cfg(all(test, feature = "wallet"))]
mod tests {
use super::*;
use crate::TOKIO_SHARED_RT;
use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
use async_trait::async_trait;
use std::collections::HashMap;
struct DummyRestApiResponse<T> {
inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
status: u16,
headers: HashMap<String, String>,
rate_limits: Option<Vec<RestApiRateLimit>>,
}
impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
fn from(dummy: DummyRestApiResponse<T>) -> Self {
Self {
data_fn: dummy.inner,
status: dummy.status,
headers: dummy.headers,
rate_limits: dummy.rate_limits,
}
}
}
struct MockAssetApiClient {
force_error: bool,
}
#[async_trait]
impl AssetApi for MockAssetApiClient {
async fn asset_detail(
&self,
_params: AssetDetailParams,
) -> anyhow::Result<RestApiResponse<models::AssetDetailResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::AssetDetailResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::AssetDetailResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn asset_dividend_record(
&self,
_params: AssetDividendRecordParams,
) -> anyhow::Result<RestApiResponse<models::AssetDividendRecordResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::AssetDividendRecordResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::AssetDividendRecordResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn dust_convert(
&self,
_params: DustConvertParams,
) -> anyhow::Result<RestApiResponse<models::DustConvertResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::DustConvertResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::DustConvertResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn dust_convertible_assets(
&self,
_params: DustConvertibleAssetsParams,
) -> anyhow::Result<RestApiResponse<models::DustConvertibleAssetsResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::DustConvertibleAssetsResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::DustConvertibleAssetsResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn dust_transfer(
&self,
_params: DustTransferParams,
) -> anyhow::Result<RestApiResponse<models::DustTransferResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::DustTransferResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::DustTransferResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn dustlog(
&self,
_params: DustlogParams,
) -> anyhow::Result<RestApiResponse<models::DustlogResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::DustlogResponse = serde_json::from_value(resp_json.clone())
.expect("should parse into models::DustlogResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn funding_wallet(
&self,
_params: FundingWalletParams,
) -> anyhow::Result<RestApiResponse<Vec<models::FundingWalletResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: Vec<models::FundingWalletResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::FundingWalletResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_assets_that_can_be_converted_into_bnb(
&self,
_params: GetAssetsThatCanBeConvertedIntoBnbParams,
) -> anyhow::Result<RestApiResponse<models::GetAssetsThatCanBeConvertedIntoBnbResponse>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::GetAssetsThatCanBeConvertedIntoBnbResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_cloud_mining_payment_and_refund_history(
&self,
_params: GetCloudMiningPaymentAndRefundHistoryParams,
) -> anyhow::Result<RestApiResponse<models::GetCloudMiningPaymentAndRefundHistoryResponse>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::GetCloudMiningPaymentAndRefundHistoryResponse =
serde_json::from_value(resp_json.clone()).expect(
"should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn get_open_symbol_list(
&self,
) -> anyhow::Result<RestApiResponse<Vec<models::GetOpenSymbolListResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value =
serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
.unwrap_or_else(|_| serde_json::json!({}));
let dummy_response: Vec<models::GetOpenSymbolListResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_user_delegation_history(
&self,
_params: QueryUserDelegationHistoryParams,
) -> anyhow::Result<RestApiResponse<models::QueryUserDelegationHistoryResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::QueryUserDelegationHistoryResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryUserDelegationHistoryResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_user_universal_transfer_history(
&self,
_params: QueryUserUniversalTransferHistoryParams,
) -> anyhow::Result<RestApiResponse<models::QueryUserUniversalTransferHistoryResponse>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: models::QueryUserUniversalTransferHistoryResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn query_user_wallet_balance(
&self,
_params: QueryUserWalletBalanceParams,
) -> anyhow::Result<RestApiResponse<Vec<models::QueryUserWalletBalanceResponseInner>>>
{
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value =
serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot"}]"#)
.unwrap_or_else(|_| serde_json::json!({}));
let dummy_response: Vec<models::QueryUserWalletBalanceResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn toggle_bnb_burn_on_spot_trade_and_margin_interest(
&self,
_params: ToggleBnbBurnOnSpotTradeAndMarginInterestParams,
) -> anyhow::Result<
RestApiResponse<models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse>,
> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value =
serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
.unwrap_or_else(|_| serde_json::json!({}));
let dummy_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
serde_json::from_value(resp_json.clone()).expect(
"should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
);
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn trade_fee(
&self,
_params: TradeFeeParams,
) -> anyhow::Result<RestApiResponse<Vec<models::TradeFeeResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(
r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
)
.unwrap_or_else(|_| serde_json::json!({}));
let dummy_response: Vec<models::TradeFeeResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::TradeFeeResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn user_asset(
&self,
_params: UserAssetParams,
) -> anyhow::Result<RestApiResponse<Vec<models::UserAssetResponseInner>>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
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!({}));
let dummy_response: Vec<models::UserAssetResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::UserAssetResponseInner>");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
async fn user_universal_transfer(
&self,
_params: UserUniversalTransferParams,
) -> anyhow::Result<RestApiResponse<models::UserUniversalTransferResponse>> {
if self.force_error {
return Err(ConnectorError::ConnectorClientError {
msg: "ResponseError".to_string(),
code: None,
}
.into());
}
let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
.unwrap_or_else(|_| serde_json::json!({}));
let dummy_response: models::UserUniversalTransferResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::UserUniversalTransferResponse");
let dummy = DummyRestApiResponse {
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
status: 200,
headers: HashMap::new(),
rate_limits: None,
};
Ok(dummy.into())
}
}
#[test]
fn asset_detail_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = AssetDetailParams::builder().build().unwrap();
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!({}));
let expected_response : models::AssetDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDetailResponse");
let resp = client.asset_detail(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn asset_detail_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = AssetDetailParams::builder().asset("BTC".to_string()).recv_window(5000).build().unwrap();
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!({}));
let expected_response : models::AssetDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDetailResponse");
let resp = client.asset_detail(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn asset_detail_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = AssetDetailParams::builder().build().unwrap();
match client.asset_detail(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn asset_dividend_record_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = AssetDividendRecordParams::builder().build().unwrap();
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!({}));
let expected_response : models::AssetDividendRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDividendRecordResponse");
let resp = client.asset_dividend_record(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn asset_dividend_record_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = AssetDividendRecordParams::builder().asset("BTC".to_string()).start_time(1623319461670).end_time(1641782889000).limit(20).recv_window(5000).build().unwrap();
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!({}));
let expected_response : models::AssetDividendRecordResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::AssetDividendRecordResponse");
let resp = client.asset_dividend_record(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn asset_dividend_record_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = AssetDividendRecordParams::builder().build().unwrap();
match client.asset_dividend_record(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn dust_convert_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustConvertParams::builder("USDT".to_string(),).build().unwrap();
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!({}));
let expected_response : models::DustConvertResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertResponse");
let resp = client.dust_convert(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dust_convert_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
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();
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!({}));
let expected_response : models::DustConvertResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertResponse");
let resp = client.dust_convert(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dust_convert_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = DustConvertParams::builder("USDT".to_string())
.build()
.unwrap();
match client.dust_convert(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn dust_convertible_assets_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustConvertibleAssetsParams::builder("BTC".to_string(),).build().unwrap();
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!({}));
let expected_response : models::DustConvertibleAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertibleAssetsResponse");
let resp = client.dust_convertible_assets(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dust_convertible_assets_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustConvertibleAssetsParams::builder("BTC".to_string(),).account_type("SPOT".to_string()).dust_quota_asset_to_target_asset_price(dec!(1.0)).build().unwrap();
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!({}));
let expected_response : models::DustConvertibleAssetsResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustConvertibleAssetsResponse");
let resp = client.dust_convertible_assets(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dust_convertible_assets_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = DustConvertibleAssetsParams::builder("BTC".to_string())
.build()
.unwrap();
match client.dust_convertible_assets(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn dust_transfer_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustTransferParams::builder("BTC".to_string(),).build().unwrap();
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!({}));
let expected_response : models::DustTransferResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustTransferResponse");
let resp = client.dust_transfer(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dust_transfer_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustTransferParams::builder("BTC".to_string(),).account_type(DustTransferAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
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!({}));
let expected_response : models::DustTransferResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustTransferResponse");
let resp = client.dust_transfer(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dust_transfer_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = DustTransferParams::builder("BTC".to_string())
.build()
.unwrap();
match client.dust_transfer(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn dustlog_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustlogParams::builder().build().unwrap();
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!({}));
let expected_response : models::DustlogResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustlogResponse");
let resp = client.dustlog(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dustlog_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = DustlogParams::builder().account_type(DustlogAccountTypeEnum::Spot).start_time(1623319461670).end_time(1641782889000).recv_window(5000).build().unwrap();
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!({}));
let expected_response : models::DustlogResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::DustlogResponse");
let resp = client.dustlog(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn dustlog_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = DustlogParams::builder().build().unwrap();
match client.dustlog(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn funding_wallet_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = FundingWalletParams::builder().build().unwrap();
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!({}));
let expected_response : Vec<models::FundingWalletResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::FundingWalletResponseInner>");
let resp = client.funding_wallet(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn funding_wallet_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = FundingWalletParams::builder().asset("BTC".to_string()).need_btc_valuation(true).recv_window(5000).build().unwrap();
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!({}));
let expected_response : Vec<models::FundingWalletResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::FundingWalletResponseInner>");
let resp = client.funding_wallet(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn funding_wallet_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = FundingWalletParams::builder().build().unwrap();
match client.funding_wallet(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_assets_that_can_be_converted_into_bnb_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder().build().unwrap();
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!({}));
let expected_response : models::GetAssetsThatCanBeConvertedIntoBnbResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
let resp = client.get_assets_that_can_be_converted_into_bnb(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_assets_that_can_be_converted_into_bnb_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder().account_type(GetAssetsThatCanBeConvertedIntoBnbAccountTypeEnum::Spot).recv_window(5000).build().unwrap();
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!({}));
let expected_response : models::GetAssetsThatCanBeConvertedIntoBnbResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetAssetsThatCanBeConvertedIntoBnbResponse");
let resp = client.get_assets_that_can_be_converted_into_bnb(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_assets_that_can_be_converted_into_bnb_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = GetAssetsThatCanBeConvertedIntoBnbParams::builder()
.build()
.unwrap();
match client
.get_assets_that_can_be_converted_into_bnb(params)
.await
{
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_cloud_mining_payment_and_refund_history_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670,1641782889000,).build().unwrap();
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!({}));
let expected_response : models::GetCloudMiningPaymentAndRefundHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse");
let resp = client.get_cloud_mining_payment_and_refund_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_cloud_mining_payment_and_refund_history_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
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();
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!({}));
let expected_response : models::GetCloudMiningPaymentAndRefundHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetCloudMiningPaymentAndRefundHistoryResponse");
let resp = client.get_cloud_mining_payment_and_refund_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_cloud_mining_payment_and_refund_history_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params =
GetCloudMiningPaymentAndRefundHistoryParams::builder(1623319461670, 1641782889000)
.build()
.unwrap();
match client
.get_cloud_mining_payment_and_refund_history(params)
.await
{
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn get_open_symbol_list_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let resp_json: Value =
serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: Vec<models::GetOpenSymbolListResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
let resp = client
.get_open_symbol_list()
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_open_symbol_list_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let resp_json: Value =
serde_json::from_str(r#"[{"openTime":1686161202000,"symbols":["BNBBTC"]}]"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: Vec<models::GetOpenSymbolListResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::GetOpenSymbolListResponseInner>");
let resp = client
.get_open_symbol_list()
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn get_open_symbol_list_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
match client.get_open_symbol_list().await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_user_delegation_history_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = QueryUserDelegationHistoryParams::builder("abc@test.com".to_string(),1623319461670,1641782889000,).build().unwrap();
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!({}));
let expected_response : models::QueryUserDelegationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserDelegationHistoryResponse");
let resp = client.query_user_delegation_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_user_delegation_history_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
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();
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!({}));
let expected_response : models::QueryUserDelegationHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserDelegationHistoryResponse");
let resp = client.query_user_delegation_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_user_delegation_history_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = QueryUserDelegationHistoryParams::builder(
"abc@test.com".to_string(),
1623319461670,
1641782889000,
)
.build()
.unwrap();
match client.query_user_delegation_history(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_user_universal_transfer_history_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string(),).build().unwrap();
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!({}));
let expected_response : models::QueryUserUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
let resp = client.query_user_universal_transfer_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_user_universal_transfer_history_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
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();
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!({}));
let expected_response : models::QueryUserUniversalTransferHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::QueryUserUniversalTransferHistoryResponse");
let resp = client.query_user_universal_transfer_history(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_user_universal_transfer_history_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params =
QueryUserUniversalTransferHistoryParams::builder("r#type_example".to_string())
.build()
.unwrap();
match client.query_user_universal_transfer_history(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn query_user_wallet_balance_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = QueryUserWalletBalanceParams::builder().build().unwrap();
let resp_json: Value =
serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot"}]"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: Vec<models::QueryUserWalletBalanceResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
let resp = client
.query_user_wallet_balance(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_user_wallet_balance_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = QueryUserWalletBalanceParams::builder()
.quote_asset("BTC".to_string())
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value =
serde_json::from_str(r#"[{"activate":true,"balance":"0","walletName":"Spot"}]"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: Vec<models::QueryUserWalletBalanceResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::QueryUserWalletBalanceResponseInner>");
let resp = client
.query_user_wallet_balance(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn query_user_wallet_balance_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = QueryUserWalletBalanceParams::builder().build().unwrap();
match client.query_user_wallet_balance(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn toggle_bnb_burn_on_spot_trade_and_margin_interest_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
.build()
.unwrap();
let resp_json: Value =
serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
serde_json::from_value(resp_json.clone()).expect(
"should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
);
let resp = client
.toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn toggle_bnb_burn_on_spot_trade_and_margin_interest_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
.spot_bnb_burn("true".to_string())
.interest_bnb_burn("true".to_string())
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value =
serde_json::from_str(r#"{"spotBNBBurn":true,"interestBNBBurn":false}"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse =
serde_json::from_value(resp_json.clone()).expect(
"should parse into models::ToggleBnbBurnOnSpotTradeAndMarginInterestResponse",
);
let resp = client
.toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn toggle_bnb_burn_on_spot_trade_and_margin_interest_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = ToggleBnbBurnOnSpotTradeAndMarginInterestParams::builder()
.build()
.unwrap();
match client
.toggle_bnb_burn_on_spot_trade_and_margin_interest(params)
.await
{
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn trade_fee_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = TradeFeeParams::builder().build().unwrap();
let resp_json: Value = serde_json::from_str(
r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: Vec<models::TradeFeeResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::TradeFeeResponseInner>");
let resp = client.trade_fee(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn trade_fee_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = TradeFeeParams::builder()
.symbol("ADABNB".to_string())
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(
r#"[{"symbol":"ADABNB","makerCommission":"0.001","takerCommission":"0.001"}]"#,
)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: Vec<models::TradeFeeResponseInner> =
serde_json::from_value(resp_json.clone())
.expect("should parse into Vec<models::TradeFeeResponseInner>");
let resp = client.trade_fee(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn trade_fee_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = TradeFeeParams::builder().build().unwrap();
match client.trade_fee(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn user_asset_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = UserAssetParams::builder().build().unwrap();
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!({}));
let expected_response : Vec<models::UserAssetResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UserAssetResponseInner>");
let resp = client.user_asset(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn user_asset_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = UserAssetParams::builder().asset("BTC".to_string()).need_btc_valuation(true).recv_window(5000).build().unwrap();
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!({}));
let expected_response : Vec<models::UserAssetResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::UserAssetResponseInner>");
let resp = client.user_asset(params).await.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn user_asset_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = UserAssetParams::builder().build().unwrap();
match client.user_asset(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
#[test]
fn user_universal_transfer_required_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = UserUniversalTransferParams::builder(
UserUniversalTransferTypeEnum::MainUmfuture,
"BTC".to_string(),
dec!(1.0),
)
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: models::UserUniversalTransferResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::UserUniversalTransferResponse");
let resp = client
.user_universal_transfer(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn user_universal_transfer_optional_params_success() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: false };
let params = UserUniversalTransferParams::builder(
UserUniversalTransferTypeEnum::MainUmfuture,
"BTC".to_string(),
dec!(1.0),
)
.from_symbol(UserUniversalTransferFromSymbolEnum::IsolatedmarginMargin)
.to_symbol(UserUniversalTransferToSymbolEnum::MarginIsolatedmargin)
.recv_window(5000)
.build()
.unwrap();
let resp_json: Value = serde_json::from_str(r#"{"tranId":13526853623}"#)
.unwrap_or_else(|_| serde_json::json!({}));
let expected_response: models::UserUniversalTransferResponse =
serde_json::from_value(resp_json.clone())
.expect("should parse into models::UserUniversalTransferResponse");
let resp = client
.user_universal_transfer(params)
.await
.expect("Expected a response");
let data_future = resp.data();
let actual_response = data_future.await.unwrap();
assert_eq!(actual_response, expected_response);
});
}
#[test]
fn user_universal_transfer_response_error() {
TOKIO_SHARED_RT.block_on(async {
let client = MockAssetApiClient { force_error: true };
let params = UserUniversalTransferParams::builder(
UserUniversalTransferTypeEnum::MainUmfuture,
"BTC".to_string(),
dec!(1.0),
)
.build()
.unwrap();
match client.user_universal_transfer(params).await {
Ok(_) => panic!("Expected an error"),
Err(err) => {
assert_eq!(err.to_string(), "Connector client error: ResponseError");
}
}
});
}
}