Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Lightcone SDK
Rust SDK for the Lightcone impact market protocol on Solana.
Table of Contents
- Installation
- Feature Flags
- Quick Start
- Start Trading
- Examples
- Authentication
- Error Handling
- Retry Strategy
Installation
Add to your Cargo.toml:
[]
= { = "0.4.1", = ["native"] }
For browser/WASM targets:
[]
= { = "0.4.1", = ["wasm"] }
Feature Flags
| Feature | What it enables | Use case |
|---|---|---|
native |
http + native-auth + ws-native + solana-rpc |
Market makers, bots, CLI tools |
wasm |
http + ws-wasm |
Browser applications |
Quick Start
use *;
use sign_login_message;
use Keypair;
async
Start Trading
use *;
use read_keypair_file;
use Signer;
// Defaults to Prod. Use .env(LightconeEnv::Staging) for staging.
let client = builder
.deposit_source
.build?;
let keypair = read_keypair_file?;
Step 1: Find a Market
let market = client.markets.get.await?.markets.into_iter.next.unwrap;
let orderbook = market
.orderbook_pairs
.iter
.find
.or_else
.expect;
Step 2: Deposit Collateral
let deposit_mint = market.deposit_assets.pubkey.to_pubkey?;
let deposit_ix = client.positions.deposit.await
.user
.mint
.amount
.build_ix
.await?;
Step 3: Place an Order
let request = client.orders.limit_order.await
.maker
.bid
.price
.size
.sign?;
let order = client.orders.submit.await?;
Step 4: Monitor
let open = client
.orders
.get_user_orders
.await?;
let mut ws = client.ws_native;
ws.connect.await?;
ws.subscribe?;
ws.subscribe?;
Step 5: Cancel an Order
let cancel = signed;
client.orders.cancel.await?;
Step 6: Exit a Position
// sign_and_submit builds the tx, signs it using the client's signing strategy, and submits
let tx_hash = client.positions.merge
.user
.market
.mint
.amount
.sign_and_submit
.await?;
Step 7: Withdraw
let withdraw_ix = client.positions.withdraw.await
.user
.mint
.amount
.build_ix
.await?;
Authentication
Authentication is only required for user-specific endpoints. Authentication is session-based using ED25519 signed messages. The flow is: request a nonce, sign it with your wallet, and exchange it for a session token.
Environment Configuration
The SDK defaults to the production environment. Use LightconeEnv to target a different deployment:
// Production (default — no .env() call needed)
let client = builder.build?;
// Staging
let client = builder
.env
.build?;
// Local development
let client = builder
.env
.build?;
Each environment configures the API URL, WebSocket URL, Solana RPC URL, and on-chain program ID automatically. Individual URL overrides (.base_url(), .ws_url(), .rpc_url()) take precedence when called after .env().
Examples
All examples are runnable with cargo run --example <name> --features native. Examples default to the production environment and read the wallet keypair from ~/.config/solana/id.json.
Setup & Authentication
| Example | Description |
|---|---|
login |
Full auth lifecycle: sign message, login, check session, logout |
Market Discovery & Data
| Example | Description |
|---|---|
markets |
Featured markets, paginated listing, fetch by pubkey, search |
orderbook |
Fetch orderbook depth (bids/asks) and decimal precision metadata |
trades |
Recent trade history with cursor-based pagination |
price_history |
Historical candlestick data (OHLCV) at various resolutions |
positions |
User positions across all markets and per-market |
Placing Orders
| Example | Description |
|---|---|
submit_order |
Limit order via client.orders().limit_order() with human-readable price/size, auto-scaling, and fill tracking |
Cancelling Orders
| Example | Description |
|---|---|
cancel_order |
Cancel a single order by hash and cancel all orders in an orderbook |
user_orders |
Fetch open orders for an authenticated user |
On-Chain Operations
| Example | Description |
|---|---|
read_onchain |
Read exchange state, market state, user nonce, and PDA derivations via RPC |
onchain_transactions |
Build, sign, and submit mint/merge complete set and increment nonce on-chain |
global_deposit_withdrawal |
Init position tokens, deposit to global pool, move capital into a market, extend an existing ALT, and withdraw from global |
WebSocket Streaming
| Example | Description |
|---|---|
ws_book_and_trades |
Live orderbook depth with OrderbookSnapshot state + rolling TradeHistory buffer |
ws_ticker_and_prices |
Best bid/ask ticker + price history candles with PriceHistoryState |
ws_user_and_market |
Authenticated user stream (orders, balances) + market lifecycle events |
Error Handling
All SDK operations return Result<T, SdkError>:
| Variant | When |
|---|---|
SdkError::Http(HttpError) |
REST request failures |
SdkError::Ws(WsError) |
WebSocket connection/protocol errors |
SdkError::Auth(AuthError) |
Authentication failures |
SdkError::Validation(String) |
Domain type conversion failures |
SdkError::Serde(serde_json::Error) |
Serialization errors |
SdkError::MissingMarketContext(string) |
Market context not provided for operation requiring DepositSource::Market |
SdkError::Signing(String) |
Signing operation failures |
SdkError::UserCancelled |
User cancelled wallet signing prompt |
SdkError::Program(program::SdkError) |
On-chain program errors (RPC, account parsing) |
SdkError::Other(String) |
Catch-all |
HttpError variants:
| Variant | Meaning |
|---|---|
Reqwest(reqwest::Error) |
Network/transport failure |
ServerError { status, body } |
Non-2xx response from the backend |
RateLimited { retry_after_ms } |
429 - back off and retry |
Unauthorized |
401 - session expired or missing |
NotFound(String) |
404 - resource not found |
BadRequest(String) |
400 - invalid request |
Timeout |
Request timed out |
MaxRetriesExceeded { attempts, last_error } |
All retry attempts exhausted |
Retry Strategy
- GET requests:
RetryPolicy::Idempotent- retries on transport failures and 502/503/504, backs off on 429 with exponential backoff + jitter. - POST requests (order submit, cancel, auth):
RetryPolicy::None- no automatic retry. Non-idempotent actions are never retried to prevent duplicate side effects. - Customizable per-call with
RetryPolicy::Custom(RetryConfig { .. }).