- Introduced `ibc_example.rs` demonstrating Inter-Blockchain Communication operations including cross-chain transfers, channel management, packet handling, and relayer operations. - Introduced `zk_example.rs` showcasing Zero-Knowledge proof operations such as circuit compilation, proof generation and verification, and on-chain verification with multiple proving systems.
387 lines
13 KiB
Rust
387 lines
13 KiB
Rust
//! Synor DEX SDK Examples for Rust
|
|
//!
|
|
//! Demonstrates decentralized exchange operations:
|
|
//! - Spot trading (limit/market orders)
|
|
//! - Perpetual futures trading
|
|
//! - Liquidity provision (AMM pools)
|
|
//! - Order book management
|
|
//! - Portfolio tracking
|
|
|
|
use std::env;
|
|
use synor_dex::{
|
|
AddLiquidityRequest, DexConfig, OrderRequest, OrderSide, OrderType, PerpsOrderRequest,
|
|
RemoveLiquidityRequest, SynorDex, TimeInForce,
|
|
};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Initialize client
|
|
let config = DexConfig {
|
|
api_key: env::var("SYNOR_API_KEY").unwrap_or_else(|_| "your-api-key".to_string()),
|
|
endpoint: "https://dex.synor.io/v1".to_string(),
|
|
timeout: 30000,
|
|
retries: 3,
|
|
debug: false,
|
|
default_market: "SYN-USDC".to_string(),
|
|
};
|
|
|
|
let dex = SynorDex::new(config)?;
|
|
|
|
// Check service health
|
|
let healthy = dex.health_check().await?;
|
|
println!("Service healthy: {}\n", healthy);
|
|
|
|
// Run examples
|
|
markets_example(&dex).await?;
|
|
spot_trading_example(&dex).await?;
|
|
perps_trading_example(&dex).await?;
|
|
liquidity_example(&dex).await?;
|
|
orderbook_example(&dex).await?;
|
|
portfolio_example(&dex).await?;
|
|
|
|
dex.close().await?;
|
|
Ok(())
|
|
}
|
|
|
|
async fn markets_example(dex: &SynorDex) -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("=== Markets ===");
|
|
|
|
// Get all markets
|
|
let markets = dex.markets.list().await?;
|
|
println!("Available markets: {}", markets.len());
|
|
|
|
for market in markets.iter().take(5) {
|
|
println!("\n {}:", market.symbol);
|
|
println!(" Base: {}, Quote: {}", market.base_asset, market.quote_asset);
|
|
println!(" Price: {}", market.last_price);
|
|
println!(" 24h Volume: {}", market.volume_24h);
|
|
println!(" 24h Change: {}%", market.change_24h);
|
|
println!(" Status: {}", market.status);
|
|
}
|
|
|
|
// Get specific market
|
|
let market = dex.markets.get("SYN-USDC").await?;
|
|
println!("\nSYN-USDC details:");
|
|
println!(" Min order size: {}", market.min_order_size);
|
|
println!(" Tick size: {}", market.tick_size);
|
|
println!(" Maker fee: {}%", market.maker_fee);
|
|
println!(" Taker fee: {}%", market.taker_fee);
|
|
|
|
// Get market statistics
|
|
let stats = dex.markets.get_stats("SYN-USDC").await?;
|
|
println!("\nMarket statistics:");
|
|
println!(" High 24h: {}", stats.high_24h);
|
|
println!(" Low 24h: {}", stats.low_24h);
|
|
println!(" Open interest: {}", stats.open_interest);
|
|
println!(" Funding rate: {}%", stats.funding_rate);
|
|
|
|
println!();
|
|
Ok(())
|
|
}
|
|
|
|
async fn spot_trading_example(dex: &SynorDex) -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("=== Spot Trading ===");
|
|
|
|
// Place a limit order
|
|
println!("Placing limit buy order...");
|
|
let limit_order = dex
|
|
.spot
|
|
.place_order(OrderRequest {
|
|
market: "SYN-USDC".to_string(),
|
|
side: OrderSide::Buy,
|
|
order_type: OrderType::Limit,
|
|
price: Some("1.50".to_string()),
|
|
quantity: "100".to_string(),
|
|
time_in_force: Some(TimeInForce::GTC),
|
|
})
|
|
.await?;
|
|
|
|
println!("Limit order placed:");
|
|
println!(" Order ID: {}", limit_order.order_id);
|
|
println!(" Status: {}", limit_order.status);
|
|
println!(" Price: {}", limit_order.price.unwrap_or_default());
|
|
println!(" Quantity: {}", limit_order.quantity);
|
|
|
|
// Place a market order
|
|
println!("\nPlacing market sell order...");
|
|
let market_order = dex
|
|
.spot
|
|
.place_order(OrderRequest {
|
|
market: "SYN-USDC".to_string(),
|
|
side: OrderSide::Sell,
|
|
order_type: OrderType::Market,
|
|
price: None,
|
|
quantity: "50".to_string(),
|
|
time_in_force: None,
|
|
})
|
|
.await?;
|
|
|
|
println!("Market order executed:");
|
|
println!(" Order ID: {}", market_order.order_id);
|
|
println!(" Status: {}", market_order.status);
|
|
println!(" Filled: {}", market_order.filled_quantity);
|
|
println!(" Avg price: {}", market_order.average_price.unwrap_or_default());
|
|
|
|
// Get order status
|
|
let status = dex.spot.get_order(&limit_order.order_id).await?;
|
|
println!("\nOrder status:");
|
|
println!(" Status: {}", status.status);
|
|
println!(" Filled: {} / {}", status.filled_quantity, status.quantity);
|
|
println!(" Remaining: {}", status.remaining_quantity);
|
|
|
|
// Cancel order
|
|
println!("\nCancelling order...");
|
|
dex.spot.cancel_order(&limit_order.order_id).await?;
|
|
println!("Order cancelled successfully");
|
|
|
|
// Get open orders
|
|
let open_orders = dex.spot.get_open_orders("SYN-USDC").await?;
|
|
println!("\nOpen orders: {}", open_orders.len());
|
|
|
|
// Get trade history
|
|
let trades = dex.spot.get_trade_history("SYN-USDC", 10).await?;
|
|
println!("\nRecent trades: {}", trades.len());
|
|
for trade in trades.iter().take(3) {
|
|
println!(" {:?} {} @ {} ({})", trade.side, trade.quantity, trade.price, trade.timestamp);
|
|
}
|
|
|
|
println!();
|
|
Ok(())
|
|
}
|
|
|
|
async fn perps_trading_example(dex: &SynorDex) -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("=== Perpetual Futures Trading ===");
|
|
|
|
// Get available perps markets
|
|
let perps_markets = dex.perps.list_markets().await?;
|
|
println!("Available perps markets: {}", perps_markets.len());
|
|
|
|
for market in perps_markets.iter().take(3) {
|
|
println!(
|
|
" {}: {} (funding: {}%)",
|
|
market.symbol, market.mark_price, market.funding_rate
|
|
);
|
|
}
|
|
|
|
// Open a long position
|
|
println!("\nOpening long position...");
|
|
let position = dex
|
|
.perps
|
|
.open_position(PerpsOrderRequest {
|
|
market: "SYN-USDC-PERP".to_string(),
|
|
side: OrderSide::Buy,
|
|
order_type: OrderType::Limit,
|
|
price: Some("1.50".to_string()),
|
|
size: "1000".to_string(),
|
|
leverage: 10,
|
|
reduce_only: false,
|
|
})
|
|
.await?;
|
|
|
|
println!("Position opened:");
|
|
println!(" Position ID: {}", position.position_id);
|
|
println!(" Size: {}", position.size);
|
|
println!(" Entry price: {}", position.entry_price);
|
|
println!(" Leverage: {}x", position.leverage);
|
|
println!(" Liquidation price: {}", position.liquidation_price);
|
|
|
|
// Get position details
|
|
let details = dex.perps.get_position(&position.position_id).await?;
|
|
println!("\nPosition details:");
|
|
println!(" Unrealized PnL: {}", details.unrealized_pnl);
|
|
println!(" Margin: {}", details.margin);
|
|
println!(" Margin ratio: {}%", details.margin_ratio);
|
|
|
|
// Set stop loss and take profit
|
|
println!("\nSetting stop loss and take profit...");
|
|
dex.perps
|
|
.set_stop_loss(&position.position_id, "1.40")
|
|
.await?;
|
|
println!("Stop loss set at 1.40");
|
|
|
|
dex.perps
|
|
.set_take_profit(&position.position_id, "1.80")
|
|
.await?;
|
|
println!("Take profit set at 1.80");
|
|
|
|
// Close position
|
|
println!("\nClosing position...");
|
|
let close_result = dex.perps.close_position(&position.position_id).await?;
|
|
println!("Position closed:");
|
|
println!(" Realized PnL: {}", close_result.realized_pnl);
|
|
println!(" Close price: {}", close_result.close_price);
|
|
|
|
// Get all positions
|
|
let positions = dex.perps.get_positions().await?;
|
|
println!("\nOpen positions: {}", positions.len());
|
|
|
|
// Get funding history
|
|
let funding = dex.perps.get_funding_history("SYN-USDC-PERP", 10).await?;
|
|
println!("Funding payments: {}", funding.len());
|
|
|
|
println!();
|
|
Ok(())
|
|
}
|
|
|
|
async fn liquidity_example(dex: &SynorDex) -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("=== Liquidity Provision ===");
|
|
|
|
// Get available pools
|
|
let pools = dex.liquidity.list_pools().await?;
|
|
println!("Available pools: {}", pools.len());
|
|
|
|
for pool in pools.iter().take(3) {
|
|
println!("\n {}:", pool.name);
|
|
println!(" TVL: ${}", pool.tvl);
|
|
println!(" APR: {}%", pool.apr);
|
|
println!(" Volume 24h: ${}", pool.volume_24h);
|
|
println!(" Fee tier: {}%", pool.fee_tier);
|
|
}
|
|
|
|
// Get pool details
|
|
let pool = dex.liquidity.get_pool("SYN-USDC").await?;
|
|
println!("\nSYN-USDC pool details:");
|
|
println!(" Token0: {} ({})", pool.token0.symbol, pool.token0_reserve);
|
|
println!(" Token1: {} ({})", pool.token1.symbol, pool.token1_reserve);
|
|
println!(" Price: {}", pool.price);
|
|
println!(" Total LP tokens: {}", pool.total_lp_tokens);
|
|
|
|
// Add liquidity
|
|
println!("\nAdding liquidity...");
|
|
let add_result = dex
|
|
.liquidity
|
|
.add_liquidity(AddLiquidityRequest {
|
|
pool: "SYN-USDC".to_string(),
|
|
amount0: "100".to_string(),
|
|
amount1: "150".to_string(),
|
|
slippage_bps: 50, // 0.5%
|
|
})
|
|
.await?;
|
|
|
|
println!("Liquidity added:");
|
|
println!(" LP tokens received: {}", add_result.lp_tokens);
|
|
println!(" Position ID: {}", add_result.position_id);
|
|
println!(" Share of pool: {}%", add_result.share_of_pool);
|
|
|
|
// Get LP positions
|
|
let lp_positions = dex.liquidity.get_positions().await?;
|
|
println!("\nLP positions: {}", lp_positions.len());
|
|
for pos in &lp_positions {
|
|
println!(" {}: {} LP tokens (value: ${})", pos.pool, pos.lp_tokens, pos.value);
|
|
}
|
|
|
|
// Claim fees
|
|
println!("\nClaiming fees...");
|
|
let fees = dex.liquidity.claim_fees(&add_result.position_id).await?;
|
|
println!("Fees claimed:");
|
|
println!(" Token0: {}", fees.amount0);
|
|
println!(" Token1: {}", fees.amount1);
|
|
|
|
// Remove liquidity
|
|
println!("\nRemoving liquidity...");
|
|
let remove_result = dex
|
|
.liquidity
|
|
.remove_liquidity(RemoveLiquidityRequest {
|
|
position_id: add_result.position_id.clone(),
|
|
lp_tokens: add_result.lp_tokens.clone(),
|
|
slippage_bps: 50,
|
|
})
|
|
.await?;
|
|
|
|
println!("Liquidity removed:");
|
|
println!(" Token0 received: {}", remove_result.amount0);
|
|
println!(" Token1 received: {}", remove_result.amount1);
|
|
|
|
println!();
|
|
Ok(())
|
|
}
|
|
|
|
async fn orderbook_example(dex: &SynorDex) -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("=== Order Book ===");
|
|
|
|
// Get order book snapshot
|
|
let orderbook = dex.orderbook.get_snapshot("SYN-USDC", 10).await?;
|
|
|
|
println!("Order book for SYN-USDC:");
|
|
println!("\nAsks (sells):");
|
|
for ask in orderbook.asks.iter().take(5) {
|
|
println!(" {} @ {}", ask.quantity, ask.price);
|
|
}
|
|
|
|
println!("\nBids (buys):");
|
|
for bid in orderbook.bids.iter().take(5) {
|
|
println!(" {} @ {}", bid.quantity, bid.price);
|
|
}
|
|
|
|
println!("\nSpread: {} ({}%)", orderbook.spread, orderbook.spread_percent);
|
|
println!("Mid price: {}", orderbook.mid_price);
|
|
|
|
// Get recent trades
|
|
let recent_trades = dex.orderbook.get_recent_trades("SYN-USDC", 10).await?;
|
|
println!("\nRecent trades:");
|
|
for trade in recent_trades.iter().take(5) {
|
|
println!(" {:?} {} @ {}", trade.side, trade.quantity, trade.price);
|
|
}
|
|
|
|
// Subscribe to orderbook updates (simulated)
|
|
println!("\nSubscribing to orderbook updates...");
|
|
let mut updates = dex.orderbook.subscribe("SYN-USDC").await?;
|
|
|
|
// Process a few updates
|
|
tokio::spawn(async move {
|
|
for _ in 0..3 {
|
|
if let Some(update) = updates.recv().await {
|
|
println!(" Update: {:?} {} @ {}", update.side, update.quantity, update.price);
|
|
}
|
|
}
|
|
});
|
|
|
|
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
|
|
|
println!();
|
|
Ok(())
|
|
}
|
|
|
|
async fn portfolio_example(dex: &SynorDex) -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("=== Portfolio ===");
|
|
|
|
// Get portfolio overview
|
|
let portfolio = dex.portfolio.get_overview().await?;
|
|
|
|
println!("Portfolio overview:");
|
|
println!(" Total value: ${}", portfolio.total_value);
|
|
println!(" Available balance: ${}", portfolio.available_balance);
|
|
println!(" In orders: ${}", portfolio.in_orders);
|
|
println!(" In positions: ${}", portfolio.in_positions);
|
|
println!(" Unrealized PnL: ${}", portfolio.unrealized_pnl);
|
|
|
|
// Get balances
|
|
let balances = dex.portfolio.get_balances().await?;
|
|
println!("\nBalances:");
|
|
for balance in &balances {
|
|
println!(
|
|
" {}: {} (available: {}, in orders: {})",
|
|
balance.asset, balance.total, balance.available, balance.in_orders
|
|
);
|
|
}
|
|
|
|
// Get PnL history
|
|
let pnl_history = dex.portfolio.get_pnl_history(30).await?; // Last 30 days
|
|
println!("\nPnL history (last {} days):", pnl_history.len());
|
|
if let Some(last) = pnl_history.last() {
|
|
println!(" Total PnL: ${}", last.cumulative_pnl);
|
|
}
|
|
|
|
// Get trade statistics
|
|
let stats = dex.portfolio.get_stats().await?;
|
|
println!("\nTrade statistics:");
|
|
println!(" Total trades: {}", stats.total_trades);
|
|
println!(" Win rate: {}%", stats.win_rate);
|
|
println!(" Avg profit: ${}", stats.avg_profit);
|
|
println!(" Avg loss: ${}", stats.avg_loss);
|
|
println!(" Best trade: ${}", stats.best_trade);
|
|
println!(" Worst trade: ${}", stats.worst_trade);
|
|
|
|
println!();
|
|
Ok(())
|
|
}
|