synor/sdk/go/examples/dex_example.go
Gulshan Yadav 9416d76108 Add IBC and ZK SDK examples for Rust
- 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.
2026-01-28 14:15:51 +05:30

506 lines
14 KiB
Go

// Package main demonstrates the Synor DEX SDK for Go
//
// This example covers decentralized exchange operations:
// - Spot trading (limit/market orders)
// - Perpetual futures trading
// - Liquidity provision (AMM pools)
// - Order book management
// - Portfolio tracking
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/synor/sdk-go/dex"
)
func main() {
// Initialize client
config := dex.Config{
APIKey: getEnv("SYNOR_API_KEY", "your-api-key"),
Endpoint: "https://dex.synor.io/v1",
Timeout: 30 * time.Second,
Retries: 3,
Debug: false,
DefaultMarket: "SYN-USDC",
}
client, err := dex.NewClient(config)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
ctx := context.Background()
// Check service health
healthy, err := client.HealthCheck(ctx)
if err != nil {
log.Printf("Health check failed: %v", err)
} else {
fmt.Printf("Service healthy: %v\n\n", healthy)
}
// Run examples
marketsExample(ctx, client)
spotTradingExample(ctx, client)
perpsTradingExample(ctx, client)
liquidityExample(ctx, client)
orderbookExample(ctx, client)
portfolioExample(ctx, client)
}
func marketsExample(ctx context.Context, client *dex.Client) {
fmt.Println("=== Markets ===")
// Get all markets
markets, err := client.Markets.List(ctx)
if err != nil {
log.Printf("Failed to list markets: %v", err)
return
}
fmt.Printf("Available markets: %d\n", len(markets))
for _, market := range markets[:min(5, len(markets))] {
fmt.Printf("\n %s:\n", market.Symbol)
fmt.Printf(" Base: %s, Quote: %s\n", market.BaseAsset, market.QuoteAsset)
fmt.Printf(" Price: %s\n", market.LastPrice)
fmt.Printf(" 24h Volume: %s\n", market.Volume24h)
fmt.Printf(" 24h Change: %s%%\n", market.Change24h)
fmt.Printf(" Status: %s\n", market.Status)
}
// Get specific market
market, err := client.Markets.Get(ctx, "SYN-USDC")
if err != nil {
log.Printf("Failed to get market: %v", err)
return
}
fmt.Printf("\nSYN-USDC details:\n")
fmt.Printf(" Min order size: %s\n", market.MinOrderSize)
fmt.Printf(" Tick size: %s\n", market.TickSize)
fmt.Printf(" Maker fee: %s%%\n", market.MakerFee)
fmt.Printf(" Taker fee: %s%%\n", market.TakerFee)
// Get market statistics
stats, err := client.Markets.GetStats(ctx, "SYN-USDC")
if err != nil {
log.Printf("Failed to get market stats: %v", err)
return
}
fmt.Printf("\nMarket statistics:\n")
fmt.Printf(" High 24h: %s\n", stats.High24h)
fmt.Printf(" Low 24h: %s\n", stats.Low24h)
fmt.Printf(" Open interest: %s\n", stats.OpenInterest)
fmt.Printf(" Funding rate: %s%%\n", stats.FundingRate)
fmt.Println()
}
func spotTradingExample(ctx context.Context, client *dex.Client) {
fmt.Println("=== Spot Trading ===")
// Place a limit order
fmt.Println("Placing limit buy order...")
limitOrder, err := client.Spot.PlaceOrder(ctx, &dex.OrderRequest{
Market: "SYN-USDC",
Side: dex.SideBuy,
OrderType: dex.OrderTypeLimit,
Price: "1.50",
Quantity: "100",
TimeInForce: dex.TimeInForceGTC,
})
if err != nil {
log.Printf("Failed to place limit order: %v", err)
} else {
fmt.Printf("Limit order placed:\n")
fmt.Printf(" Order ID: %s\n", limitOrder.OrderID)
fmt.Printf(" Status: %s\n", limitOrder.Status)
fmt.Printf(" Price: %s\n", limitOrder.Price)
fmt.Printf(" Quantity: %s\n", limitOrder.Quantity)
}
// Place a market order
fmt.Println("\nPlacing market sell order...")
marketOrder, err := client.Spot.PlaceOrder(ctx, &dex.OrderRequest{
Market: "SYN-USDC",
Side: dex.SideSell,
OrderType: dex.OrderTypeMarket,
Quantity: "50",
})
if err != nil {
log.Printf("Failed to place market order: %v", err)
} else {
fmt.Printf("Market order executed:\n")
fmt.Printf(" Order ID: %s\n", marketOrder.OrderID)
fmt.Printf(" Status: %s\n", marketOrder.Status)
fmt.Printf(" Filled: %s\n", marketOrder.FilledQuantity)
fmt.Printf(" Avg price: %s\n", marketOrder.AveragePrice)
}
// Get order status
if limitOrder != nil {
status, err := client.Spot.GetOrder(ctx, limitOrder.OrderID)
if err != nil {
log.Printf("Failed to get order status: %v", err)
} else {
fmt.Printf("\nOrder status:\n")
fmt.Printf(" Status: %s\n", status.Status)
fmt.Printf(" Filled: %s / %s\n", status.FilledQuantity, status.Quantity)
fmt.Printf(" Remaining: %s\n", status.RemainingQuantity)
}
// Cancel order
fmt.Println("\nCancelling order...")
err = client.Spot.CancelOrder(ctx, limitOrder.OrderID)
if err != nil {
log.Printf("Failed to cancel order: %v", err)
} else {
fmt.Println("Order cancelled successfully")
}
}
// Get open orders
openOrders, err := client.Spot.GetOpenOrders(ctx, "SYN-USDC")
if err != nil {
log.Printf("Failed to get open orders: %v", err)
} else {
fmt.Printf("\nOpen orders: %d\n", len(openOrders))
}
// Get trade history
trades, err := client.Spot.GetTradeHistory(ctx, "SYN-USDC", 10)
if err != nil {
log.Printf("Failed to get trade history: %v", err)
} else {
fmt.Printf("\nRecent trades: %d\n", len(trades))
for _, trade := range trades[:min(3, len(trades))] {
fmt.Printf(" %s %s @ %s (%s)\n", trade.Side, trade.Quantity, trade.Price, trade.Timestamp.Format(time.RFC3339))
}
}
fmt.Println()
}
func perpsTradingExample(ctx context.Context, client *dex.Client) {
fmt.Println("=== Perpetual Futures Trading ===")
// Get available perps markets
perpsMarkets, err := client.Perps.ListMarkets(ctx)
if err != nil {
log.Printf("Failed to list perps markets: %v", err)
return
}
fmt.Printf("Available perps markets: %d\n", len(perpsMarkets))
for _, market := range perpsMarkets[:min(3, len(perpsMarkets))] {
fmt.Printf(" %s: %s (funding: %s%%)\n", market.Symbol, market.MarkPrice, market.FundingRate)
}
// Open a long position
fmt.Println("\nOpening long position...")
position, err := client.Perps.OpenPosition(ctx, &dex.PerpsOrderRequest{
Market: "SYN-USDC-PERP",
Side: dex.SideBuy,
OrderType: dex.OrderTypeLimit,
Price: "1.50",
Size: "1000",
Leverage: 10,
ReduceOnly: false,
})
if err != nil {
log.Printf("Failed to open position: %v", err)
} else {
fmt.Printf("Position opened:\n")
fmt.Printf(" Position ID: %s\n", position.PositionID)
fmt.Printf(" Size: %s\n", position.Size)
fmt.Printf(" Entry price: %s\n", position.EntryPrice)
fmt.Printf(" Leverage: %dx\n", position.Leverage)
fmt.Printf(" Liquidation price: %s\n", position.LiquidationPrice)
}
// Get position details
if position != nil {
details, err := client.Perps.GetPosition(ctx, position.PositionID)
if err != nil {
log.Printf("Failed to get position: %v", err)
} else {
fmt.Printf("\nPosition details:\n")
fmt.Printf(" Unrealized PnL: %s\n", details.UnrealizedPnL)
fmt.Printf(" Margin: %s\n", details.Margin)
fmt.Printf(" Margin ratio: %s%%\n", details.MarginRatio)
}
}
// Set stop loss and take profit
if position != nil {
fmt.Println("\nSetting stop loss and take profit...")
err = client.Perps.SetStopLoss(ctx, position.PositionID, "1.40")
if err != nil {
log.Printf("Failed to set stop loss: %v", err)
} else {
fmt.Println("Stop loss set at 1.40")
}
err = client.Perps.SetTakeProfit(ctx, position.PositionID, "1.80")
if err != nil {
log.Printf("Failed to set take profit: %v", err)
} else {
fmt.Println("Take profit set at 1.80")
}
// Close position
fmt.Println("\nClosing position...")
closeResult, err := client.Perps.ClosePosition(ctx, position.PositionID)
if err != nil {
log.Printf("Failed to close position: %v", err)
} else {
fmt.Printf("Position closed:\n")
fmt.Printf(" Realized PnL: %s\n", closeResult.RealizedPnL)
fmt.Printf(" Close price: %s\n", closeResult.ClosePrice)
}
}
// Get all positions
positions, err := client.Perps.GetPositions(ctx)
if err != nil {
log.Printf("Failed to get positions: %v", err)
} else {
fmt.Printf("\nOpen positions: %d\n", len(positions))
}
// Get funding history
funding, err := client.Perps.GetFundingHistory(ctx, "SYN-USDC-PERP", 10)
if err != nil {
log.Printf("Failed to get funding history: %v", err)
} else {
fmt.Printf("Funding payments: %d\n", len(funding))
}
fmt.Println()
}
func liquidityExample(ctx context.Context, client *dex.Client) {
fmt.Println("=== Liquidity Provision ===")
// Get available pools
pools, err := client.Liquidity.ListPools(ctx)
if err != nil {
log.Printf("Failed to list pools: %v", err)
return
}
fmt.Printf("Available pools: %d\n", len(pools))
for _, pool := range pools[:min(3, len(pools))] {
fmt.Printf("\n %s:\n", pool.Name)
fmt.Printf(" TVL: $%s\n", pool.TVL)
fmt.Printf(" APR: %s%%\n", pool.APR)
fmt.Printf(" Volume 24h: $%s\n", pool.Volume24h)
fmt.Printf(" Fee tier: %s%%\n", pool.FeeTier)
}
// Get pool details
pool, err := client.Liquidity.GetPool(ctx, "SYN-USDC")
if err != nil {
log.Printf("Failed to get pool: %v", err)
return
}
fmt.Printf("\nSYN-USDC pool details:\n")
fmt.Printf(" Token0: %s (%s)\n", pool.Token0.Symbol, pool.Token0Reserve)
fmt.Printf(" Token1: %s (%s)\n", pool.Token1.Symbol, pool.Token1Reserve)
fmt.Printf(" Price: %s\n", pool.Price)
fmt.Printf(" Total LP tokens: %s\n", pool.TotalLPTokens)
// Add liquidity
fmt.Println("\nAdding liquidity...")
addResult, err := client.Liquidity.AddLiquidity(ctx, &dex.AddLiquidityRequest{
Pool: "SYN-USDC",
Amount0: "100",
Amount1: "150",
SlippageBps: 50, // 0.5%
})
if err != nil {
log.Printf("Failed to add liquidity: %v", err)
} else {
fmt.Printf("Liquidity added:\n")
fmt.Printf(" LP tokens received: %s\n", addResult.LPTokens)
fmt.Printf(" Position ID: %s\n", addResult.PositionID)
fmt.Printf(" Share of pool: %s%%\n", addResult.ShareOfPool)
}
// Get LP positions
lpPositions, err := client.Liquidity.GetPositions(ctx)
if err != nil {
log.Printf("Failed to get LP positions: %v", err)
} else {
fmt.Printf("\nLP positions: %d\n", len(lpPositions))
for _, pos := range lpPositions {
fmt.Printf(" %s: %s LP tokens (value: $%s)\n", pos.Pool, pos.LPTokens, pos.Value)
}
}
// Claim fees
if addResult != nil {
fmt.Println("\nClaiming fees...")
fees, err := client.Liquidity.ClaimFees(ctx, addResult.PositionID)
if err != nil {
log.Printf("Failed to claim fees: %v", err)
} else {
fmt.Printf("Fees claimed:\n")
fmt.Printf(" Token0: %s\n", fees.Amount0)
fmt.Printf(" Token1: %s\n", fees.Amount1)
}
// Remove liquidity
fmt.Println("\nRemoving liquidity...")
removeResult, err := client.Liquidity.RemoveLiquidity(ctx, &dex.RemoveLiquidityRequest{
PositionID: addResult.PositionID,
LPTokens: addResult.LPTokens,
SlippageBps: 50,
})
if err != nil {
log.Printf("Failed to remove liquidity: %v", err)
} else {
fmt.Printf("Liquidity removed:\n")
fmt.Printf(" Token0 received: %s\n", removeResult.Amount0)
fmt.Printf(" Token1 received: %s\n", removeResult.Amount1)
}
}
fmt.Println()
}
func orderbookExample(ctx context.Context, client *dex.Client) {
fmt.Println("=== Order Book ===")
// Get order book snapshot
orderbook, err := client.Orderbook.GetSnapshot(ctx, "SYN-USDC", 10)
if err != nil {
log.Printf("Failed to get orderbook: %v", err)
return
}
fmt.Println("Order book for SYN-USDC:")
fmt.Println("\nAsks (sells):")
for _, ask := range orderbook.Asks[:min(5, len(orderbook.Asks))] {
fmt.Printf(" %s @ %s\n", ask.Quantity, ask.Price)
}
fmt.Println("\nBids (buys):")
for _, bid := range orderbook.Bids[:min(5, len(orderbook.Bids))] {
fmt.Printf(" %s @ %s\n", bid.Quantity, bid.Price)
}
fmt.Printf("\nSpread: %s (%s%%)\n", orderbook.Spread, orderbook.SpreadPercent)
fmt.Printf("Mid price: %s\n", orderbook.MidPrice)
// Get recent trades
recentTrades, err := client.Orderbook.GetRecentTrades(ctx, "SYN-USDC", 10)
if err != nil {
log.Printf("Failed to get recent trades: %v", err)
} else {
fmt.Println("\nRecent trades:")
for _, trade := range recentTrades[:min(5, len(recentTrades))] {
fmt.Printf(" %s %s @ %s\n", trade.Side, trade.Quantity, trade.Price)
}
}
// Subscribe to orderbook updates (simulated)
fmt.Println("\nSubscribing to orderbook updates...")
updates := client.Orderbook.Subscribe(ctx, "SYN-USDC")
// Process a few updates (in real usage, this would be a goroutine)
go func() {
for i := 0; i < 3; i++ {
select {
case update := <-updates:
fmt.Printf(" Update: %s %s @ %s\n", update.Side, update.Quantity, update.Price)
case <-time.After(5 * time.Second):
return
}
}
}()
time.Sleep(2 * time.Second) // Wait for some updates
fmt.Println()
}
func portfolioExample(ctx context.Context, client *dex.Client) {
fmt.Println("=== Portfolio ===")
// Get portfolio overview
portfolio, err := client.Portfolio.GetOverview(ctx)
if err != nil {
log.Printf("Failed to get portfolio: %v", err)
return
}
fmt.Println("Portfolio overview:")
fmt.Printf(" Total value: $%s\n", portfolio.TotalValue)
fmt.Printf(" Available balance: $%s\n", portfolio.AvailableBalance)
fmt.Printf(" In orders: $%s\n", portfolio.InOrders)
fmt.Printf(" In positions: $%s\n", portfolio.InPositions)
fmt.Printf(" Unrealized PnL: $%s\n", portfolio.UnrealizedPnL)
// Get balances
balances, err := client.Portfolio.GetBalances(ctx)
if err != nil {
log.Printf("Failed to get balances: %v", err)
} else {
fmt.Println("\nBalances:")
for _, balance := range balances {
fmt.Printf(" %s: %s (available: %s, in orders: %s)\n",
balance.Asset, balance.Total, balance.Available, balance.InOrders)
}
}
// Get PnL history
pnlHistory, err := client.Portfolio.GetPnLHistory(ctx, 30) // Last 30 days
if err != nil {
log.Printf("Failed to get PnL history: %v", err)
} else {
fmt.Printf("\nPnL history (last %d days):\n", len(pnlHistory))
if len(pnlHistory) > 0 {
totalPnL := "0"
for _, day := range pnlHistory {
totalPnL = day.CumulativePnL
}
fmt.Printf(" Total PnL: $%s\n", totalPnL)
}
}
// Get trade statistics
stats, err := client.Portfolio.GetStats(ctx)
if err != nil {
log.Printf("Failed to get trade stats: %v", err)
} else {
fmt.Println("\nTrade statistics:")
fmt.Printf(" Total trades: %d\n", stats.TotalTrades)
fmt.Printf(" Win rate: %s%%\n", stats.WinRate)
fmt.Printf(" Avg profit: $%s\n", stats.AvgProfit)
fmt.Printf(" Avg loss: $%s\n", stats.AvgLoss)
fmt.Printf(" Best trade: $%s\n", stats.BestTrade)
fmt.Printf(" Worst trade: $%s\n", stats.WorstTrade)
}
fmt.Println()
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}