Skip to content

robustfengbin/lighter-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Lighter SDK

A pure Rust SDK for Lighter DEX - a zk-powered perpetual futures exchange on Hyperliquid.

Features

  • Pure Rust - No external .so files or FFI dependencies required
  • Complete API Coverage - HTTP REST API and WebSocket streaming
  • Transaction Signing - Built-in ECgFp5/Poseidon2 cryptographic signing
  • Thread-safe - Concurrent nonce management with atomic operations
  • Async/Await - Built on tokio for high-performance async operations

Installation

Add this to your Cargo.toml:

[dependencies]
lighter-sdk = "0.1"

Quick Start

use lighter_sdk::{LighterClient, LighterSigner};
use rust_decimal_macros::dec;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Create a signer with your API key
    let signer = LighterSigner::new(
        "your_private_key_hex",  // 40-byte hex string
        0,                        // api_key_index
        12345,                    // account_index
        true,                     // is_mainnet
    )?;

    // Create a client
    let client = LighterClient::mainnet(signer);

    // Sync nonce from API (required before placing orders)
    client.sync_nonce().await?;

    // Get account info
    let account = client.get_account_info().await?;
    println!("Balance: {}", account.available_balance);

    // Place a limit order
    let response = client.place_limit_order(
        "HYPE",         // symbol
        dec!(25.50),    // price
        dec!(100.0),    // quantity
        true,           // is_buy (true = buy, false = sell)
        false,          // reduce_only
    ).await?;

    println!("Order placed: {:?}", response);
    Ok(())
}

WebSocket Streaming

use lighter_sdk::LighterWebSocket;
use tokio::sync::mpsc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let ws = LighterWebSocket::mainnet();

    // Create channel for orderbook updates
    let (tx, mut rx) = mpsc::unbounded_channel();

    // Subscribe to orderbook updates (symbol, market_id, sender)
    // Note: Get market_id from client.get_market_info() or API
    ws.subscribe_orderbook("HYPE".to_string(), 24, tx).await?;

    // Receive updates
    while let Some(update) = rx.recv().await {
        println!("Best bid: {}, Best ask: {}",
            update.best_bid, update.best_ask);
    }

    Ok(())
}

API Reference

LighterSigner

Transaction signing with ECgFp5 elliptic curve and Poseidon2 hash.

let signer = LighterSigner::new(
    api_key_private,  // 40-byte hex private key
    api_key_index,    // API key index (u8)
    account_index,    // Account index (i64)
    is_mainnet,       // true for mainnet, false for testnet
)?;

// Get public key
println!("Public key: {}", signer.public_key_hex());

// Create auth token for private APIs
let token = signer.create_auth_token(3600)?; // 1 hour validity

LighterClient

HTTP client for Lighter API.

// Create client
let client = LighterClient::mainnet(signer);
// or
let client = LighterClient::testnet(signer);

// Sync nonce (required before placing orders)
client.sync_nonce().await?;

// Account operations
let account = client.get_account_info().await?;
let position = client.get_position("HYPE").await?;

// Market data
let market = client.get_market_info("HYPE").await?;
let (bid, ask) = client.get_best_prices("HYPE").await?;

// Order operations
client.place_limit_order(symbol, price, quantity, is_buy, reduce_only).await?;
client.place_market_order(symbol, quantity, is_buy, reduce_only, slippage_price).await?;
client.cancel_order(symbol, order_index).await?;

// Position operations
client.set_leverage(symbol, leverage, is_cross).await?;
client.close_position(symbol).await?;

LighterWebSocket

Real-time data streaming with automatic reconnection.

use tokio::sync::mpsc;

let ws = LighterWebSocket::mainnet();

// Public: Orderbook updates
let (tx, mut rx) = mpsc::unbounded_channel();
ws.subscribe_orderbook("HYPE".to_string(), market_id, tx).await?;

while let Some(update) = rx.recv().await {
    println!("{}: {} / {}", update.symbol, update.best_bid, update.best_ask);
}

// Private: Fill notifications (requires auth)
let (fill_tx, mut fill_rx) = mpsc::unbounded_channel();
ws.subscribe_fills(account_index, auth_token, market_symbols, fill_tx).await?;

while let Some(fill) = fill_rx.recv().await {
    println!("Filled: {} {} @ {}", fill.quantity, fill.symbol, fill.price);
}

Order Types

use lighter_sdk::OrderType;

OrderType::Limit         // 0 - Limit order
OrderType::Market        // 1 - Market order
OrderType::StopLoss      // 2 - Stop loss
OrderType::StopLossLimit // 3 - Stop loss limit
OrderType::TakeProfit    // 4 - Take profit
OrderType::TakeProfitLimit // 5 - Take profit limit
OrderType::TWAP          // 6 - Time-weighted average price

Time in Force

use lighter_sdk::TimeInForce;

TimeInForce::ImmediateOrCancel // 0 - IOC
TimeInForce::GoodTillTime      // 1 - GTT
TimeInForce::PostOnly          // 2 - Post only

Environment Variables

The examples use these environment variables:

Variable Description Required
LIGHTER_API_KEY_PRIVATE 40-byte hex private key Yes
LIGHTER_API_KEY_INDEX API key index (default: 0) No
LIGHTER_ACCOUNT_INDEX Account index Yes
LIGHTER_MAINNET "true" for mainnet, "false" for testnet No

Examples

Run the examples:

# Place orders - limit, market, close, cancel, set leverage, etc.
cargo run --example place_order -- --help
cargo run --example place_order -- limit buy HYPE 0.5 25.0
cargo run --example place_order -- market sell HYPE 0.5
cargo run --example place_order -- position
cargo run --example place_order -- account

# WebSocket orderbook streaming
cargo run --example websocket_orderbook

# Account fills/trades monitoring (requires authentication)
cargo run --example account_fills

# Basic usage - account info and market data
cargo run --example basic_usage

Architecture

lighter-sdk/
├── src/
│   ├── lib.rs          # Public API exports
│   ├── client.rs       # HTTP REST client
│   ├── signer.rs       # Transaction signing
│   ├── websocket.rs    # WebSocket streaming
│   ├── types.rs        # Data types
│   ├── nonce.rs        # Nonce management
│   └── crypto/         # Cryptographic primitives
│       ├── mod.rs
│       ├── goldilocks.rs   # Goldilocks field
│       ├── gfp5.rs         # Quintic extension
│       ├── poseidon2.rs    # Poseidon2 hash
│       ├── ecgfp5.rs       # Elliptic curve
│       └── schnorr.rs      # Schnorr signatures
└── examples/
    ├── basic_usage.rs
    ├── place_order.rs
    ├── websocket_orderbook.rs
    └── account_fills.rs

Cryptography

This SDK implements Lighter's transaction signing using:

  • Goldilocks Field - 64-bit prime field (p = 2^64 - 2^32 + 1)
  • GFp5 - Quintic extension field
  • ECgFp5 - Elliptic curve for digital signatures
  • Poseidon2 - Hash function for transaction hashing
  • Schnorr Signatures - Digital signature scheme

All cryptographic operations are implemented in pure Rust without external dependencies.

License

MIT OR Apache-2.0

About

A pure Rust SDK for [Lighter DEX](https://lighter.xyz) - a zk-powered perpetual futures exchange on lighter.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages