ndaxrs 0.1.0

Rust client library for the NDAX cryptocurrency exchange API
Documentation

ndaxrs

Unofficial Rust bindings for the NDAX exchange WebSocket API.

NDAX API Docs | Project NDAX notes | Examples

This library provides a Rust client for NDAX market data and trading over WebSockets, with a synchronous API surface that is easy to integrate into CLI apps, bots, and services.

  • Strongly typed requests and responses via serde
  • WebSocket transport via tokio-tungstenite
  • NDAX HMAC authentication support for private endpoints
  • Decimal-safe price/quantity handling via rust_decimal
  • Builder-based config for feeds, auth, depth, and gateway URL
  • Logging support via log
  • .env loading support via dotenvy

Both public and private APIs are supported. Current coverage focuses on the endpoints needed for market data, account balances, open orders, placing orders, and canceling orders.

If something you need is missing, patches are welcome.

Capabilities

ndaxrs currently includes:

  • Public market data subscriptions:
    • Level1 (ticker)
    • Level2 (order book)
    • Trades
  • Private/authenticated workflows:
    • Authenticate user
    • Subscribe account events
    • Get account positions
    • Get open orders
    • Send order
    • Cancel order

Threading

NdaxWsAPI is a blocking/synchronous interface that spawns an internal worker thread and drives an async WebSocket client behind the scenes.

Architecture:

User Code
    |
    v
NdaxWsAPI (sync)
    |
    v   mpsc channel
Worker Thread (tokio runtime)
    |
    v
NdaxWsClient (async)
    |
    v
NDAX WebSocket Gateway

This keeps application code simple for most use-cases while still using async I/O internally.

Quick Start

Add dependency:

[dependencies]
ndaxrs = "0.1.0" # or: { path = "../ndaxrs" }

Public market data

use ndaxrs::ws::{NdaxWsAPI, NdaxWsConfig};
use std::{thread, time::Duration};

fn main() -> ndaxrs::Result<()> {
    let instrument_id = 1; // BTC/CAD on NDAX

    let config = NdaxWsConfig::builder()
        .subscribe_level1(vec![instrument_id])
        .subscribe_level2(vec![instrument_id])
        .subscribe_trades(vec![instrument_id])
        .book_depth(20)
        .build();

    let api = NdaxWsAPI::new(config)?;
    thread::sleep(Duration::from_secs(2));

    if let Some(level1) = api.get_level1(instrument_id) {
        println!(
            "last={} bid={} ask={} vol={}",
            level1.last_price, level1.best_bid, level1.best_ask, level1.volume
        );
    }

    if let Some(book) = api.get_book(instrument_id) {
        println!("best bid: {:?}", book.best_bid());
        println!("best ask: {:?}", book.best_ask());
    }

    if let Some(trades) = api.get_trades(instrument_id) {
        println!("recent trades: {}", trades.len());
    }

    api.close();
    Ok(())
}

Authenticated trading

use ndaxrs::messages::orders::create_limit_order;
use ndaxrs::ws::{NdaxWsAPI, NdaxWsConfig, PrivateConfig};
use ndaxrs::{NdaxCredentials, Side};
use rust_decimal::Decimal;
use std::str::FromStr;

fn main() -> ndaxrs::Result<()> {
    let creds = NdaxCredentials::from_env()?;
    let account_id: u64 = std::env::var("NDAX_ACCOUNT_ID")
        .expect("NDAX_ACCOUNT_ID must be set")
        .parse()
        .expect("NDAX_ACCOUNT_ID must be a u64");

    let config = NdaxWsConfig::builder()
        .credentials(creds)
        .private(PrivateConfig::new(account_id).with_account_events())
        .build();

    let api = NdaxWsAPI::new(config)?;
    assert!(api.is_authenticated(), "authentication failed");

    let order = create_limit_order(
        1, // instrument_id
        account_id,
        Side::Buy,
        Decimal::from_str("0.0001").unwrap(),
        Decimal::from_str("1.00").unwrap(), // intentionally far from market
    );

    let resp = api.send_order(&order)?;
    println!("order response: status={}, order_id={:?}", resp.status, resp.order_id);

    api.close();
    Ok(())
}

Environment Variables

For authenticated APIs, NdaxCredentials::from_env() reads:

  • NDAX_API_KEY
  • NDAX_API_SECRET
  • NDAX_USER_ID

For private account operations and the trading example:

  • NDAX_ACCOUNT_ID

Examples

Library examples:

  • cargo run --example public_data
  • cargo run --example trading

The trading example performs real authenticated operations and submits a test order. Use a funded account with caution.

TUI example app:

cd examples/ndax-tui
cp .env.example .env
cargo run

ndax-tui shows:

  • Live Level2 order book
  • Price chart driven by Level1 updates
  • Latest market trades
  • Latest user trades (when authenticated)

Disclaimer

Use at your own risk. If you build trading software with this library and incur losses due to bugs, connectivity issues, or exchange behavior, you are responsible for validating and monitoring your system.

Reference