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
288 lines
9.6 KiB
Ruby
288 lines
9.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Synor DEX SDK Examples for Ruby
|
|
#
|
|
# Demonstrates decentralized exchange operations:
|
|
# - Market data and orderbook queries
|
|
# - Spot trading (limit and market orders)
|
|
# - Perpetual futures trading
|
|
# - Liquidity provision (AMM)
|
|
# - Portfolio management
|
|
#
|
|
|
|
require 'synor/dex'
|
|
|
|
class DexExample
|
|
def initialize(dex)
|
|
@dex = dex
|
|
end
|
|
|
|
def run_markets_example
|
|
puts '=== Market Information ==='
|
|
|
|
# List all available markets
|
|
markets = @dex.markets.list
|
|
puts "Available markets: #{markets.length}"
|
|
markets.first(5).each do |market|
|
|
puts " #{market.symbol}: #{market.base_asset}/#{market.quote_asset} (#{market.status})"
|
|
end
|
|
|
|
# Get specific market details
|
|
eth_usdc = @dex.markets.get('ETH-USDC')
|
|
puts "\n#{eth_usdc.symbol} market:"
|
|
puts " Price: $#{format('%.2f', eth_usdc.last_price)}"
|
|
puts " 24h Change: #{format('%.2f', eth_usdc.change_24h)}%"
|
|
puts " 24h Volume: $#{eth_usdc.volume_24h.to_i.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse}"
|
|
puts " 24h High: $#{format('%.2f', eth_usdc.high_24h)}"
|
|
puts " 24h Low: $#{format('%.2f', eth_usdc.low_24h)}"
|
|
|
|
# Get orderbook
|
|
orderbook = @dex.markets.get_orderbook('ETH-USDC', depth: 10)
|
|
puts "\nOrderbook (#{orderbook.bids.length} bids, #{orderbook.asks.length} asks):"
|
|
puts " Best bid: $#{format('%.2f', orderbook.bids.first.price)} (#{format('%.4f', orderbook.bids.first.quantity)} ETH)"
|
|
puts " Best ask: $#{format('%.2f', orderbook.asks.first.price)} (#{format('%.4f', orderbook.asks.first.quantity)} ETH)"
|
|
puts " Spread: $#{format('%.2f', orderbook.spread)} (#{format('%.3f', orderbook.spread_percent)}%)"
|
|
|
|
# Get recent trades
|
|
trades = @dex.markets.get_trades('ETH-USDC', limit: 5)
|
|
puts "\nRecent trades:"
|
|
trades.each do |trade|
|
|
puts " #{trade.side}: #{format('%.4f', trade.quantity)} @ $#{format('%.2f', trade.price)}"
|
|
end
|
|
puts
|
|
end
|
|
|
|
def run_spot_trading_example
|
|
puts '=== Spot Trading ==='
|
|
|
|
# Get account balance
|
|
balances = @dex.account.get_balances
|
|
puts 'Account balances:'
|
|
balances.select { |b| b.total.positive? }.each do |balance|
|
|
puts " #{balance.asset}: #{format('%.4f', balance.available)} available, #{format('%.4f', balance.locked)} locked"
|
|
end
|
|
|
|
# Place a limit buy order
|
|
puts "\nPlacing limit buy order..."
|
|
limit_order = @dex.spot.place_order(
|
|
symbol: 'ETH-USDC',
|
|
side: :buy,
|
|
type: :limit,
|
|
quantity: 0.1,
|
|
price: 3000.00,
|
|
time_in_force: :gtc
|
|
)
|
|
|
|
puts 'Limit order placed:'
|
|
puts " Order ID: #{limit_order.order_id}"
|
|
puts " Status: #{limit_order.status}"
|
|
puts " Price: $#{format('%.2f', limit_order.price)}"
|
|
puts " Quantity: #{format('%.4f', limit_order.quantity)}"
|
|
|
|
# Place a market sell order
|
|
puts "\nPlacing market sell order..."
|
|
market_order = @dex.spot.place_order(
|
|
symbol: 'ETH-USDC',
|
|
side: :sell,
|
|
type: :market,
|
|
quantity: 0.05
|
|
)
|
|
|
|
puts 'Market order executed:'
|
|
puts " Order ID: #{market_order.order_id}"
|
|
puts " Status: #{market_order.status}"
|
|
puts " Filled: #{format('%.4f', market_order.filled_quantity)}"
|
|
puts " Avg price: $#{format('%.2f', market_order.average_price)}"
|
|
|
|
# Get open orders
|
|
open_orders = @dex.spot.get_open_orders(symbol: 'ETH-USDC')
|
|
puts "\nOpen orders: #{open_orders.length}"
|
|
open_orders.each do |order|
|
|
puts " #{order.order_id}: #{order.side} #{format('%.4f', order.quantity)} @ $#{format('%.2f', order.price)}"
|
|
end
|
|
|
|
# Cancel an order
|
|
if open_orders.any?
|
|
cancelled = @dex.spot.cancel_order(open_orders.first.order_id)
|
|
puts "\nCancelled order: #{cancelled.order_id}"
|
|
end
|
|
puts
|
|
end
|
|
|
|
def run_perps_example
|
|
puts '=== Perpetual Futures ==='
|
|
|
|
# Get perpetual markets
|
|
perp_markets = @dex.perps.get_markets
|
|
puts "Perpetual markets: #{perp_markets.length}"
|
|
perp_markets.first(3).each do |market|
|
|
puts " #{market.symbol}: Mark $#{format('%.2f', market.mark_price)}, Funding #{format('%.4f', market.funding_rate)}%"
|
|
end
|
|
|
|
# Get account position
|
|
positions = @dex.perps.get_positions
|
|
puts "\nOpen positions: #{positions.length}"
|
|
positions.each do |position|
|
|
puts " #{position.symbol}: #{position.side} #{format('%.4f', position.size)}"
|
|
puts " Entry: $#{format('%.2f', position.entry_price)}, PnL: $#{format('%.2f', position.unrealized_pnl)}"
|
|
end
|
|
|
|
# Open a long position
|
|
puts "\nOpening long position..."
|
|
long_order = @dex.perps.place_order(
|
|
symbol: 'BTC-USDC-PERP',
|
|
side: :buy,
|
|
type: :limit,
|
|
quantity: 0.01,
|
|
price: 95_000.00,
|
|
leverage: 10,
|
|
reduce_only: false
|
|
)
|
|
|
|
puts 'Position order placed:'
|
|
puts " Order ID: #{long_order.order_id}"
|
|
puts " Leverage: #{long_order.leverage}x"
|
|
puts " Margin: $#{format('%.2f', long_order.required_margin)}"
|
|
|
|
# Set stop-loss and take-profit
|
|
puts "\nSetting SL/TP..."
|
|
@dex.perps.set_stop_loss('BTC-USDC-PERP', 90_000.00)
|
|
@dex.perps.set_take_profit('BTC-USDC-PERP', 100_000.00)
|
|
puts ' Stop loss: $90,000'
|
|
puts ' Take profit: $100,000'
|
|
|
|
# Get funding rate history
|
|
funding_history = @dex.perps.get_funding_history('BTC-USDC-PERP', limit: 5)
|
|
puts "\nFunding rate history:"
|
|
funding_history.each do |funding|
|
|
puts " #{funding.timestamp}: #{format('%.4f', funding.rate)}%"
|
|
end
|
|
puts
|
|
end
|
|
|
|
def run_liquidity_example
|
|
puts '=== Liquidity Provision ==='
|
|
|
|
# Get available pools
|
|
pools = @dex.liquidity.get_pools
|
|
puts "Liquidity pools: #{pools.length}"
|
|
pools.first(5).each do |pool|
|
|
tvl = pool.total_value_locked.to_i.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
|
puts " #{pool.name}: TVL $#{tvl}, APR #{format('%.2f', pool.apr)}%"
|
|
end
|
|
|
|
# Get pool details
|
|
eth_usdc_pool = @dex.liquidity.get_pool('ETH-USDC')
|
|
tvl = eth_usdc_pool.total_value_locked.to_i.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
|
vol = eth_usdc_pool.volume_24h.to_i.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
|
puts "\n#{eth_usdc_pool.name} pool:"
|
|
puts " TVL: $#{tvl}"
|
|
puts " Volume 24h: $#{vol}"
|
|
puts " Fee tier: #{format('%.2f', eth_usdc_pool.fee_tier)}%"
|
|
puts " APR: #{format('%.2f', eth_usdc_pool.apr)}%"
|
|
puts " Reserve A: #{format('%.4f', eth_usdc_pool.reserve_a)} ETH"
|
|
puts " Reserve B: #{format('%.2f', eth_usdc_pool.reserve_b)} USDC"
|
|
|
|
# Add liquidity
|
|
puts "\nAdding liquidity..."
|
|
add_result = @dex.liquidity.add_liquidity(
|
|
pool_id: 'ETH-USDC',
|
|
amount_a: 0.1,
|
|
amount_b: 300.0,
|
|
slippage_tolerance: 0.5
|
|
)
|
|
|
|
puts 'Liquidity added:'
|
|
puts " LP tokens received: #{format('%.8f', add_result.lp_tokens_received)}"
|
|
puts " Share of pool: #{format('%.4f', add_result.share_of_pool)}%"
|
|
|
|
# Get LP positions
|
|
lp_positions = @dex.liquidity.get_positions
|
|
puts "\nLP positions: #{lp_positions.length}"
|
|
lp_positions.each do |position|
|
|
puts " #{position.pool_id}: #{format('%.8f', position.lp_tokens)} tokens, $#{format('%.2f', position.value)}"
|
|
puts " Earned fees: $#{format('%.2f', position.earned_fees)}"
|
|
end
|
|
|
|
# Remove liquidity
|
|
puts "\nRemoving liquidity..."
|
|
remove_result = @dex.liquidity.remove_liquidity(
|
|
pool_id: 'ETH-USDC',
|
|
lp_tokens: add_result.lp_tokens_received,
|
|
slippage_tolerance: 0.5
|
|
)
|
|
|
|
puts 'Liquidity removed:'
|
|
puts " Amount A: #{format('%.4f', remove_result.amount_a)} ETH"
|
|
puts " Amount B: #{format('%.2f', remove_result.amount_b)} USDC"
|
|
puts
|
|
end
|
|
|
|
def run_portfolio_example
|
|
puts '=== Portfolio Management ==='
|
|
|
|
# Get portfolio summary
|
|
portfolio = @dex.portfolio.get_summary
|
|
puts 'Portfolio summary:'
|
|
puts " Total value: $#{format('%.2f', portfolio.total_value)}"
|
|
puts " Available: $#{format('%.2f', portfolio.available_balance)}"
|
|
puts " In orders: $#{format('%.2f', portfolio.in_orders)}"
|
|
puts " In positions: $#{format('%.2f', portfolio.in_positions)}"
|
|
puts " Unrealized PnL: $#{format('%.2f', portfolio.unrealized_pnl)}"
|
|
|
|
# Get asset allocation
|
|
puts "\nAsset allocation:"
|
|
portfolio.allocations.each do |allocation|
|
|
puts " #{allocation.asset}: #{format('%.1f', allocation.percentage)}% ($#{format('%.2f', allocation.value)})"
|
|
end
|
|
|
|
# Get trade history
|
|
trade_history = @dex.portfolio.get_trade_history(limit: 10)
|
|
puts "\nRecent trades: #{trade_history.length}"
|
|
trade_history.each do |trade|
|
|
puts " #{trade.timestamp}: #{trade.side} #{format('%.4f', trade.quantity)} #{trade.symbol} @ $#{format('%.2f', trade.price)}"
|
|
end
|
|
|
|
# Get PnL report
|
|
pnl_report = @dex.portfolio.get_pnl_report(:month)
|
|
puts "\nMonthly PnL report:"
|
|
puts " Realized PnL: $#{format('%.2f', pnl_report.realized_pnl)}"
|
|
puts " Unrealized PnL: $#{format('%.2f', pnl_report.unrealized_pnl)}"
|
|
puts " Total fees: $#{format('%.2f', pnl_report.total_fees)}"
|
|
puts " Net profit: $#{format('%.2f', pnl_report.net_profit)}"
|
|
puts
|
|
end
|
|
end
|
|
|
|
# Main execution
|
|
if __FILE__ == $PROGRAM_NAME
|
|
# Initialize client
|
|
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
|
|
config = Synor::Dex::Config.new(
|
|
api_key: api_key,
|
|
endpoint: 'https://dex.synor.io/v1',
|
|
timeout: 30,
|
|
retries: 3,
|
|
debug: false
|
|
)
|
|
|
|
dex = Synor::Dex::Client.new(config)
|
|
example = DexExample.new(dex)
|
|
|
|
begin
|
|
# Check service health
|
|
healthy = dex.health_check
|
|
puts "Service healthy: #{healthy}\n\n"
|
|
|
|
# Run examples
|
|
example.run_markets_example
|
|
example.run_spot_trading_example
|
|
example.run_perps_example
|
|
example.run_liquidity_example
|
|
example.run_portfolio_example
|
|
rescue StandardError => e
|
|
warn "Error: #{e.message}"
|
|
exit 1
|
|
end
|
|
end
|