This is the official Rust SDK for the Derive Protocol. It is designed to interact with the Derive Protocol's smart contracts and provides a set of tools and utilities for developers to interact with the protocol in a Rust environment.
We expose Websocket as the transport layer. The SDK is designed to be easy to use and integrate into existing Rust projects.
**High-performance, type-safe Rust client for interacting with Derive Protocol's perpetual futures and options platform**
## Examples
[Getting Started](#-getting-started) •
[Documentation](https://docs.rs/derive-rs) •
[Examples](#-examples) •
[Features](#-features) •
[Contributing](#-contributing)
## Features & Roadmap
</div>
---- [x] Support rfq
- [x] Support position movements
## ✨ Overview- [] Test reconnection flow
`derive-rs` is a comprehensive Rust SDK for [Derive Protocol](https://derive.xyz), providing seamless access to decentralized derivatives trading. Built with modern async Rust, it offers a robust, production-ready solution for algorithmic trading, market making, and DeFi integrations.
### Why derive-rs?
- 🚀 **Blazingly Fast** - Built on Tokio with async/await for maximum concurrency
- 🔒 **Type-Safe** - Compile-time guarantees with comprehensive type definitions
- 🔌 **WebSocket & REST** - Real-time market data and reliable REST endpoints
- 📦 **Zero Config** - Works out of the box with sensible defaults
- 🧪 **Battle-Tested** - Extensive test coverage and production-ready
- 🛠️ **Developer Friendly** - Intuitive API design with builder patterns
---
## 🚀 Getting Started
### Installation
Add `derive-rs` to your `Cargo.toml`:
```toml
[dependencies]
derive-rs = "0.1.5"
tokio = { version = "1.53", features = ["full"] }
Or use cargo:
cargo add derive-rs// examples/get_all_instruments.rs
use derive_rs::{
Environment, WsClient,
models::{AssetType, GetAllInstrumentsRequest},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = WsClient::new_public(Environment::Testnet).await?;
let params = GetAllInstrumentsRequest::builder()
.expired(false)
.instrument_type(AssetType::Option)
.try_into()?;
let instruments = client
.rpc()
.market_data()
.get_all_instruments(params)
.await?;
println!("Available instruments: {:#?}", instruments);
Ok(())
}use derive_rs::{WsClient, Environment};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize client with credentials
let client = WsClient::new(
Environment::Testnet,
Some("YOUR_PRIVATE_KEY".to_string()),
Some("YOUR_WALLET_ADDRESS".to_string()),
Some(1234), // subaccount_id
).await?;
// Login to the WebSocket
client.login().await?;
// Place your first order
use derive_rs::actions::OrderArgs;
use derive_rs::models::{Direction, OrderType, TimeInForce};
use bigdecimal::BigDecimal;
let order = OrderArgs::builder()
.instrument_name("ETH-PERP")
.amount(BigDecimal::from(1))
.limit_price(BigDecimal::from(3000))
.direction(Direction::Buy)
.order_type(OrderType::Limit)
.time_in_force(TimeInForce::GTC)
.build();
let result = client.orders().place(order).await?;
println!("Order placed: {:#?}", result);
Ok(())
}
use derive_rs::{WsClient, Environment, types::ExternalEvent};
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = WsClient::new_public(Environment::Testnet).await?;
// Subscribe to ticker updates
let mut ticker_stream = client.subscriptions()
.market_data()
.ticker_slim("ETH-USDC", "100")
.await?;
// Process tickers in real-time
loop {
tokio::select! {
Some(ticker) = ticker_stream.next() => {
match ticker {
Ok(data) => println!("ETH Price: {:?}", data),
Err(e) => eprintln!("Error: {:?}", e),
}
}
event = client.run_till_event() => {
match event {
ExternalEvent::Connected => {
println!("WebSocket connected");
client.resubscribe_all().await?;
}
ExternalEvent::Disconnected => println!("Disconnected"),
ExternalEvent::Exited => break,
}
}
}
}
Ok(())
}
The repository includes comprehensive examples demonstrating various features:
| Example | Description |
|---|---|
get_all_currencies |
Fetch all supported currencies and ERC-20 details |
ws_stream_tickers |
Real-time ticker streaming for multiple instruments |
ws_rfq_subscriber |
Subscribe to Request for Quote (RFQ) updates |
order_lifecycle |
Complete order management: create, replace, cancel |
rfq |
Request for Quote workflow for large trades |
Run any example with:
cargo run --example ws_stream_tickers-
✅ WebSocket API
- Real-time market data streaming
- Private account updates
- Automatic reconnection with state recovery
- Heartbeat/ping-pong handling
-
✅ Order Management
- Place, replace, and cancel orders
- Support for all order types (limit, market, stop-loss)
- Time-in-force options (GTC, IOC, FOK)
- Post-only and reduce-only orders
-
✅ Request for Quote (RFQ)
- Multi-leg RFQ creation
- Quote execution
- Position transfers between subaccounts
-
✅ Market Data
- Instrument details and specifications
- Order book snapshots and updates
- Trade history
- Ticker data (full and slim)
-
✅ Account Management
- Subaccount operations
- Session key authentication
- Position tracking
- Balance queries
-
✅ Risk Management
- Market maker protection
- Cancel on disconnect
- Portfolio margining
-
✅ Fund Movements
- Deposits and withdrawals
- Spot transfers
- Position transfers
All trading actions are EIP-712 compliant with cryptographic signing:
use derive_rs::actions::{OrderArgs, ReplaceArgs, ExecuteQuoteArgs};
Organized API surface for intuitive usage:
// Orders
client.orders().place(order_args).await?;
client.orders().replace(replace_args).await?;
// RFQs
client.rfqs().send_rfq(rfq_request).await?;
client.rfqs().execute_best_quote(quote_args).await?;
// Fund Movements
client.fund_movements().deposit(deposit_args).await?;
client.fund_movements().withdraw(withdraw_args).await?;
// Session Keys
client.session_keys().add(session_key_args).await?;
┌─────────────────────────────────────────────────────────────┐
│ Your Application │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────┴──────────────────────────────────┐
│ derive-rs SDK │
├──────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Actions │ │ RPC │ │ Subscriptions │ │
│ │ (Signing) │ │ (Request) │ │ (Streaming) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┤
│ │ WebSocket Client (yawc) │
│ └──────────────────────────────────────────────────────────┤
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────┴──────────────────────────────────┐
│ Derive Protocol API │
│ wss://testnet.api.derive.xyz/v3/ws │
└──────────────────────────────────────────────────────────────┘
Run the test suite:
# All tests
cargo test
# Specific test
cargo test order_lifecycle
# With logging
RUST_LOG=debug cargo testMarket Data
get_all_instruments- List all available instrumentsget_instrument- Get specific instrument detailsget_all_currencies- List supported currenciesget_ticker- Get current ticker dataget_orderbook- Fetch order book snapshotget_trade_history- Query historical trades
Trading
order- Place new orderreplace_order- Replace existing ordercancel_order- Cancel ordercancel_all_orders- Cancel all ordersget_order- Get order detailsget_open_orders- List open orders
RFQ
send_rfq- Create RFQpoll_rfqs- Poll for RFQssend_quote- Submit quoteexecute_best_quote- Execute quotecancel_batch_rfqs- Cancel multiple RFQs
Account
get_subaccount- Get subaccount detailsget_subaccounts- List all subaccountsget_positions- Get open positionsget_collateral- Get collateral balancesset_cancel_on_disconnect- Configure cancel on disconnect
Public Channels
ticker/ticker_slim- Real-time price updatesorderbook- Order book updatestrades- Trade feedinstrument- Instrument updates
Private Channels
orders- Order updatespositions- Position updatesaccount_summary- Account balance updatestrades- User trade executionsrfqs- RFQ notifications
Load configuration from environment:
// examples/env_login.rs
use derive_rs::WsClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Reads DERIVE_PRIVATE_KEY, DERIVE_WALLET, DERIVE_SUBACCOUNT_ID, DERIVE_ENVIRONMENT from the environment
let client = WsClient::from_env().await?;
client.login().await?;
Ok(())
}| Environment | WebSocket URL | Network |
|---|---|---|
| Testnet | wss://testnet.api.derive.xyz/v3/ws |
Sepolia |
| Mainnet | wss://api.lyra.finance/ws |
Ethereum |
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
# Clone the repository
git clone https://github.com/derivexyz/derive-rs.git
cd derive-rs
# Build the project
make build
# Run tests
make test
# Check formatting
make fmt
# Run linter
make lintThis project is licensed under the MIT License - see the LICENSE file for details.
- Website: https://derive.xyz
- Documentation: https://docs.derive.xyz
- API Docs: https://docs.rs/derive-rs
- Discord: Join our community
- Twitter: @derivexyz
This software is provided "as is" without warranty of any kind. Trading derivatives involves substantial risk of loss. Use at your own risk.
Built with ❤️ by the Derive team and contributors.
Special thanks to:
Made with 🦀 and ☕