-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e6ae773
Showing
257 changed files
with
18,758 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Rust Main Workflow | ||
|
||
on: | ||
push: | ||
branches: [master] | ||
pull_request: | ||
branches: [master, rc-**] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Fix Rust Version | ||
run: rustup install 1.65 | ||
|
||
- name: Test | ||
run: cargo test | ||
|
||
- name: Format Check | ||
run: cargo fmt -- --check | ||
|
||
- name: Lint Check | ||
run: cargo clippy --all-targets -- -D clippy::all | ||
|
||
- name: Examples Format Check | ||
working-directory: ./examples | ||
run: cargo fmt -- --check | ||
|
||
- name: Examples Lint Check | ||
working-directory: ./examples | ||
run: cargo clippy --all-targets -- -D clippy::all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
debug/ | ||
target/ | ||
Cargo.lock | ||
**/*.rs.bk | ||
*.pdb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Changelog | ||
|
||
## 0.0.1 - Undefined |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
[package] | ||
name = "binance_spot_connector_rust" | ||
version = "1.0.0" | ||
authors = ["Binance"] | ||
edition = "2021" | ||
resolver = "2" | ||
autoexamples = false | ||
description = "This is a lightweight library that works as a connector to the Binance public API" | ||
readme = "README.md" | ||
repository = "https://github.com/binance/binance-connector-rust" | ||
license = "MIT" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[features] | ||
default = ["enable-ureq", "enable-tungstenite"] | ||
enable-hyper = [ "hyper", "hyper-tls", "serde_json", "futures-util", "tokio" ] | ||
enable-ureq = [ "ureq", "serde_json" ] | ||
enable-tungstenite = ["tungstenite"] | ||
enable-tokio-tungstenite = ["tokio-tungstenite"] | ||
full = ["enable-hyper", "enable-tungstenite", "enable-ureq", "enable-tokio-tungstenite"] | ||
|
||
[dependencies] | ||
hmac = "0.12.0" | ||
log = "0.4.14" | ||
serde = { version = "1.0.136", features = ["derive"] } | ||
sha2 = { version = "0.10.6", default-features = false, features = ["oid"] } | ||
url = "2.2.2" | ||
rust_decimal = "1.24.0" | ||
http = "0.2.7" | ||
strum = { version = "0.24", features = ["derive"] } | ||
rsa = { version = "0.7.1", features = ["pkcs5"] } | ||
rand = "0.8.5" | ||
signature = "1.6.4" | ||
base64 = "0.13.1" | ||
|
||
# enable-ureq | ||
ureq = { version = "2.4.0", optional = true } | ||
|
||
# enable-hyper | ||
hyper = { version = "0.14.16", features = ["full"], optional = true } | ||
serde_json = { version = "1.0.78", optional = true } | ||
hyper-tls = {version = "0.5.0", optional = true } | ||
futures-util = {version = "0.3.21", optional = true } | ||
tokio = { version = "1", features = ["time"], optional = true } | ||
|
||
# enable-tungstenite | ||
tungstenite = {version = "0.16.0", features = ["native-tls"], optional = true} | ||
|
||
# enable-tokio-tungstenite | ||
tokio-tungstenite = {version = "0.17.1", features = ["native-tls"], optional = true} | ||
|
||
[dev-dependencies] | ||
tokio = { version = "1", features = ["full"] } | ||
env_logger = "0.10.0" | ||
tower = "0.4.12" | ||
rust_decimal_macros = "1.24.0" | ||
cargo-audit = "0.17.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) [2022] [Binance] | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
# Binance Public API Connector Rust | ||
|
||
This is a lightweight library that works as a connector to [Binance public API](https://github.com/binance/binance-spot-api-docs) | ||
|
||
- Supported APIs: | ||
- `/api/*` | ||
- `/sapi/*` | ||
- Spot Websocket Market Stream | ||
- Spot User Data Stream | ||
- Test cases and examples | ||
- Customizable base URL and request timeout | ||
- Blocking and Non-blocking clients | ||
- Response Metadata | ||
|
||
## RESTful APIs | ||
|
||
The Binance Rust Connector exposes two abstraction layers to integrete with Binance RESTful APIs; a high level | ||
abstraction consisting of maintained functions mapped one-to-one with Binance API endpoints, and a low level | ||
generic abstraction for more control over the request. | ||
|
||
**High Level Usage Example** | ||
|
||
```rust | ||
use env_logger::Builder; | ||
use binance_spot_connector_rust::{ | ||
http::Credentials, | ||
hyper::{BinanceHttpClient, Error}, | ||
market::{self, klines::KlineInterval}, | ||
trade | ||
}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Error> { | ||
Builder::from_default_env() | ||
.filter(None, log::LevelFilter::Info) | ||
.init(); | ||
|
||
let credentials = Credentials::from_hmac("api-key".to_owned(), "api-secret".to_owned()); | ||
let client = BinanceHttpClient::default().credentials(credentials); | ||
|
||
// Get candlesticks for BTCUSDT with a 1 minute interval | ||
let data = client.send(market::klines("BTCUSDT", KlineInterval::Minutes1)).await | ||
.expect("Request failed") | ||
.into_body_str().await | ||
.expect("Failed to read response body"); | ||
log::info!("{}", data); | ||
|
||
// Get the last 10 candlesticks for BTCUSDT with a 1 hour interval | ||
let data = client.send(market::klines("BTCUSDT", KlineInterval::Hours1).limit(10)).await | ||
.expect("Request failed") | ||
.into_body_str().await | ||
.expect("Failed to read response body"); | ||
log::info!("{}", data); | ||
|
||
// Get account information | ||
let data = client.send(trade::account()).await | ||
.expect("Request failed") | ||
.into_body_str().await | ||
.expect("Failed to read response body"); | ||
log::info!("{}", data); | ||
|
||
Ok(()) | ||
} | ||
``` | ||
|
||
Examples for other endpoints are available in the `examples` folder. | ||
|
||
**Low Level Usage Example** | ||
|
||
```rust | ||
use binance_spot_connector_rust::{ | ||
http::{request::RequestBuilder, Method}, | ||
hyper::{BinanceHttpClient, Error}, | ||
}; | ||
use env_logger::Builder; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Error> { | ||
Builder::from_default_env() | ||
.filter(None, log::LevelFilter::Info) | ||
.init(); | ||
|
||
let client = BinanceHttpClient::default(); | ||
|
||
let builder = RequestBuilder::new(Method::Get, "/api/v3/klines") | ||
.params(vec![("symbol", "BTCUSDT"), ("interval", "1m")]); | ||
|
||
// Get candlesticks for BTCUSDT with a 1 minute interval | ||
let data = client | ||
.send(builder) | ||
.await | ||
.expect("Request failed") | ||
.into_body_str() | ||
.await | ||
.expect("Failed to read response body"); | ||
log::info!("{}", data); | ||
|
||
Ok(()) | ||
} | ||
``` | ||
|
||
## Websocket | ||
|
||
```rust | ||
use binance_spot_connector_rust::{ | ||
market::klines::KlineInterval, market_stream::kline::KlineStream, | ||
tokio_tungstenite::BinanceWebSocketClient, | ||
}; | ||
use env_logger::Builder; | ||
use futures_util::StreamExt; | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
Builder::from_default_env() | ||
.filter(None, log::LevelFilter::Info) | ||
.init(); | ||
// Establish connection | ||
let (mut conn, _) = BinanceWebSocketClient::connect_async_default() | ||
.await | ||
.expect("Failed to connect"); | ||
// Subscribe to streams | ||
conn.subscribe(vec![ | ||
&KlineStream::new("BTCUSDT", KlineInterval::Minutes1).into() | ||
]) | ||
.await; | ||
// Read messages | ||
while let Some(message) = conn.as_mut().next().await { | ||
match message { | ||
Ok(message) => { | ||
let binary_data = message.into_data(); | ||
let data = std::str::from_utf8(&binary_data).expect("Failed to parse message"); | ||
log::info!("{:?}", data); | ||
} | ||
Err(_) => break, | ||
} | ||
} | ||
// Disconnect | ||
conn.close().await.expect("Failed to disconnect"); | ||
} | ||
|
||
``` | ||
|
||
Examples for other websocket streams are available in the `examples` folder. | ||
|
||
### Heartbeat | ||
|
||
Once connected, the websocket server sends a ping frame every 3 minutes and requires a response pong frame back within | ||
a 10 minutes period. This package handles the pong responses automatically. | ||
|
||
### Testnet | ||
|
||
`/api/*` endpoints can be tested in [Spot Testnet](https://testnet.binance.vision/). `/sapi/*` endpoints are not supported. | ||
|
||
```rust | ||
let client = BinanceHttpClient::with_url("https://testnet.binance.vision"); | ||
``` | ||
|
||
### Base URL | ||
|
||
It's recommended to pass in the `baseUrl` parameter, even in production as Binance provides alternative URLs | ||
in case of performance issues: | ||
|
||
- `https://api1.binance.com` | ||
- `https://api2.binance.com` | ||
- `https://api3.binance.com` | ||
|
||
### Timeout | ||
|
||
The default timeout is 100,000 milliseconds (100 seconds). | ||
|
||
### Logging | ||
|
||
This library implements the standard rust logging framework which works with a variety of built-in and third-party logging providers. | ||
|
||
For more information on how to configure logging in Rust, visit [Rust Log](https://docs.rs/log/latest/log/) | ||
|
||
**Usage Example** | ||
|
||
```rust | ||
use binance_spot_connector_rust::{ | ||
http::Credentials, | ||
hyper::{BinanceHttpClient, Error}, | ||
wallet, | ||
}; | ||
use env_logger::Builder; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Error> { | ||
Builder::from_default_env() | ||
.filter(None, log::LevelFilter::Debug) | ||
.init(); | ||
|
||
let credentials = Credentials::from_hmac("api-key".to_owned(), "api-secret".to_owned()); | ||
let client = BinanceHttpClient::default().credentials(credentials); | ||
|
||
// Get candlesticks for BTCUSDT with a 1 minute interval | ||
let data = client | ||
.send(wallet::system_status()) | ||
.await | ||
.expect("Request failed") | ||
.into_body_str() | ||
.await | ||
.expect("Failed to read response body"); | ||
|
||
Ok(()) | ||
} | ||
``` | ||
|
||
**Sample Output** | ||
|
||
``` | ||
[2022-02-22T00:00:00Z DEBUG binance_spot_connector_rust::hyper::client] https://api.binance.com/sapi/v1/system/status | ||
[2022-02-22T00:00:00Z DEBUG binance_spot_connector_rust::hyper::client] 200 OK | ||
[2022-02-22T00:00:00Z INFO binance_spot_connector_rust::hyper::client] {"status":0,"msg":"normal"} | ||
``` | ||
|
||
## Test Cases | ||
|
||
```bash | ||
cargo test | ||
``` | ||
|
||
## Examples | ||
|
||
All snippets for spot endpoints and streams can be found in the `examples` folder. Example names are a concatanation of the example directory name and the example file name separated by an underscore. | ||
|
||
```bash | ||
cd examples && cargo run --example market_exchange_info | ||
``` | ||
|
||
## Limitations | ||
|
||
Futures and Vanilla Options APIs are not supported: | ||
|
||
- /fapi/\* | ||
- /dapi/\* | ||
- /vapi/\* | ||
- Associated Websocket Market and User Data Streams | ||
|
||
## Contributing | ||
|
||
Contributions are welcome. | ||
|
||
If you've found a bug within this project, please open an issue to discuss what you would like to change. | ||
|
||
If it's an issue with the API, please open a topic at [Binance Developer Community](https://dev.binance.vision) |
Oops, something went wrong.