> ## Documentation Index
> Fetch the complete documentation index at: https://docs.limitless.exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket

> Real-time market data and position updates with the Rust SDK

## Overview

The Rust SDK provides a Socket.IO-based `WebSocketClient` for:

* orderbook and trade streams
* market and price updates
* authenticated order, fill, position, and transaction streams
* automatic reconnect with subscription replay

## Setup

Create a WebSocket client from the root SDK client:

```rust theme={null}
use limitless_exchange_rust_sdk::Client;

let client = Client::new()?;
let ws = client.new_websocket_client(None);
```

Or configure it directly:

```rust theme={null}
use std::sync::Arc;

use limitless_exchange_rust_sdk::{
    ConsoleLogger, HmacCredentials, LogLevel, WebSocketClient, WebSocketConfig,
};

let ws = WebSocketClient::new(Some(WebSocketConfig {
    // Required for authenticated channels (positions, order events, transactions);
    // the SDK signs the handshake automatically.
    hmac_credentials: Some(HmacCredentials {
        token_id: "your_token_id".to_string(),
        secret: "your_token_secret".to_string(), // base64 secret from token creation
    }),
    logger: Some(Arc::new(ConsoleLogger::new(LogLevel::Info))),
    ..Default::default()
}));
```

## Connect and Disconnect

```rust theme={null}
ws.connect().await?;
println!("{:?}", ws.state());
println!("{}", ws.is_connected());

ws.disconnect().await?;
```

### `WebSocketConfig`

| Field                    | Type                      | Default                       | Description                                                                                                                                        |
| ------------------------ | ------------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`                    | `String`                  | `wss://ws.limitless.exchange` | WebSocket URL                                                                                                                                      |
| `hmac_credentials`       | `Option<HmacCredentials>` | `None`                        | HMAC credentials (`token_id`, `secret`) for authenticated channels; the SDK signs the handshake. See [Authentication](/developers/authentication). |
| `auto_reconnect`         | `bool`                    | `true`                        | Reconnect automatically after disconnects                                                                                                          |
| `reconnect_delay_ms`     | `u64`                     | `1000`                        | Base reconnect delay                                                                                                                               |
| `max_reconnect_attempts` | `u32`                     | `0`                           | Max reconnect attempts (`0` means unlimited)                                                                                                       |
| `timeout_ms`             | `u64`                     | `10000`                       | Connect timeout                                                                                                                                    |
| `logger`                 | `Option<SharedLogger>`    | `None`                        | Optional logger                                                                                                                                    |

## Event Handlers

Use `on()` for raw JSON handlers, `once()` for one-shot handlers, and `off()` to unregister:

```rust theme={null}
let id = ws.on("orderbookUpdate", |data| {
    println!("{}", data);
});

let once_id = ws.once("trade", |data| {
    println!("first trade {}", data);
});

ws.off("trade", &[once_id]);
ws.off("orderbookUpdate", &[id]);
```

### Typed handlers

The SDK also provides typed event handlers:

```rust theme={null}
ws.on_orderbook_update(|update| {
    println!(
        "{} bids={} asks={} midpoint={:.3}",
        update.market_slug,
        update.orderbook.bids.len(),
        update.orderbook.asks.len(),
        update.orderbook.adjusted_midpoint
    );
});

ws.on_new_price_data(|price| {
    println!("AMM price update: {:?}", price);
});

// Order lifecycle (authenticated; subscribe to SubscribeOrderEvents).
// on_order_event receives raw serde_json::Value; on_order_event_typed deserializes to OrderEvent.
ws.on_order_event_typed(|event| {
    println!("order event: {:?}", event);
});

ws.on_transaction(|tx| {
    println!("{:?} {}", tx.tx_hash, tx.status);
});

// Market lifecycle (subscribe to SubscribeMarketLifecycle)
ws.on_market_created(|event| {
    println!("created: {:?}", event);
});

ws.on_market_resolved(|event| {
    println!("resolved: {:?}", event);
});
```

## Subscribing to Channels

After connecting, subscribe to specific channels:

```rust theme={null}
use limitless_exchange_rust_sdk::{SubscriptionChannel, SubscriptionOptions};

ws.connect().await?;

// CLOB orderbook updates are delivered through the market-price subscription
ws.subscribe(
    SubscriptionChannel::SubscribeMarketPrices,
    SubscriptionOptions {
        market_slugs: vec!["btc-above-100k-march-2025".to_string()],
        ..Default::default()
    },
)
.await?;
```

### Public channels

| Variant                                         | Description                                    |
| ----------------------------------------------- | ---------------------------------------------- |
| `SubscriptionChannel::SubscribeMarketPrices`    | Orderbook + price updates for specific markets |
| `SubscriptionChannel::SubscribeMarketLifecycle` | Market created / resolved events               |
| `SubscriptionChannel::SubscribeLiveSports`      | Live sports updates                            |
| `SubscriptionChannel::SubscribeLiveEsports`     | Live esports updates                           |

### Authenticated channels

| Variant                                      | Description                 |
| -------------------------------------------- | --------------------------- |
| `SubscriptionChannel::SubscribePositions`    | Your position updates       |
| `SubscriptionChannel::SubscribeOrderEvents`  | Your order lifecycle events |
| `SubscriptionChannel::SubscribeTransactions` | Your transaction updates    |

### `SubscriptionOptions`

| Field              | Type                      | Description               |
| ------------------ | ------------------------- | ------------------------- |
| `market_slug`      | `Option<String>`          | Single market slug        |
| `market_slugs`     | `Vec<String>`             | Multiple market slugs     |
| `market_address`   | `Option<String>`          | Single market address     |
| `market_addresses` | `Vec<String>`             | Multiple market addresses |
| `filters`          | `BTreeMap<String, Value>` | Additional filters        |

## Unsubscribing

```rust theme={null}
ws.unsubscribe(
    SubscriptionChannel::SubscribeMarketPrices,
    SubscriptionOptions {
        market_slugs: vec!["btc-above-100k-march-2025".to_string()],
        ..Default::default()
    },
)
.await?;
```

## Updating credentials

You can rotate credentials at runtime:

```rust theme={null}
use limitless_exchange_rust_sdk::HmacCredentials;

ws.set_hmac_credentials(HmacCredentials {
    token_id: "new-token-id".to_string(),
    secret: "new-base64-secret".to_string(),
});
```

If the socket is already connected, the client reconnects automatically with the new credentials.

## Auto-reconnect

When `auto_reconnect` is enabled, the client reconnects and replays saved subscriptions automatically.

<Note>
  The Rust client preserves normalized subscription options internally, so reconnects restore previous subscriptions without extra application code.
</Note>
