2 stable releases
new 1.1.0 | Jan 22, 2025 |
---|---|
1.0.0 | Jan 21, 2025 |
#344 in Magic Beans
172 downloads per month
105KB
2K
SLoC
Onise, Kraken Client for Rust
A comprehensive, typed, rate-limited, testable Rust client for:
- Kraken's Spot REST API (all public and private endpoints)
- Kraken's Spot WebSocket API v2 (market data, user data, and user trading)
This library provides:
- Strongly typed request/response models for Kraken's endpoints
- Advanced error handling that parses Kraken's known error codes
- Configurable rate limiting (token-bucket or others) to avoid hitting limits
- Integration tests (mocked and local) for both REST and WebSocket
- WebSocket support with a split read/write approach, typed subscription/unsubscription, user trading, etc.
Disclaimer
This is not an official Kraken product. Always consult the official docs and WebSocket v2 docs for the latest changes or usage policies.
Features
- Complete REST coverage: All documented endpoints (public & private)
- Spot WebSocket API v2 coverage: Market Data (Ticker, Book, Candles, Trades, Instruments), User Data (Executions, Balances), User Trading (Add/Amend/Edit/Cancel, etc.)
- Fully typed models: no placeholders or stubs for request/response fields
- Rate limiting: A token-bucket approach (via [governor] or similar) can be configured
- Integration tests: Local mocking for the WebSocket, real environment tests for REST (if you provide credentials)
Requirements
- Rust (edition 2021 or later)
- Cargo for dependency management
- An Internet connection (for real calls to Kraken)
- Kraken API Key & Secret if you need private endpoints (REST) or user trading/private data over WebSocket
- Optionally, a WebSocket token for private data/trading (obtained via
GetWebSocketsToken
from the REST API)
Installation
In your Cargo.toml
:
[dependencies]
onise = "0.1.0"
# or
# onise = { git = "https://github.com/yourorg/onise-rs.git", branch = "main" }
(Adjust the version or Git URL to match your repository or crates.io version.)
Then run:
cargo build
to download and compile.
Usage Modes (REST vs. WebSocket)
Our main.rs
supports two modes: REST and WebSocket, selected by a command-line argument:
cargo run -- rest
— Runs the REST client logiccargo run -- ws
— Runs the WebSocket client logic- Omit or use another argument to default to REST
Example: Running the REST client
cargo run -- rest
- Reads
KRAKEN_API_KEY
andKRAKEN_API_SECRET
from your environment if you want private endpoint calls - Calls
get_server_time()
, then callsget_balance()
Example: Running the WebSocket client
cargo run -- ws
- Reads
WS_URL
from environment (defaults towss://ws.kraken.com/v2
) - Optionally reads
KRAKEN_WS_TOKEN
for private data - Connects, sends a ping, subscribes to a Ticker channel, and loops indefinitely to process incoming messages
You can customize or extend this logic in main.rs
to handle more endpoints, advanced trading flows, or reconnection strategies.
REST Usage (API Details)
REST endpoints are in a KrakenClient
struct with methods for:
- Public:
get_server_time
,get_system_status
,get_asset_info
,get_ticker_information
, etc. - Private:
get_balance
,get_trade_balance
,get_open_orders
,add_order
, etc.
Example snippet (how the code might look if you ran it solely in REST mode):
use onise::KrakenClient;
use std::env;
#[tokio::main]
async fn main() {
let api_key = env::var("KRAKEN_API_KEY").ok();
let api_secret = env::var("KRAKEN_API_SECRET").ok();
// Create a rate-limited client
let client = KrakenClient::new(api_key, api_secret, None, 3, 2);
// Public call: get server time
match client.get_server_time().await {
Ok(time_resp) => println!("Server time: {:?}", time_resp),
Err(e) => eprintln!("Error: {}", e),
}
// Private call: get balance
match client.get_balance().await {
Ok(balance) => println!("Balance: {:?}", balance.balances),
Err(e) => eprintln!("Error fetching balance: {}", e),
}
}
WebSocket Usage (API Details)
Spot WebSocket API v2 is handled by a KrakenWsClient
:
- Connect with
KrakenWsClient::connect("wss://ws.kraken.com/v2").await?
- Send typed requests (e.g.,
ping
,authorize
,subscribe
,add_order
) - Automatically spawns a read loop to process messages like Ticker updates or ExecutionReports
Example (if you ran it in WebSocket mode):
use onise::ws_client::KrakenWsClient;
use onise::ws_models::WsSubscriptionPayload;
use std::env;
#[tokio::main]
async fn main() {
let url = env::var("WS_URL").unwrap_or("wss://ws.kraken.com/v2".to_string());
let token = env::var("KRAKEN_WS_TOKEN").ok();
let client = KrakenWsClient::connect(&url).await.expect("Failed to connect");
// Authorize if you have a token for private data/trading
if let Some(t) = token {
client.authorize(&t, Some(1)).await.expect("Auth failed");
}
// Send a ping
client.send_ping(Some(2)).await.expect("Ping failed");
// Subscribe to ticker updates for BTC/USD
client.subscribe(
WsSubscriptionPayload::Ticker { symbol: "XBT/USD".to_string() },
Some(3),
).await.expect("Subscribe failed");
println!("Connected to {url}, listening...");
loop {
// Just wait indefinitely to see inbound messages
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
}
}
Testing & Integration
REST Testing
- Unit tests: Each REST endpoint can have a unit test with mock responses (via [wiremock] or similar)
- Live integration: Provide real credentials:
export KRAKEN_API_KEY="..."
export KRAKEN_API_SECRET="..."
cargo test -- --nocapture
WebSocket Testing
-
Local Integration Test:
- A file like
tests/ws_integration_test.rs
can spin up a local WebSocket server usingtokio_tungstenite
- The
KrakenWsClient
connects tows://127.0.0.1:some_port
, sends a ping, you confirm on the server side
- A file like
-
Live:
- Set
WS_URL="wss://ws.kraken.com/v2"
, optionallyKRAKEN_WS_TOKEN
if you want private streams - Run
cargo test -- --nocapture
or a dedicated test verifying ping, subscribe, user trading, etc.
- Set
Production Considerations
- Secrets: Do not commit your API key/secret to version control. Use environment variables or a secure vault
- Rate-Limiting: Adjust token-bucket quotas for REST usage; handle
subscribe
/unsubscribe
carefully in WebSocket usage - Reconnection: For WebSocket, handle reconnection if the socket closes unexpectedly. The example does not show automatic reconnection logic
- Logging: Convert simple
eprintln!
calls into structured logs (e.g. with [tracing] or [log]/[env_logger]) if you need advanced debugging
Final Notes
By combining both REST and WebSocket modes in a single binary, you can select between them at runtime with:
# REST mode
cargo run -- rest
# WebSocket mode
cargo run -- ws
Either way, Onise offers a robust, typed interface to Kraken's Spot REST and Spot WebSocket API v2—no stubs, with typed requests and responses for all major endpoints. Enjoy building your Kraken-based applications in Rust!
Dependencies
~11–25MB
~384K SLoC