bybit/lib.rs
1//! Unofficial Rust SDK for the [Bybit V5 API](https://bybit-exchange.github.io/docs/v5/intro).
2//!
3//! The library crate is named `bybit` (package `patisson-bybit-sdk`).
4//!
5//! - [`http::Client`]: REST endpoints (market data, trading, positions, account,
6//! assets), request signing, optional local rate limiting
7//! ([`http::RateLimiterConfig`]) and clock synchronization
8//! ([`http::Client::sync_time`]).
9//! - [`ws::Stream`]: WebSocket driver with automatic reconnects and heartbeat;
10//! commands go through [`ws::Handle`], messages and connection state arrive as
11//! [`ws::Event`]s.
12//! - [`OrderBookState`]: local order book from snapshots and deltas.
13//! - [`AccountState`]: local copy of open orders, positions and wallet
14//! balances from REST snapshots and the private stream.
15//!
16//! Everything is async and runs on Tokio.
17//!
18//! # TLS
19//!
20//! REST and WebSocket use the same TLS backend, chosen with a Cargo feature
21//! (enable exactly one): `rustls` (default; aws-lc-rs and the operating
22//! system's root certificates, no OpenSSL) or `native-tls` (OpenSSL,
23//! Schannel or Security.framework).
24//!
25//! # REST
26//!
27//! ```no_run
28//! use bybit::{
29//! Category, Environment,
30//! http::{Client, Config, GetTickersParams},
31//! };
32//!
33//! # async fn run() -> Result<(), bybit::Error> {
34//! let client = Client::new(Config::for_env(Environment::Mainnet))?;
35//! let params = GetTickersParams::new(Category::Linear).with_symbol("BTCUSDT");
36//! let tickers = client.get_tickers(¶ms).await?;
37//! println!("{:?}", tickers.result);
38//! # Ok(())
39//! # }
40//! ```
41//!
42//! Private endpoints need credentials. Call [`http::Client::sync_time`] once
43//! so that signed requests use the server clock even if the local clock is
44//! off:
45//!
46//! ```no_run
47//! use bybit::{
48//! AccountType, Environment,
49//! http::{Client, Config, GetWalletBalanceParams},
50//! };
51//!
52//! # async fn run() -> Result<(), bybit::Error> {
53//! let client = Client::new(Config::for_env(Environment::Demo).credentials("API_KEY", "API_SECRET"))?;
54//! client.sync_time().await?;
55//! let params = GetWalletBalanceParams {
56//! account_type: AccountType::UNIFIED,
57//! coin: None,
58//! };
59//! let wallet = client.get_wallet_balance(¶ms).await?;
60//! # Ok(())
61//! # }
62//! ```
63//!
64//! # WebSocket
65//!
66//! The driver reconnects by itself and restores the topics subscribed with
67//! [`ws::Handle::subscribe`]. With [`ws::Config::credentials`] it also sends
68//! `auth` on every connection (using [`ServerClock`], shared with
69//! [`http::Client::clock`]) and subscribes once it succeeded:
70//!
71//! ```no_run
72//! use bybit::{
73//! Environment, Topic,
74//! http::{Client, Config},
75//! ws,
76//! };
77//!
78//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
79//! let client = Client::new(Config::for_env(Environment::Demo))?;
80//! client.sync_time().await?;
81//!
82//! let config = ws::Config::private(Environment::Demo)
83//! .credentials("API_KEY", "API_SECRET")
84//! .server_clock(client.clock());
85//! let (handle, mut events) = ws::Stream::new(config);
86//! handle.subscribe(vec![Topic::OrderAllCategory, Topic::Wallet]).await?;
87//! handle.connect().await?;
88//!
89//! while let Some(event) = events.recv().await {
90//! match event {
91//! ws::Event::Message(msg) => println!("{msg:?}"),
92//! ws::Event::AuthFailed { .. } | ws::Event::Disconnected { .. } => break,
93//! _ => {}
94//! }
95//! }
96//! # Ok(())
97//! # }
98//! ```
99//!
100//! Public streams work the same way without credentials
101//! ([`ws::Config::public`]). See the
102//! [examples](https://github.com/yurii-musolov/patisson-bybit-sdk/tree/main/examples),
103//! in particular `account-state` for [`AccountState`] and `stream-orderbook`
104//! for [`OrderBookState`].
105//!
106//! # Versioning
107//!
108//! There are no stability guarantees yet: treat every version change as
109//! breaking and pin an exact version (`patisson-bybit-sdk = "=x.y.z"`).
110
111#![warn(missing_docs)]
112
113#[cfg(not(any(feature = "rustls", feature = "native-tls")))]
114compile_error!("enable a TLS backend: the `rustls` (default) or the `native-tls` feature");
115
116mod account_state;
117mod clock;
118mod common;
119mod crypto;
120mod enums;
121mod environment;
122mod error;
123mod orderbook_state;
124mod serde;
125mod url;
126
127/// REST API: [`http::Client`], its [`http::Config`], request parameters and responses.
128pub mod http;
129pub mod ret_code;
130/// WebSocket streams: [`ws::Stream`], [`ws::Handle`], [`ws::Config`] and the messages.
131pub mod ws;
132
133pub use account_state::*;
134pub use clock::ServerClock;
135pub use common::*;
136pub use crypto::*;
137pub use enums::*;
138pub use environment::Environment;
139pub use error::*;
140pub use orderbook_state::*;
141// The BASE_URL_* constants are deprecated in favour of `Environment`.
142#[allow(deprecated)]
143pub use url::{
144 BASE_URL_API_DEMO, BASE_URL_API_MAINNET_1, BASE_URL_API_MAINNET_2, BASE_URL_API_MAINNET_3,
145 BASE_URL_API_MAINNET_4, BASE_URL_API_MAINNET_5, BASE_URL_API_MAINNET_6, BASE_URL_API_TESTNET,
146 BASE_URL_STREAM_DEMO, BASE_URL_STREAM_MAINNET_1, BASE_URL_STREAM_MAINNET_2,
147 BASE_URL_STREAM_MAINNET_3, BASE_URL_STREAM_TESTNET, Path,
148};