Skip to content

Commit 2e0eca5

Browse files
authored
Merge pull request #33 from binance/rc-v2.0.0
Release v2.0.0
2 parents e75b5cc + 9c948fe commit 2e0eca5

File tree

7 files changed

+260
-1
lines changed

7 files changed

+260
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 2.0.0 - 2025-06-17
4+
5+
### Added (1)
6+
7+
- `get_list_schedule()` (`GET /sapi/v1/margin/list-schedule`)
8+
39
## 1.0.0 - 2025-06-12
410

511
- Initial release.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "binance-sdk"
3-
version = "1.0.0"
3+
version = "2.0.0"
44
authors = [ "Binance" ]
55
edition = "2024"
66
resolver = "3"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use anyhow::{Context, Result};
2+
use std::env;
3+
use tracing::info;
4+
5+
use binance_sdk::config::ConfigurationRestApi;
6+
use binance_sdk::margin_trading::{MarginTradingRestApi, rest_api::GetListScheduleParams};
7+
8+
#[tokio::main]
9+
async fn main() -> Result<()> {
10+
// Load credentials from env
11+
let api_key = env::var("API_KEY").context("API_KEY must be set")?;
12+
let api_secret = env::var("API_SECRET").context("API_SECRET must be set")?;
13+
14+
// Build REST config
15+
let rest_conf = ConfigurationRestApi::builder()
16+
.api_key(api_key)
17+
.api_secret(api_secret)
18+
.build()?;
19+
20+
// Create the MarginTrading REST API client
21+
let rest_client = MarginTradingRestApi::production(rest_conf);
22+
23+
// Setup the API parameters
24+
let params = GetListScheduleParams::default();
25+
26+
// Make the API call
27+
let response = rest_client
28+
.get_list_schedule(params)
29+
.await
30+
.context("get_list_schedule request failed")?;
31+
32+
info!(?response.rate_limits, "get_list_schedule rate limits");
33+
let data = response.data().await?;
34+
info!(?data, "get_list_schedule data");
35+
36+
Ok(())
37+
}

src/margin_trading/rest_api/apis/market_data_api.rs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ pub trait MarketDataApi: Send + Sync {
4949
&self,
5050
params: GetDelistScheduleParams,
5151
) -> anyhow::Result<RestApiResponse<Vec<models::GetDelistScheduleResponseInner>>>;
52+
async fn get_list_schedule(
53+
&self,
54+
params: GetListScheduleParams,
55+
) -> anyhow::Result<RestApiResponse<Vec<models::GetListScheduleResponseInner>>>;
5256
async fn query_isolated_margin_tier_data(
5357
&self,
5458
params: QueryIsolatedMarginTierDataParams,
@@ -187,6 +191,31 @@ impl GetDelistScheduleParams {
187191
GetDelistScheduleParamsBuilder::default()
188192
}
189193
}
194+
/// Request parameters for the [`get_list_schedule`] operation.
195+
///
196+
/// This struct holds all of the inputs you can pass when calling
197+
/// [`get_list_schedule`](#method.get_list_schedule).
198+
#[derive(Clone, Debug, Builder, Default)]
199+
#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
200+
pub struct GetListScheduleParams {
201+
/// No more than 60000
202+
///
203+
/// This field is **optional.
204+
#[builder(setter(into), default)]
205+
pub recv_window: Option<i64>,
206+
}
207+
208+
impl GetListScheduleParams {
209+
/// Create a builder for [`get_list_schedule`].
210+
///
211+
/// Required parameters:
212+
///
213+
///
214+
#[must_use]
215+
pub fn builder() -> GetListScheduleParamsBuilder {
216+
GetListScheduleParamsBuilder::default()
217+
}
218+
}
190219
/// Request parameters for the [`query_isolated_margin_tier_data`] operation.
191220
///
192221
/// This struct holds all of the inputs you can pass when calling
@@ -415,6 +444,33 @@ impl MarketDataApi for MarketDataApiClient {
415444
.await
416445
}
417446

