Skip to main content

Module bulk_ws

Module bulk_ws 

Source
Expand description

Bulk Labs WebSocket Trading Client — Actor + Watch architecture.

All mutable state lives inside a single [Actor] task. The public BulkWsClient handle is a cheap, cloneable struct that communicates with the actor via:

  • tokio::sync::watch for hot-path reads (tickers, prices, margin) — zero-cost .borrow(), no async round-trip.
  • mpsc command channel for writes (subscribe, place orders, etc.).
  • oneshot for request/response flows (order placement).
 ┌──────────────┐         mpsc::channel           ┌───────────────┐
 │ BulkWsClient │ ───── Command ────────────────▶ │     Actor     │
 │   (handle)   │ ◀──── watch::Receiver ────────  │  (owns state) │
 └──────────────┘                                 └───────┬───────┘
       │                                                  │
       │ oneshot for order responses                      │ tokio::select!
       └─────────────────────────────────────────────────▶│◀── ws_read

§Example

use bulk_client::*;
use bulk_client::common::side::Side;
use bulk_client::common::tif::TimeInForce;
use bulk_client::transaction::TransactionSigner;
use bulk_client::parts::WSConfig;

#[tokio::main]
async fn main() -> eyre::Result<()> {
    let signer = TransactionSigner::from_private_key("your_base58_key")?;

    let client = BulkWsClient::connect(WSConfig {
        url: "wss://exchange-wss.bulk.trade".into(),
        symbols: vec!["BTC-USD".into(), "ETH-USD".into()],
        signer: Some(signer),
        ..Default::default()
    }).await?;

    // Zero-cost read — no lock, no channel round-trip
    if let Some(ticker) = client.get_ticker("BTC-USD") {
        println!("BTC mark price: {}", ticker.mark_price);
    }

    // Place an order — goes through actor → ws
    let resp = client.place_limit_order(
        "BTC-USD", Side::Buy, 95_000.0, 0.01,
        TimeInForce::GTC, false, None, None,
    ).await?;

    client.shutdown().await;
    Ok(())
}

Structs§

AccountState
Everything a reader might want, exposed as one cheap clone via watch. The actor publishes a new snapshot after every state-mutating message.
BulkWsClient
Cloneable client handle.

Type Aliases§

EventHandler
User-supplied callback. Receives the raw JSON payload for the topic. Runs synchronously inside the actor loop — keep it fast or spawn.