Add example code demonstrating all SDK services (Crypto, DEX, ZK, IBC, Compiler) for the remaining languages: - C SDK (5 examples): Using synor_* C API with explicit memory management - C++ SDK (5 examples): Modern C++17 with RAII and designated initializers - C# SDK (5 examples): Async/await patterns with .NET conventions - Ruby SDK (5 examples): Ruby idioms with blocks and symbols Each example covers: - Crypto: Hybrid signatures, mnemonics, Falcon, SPHINCS+, KDF, hashing - DEX: Markets, spot trading, perpetuals, liquidity, portfolio - ZK: Circuits, Groth16, PLONK, STARK, recursive proofs, ceremonies - IBC: Chains, channels, transfers, packets, relayer, monitoring - Compiler: Compilation, optimization, ABI, analysis, validation, security
324 lines
12 KiB
C#
324 lines
12 KiB
C#
/**
|
|
* Synor DEX SDK Examples for C#
|
|
*
|
|
* Demonstrates decentralized exchange operations:
|
|
* - Market data and orderbook queries
|
|
* - Spot trading (limit and market orders)
|
|
* - Perpetual futures trading
|
|
* - Liquidity provision (AMM)
|
|
* - Portfolio management
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Synor.Dex;
|
|
|
|
namespace Synor.Examples;
|
|
|
|
public class DexExample
|
|
{
|
|
private readonly SynorDex _dex;
|
|
|
|
public DexExample(SynorDex dex)
|
|
{
|
|
_dex = dex;
|
|
}
|
|
|
|
public async Task RunMarketsExample()
|
|
{
|
|
Console.WriteLine("=== Market Information ===");
|
|
|
|
// List all available markets
|
|
var markets = await _dex.Markets.ListAsync();
|
|
Console.WriteLine($"Available markets: {markets.Count}");
|
|
foreach (var market in markets.GetRange(0, Math.Min(markets.Count, 5)))
|
|
{
|
|
Console.WriteLine($" {market.Symbol}: {market.BaseAsset}/{market.QuoteAsset} ({market.Status})");
|
|
}
|
|
|
|
// Get specific market details
|
|
var ethUsdc = await _dex.Markets.GetAsync("ETH-USDC");
|
|
Console.WriteLine($"\n{ethUsdc.Symbol} market:");
|
|
Console.WriteLine($" Price: ${ethUsdc.LastPrice:F2}");
|
|
Console.WriteLine($" 24h Change: {ethUsdc.Change24h:F2}%");
|
|
Console.WriteLine($" 24h Volume: ${ethUsdc.Volume24h:N0}");
|
|
Console.WriteLine($" 24h High: ${ethUsdc.High24h:F2}");
|
|
Console.WriteLine($" 24h Low: ${ethUsdc.Low24h:F2}");
|
|
|
|
// Get orderbook
|
|
var orderbook = await _dex.Markets.GetOrderbookAsync("ETH-USDC", 10);
|
|
Console.WriteLine($"\nOrderbook ({orderbook.Bids.Count} bids, {orderbook.Asks.Count} asks):");
|
|
Console.WriteLine(" Best bid: ${0:F2} ({1:F4} ETH)", orderbook.Bids[0].Price, orderbook.Bids[0].Quantity);
|
|
Console.WriteLine(" Best ask: ${0:F2} ({1:F4} ETH)", orderbook.Asks[0].Price, orderbook.Asks[0].Quantity);
|
|
Console.WriteLine($" Spread: ${orderbook.Spread:F2} ({orderbook.SpreadPercent:F3}%)");
|
|
|
|
// Get recent trades
|
|
var trades = await _dex.Markets.GetTradesAsync("ETH-USDC", 5);
|
|
Console.WriteLine("\nRecent trades:");
|
|
foreach (var trade in trades)
|
|
{
|
|
Console.WriteLine($" {trade.Side}: {trade.Quantity:F4} @ ${trade.Price:F2}");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunSpotTradingExample()
|
|
{
|
|
Console.WriteLine("=== Spot Trading ===");
|
|
|
|
// Get account balance
|
|
var balances = await _dex.Account.GetBalancesAsync();
|
|
Console.WriteLine("Account balances:");
|
|
foreach (var balance in balances)
|
|
{
|
|
if (balance.Total > 0)
|
|
{
|
|
Console.WriteLine($" {balance.Asset}: {balance.Available:F4} available, {balance.Locked:F4} locked");
|
|
}
|
|
}
|
|
|
|
// Place a limit buy order
|
|
Console.WriteLine("\nPlacing limit buy order...");
|
|
var limitOrder = await _dex.Spot.PlaceOrderAsync(new SpotOrderRequest
|
|
{
|
|
Symbol = "ETH-USDC",
|
|
Side = OrderSide.Buy,
|
|
Type = OrderType.Limit,
|
|
Quantity = 0.1m,
|
|
Price = 3000.00m,
|
|
TimeInForce = TimeInForce.GoodTillCancel
|
|
});
|
|
|
|
Console.WriteLine($"Limit order placed:");
|
|
Console.WriteLine($" Order ID: {limitOrder.OrderId}");
|
|
Console.WriteLine($" Status: {limitOrder.Status}");
|
|
Console.WriteLine($" Price: ${limitOrder.Price:F2}");
|
|
Console.WriteLine($" Quantity: {limitOrder.Quantity:F4}");
|
|
|
|
// Place a market sell order
|
|
Console.WriteLine("\nPlacing market sell order...");
|
|
var marketOrder = await _dex.Spot.PlaceOrderAsync(new SpotOrderRequest
|
|
{
|
|
Symbol = "ETH-USDC",
|
|
Side = OrderSide.Sell,
|
|
Type = OrderType.Market,
|
|
Quantity = 0.05m
|
|
});
|
|
|
|
Console.WriteLine($"Market order executed:");
|
|
Console.WriteLine($" Order ID: {marketOrder.OrderId}");
|
|
Console.WriteLine($" Status: {marketOrder.Status}");
|
|
Console.WriteLine($" Filled: {marketOrder.FilledQuantity:F4}");
|
|
Console.WriteLine($" Avg price: ${marketOrder.AveragePrice:F2}");
|
|
|
|
// Get open orders
|
|
var openOrders = await _dex.Spot.GetOpenOrdersAsync("ETH-USDC");
|
|
Console.WriteLine($"\nOpen orders: {openOrders.Count}");
|
|
foreach (var order in openOrders)
|
|
{
|
|
Console.WriteLine($" {order.OrderId}: {order.Side} {order.Quantity:F4} @ ${order.Price:F2}");
|
|
}
|
|
|
|
// Cancel an order
|
|
if (openOrders.Count > 0)
|
|
{
|
|
var cancelled = await _dex.Spot.CancelOrderAsync(openOrders[0].OrderId);
|
|
Console.WriteLine($"\nCancelled order: {cancelled.OrderId}");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunPerpsExample()
|
|
{
|
|
Console.WriteLine("=== Perpetual Futures ===");
|
|
|
|
// Get perpetual markets
|
|
var perpMarkets = await _dex.Perps.GetMarketsAsync();
|
|
Console.WriteLine($"Perpetual markets: {perpMarkets.Count}");
|
|
foreach (var market in perpMarkets.GetRange(0, Math.Min(perpMarkets.Count, 3)))
|
|
{
|
|
Console.WriteLine($" {market.Symbol}: Mark ${market.MarkPrice:F2}, Funding {market.FundingRate:F4}%");
|
|
}
|
|
|
|
// Get account position
|
|
var positions = await _dex.Perps.GetPositionsAsync();
|
|
Console.WriteLine($"\nOpen positions: {positions.Count}");
|
|
foreach (var position in positions)
|
|
{
|
|
Console.WriteLine($" {position.Symbol}: {position.Side} {position.Size:F4}");
|
|
Console.WriteLine($" Entry: ${position.EntryPrice:F2}, PnL: ${position.UnrealizedPnl:F2}");
|
|
}
|
|
|
|
// Open a long position
|
|
Console.WriteLine("\nOpening long position...");
|
|
var longOrder = await _dex.Perps.PlaceOrderAsync(new PerpOrderRequest
|
|
{
|
|
Symbol = "BTC-USDC-PERP",
|
|
Side = OrderSide.Buy,
|
|
Type = OrderType.Limit,
|
|
Quantity = 0.01m,
|
|
Price = 95000.00m,
|
|
Leverage = 10,
|
|
ReduceOnly = false
|
|
});
|
|
|
|
Console.WriteLine($"Position order placed:");
|
|
Console.WriteLine($" Order ID: {longOrder.OrderId}");
|
|
Console.WriteLine($" Leverage: {longOrder.Leverage}x");
|
|
Console.WriteLine($" Margin: ${longOrder.RequiredMargin:F2}");
|
|
|
|
// Set stop-loss and take-profit
|
|
Console.WriteLine("\nSetting SL/TP...");
|
|
await _dex.Perps.SetStopLossAsync("BTC-USDC-PERP", 90000.00m);
|
|
await _dex.Perps.SetTakeProfitAsync("BTC-USDC-PERP", 100000.00m);
|
|
Console.WriteLine(" Stop loss: $90,000");
|
|
Console.WriteLine(" Take profit: $100,000");
|
|
|
|
// Get funding rate history
|
|
var fundingHistory = await _dex.Perps.GetFundingHistoryAsync("BTC-USDC-PERP", 5);
|
|
Console.WriteLine("\nFunding rate history:");
|
|
foreach (var funding in fundingHistory)
|
|
{
|
|
Console.WriteLine($" {funding.Timestamp}: {funding.Rate:F4}%");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunLiquidityExample()
|
|
{
|
|
Console.WriteLine("=== Liquidity Provision ===");
|
|
|
|
// Get available pools
|
|
var pools = await _dex.Liquidity.GetPoolsAsync();
|
|
Console.WriteLine($"Liquidity pools: {pools.Count}");
|
|
foreach (var pool in pools.GetRange(0, Math.Min(pools.Count, 5)))
|
|
{
|
|
Console.WriteLine($" {pool.Name}: TVL ${pool.TotalValueLocked:N0}, APR {pool.Apr:F2}%");
|
|
}
|
|
|
|
// Get pool details
|
|
var ethUsdcPool = await _dex.Liquidity.GetPoolAsync("ETH-USDC");
|
|
Console.WriteLine($"\n{ethUsdcPool.Name} pool:");
|
|
Console.WriteLine($" TVL: ${ethUsdcPool.TotalValueLocked:N0}");
|
|
Console.WriteLine($" Volume 24h: ${ethUsdcPool.Volume24h:N0}");
|
|
Console.WriteLine($" Fee tier: {ethUsdcPool.FeeTier:F2}%");
|
|
Console.WriteLine($" APR: {ethUsdcPool.Apr:F2}%");
|
|
Console.WriteLine($" Reserve A: {ethUsdcPool.ReserveA:F4} ETH");
|
|
Console.WriteLine($" Reserve B: {ethUsdcPool.ReserveB:F2} USDC");
|
|
|
|
// Add liquidity
|
|
Console.WriteLine("\nAdding liquidity...");
|
|
var addResult = await _dex.Liquidity.AddLiquidityAsync(new AddLiquidityRequest
|
|
{
|
|
PoolId = "ETH-USDC",
|
|
AmountA = 0.1m,
|
|
AmountB = 300.0m,
|
|
SlippageTolerance = 0.5m
|
|
});
|
|
|
|
Console.WriteLine($"Liquidity added:");
|
|
Console.WriteLine($" LP tokens received: {addResult.LpTokensReceived:F8}");
|
|
Console.WriteLine($" Share of pool: {addResult.ShareOfPool:F4}%");
|
|
|
|
// Get LP positions
|
|
var lpPositions = await _dex.Liquidity.GetPositionsAsync();
|
|
Console.WriteLine($"\nLP positions: {lpPositions.Count}");
|
|
foreach (var position in lpPositions)
|
|
{
|
|
Console.WriteLine($" {position.PoolId}: {position.LpTokens:F8} tokens, ${position.Value:F2}");
|
|
Console.WriteLine($" Earned fees: ${position.EarnedFees:F2}");
|
|
}
|
|
|
|
// Remove liquidity
|
|
Console.WriteLine("\nRemoving liquidity...");
|
|
var removeResult = await _dex.Liquidity.RemoveLiquidityAsync(new RemoveLiquidityRequest
|
|
{
|
|
PoolId = "ETH-USDC",
|
|
LpTokens = addResult.LpTokensReceived,
|
|
SlippageTolerance = 0.5m
|
|
});
|
|
|
|
Console.WriteLine($"Liquidity removed:");
|
|
Console.WriteLine($" Amount A: {removeResult.AmountA:F4} ETH");
|
|
Console.WriteLine($" Amount B: {removeResult.AmountB:F2} USDC");
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunPortfolioExample()
|
|
{
|
|
Console.WriteLine("=== Portfolio Management ===");
|
|
|
|
// Get portfolio summary
|
|
var portfolio = await _dex.Portfolio.GetSummaryAsync();
|
|
Console.WriteLine("Portfolio summary:");
|
|
Console.WriteLine($" Total value: ${portfolio.TotalValue:N2}");
|
|
Console.WriteLine($" Available: ${portfolio.AvailableBalance:N2}");
|
|
Console.WriteLine($" In orders: ${portfolio.InOrders:N2}");
|
|
Console.WriteLine($" In positions: ${portfolio.InPositions:N2}");
|
|
Console.WriteLine($" Unrealized PnL: ${portfolio.UnrealizedPnl:N2}");
|
|
|
|
// Get asset allocation
|
|
Console.WriteLine("\nAsset allocation:");
|
|
foreach (var allocation in portfolio.Allocations)
|
|
{
|
|
Console.WriteLine($" {allocation.Asset}: {allocation.Percentage:F1}% (${allocation.Value:N2})");
|
|
}
|
|
|
|
// Get trade history
|
|
var tradeHistory = await _dex.Portfolio.GetTradeHistoryAsync(new TradeHistoryFilter
|
|
{
|
|
Limit = 10
|
|
});
|
|
Console.WriteLine($"\nRecent trades: {tradeHistory.Count}");
|
|
foreach (var trade in tradeHistory)
|
|
{
|
|
Console.WriteLine($" {trade.Timestamp}: {trade.Side} {trade.Quantity:F4} {trade.Symbol} @ ${trade.Price:F2}");
|
|
}
|
|
|
|
// Get PnL report
|
|
var pnlReport = await _dex.Portfolio.GetPnlReportAsync(Period.Month);
|
|
Console.WriteLine($"\nMonthly PnL report:");
|
|
Console.WriteLine($" Realized PnL: ${pnlReport.RealizedPnl:N2}");
|
|
Console.WriteLine($" Unrealized PnL: ${pnlReport.UnrealizedPnl:N2}");
|
|
Console.WriteLine($" Total fees: ${pnlReport.TotalFees:N2}");
|
|
Console.WriteLine($" Net profit: ${pnlReport.NetProfit:N2}");
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public static async Task Main(string[] args)
|
|
{
|
|
// Initialize client
|
|
var apiKey = Environment.GetEnvironmentVariable("SYNOR_API_KEY") ?? "your-api-key";
|
|
var config = new DexConfig
|
|
{
|
|
ApiKey = apiKey,
|
|
Endpoint = "https://dex.synor.io/v1",
|
|
Timeout = TimeSpan.FromSeconds(30),
|
|
Retries = 3,
|
|
Debug = false
|
|
};
|
|
|
|
var dex = new SynorDex(config);
|
|
var example = new DexExample(dex);
|
|
|
|
try
|
|
{
|
|
// Check service health
|
|
var healthy = await dex.HealthCheckAsync();
|
|
Console.WriteLine($"Service healthy: {healthy}\n");
|
|
|
|
// Run examples
|
|
await example.RunMarketsExample();
|
|
await example.RunSpotTradingExample();
|
|
await example.RunPerpsExample();
|
|
await example.RunLiquidityExample();
|
|
await example.RunPortfolioExample();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.Error.WriteLine($"Error: {ex.Message}");
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
}
|