447+
async fn get_list_schedule(
448+
&self,
449+
params: GetListScheduleParams,
450+
) -> anyhow::Result<RestApiResponse<Vec<models::GetListScheduleResponseInner>>> {
451+
let GetListScheduleParams { recv_window } = params;
452+
453+
let mut query_params = BTreeMap::new();
454+
455+
if let Some(rw) = recv_window {
456+
query_params.insert("recv_window".to_string(), json!(rw));
457+
}
458+
459+
send_request::<Vec<models::GetListScheduleResponseInner>>(
460+
&self.configuration,
461+
"/sapi/v1/margin/list-schedule",
462+
reqwest::Method::GET,
463+
query_params,
464+
if HAS_TIME_UNIT {
465+
self.configuration.time_unit
466+
} else {
467+
None
468+
},
469+
false,
470+
)
471+
.await
472+
}
473+
418474
async fn query_isolated_margin_tier_data(
419475
&self,
420476
params: QueryIsolatedMarginTierDataParams,
@@ -691,6 +747,31 @@ mod tests {
691747
Ok(dummy.into())
692748
}
693749

750+
async fn get_list_schedule(
751+
&self,
752+
_params: GetListScheduleParams,
753+
) -> anyhow::Result<RestApiResponse<Vec<models::GetListScheduleResponseInner>>> {
754+
if self.force_error {
755+
return Err(
756+
ConnectorError::ConnectorClientError("ResponseError".to_string()).into(),
757+
);
758+
}
759+
760+
let resp_json: Value = serde_json::from_str(r#"[{"listTime":1686161202000,"crossMarginAssets":["BTC","USDT"],"isolatedMarginSymbols":["ADAUSDT","BNBUSDT"]},{"listTime":1686222232000,"crossMarginAssets":["ADA"],"isolatedMarginSymbols":[]}]"#).unwrap();
761+
let dummy_response: Vec<models::GetListScheduleResponseInner> =
762+
serde_json::from_value(resp_json.clone())
763+
.expect("should parse into Vec<models::GetListScheduleResponseInner>");
764+
765+
let dummy = DummyRestApiResponse {
766+
inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
767+
status: 200,
768+
headers: HashMap::new(),
769+
rate_limits: None,
770+
};
771+
772+
Ok(dummy.into())
773+
}
774+
694775
async fn query_isolated_margin_tier_data(
695776
&self,
696777
_params: QueryIsolatedMarginTierDataParams,
@@ -1045,6 +1126,56 @@ mod tests {
10451126
});
10461127
}
10471128

1129+
#[test]
1130+
fn get_list_schedule_required_params_success() {
1131+
TOKIO_SHARED_RT.block_on(async {
1132+
let client = MockMarketDataApiClient { force_error: false };
1133+
1134+
let params = GetListScheduleParams::builder().build().unwrap();
1135+
1136+
let resp_json: Value = serde_json::from_str(r#"[{"listTime":1686161202000,"crossMarginAssets":["BTC","USDT"],"isolatedMarginSymbols":["ADAUSDT","BNBUSDT"]},{"listTime":1686222232000,"crossMarginAssets":["ADA"],"isolatedMarginSymbols":[]}]"#).unwrap();
1137+
let expected_response : Vec<models::GetListScheduleResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetListScheduleResponseInner>");
1138+
1139+
let resp = client.get_list_schedule(params).await.expect("Expected a response");
1140+
let data_future = resp.data();
1141+
let actual_response = data_future.await.unwrap();
1142+
assert_eq!(actual_response, expected_response);
1143+
});
1144+
}
1145+
1146+
#[test]
1147+
fn get_list_schedule_optional_params_success() {
1148+
TOKIO_SHARED_RT.block_on(async {
1149+
let client = MockMarketDataApiClient { force_error: false };
1150+
1151+
let params = GetListScheduleParams::builder().recv_window(5000).build().unwrap();
1152+
1153+
let resp_json: Value = serde_json::from_str(r#"[{"listTime":1686161202000,"crossMarginAssets":["BTC","USDT"],"isolatedMarginSymbols":["ADAUSDT","BNBUSDT"]},{"listTime":1686222232000,"crossMarginAssets":["ADA"],"isolatedMarginSymbols":[]}]"#).unwrap();
1154+
let expected_response : Vec<models::GetListScheduleResponseInner> = serde_json::from_value(resp_json.clone()).expect("should parse into Vec<models::GetListScheduleResponseInner>");
1155+
1156+
let resp = client.get_list_schedule(params).await.expect("Expected a response");
1157+
let data_future = resp.data();
1158+
let actual_response = data_future.await.unwrap();
1159+
assert_eq!(actual_response, expected_response);
1160+
});
1161+
}
1162+
1163+
#[test]
1164+
fn get_list_schedule_response_error() {
1165+
TOKIO_SHARED_RT.block_on(async {
1166+
let client = MockMarketDataApiClient { force_error: true };
1167+
1168+
let params = GetListScheduleParams::builder().build().unwrap();
1169+
1170+
match client.get_list_schedule(params).await {
1171+
Ok(_) => panic!("Expected an error"),
1172+
Err(err) => {
1173+
assert_eq!(err.to_string(), "Connector client error: ResponseError");
1174+
}
1175+
}
1176+
});
1177+
}
1178+
10481179
#[test]
10491180
fn query_isolated_margin_tier_data_required_params_success() {
10501181
TOKIO_SHARED_RT.block_on(async {

src/margin_trading/rest_api/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,49 @@ impl RestApi {
11251125
.await
11261126
}
11271127

1128+
/// Get list Schedule (`MARKET_DATA`)
1129+
///
1130+
/// Get the upcoming tokens or symbols listing schedule for Cross Margin and Isolated Margin.
1131+
///
1132+
/// Weight: 100
1133+
///
1134+
/// # Arguments
1135+
///
1136+
/// - `params`: [`GetListScheduleParams`]
1137+
/// The parameters for this operation.
1138+
///
1139+
/// # Returns
1140+
///
1141+
/// [`RestApiResponse<Vec<models::GetListScheduleResponseInner>>`] on success.
1142+
///
1143+
/// # Errors
1144+
///
1145+
/// This function will return an [`anyhow::Error`] if:
1146+
/// - the HTTP request fails
1147+
/// - any parameter is invalid
1148+
/// - the response cannot be parsed
1149+
/// - or one of the following occurs:
1150+
/// - `RequiredError`
1151+
/// - `ConnectorClientError`
1152+
/// - `UnauthorizedError`
1153+
/// - `ForbiddenError`
1154+
/// - `TooManyRequestsError`
1155+
/// - `RateLimitBanError`
1156+
/// - `ServerError`
1157+
/// - `NotFoundError`
1158+
/// - `NetworkError`
1159+
/// - `BadRequestError`
1160+
///
1161+
///
1162+
/// For full API details, see the [Binance API Documentation](https://developers.binance.com/docs/margin_trading/market-data/Get-list-Schedule).
1163+
///
1164+
pub async fn get_list_schedule(
1165+
&self,
1166+
params: GetListScheduleParams,
1167+
) -> anyhow::Result<RestApiResponse<Vec<models::GetListScheduleResponseInner>>> {
1168+
self.market_data_api_client.get_list_schedule(params).await
1169+
}
1170+
11281171
/// Query Isolated Margin Tier Data (`USER_DATA`)
11291172
///
11301173
/// Get isolated margin tier data collection with any tier as <https://www.binance.com/en/margin-data>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Binance Margin Trading REST API
3+
*
4+
* OpenAPI Specification for the Binance Margin Trading REST API
5+
*
6+
* The version of the OpenAPI document: 1.0.0
7+
*
8+
*
9+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10+
* https://openapi-generator.tech
11+
* Do not edit the class manually.
12+
*/
13+
14+
#![allow(unused_imports)]
15+
use crate::margin_trading::rest_api::models;
16+
use serde::{Deserialize, Serialize};
17+
18+
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
19+
pub struct GetListScheduleResponseInner {
20+
#[serde(rename = "listTime", skip_serializing_if = "Option::is_none")]
21+
pub list_time: Option<i64>,
22+
#[serde(rename = "crossMarginAssets", skip_serializing_if = "Option::is_none")]
23+
pub cross_margin_assets: Option<Vec<String>>,
24+
#[serde(
25+
rename = "isolatedMarginSymbols",
26+
skip_serializing_if = "Option::is_none"
27+
)]
28+
pub isolated_margin_symbols: Option<Vec<String>>,
29+
}
30+
31+
impl GetListScheduleResponseInner {
32+
#[must_use]
33+
pub fn new() -> GetListScheduleResponseInner {
34+
GetListScheduleResponseInner {
35+
list_time: None,
36+
cross_margin_assets: None,
37+
isolated_margin_symbols: None,
38+
}
39+
}
40+
}

src/margin_trading/rest_api/models/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub mod get_interest_history_response;
4747
pub use self::get_interest_history_response::GetInterestHistoryResponse;
4848
pub mod get_interest_history_response_rows_inner;
4949
pub use self::get_interest_history_response_rows_inner::GetInterestHistoryResponseRowsInner;
50+
pub mod get_list_schedule_response_inner;
51+
pub use self::get_list_schedule_response_inner::GetListScheduleResponseInner;
5052
pub mod get_small_liability_exchange_coin_list_response_inner;
5153
pub use self::get_small_liability_exchange_coin_list_response_inner::GetSmallLiabilityExchangeCoinListResponseInner;
5254
pub mod get_small_liability_exchange_history_response;

0 commit comments

Comments
 (0)