Skip to content

Commit

Permalink
first release
Browse files Browse the repository at this point in the history
  • Loading branch information
2pd committed Dec 6, 2022
0 parents commit e6ae773
Show file tree
Hide file tree
Showing 257 changed files with 18,758 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/rust.yaml
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
debug/
target/
Cargo.lock
**/*.rs.bk
*.pdb
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Changelog

## 0.0.1 - Undefined
58 changes: 58 additions & 0 deletions Cargo.toml
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"
21 changes: 21 additions & 0 deletions LICENSE.md
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.
246 changes: 246 additions & 0 deletions README.md
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)
Loading

0 comments on commit e6ae773

Please sign in to comment.