Rust SDK
Client Configuration
Rust SDK client initialization, TLS configuration, connection pooling, and retry strategies
Client Configuration
The Client struct is the main entry point for interacting with LX. It manages HTTP connections, WebSocket streams, and optional gRPC channels.
Basic Initialization
use lux_dex_sdk::{Client, Result};
#[tokio::main]
async fn main() -> Result<()> {
let client = Client::builder()
.json_rpc_url("http://localhost:8080/rpc")
.build()
.await?;
// Test connectivity
let info = client.get_info().await?;
println!("Connected to node: {}", info.version);
Ok(())
}Builder Pattern
The client uses a builder pattern for flexible configuration:
use lux_dex_sdk::{Client, ClientBuilder};
use std::time::Duration;
let client = Client::builder()
// Endpoints
.json_rpc_url("https://api.lux.network/rpc")
.websocket_url("wss://api.lux.network/ws")
.grpc_url("api.lux.network:50051")
// Authentication
.api_key("your-api-key")
.api_secret("your-api-secret")
// Timeouts
.connect_timeout(Duration::from_secs(10))
.request_timeout(Duration::from_secs(30))
// Connection pooling
.max_connections(100)
.idle_timeout(Duration::from_secs(90))
// Retry configuration
.max_retries(3)
.retry_backoff(Duration::from_millis(100))
.build()
.await?;TLS Configuration
Default TLS (rustls with native certs)
let client = Client::builder()
.json_rpc_url("https://api.lux.network/rpc")
.build()
.await?;Custom TLS Configuration
use lux_dex_sdk::{Client, TlsConfig};
use std::path::Path;
// Load custom CA certificate
let tls = TlsConfig::builder()
.ca_cert_path(Path::new("/path/to/ca.pem"))
.client_cert_path(Path::new("/path/to/client.pem"))
.client_key_path(Path::new("/path/to/client-key.pem"))
.build()?;
let client = Client::builder()
.json_rpc_url("https://api.lux.network/rpc")
.tls_config(tls)
.build()
.await?;TLS from PEM Strings
use lux_dex_sdk::TlsConfig;
let ca_cert = include_str!("../certs/ca.pem");
let client_cert = include_str!("../certs/client.pem");
let client_key = include_str!("../certs/client-key.pem");
let tls = TlsConfig::builder()
.ca_cert_pem(ca_cert)
.client_cert_pem(client_cert)
.client_key_pem(client_key)
.build()?;Disable TLS Verification (Development Only)
#[cfg(debug_assertions)]
let tls = TlsConfig::builder()
.danger_accept_invalid_certs(true)
.build()?;Connection Pooling
The client maintains a connection pool for HTTP requests:
use lux_dex_sdk::{Client, PoolConfig};
use std::time::Duration;
let pool = PoolConfig {
max_connections: 100, // Total connections
max_connections_per_host: 20, // Per-host limit
idle_timeout: Duration::from_secs(90),
max_idle_per_host: 10,
};
let client = Client::builder()
.pool_config(pool)
.build()
.await?;Connection Pool Metrics
let metrics = client.pool_metrics();
println!("Active connections: {}", metrics.active);
println!("Idle connections: {}", metrics.idle);
println!("Total requests: {}", metrics.total_requests);Retry Strategy
Configure automatic retry for transient failures:
use lux_dex_sdk::{Client, RetryConfig, RetryStrategy};
use std::time::Duration;
let retry = RetryConfig {
max_retries: 3,
strategy: RetryStrategy::ExponentialBackoff {
initial: Duration::from_millis(100),
max: Duration::from_secs(10),
multiplier: 2.0,
},
// Retry on these error types
retry_on: vec![
"connection_reset",
"timeout",
"rate_limit",
],
};
let client = Client::builder()
.retry_config(retry)
.build()
.await?;Custom Retry Logic
use lux_dex_sdk::{Client, Error};
impl Client {
pub async fn place_order_with_retry<F>(
&self,
order: Order,
should_retry: F,
) -> Result<OrderResponse>
where
F: Fn(&Error) -> bool,
{
let mut attempts = 0;
let max_attempts = 3;
loop {
match self.place_order(order.clone()).await {
Ok(response) => return Ok(response),
Err(e) if attempts < max_attempts && should_retry(&e) => {
attempts += 1;
let backoff = Duration::from_millis(100 * 2_u64.pow(attempts));
tokio::time::sleep(backoff).await;
}
Err(e) => return Err(e),
}
}
}
}Authentication
API Key Authentication
let client = Client::builder()
.api_key("your-api-key")
.api_secret("your-api-secret")
.build()
.await?;JWT Token
let client = Client::builder()
.jwt_token("eyJhbGciOiJIUzI1NiIs...")
.build()
.await?;Custom Authentication Header
use lux_dex_sdk::AuthProvider;
struct CustomAuth {
token: String,
}
impl AuthProvider for CustomAuth {
fn auth_header(&self) -> Option<(String, String)> {
Some(("X-Custom-Auth".to_string(), self.token.clone()))
}
}
let client = Client::builder()
.auth_provider(Box::new(CustomAuth { token: "secret".into() }))
.build()
.await?;Request Interceptors
Add custom logic to all requests:
use lux_dex_sdk::{Client, Interceptor, Request, Response};
use std::time::Instant;
struct TimingInterceptor;
impl Interceptor for TimingInterceptor {
async fn intercept(&self, req: Request, next: Next) -> Result<Response> {
let start = Instant::now();
let method = req.method().to_string();
let response = next.run(req).await?;
println!("{} completed in {:?}", method, start.elapsed());
Ok(response)
}
}
let client = Client::builder()
.interceptor(TimingInterceptor)
.build()
.await?;Multiple Environments
use lux_dex_sdk::{Client, Environment};
// Production
let prod = Client::builder()
.environment(Environment::Production)
.build()
.await?;
// Testnet
let testnet = Client::builder()
.environment(Environment::Testnet)
.build()
.await?;
// Custom endpoints
let custom = Client::builder()
.environment(Environment::Custom {
json_rpc: "http://localhost:8080/rpc".into(),
websocket: "ws://localhost:8081".into(),
grpc: "localhost:50051".into(),
})
.build()
.await?;Health Checks
use lux_dex_sdk::Client;
impl Client {
/// Check if the client can reach the server
pub async fn health_check(&self) -> Result<HealthStatus> {
let start = Instant::now();
let info = self.get_info().await?;
Ok(HealthStatus {
connected: true,
latency: start.elapsed(),
server_version: info.version,
block_height: info.block_height,
})
}
}
// Usage
let status = client.health_check().await?;
if status.latency > Duration::from_secs(1) {
eprintln!("Warning: high latency detected");
}Graceful Shutdown
use tokio::signal;
#[tokio::main]
async fn main() -> Result<()> {
let client = Client::builder().build().await?;
// Start background tasks
let ws_handle = tokio::spawn({
let client = client.clone();
async move {
client.stream_trades("BTC-USD").await
}
});
// Wait for shutdown signal
signal::ctrl_c().await?;
// Graceful shutdown
println!("Shutting down...");
client.shutdown().await?;
ws_handle.abort();
Ok(())
}Client Cloning
The client is cheaply cloneable (uses Arc internally):
let client = Client::builder().build().await?;
// Clone shares the same connection pool
let client2 = client.clone();
tokio::spawn(async move {
client2.place_order(order).await
});Debug Logging
Enable request/response logging:
use tracing_subscriber;
// Initialize tracing
tracing_subscriber::fmt()
.with_env_filter("lux_dex_sdk=debug")
.init();
let client = Client::builder()
.enable_request_logging(true)
.build()
.await?;Complete Example
use lux_dex_sdk::{Client, TlsConfig, RetryConfig, RetryStrategy};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
// Initialize logging
tracing_subscriber::fmt::init();
// TLS configuration
let tls = TlsConfig::builder()
.ca_cert_path("/etc/ssl/certs/ca.pem")
.build()?;
// Retry configuration
let retry = RetryConfig {
max_retries: 3,
strategy: RetryStrategy::ExponentialBackoff {
initial: Duration::from_millis(100),
max: Duration::from_secs(10),
multiplier: 2.0,
},
retry_on: vec!["timeout", "rate_limit"],
};
// Build client
let client = Client::builder()
.json_rpc_url("https://api.lux.network/rpc")
.websocket_url("wss://api.lux.network/ws")
.api_key(std::env::var("LUX_API_KEY")?)
.api_secret(std::env::var("LUX_API_SECRET")?)
.tls_config(tls)
.retry_config(retry)
.connect_timeout(Duration::from_secs(10))
.request_timeout(Duration::from_secs(30))
.max_connections(100)
.build()
.await?;
// Verify connection
let status = client.health_check().await?;
println!("Connected: latency={:?}", status.latency);
Ok(())
}