# AsterDex Futures SDK (Rust)
[](https://www.rust-lang.org)
[](LICENSE)
Async Rust SDK for the AsterDex Futures API v3. Covers REST and WebSocket APIs with EIP-712 signing.
## Features
- Full REST API coverage (trading, market data, account, listen key, MMP, asset)
- WebSocket market data streams (13 event types with typed deserialization)
- WebSocket user data stream (order updates, account updates, config updates)
- EIP-712 Ethereum signing via [alloy-rs](https://alloy.rs)
- Typed errors with rate-limit header exposure
- Raw JSON passthrough for untyped access
## Installation
Add to `Cargo.toml`:
```toml
[dependencies]
asterdex-sdk = "0.1.2"
```
## Quick Start
### REST — Authenticate and place an order
```rust,no_run
use asterdex_sdk::{FuturesClient, PlaceOrderParams};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load credentials from environment variables:
// ASTERDEX_USER, ASTERDEX_SIGNER_ADDRESS, ASTERDEX_SIGNER_PRIVATE_KEY, ASTERDEX_BASE_URL
let client = FuturesClient::from_env()?;
let order = client.place_order(PlaceOrderParams {
symbol: "BTCUSDT".to_string(),
side: "BUY".to_string(),
order_type: "LIMIT".to_string(),
quantity: "0.001".to_string(),
price: Some("30000.0".to_string()),
time_in_force: Some("GTC".to_string()),
..Default::default()
}).await?;
println!("Order placed: id={}", order.data.order_id);
Ok(())
}
```
### WebSocket — Subscribe to market streams
```rust,no_run
use asterdex_sdk::{WebSocketClient, WebSocketMessage};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ws = WebSocketClient::new("wss://fstream.asterdex-testnet.com")?;
let mut stream = ws.subscribe(vec!["btcusdt@aggTrade", "btcusdt@markPrice"]).await?;
while let Some(event) = stream.recv().await {
match event? {
WebSocketMessage::AggTrade(e) => println!("Trade: {} @ {}", e.symbol, e.price),
WebSocketMessage::MarkPrice(e) => println!("Mark: {} = {}", e.symbol, e.mark_price),
_ => {}
}
}
Ok(())
}
```
### WebSocket — User data stream
```rust,no_run
use asterdex_sdk::{FuturesClient, WebSocketClient, UserDataEvent};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let rest = FuturesClient::from_env()?;
let listen_key = rest.create_listen_key().await?.data.listen_key;
let ws = WebSocketClient::new("wss://fstream.asterdex-testnet.com")?;
let mut stream = ws.subscribe_user_data(&listen_key).await?;
while let Some(event) = stream.next_event().await {
match event? {
UserDataEvent::OrderUpdate(e) => {
println!("Order update: {} {}", e.order.symbol, e.order.order_status)
}
_ => {}
}
}
Ok(())
}
```
## Environment Variables
| `ASTERDEX_USER` | 0x-prefixed Ethereum address (trader account) |
| `ASTERDEX_SIGNER_ADDRESS` | 0x-prefixed Ethereum address (signing wallet) |
| `ASTERDEX_SIGNER_PRIVATE_KEY` | 64-char hex private key (no 0x prefix) |
| `ASTERDEX_BASE_URL` | REST base URL (e.g. `https://fapi.asterdex-testnet.com`) |
| `ASTERDEX_WS_BASE_URL` | WebSocket base URL (e.g. `wss://fstream.asterdex-testnet.com`) |
| `ASTERDEX_CHAIN_ID` | EIP-712 domain chainId (testnet: 714) |
Copy `.env.example` to `.env` and fill in your values. Never commit `.env`.
## Architecture
Single-crate Rust library. Key modules:
| `auth/` | EIP-712 signing engine, credentials management |
| `rest/` | HTTP client (`RestClient`), response parsing, typed errors |
| `ws/` | WebSocket client, reconnect engine, ping/pong |
| `futures/models/` | All futures request/response types (prices as `String`) |
| `futures/endpoints/` | `impl RestClient` blocks per API group |
| `spot/` | Spot trading domain — placeholder (not yet implemented) |
`FuturesClient` is a type alias for `RestClient`. All futures endpoint methods live under `src/futures/endpoints/` and are automatically available on `FuturesClient`.
See [ARCHITECTURE.md](ARCHITECTURE.md) for full design decisions and ADRs.
## Error Handling
All methods return `Result<ApiResponse<T>, AsterDexError>`. Key error variants:
```rust
pub enum AsterDexError {
ApiError { code: i64, msg: String }, // API-level error
RateLimited { retry_after: Option<Duration> }, // HTTP 429
IpBanned { retry_after: Option<Duration> }, // HTTP 418
WebSocketError { message: String },
ConfigError { message: String },
SerdeError { message: String },
}
```
## Integration Guide
For the complete API reference — all endpoints with request/response structs, usage examples, WebSocket stream types, and error handling patterns — see **[docs/integration_guide.md](docs/integration_guide.md)**.
Topics covered:
- Market data (order book, klines, mark price, funding rate, tickers)
- Trading (place, modify, cancel, query orders; positions; batch orders)
- Account (balance, leverage, margin type, position mode, ADL quantile)
- Listen key lifecycle and user data WebSocket stream
- MMP (Market Maker Protection) endpoints
- Asset / sub-account wallet transfer
- Raw JSON passthrough (`raw_get`, `raw_signed_post`, etc.)
- Full `WebSocketMessage` and `UserDataEvent` type reference
---
## Key Flows by Milestone
| M1 | Authenticate and execute trades via REST | `FuturesClient::from_env()`, `place_order`, `cancel_order`, `get_open_orders`, `get_position_risk`, EIP-712 signing |
| M2 | All market data and key account endpoints via REST | `ping`, `get_exchange_info`, `get_depth`, `get_klines`, `get_balance`, `set_leverage`, `place_batch_orders`, rate limit headers |
| M3 | Real-time market data via WebSocket | `WebSocketClient::new`, `subscribe`, typed stream, auto-reconnect within 3s, transparent ping/pong |
| M4 | Real-time account/order updates via user data stream | `create_listen_key`, `subscribe_user_data`, `OrderUpdate` events, `renew_listen_key` |
| M5 | Full REST coverage and complete polish | `get_all_orders`, `get_user_trades`, `update_mmp`, `raw_get` passthrough, clippy 0 warnings |
## Testing
```bash
# Unit tests (no network required)
cargo test --lib
# Integration tests (requires testnet credentials in environment)
cargo test --test integration -- --ignored
```