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//! # REST
19//!
20//! ```no_run
21//! use bybit::{
22//! BASE_URL_API_MAINNET_1, Category,
23//! http::{Client, Config, GetTickersParams},
24//! };
25//!
26//! # async fn run() -> Result<(), bybit::Error> {
27//! let client = Client::new(Config::new(BASE_URL_API_MAINNET_1))?;
28//! let params = GetTickersParams {
29//! category: Category::Linear,
30//! symbol: Some(String::from("BTCUSDT")),
31//! base_coin: None,
32//! exp_date: None,
33//! };
34//! let tickers = client.get_tickers(¶ms).await?;
35//! println!("{:?}", tickers.result);
36//! # Ok(())
37//! # }
38//! ```
39//!
40//! Private endpoints need credentials. Call [`http::Client::sync_time`] once
41//! so that signed requests use the server clock even if the local clock is
42//! off:
43//!
44//! ```no_run
45//! use bybit::{
46//! AccountType, BASE_URL_API_DEMO,
47//! http::{Client, Config, GetWalletBalanceParams},
48//! };
49//!
50//! # async fn run() -> Result<(), bybit::Error> {
51//! let client = Client::new(Config::new(BASE_URL_API_DEMO).credentials("API_KEY", "API_SECRET"))?;
52//! client.sync_time().await?;
53//! let params = GetWalletBalanceParams {
54//! account_type: AccountType::UNIFIED,
55//! coin: None,
56//! };
57//! let wallet = client.get_wallet_balance(¶ms).await?;
58//! # Ok(())
59//! # }
60//! ```
61//!
62//! # WebSocket
63//!
64//! The driver reconnects by itself, but subscriptions (and, on private
65//! streams, authentication) must be sent again after every
66//! [`ws::Event::Connected`]:
67//!
68//! ```no_run
69//! use bybit::{
70//! BASE_URL_STREAM_MAINNET_1, Path, Topic,
71//! ws::{self, OutgoingMessage},
72//! };
73//!
74//! # async fn run() -> Result<(), bybit::ws::Error> {
75//! let url = format!("{BASE_URL_STREAM_MAINNET_1}{}", Path::PublicLinear);
76//! let (handle, mut events) = ws::Stream::new(ws::Config::new(url));
77//! handle.connect().await?;
78//!
79//! while let Some(event) = events.recv().await {
80//! match event {
81//! ws::Event::Connected => {
82//! let args = vec![Topic::Ticker(String::from("BTCUSDT"))];
83//! let sub = OutgoingMessage::Subscribe { req_id: None, args };
84//! handle.send_command(sub).await?;
85//! }
86//! ws::Event::Message(msg) => println!("{msg:?}"),
87//! ws::Event::Disconnected { .. } => break,
88//! _ => {}
89//! }
90//! }
91//! # Ok(())
92//! # }
93//! ```
94//!
95//! For private streams build the `auth` message with
96//! [`ws::create_outgoing_message_auth_at`] and
97//! [`http::Client::server_timestamp`]. See the
98//! [examples](https://github.com/yurii-musolov/patisson-bybit-sdk/tree/main/examples),
99//! in particular `account-state` for [`AccountState`] and `stream-orderbook`
100//! for [`OrderBookState`].
101//!
102//! # Versioning
103//!
104//! There are no stability guarantees yet: treat every version change as
105//! breaking and pin an exact version (`patisson-bybit-sdk = "=x.y.z"`).
106
107mod account_state;
108mod common;
109mod crypto;
110mod enums;
111mod error;
112mod orderbook_state;
113mod serde;
114mod url;
115
116pub mod http;
117pub mod ws;
118
119pub use account_state::*;
120pub use common::*;
121pub use crypto::*;
122pub use enums::*;
123pub use error::*;
124pub use orderbook_state::*;
125pub use url::{
126 BASE_URL_API_DEMO, BASE_URL_API_MAINNET_1, BASE_URL_API_MAINNET_2, BASE_URL_API_MAINNET_3,
127 BASE_URL_API_MAINNET_4, BASE_URL_API_MAINNET_5, BASE_URL_API_MAINNET_6, BASE_URL_API_TESTNET,
128 BASE_URL_STREAM_DEMO, BASE_URL_STREAM_MAINNET_1, BASE_URL_STREAM_MAINNET_2,
129 BASE_URL_STREAM_MAINNET_3, BASE_URL_STREAM_TESTNET, Path,
130};