Official Rust SDK for the Derive Protocol
A type-safe, async Rust client for trading, market data, account management, RFQs, and protocol interactions over WebSocket.
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(())
}// examples/simple_order.rs
use bigdecimal::BigDecimal;
use derive_rs::{
WsClient,
actions::OrderArgs,
models::{CancelOrderRequest, Direction, OrderType, TimeInForce},
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing::subscriber::set_global_default(
tracing_subscriber::FmtSubscriber::builder()
.with_max_level(tracing::Level::INFO)
.finish(),
)?;
let client = WsClient::from_env().await?;
client.login().await?;
let order = OrderArgs::builder()
.instrument_name("HYPE-PERP".to_string())
.amount(BigDecimal::from(1))
.limit_price(BigDecimal::from(50))
.direction(Direction::Buy)
.order_type(OrderType::Limit)
.time_in_force(TimeInForce::Gtc)
.build();
let result = client.orders().place(order).await?;
println!("Order placed successfully.");
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
let cancel_params = CancelOrderRequest::builder()
.order_id(result.order.order_id)
.instrument_name("HYPE-PERP".to_string())
.subaccount_id(client.subaccount_id.unwrap())
.try_into()?;
let cancel_result = client.orders().cancel_order(cancel_params).await;
match cancel_result {
Ok(_) => {
println!("Order cancelled!");
}
Err(_err) => {
println!("Order cancellation failed.");
}
}
Ok(())
}// examples/ws_stream_ticker.rs
mod common;
use derive_rs::{models::TickerSlimNotification, types::ExternalEvent};
use tokio_stream::{StreamExt, wrappers::BroadcastStream};
use crate::common::get_test_ws_client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ws_client = get_test_ws_client().await;
let mut eth_ticker_stream: BroadcastStream<TickerSlimNotification> = ws_client
.subscriptions()
.market_data()
.ticker_slim("ETH-USDC", "100")
.await?;
loop {
tokio::select! {
Some(eth_ticker) = eth_ticker_stream.next() => {
match eth_ticker {
Ok(ticker) => println!("ETH Ticker: {:?}", ticker),
Err(e) => {
eprintln!("Error receiving ETH ticker: {:?}", e);
break; // Exit the loop on error
}
}
}
event = ws_client.run_till_event() => {
match event {
ExternalEvent::Connected => {
let _ = ws_client.login().await;
let _ = ws_client.resubscribe_all().await;
println!("WebSocket connected and resubscribed to all channels.");
}
ExternalEvent::Disconnected => {
println!("WebSocket disconnected");
}
ExternalEvent::Exited => {
println!("WebSocket exited");
break;
}
}
}
}
}
Ok(())
}The SDK groups functionality by signing domain rather than exposing a single flat client API.
// 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?;Signable actions use typed argument structures and EIP-712 signing.
use derive_rs::actions::{ExecuteQuoteArgs, OrderArgs, ReplaceArgs};The SDK provides typed RPC requests for market data, account management, and other protocol interactions. Every RPC request is strongly typed and returns a typed response.
The RPC client is accessible via client.rpc() and is grouped by namespace.
| Area | Supported functionality |
|---|---|
| Market data | Instruments, order books, trades, tickers |
| Streaming | Public and private WebSocket subscriptions |
| Orders | Place, replace, cancel, post-only and reduce-only orders |
| RFQ | Create RFQs, submit quotes, execute quotes |
| Accounts | Subaccounts, positions, collateral and balances |
| Authentication | Wallet authentication and session keys |
| Risk controls | Cancel-on-disconnect and market-maker protection |
| Fund movements | Deposits, withdrawals and transfers |
The client also handles WebSocket heartbeats, reconnection, and subscription recovery.
The repository contains runnable examples and integration tests covering common workflows.
| Example | Description |
|---|---|
get_all_currencies |
Fetch supported currencies and ERC-20 details |
ws_stream_tickers |
Stream ticker updates for multiple instruments |
ws_rfq_subscriber |
Subscribe to RFQ updates |
order_lifecycle |
Create, replace, and cancel orders |
rfq |
End-to-end RFQ workflow |
Run an example with:
cargo run --example ws_stream_tickersMarket data RPC
get_all_instrumentsget_instrumentget_all_currenciesget_tickerget_orderbookget_trade_history
Trading RPC
orderreplace_ordercancel_ordercancel_all_ordersget_orderget_open_orders
RFQ RPC
send_rfqpoll_rfqssend_quoteexecute_best_quotecancel_batch_rfqs
Account RPC
get_subaccountget_subaccountsget_positionsget_collateralset_cancel_on_disconnect
Public subscriptions
tickerticker_slimorderbooktradesinstrument
Private subscriptions
orderspositionsaccount_summarytradesrfqs
WsClient::from_env() reads client configuration from environment variables.
// examples/env_login.rs
use derive_rs::WsClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = WsClient::from_env().await?;
client.login().await?;
Ok(())
}The current client expects:
DERIVE_PRIVATE_KEY
DERIVE_WALLET
DERIVE_SUBACCOUNT_ID
DERIVE_ENVIRONMENT
| Environment | WebSocket URL | Network |
|---|---|---|
| Testnet | wss://testnet.api.derive.xyz/v3/ws |
Sepolia |
| Mainnet | wss://api.lyra.finance/ws |
Ethereum |
Your application
│
▼
┌───────────────────────────────────────┐
│ derive-rs │
│ │
│ Actions RPC Subscriptions │
│ (signing) (request) (streaming) │
│ │
│ WebSocket client │
└──────────────────┬────────────────────┘
│
▼
Derive Protocol API
cargo testRun a specific test:
cargo test order_lifecycleEnable debug logging:
RUST_LOG=debug cargo testgit clone https://github.com/derivexyz/derive-rs.git
cd derive-rs
make build
make test
make fmt
make lintAny issues and feature requests can be submitted via GitHub issues. Pull requests are welcome!
- Fork the repository.
- Create a feature branch.
- Make and test your changes.
- Push the branch.
- Open a pull request into
devbranch. - The PR will be reviewed and merged by the maintainers.
Licensed under the MIT License. See LICENSE.
This software is provided as-is, without warranty. Trading derivatives involves substantial risk of loss.