rs_limitless — Limitless Exchange API bindings for Rust
Rust client library for the Limitless Exchange prediction market API. Provides strongly-typed bindings for both REST and WebSocket interfaces — browse markets, trade positions, track portfolio performance, and navigate the market hierarchy.
⚠️ Disclaimer — This is a personal project, use at your own risk. Prediction market trading involves significant financial risk. Neither the author nor contributors are liable for losses.
Table of Contents
- Features
- Quick Start
- Installation
- Authentication
- Usage Guide
- Architecture
- Error Handling
- Running Tests
- Examples
- License
Features
REST API
| Module | Auth | Endpoints |
|---|---|---|
| Markets | No | Browse active, search, get details, oracle candles, feed events, category counts |
| Trader | Yes | Create GTC/FOK orders, batch status, cancel (single/batch/all), orderbook, historical prices, locked balance, user orders, market events |
| Portfolio | Yes | Profile, trade history, AMM + CLOB positions with P&L, PnL chart, points breakdown, cursor-paginated history, allowance checks |
| Navigation | No | Navigation tree, market pages, page-specific market listings, property keys & options |
WebSocket
| Stream | Auth | Description |
|---|---|---|
subscribe_market_prices |
No | AMM price updates + CLOB orderbook snapshots |
subscribe_market_lifecycle |
No | Market creation / resolution events |
subscribe_positions |
Yes | Portfolio position balance changes |
subscribe_transactions |
Yes | On-chain transaction events |
subscribe_order_events |
Yes | OME state & settlement lifecycle |
Additional
- EIP-712 signing for CLOB orders (GTC, FOK)
- HMAC-SHA256 request authentication
- Dynamic WebSocket subscriptions — sub/unsub without reconnecting
- Exponential backoff retry for transient failures
- WebSocket ping/pong keep-alive
Quick Start
use *;
async
Installation
Add to your Cargo.toml:
[]
= "0.1"
= { = "1", = ["full"] }
Or use the crate alias limitless:
[]
= { = "rs_limitless", = "0.1" }
= { = "1", = ["full"] }
Requirements
- Rust 1.70+ (edition 2021)
- OpenSSL development headers (for native TLS)
# macOS
# Ubuntu / Debian
# Fedora
Authentication
HMAC-SHA256 Signed Requests
Credentials can be supplied in three ways:
// 1. Builder (reads LIMITLESS_API_KEY + LIMITLESS_API_SECRET from env)
let client = builder.build?;
// 2. Builder with explicit credentials
let client = builder
.set_credentials
.build?;
// 3. Direct manager construction
let trader = new;
API Keys
Get your API key from the Limitless Exchange settings page. Your credentials are scoped to read/write access and can be revoked at any time.
Usage Guide
Unified Client
LimitlessClient exposes every API method directly, so you never need to reach through
intermediary managers:
use *;
async
Public Markets
use *;
async
Trading
Place GTC (Good-Till-Cancelled) limit orders and FOK (Fill-Or-Kill) market orders with a single call — the library handles EIP-712 signing, venue contract resolution, and submission automatically.
use *;
async
EIP-712 Order Signing
For advanced use cases, sign orders directly without submitting:
use *;
use Eip712Signer;
let signer = new?;
// Build and sign a GTC limit order
let order_data = signer.build_gtc_order?;
// Submit manually
let request = CreateOrderRequest ;
let body = to_string?;
let trader: Trader = new;
let response = trader.create_order.await?;
Portfolio
use *;
async
Market Navigation
use *;
async
WebSocket Streams
The WebSocket transport uses raw WebSocket with Socket.IO protocol underneath.
Use ws_subscribe_with_commands for dynamic subscription control:
use *;
use Value;
use mpsc;
async
Ping
let ws: Stream = new;
ws.ws_ping.await?;
println!;
Subscription Channels
| Channel | Wire name | Auth | Description |
|---|---|---|---|
SubscribeMarketPrices |
subscribe_market_prices |
No | AMM prices + CLOB orderbook |
SubscribeMarketLifecycle |
subscribe_market_lifecycle |
No | Market creation / resolution |
SubscribePositions |
subscribe_positions |
Yes | Portfolio position updates |
SubscribeTransactions |
subscribe_transactions |
Yes | On-chain transaction events |
SubscribeOrderEvents |
subscribe_order_events |
Yes | OME + settlement events |
Architecture
rs_limitless
├── src/
│ ├── lib.rs # Crate root, prelude, re-exports
│ ├── api.rs # API endpoint enums + Limitless trait
│ ├── client.rs # HTTP client with HMAC signing
│ ├── config.rs # REST/WS endpoint config + recv_window
│ ├── errors.rs # LimitlessError enum
│ ├── markets.rs # Public market data
│ ├── trading.rs # Order management + convenience methods
│ ├── portfolio.rs # Profile, positions, PnL, history
│ ├── navigation.rs # Market page tree & property keys
│ ├── signing.rs # EIP-712 order signing
│ ├── lclient.rs # LimitlessClient (unified builder)
│ ├── models/
│ │ ├── mod.rs # API response types + WS event types
│ │ └── order.rs # OrderData, amount calcs, validation
│ ├── ws/
│ │ ├── mod.rs # Ping interval, channel helpers
│ │ ├── channel.rs # SubscriptionChannel, event structs, config
│ │ ├── client.rs # Raw WebSocket connection wrapper
│ │ └── stream.rs # Event loop + subscription control
│ ├── serde_helpers/ # Custom serde (string-as-f64, etc.)
│ └── retry.rs # Exponential backoff with jitter
├── tests/
│ ├── markets_test.rs # Public market integration tests
│ ├── navigation_test.rs # Navigation integration tests
│ ├── portfolio_test.rs # Portfolio integration tests
│ ├── trading_test.rs # Trading integration tests
│ └── ws_test.rs # WebSocket integration tests
├── examples/
│ ├── public_markets.rs # Browse, search, orderbook demo
│ ├── portfolio.rs # Profile, positions, PnL, history demo
│ ├── trading.rs # GTC / FOK order placement demo
│ └── websocket.rs # WS CLI with 6 modes (ping/public/orderbook/...)
└── Cargo.toml
Key Types
| Type | Description |
|---|---|
LimitlessError |
Comprehensive error enum (API errors, network, validation, WS) |
Config |
REST + WS endpoint configuration |
RetryConfig |
Exponential backoff for transient failures |
SubscriptionChannel |
All WS subscription channels with as_str() |
Eip712Signer |
EIP-712 typed data signer |
OrderData |
Signed EIP-712 order payload |
Error Handling
All fallible methods return Result<T, LimitlessError>.
The error enum covers:
ApiError— The API returned a 4xx/5xx with an error bodyReqError— Network / DNS / TLS failure (transparent fromreqwest)Tungstenite— WebSocket protocol error (transparent fromtokio-tungstenite)ValidationError— Client-side parameter validation failedRateLimited— 429 Too Many Requests (retryable)Json— Serialization / deserialization errorStatusCode(u16)— Unexpected HTTP status code
match result
Use retry::with_retry
for automatic retry with exponential backoff:
use with_retry;
let result = with_retry.await?;
Running Tests
# All unit tests (no network, no auth)
# WebSocket integration tests (requires network)
LIMITLESS_API_KEY="key" LIMITLESS_API_SECRET="secret"
# All integration tests
LIMITLESS_API_KEY="key" LIMITLESS_API_SECRET="secret"
# Specific test
# With logging
RUST_LOG=debug
# Compile examples (verify they build)
Note: The integration tests (
trading_test,markets_test) hit the live API. Some tests may fail due to API schema changes — these are documented pre-existing issues.
Examples
The examples/ directory contains runnable demos:
| Example | Command | Auth |
|---|---|---|
| Public markets | cargo run --example public_markets |
No |
| Portfolio | cargo run --example portfolio |
Yes |
| Trading | cargo run --example trading |
Yes |
| WS ping | cargo run --example websocket ping |
No |
| WS public | cargo run --example websocket public |
No |
| WS orderbook | cargo run --example websocket orderbook --market btc-above-100k |
No |
| WS lifecycle | cargo run --example websocket lifecycle |
No |
| WS positions | LIMITLESS_API_KEY=k LIMITLESS_API_SECRET=s cargo run --example websocket positions |
Yes |
| WS transactions | LIMITLESS_API_KEY=k LIMITLESS_API_SECRET=s cargo run --example websocket transactions |
Yes |
License
This project is licensed under the MIT License.
Acknowledgments
Draws inspiration from rs_bybit and the
official limitless-exchange-rust-sdk.