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
489 lines
18 KiB
C
489 lines
18 KiB
C
/**
|
|
* Synor DEX SDK Examples for C
|
|
*
|
|
* Demonstrates decentralized exchange operations:
|
|
* - Spot trading (limit/market orders)
|
|
* - Perpetual futures trading
|
|
* - Liquidity provision (AMM pools)
|
|
* - Order book management
|
|
* - Portfolio tracking
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <synor/dex.h>
|
|
|
|
void markets_example(synor_dex_t* dex) {
|
|
printf("=== Markets ===\n");
|
|
|
|
synor_error_t err;
|
|
synor_market_list_t* markets = NULL;
|
|
|
|
// Get all markets
|
|
err = synor_markets_list(dex, &markets);
|
|
if (err != SYNOR_OK) {
|
|
fprintf(stderr, "Failed to get markets\n");
|
|
return;
|
|
}
|
|
|
|
printf("Available markets: %zu\n", synor_market_list_count(markets));
|
|
|
|
for (size_t i = 0; i < 5 && i < synor_market_list_count(markets); i++) {
|
|
synor_market_t* market = synor_market_list_get(markets, i);
|
|
printf("\n %s:\n", synor_market_get_symbol(market));
|
|
printf(" Base: %s, Quote: %s\n",
|
|
synor_market_get_base_asset(market),
|
|
synor_market_get_quote_asset(market));
|
|
printf(" Price: %s\n", synor_market_get_last_price(market));
|
|
printf(" 24h Volume: %s\n", synor_market_get_volume_24h(market));
|
|
printf(" 24h Change: %s%%\n", synor_market_get_change_24h(market));
|
|
printf(" Status: %s\n", synor_market_get_status(market));
|
|
}
|
|
|
|
// Get specific market
|
|
synor_market_t* market = NULL;
|
|
err = synor_markets_get(dex, "SYN-USDC", &market);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nSYN-USDC details:\n");
|
|
printf(" Min order size: %s\n", synor_market_get_min_order_size(market));
|
|
printf(" Tick size: %s\n", synor_market_get_tick_size(market));
|
|
printf(" Maker fee: %s%%\n", synor_market_get_maker_fee(market));
|
|
printf(" Taker fee: %s%%\n", synor_market_get_taker_fee(market));
|
|
synor_market_free(market);
|
|
}
|
|
|
|
// Get market statistics
|
|
synor_market_stats_t* stats = NULL;
|
|
err = synor_markets_get_stats(dex, "SYN-USDC", &stats);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nMarket statistics:\n");
|
|
printf(" High 24h: %s\n", synor_stats_get_high_24h(stats));
|
|
printf(" Low 24h: %s\n", synor_stats_get_low_24h(stats));
|
|
printf(" Open interest: %s\n", synor_stats_get_open_interest(stats));
|
|
printf(" Funding rate: %s%%\n", synor_stats_get_funding_rate(stats));
|
|
synor_market_stats_free(stats);
|
|
}
|
|
|
|
synor_market_list_free(markets);
|
|
printf("\n");
|
|
}
|
|
|
|
void spot_trading_example(synor_dex_t* dex) {
|
|
printf("=== Spot Trading ===\n");
|
|
|
|
synor_error_t err;
|
|
|
|
// Place a limit order
|
|
printf("Placing limit buy order...\n");
|
|
synor_order_request_t limit_req = {
|
|
.market = "SYN-USDC",
|
|
.side = SYNOR_ORDER_SIDE_BUY,
|
|
.order_type = SYNOR_ORDER_TYPE_LIMIT,
|
|
.price = "1.50",
|
|
.quantity = "100",
|
|
.time_in_force = SYNOR_TIME_IN_FORCE_GTC
|
|
};
|
|
|
|
synor_order_result_t* limit_order = NULL;
|
|
err = synor_spot_place_order(dex, &limit_req, &limit_order);
|
|
if (err != SYNOR_OK) {
|
|
fprintf(stderr, "Failed to place limit order\n");
|
|
return;
|
|
}
|
|
|
|
printf("Limit order placed:\n");
|
|
printf(" Order ID: %s\n", synor_order_get_id(limit_order));
|
|
printf(" Status: %s\n", synor_order_get_status(limit_order));
|
|
printf(" Price: %s\n", synor_order_get_price(limit_order));
|
|
printf(" Quantity: %s\n", synor_order_get_quantity(limit_order));
|
|
|
|
// Place a market order
|
|
printf("\nPlacing market sell order...\n");
|
|
synor_order_request_t market_req = {
|
|
.market = "SYN-USDC",
|
|
.side = SYNOR_ORDER_SIDE_SELL,
|
|
.order_type = SYNOR_ORDER_TYPE_MARKET,
|
|
.quantity = "50"
|
|
};
|
|
|
|
synor_order_result_t* market_order = NULL;
|
|
err = synor_spot_place_order(dex, &market_req, &market_order);
|
|
if (err == SYNOR_OK) {
|
|
printf("Market order executed:\n");
|
|
printf(" Order ID: %s\n", synor_order_get_id(market_order));
|
|
printf(" Status: %s\n", synor_order_get_status(market_order));
|
|
printf(" Filled: %s\n", synor_order_get_filled_quantity(market_order));
|
|
printf(" Avg price: %s\n", synor_order_get_avg_price(market_order));
|
|
synor_order_result_free(market_order);
|
|
}
|
|
|
|
// Get order status
|
|
synor_order_status_t* status = NULL;
|
|
err = synor_spot_get_order(dex, synor_order_get_id(limit_order), &status);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nOrder status:\n");
|
|
printf(" Status: %s\n", synor_order_status_get_status(status));
|
|
printf(" Filled: %s / %s\n",
|
|
synor_order_status_get_filled(status),
|
|
synor_order_status_get_quantity(status));
|
|
printf(" Remaining: %s\n", synor_order_status_get_remaining(status));
|
|
synor_order_status_free(status);
|
|
}
|
|
|
|
// Cancel order
|
|
printf("\nCancelling order...\n");
|
|
err = synor_spot_cancel_order(dex, synor_order_get_id(limit_order));
|
|
if (err == SYNOR_OK) {
|
|
printf("Order cancelled successfully\n");
|
|
}
|
|
|
|
// Get open orders
|
|
synor_order_list_t* open_orders = NULL;
|
|
err = synor_spot_get_open_orders(dex, "SYN-USDC", &open_orders);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nOpen orders: %zu\n", synor_order_list_count(open_orders));
|
|
synor_order_list_free(open_orders);
|
|
}
|
|
|
|
// Get trade history
|
|
synor_trade_list_t* trades = NULL;
|
|
err = synor_spot_get_trade_history(dex, "SYN-USDC", 10, &trades);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nRecent trades: %zu\n", synor_trade_list_count(trades));
|
|
for (size_t i = 0; i < 3 && i < synor_trade_list_count(trades); i++) {
|
|
synor_trade_t* trade = synor_trade_list_get(trades, i);
|
|
printf(" %s %s @ %s (%s)\n",
|
|
synor_trade_get_side(trade),
|
|
synor_trade_get_quantity(trade),
|
|
synor_trade_get_price(trade),
|
|
synor_trade_get_timestamp(trade));
|
|
}
|
|
synor_trade_list_free(trades);
|
|
}
|
|
|
|
synor_order_result_free(limit_order);
|
|
printf("\n");
|
|
}
|
|
|
|
void perps_trading_example(synor_dex_t* dex) {
|
|
printf("=== Perpetual Futures Trading ===\n");
|
|
|
|
synor_error_t err;
|
|
|
|
// Get available perps markets
|
|
synor_perps_market_list_t* perps_markets = NULL;
|
|
err = synor_perps_list_markets(dex, &perps_markets);
|
|
if (err == SYNOR_OK) {
|
|
printf("Available perps markets: %zu\n", synor_perps_market_list_count(perps_markets));
|
|
for (size_t i = 0; i < 3 && i < synor_perps_market_list_count(perps_markets); i++) {
|
|
synor_perps_market_t* market = synor_perps_market_list_get(perps_markets, i);
|
|
printf(" %s: %s (funding: %s%%)\n",
|
|
synor_perps_market_get_symbol(market),
|
|
synor_perps_market_get_mark_price(market),
|
|
synor_perps_market_get_funding_rate(market));
|
|
}
|
|
synor_perps_market_list_free(perps_markets);
|
|
}
|
|
|
|
// Open a long position
|
|
printf("\nOpening long position...\n");
|
|
synor_perps_order_request_t perps_req = {
|
|
.market = "SYN-USDC-PERP",
|
|
.side = SYNOR_ORDER_SIDE_BUY,
|
|
.order_type = SYNOR_ORDER_TYPE_LIMIT,
|
|
.price = "1.50",
|
|
.size = "1000",
|
|
.leverage = 10,
|
|
.reduce_only = false
|
|
};
|
|
|
|
synor_position_t* position = NULL;
|
|
err = synor_perps_open_position(dex, &perps_req, &position);
|
|
if (err != SYNOR_OK) {
|
|
fprintf(stderr, "Failed to open position\n");
|
|
return;
|
|
}
|
|
|
|
printf("Position opened:\n");
|
|
printf(" Position ID: %s\n", synor_position_get_id(position));
|
|
printf(" Size: %s\n", synor_position_get_size(position));
|
|
printf(" Entry price: %s\n", synor_position_get_entry_price(position));
|
|
printf(" Leverage: %dx\n", synor_position_get_leverage(position));
|
|
printf(" Liquidation price: %s\n", synor_position_get_liquidation_price(position));
|
|
|
|
// Get position details
|
|
synor_position_details_t* details = NULL;
|
|
err = synor_perps_get_position(dex, synor_position_get_id(position), &details);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nPosition details:\n");
|
|
printf(" Unrealized PnL: %s\n", synor_position_details_get_unrealized_pnl(details));
|
|
printf(" Margin: %s\n", synor_position_details_get_margin(details));
|
|
printf(" Margin ratio: %s%%\n", synor_position_details_get_margin_ratio(details));
|
|
synor_position_details_free(details);
|
|
}
|
|
|
|
// Set stop loss and take profit
|
|
printf("\nSetting stop loss and take profit...\n");
|
|
err = synor_perps_set_stop_loss(dex, synor_position_get_id(position), "1.40");
|
|
if (err == SYNOR_OK) printf("Stop loss set at 1.40\n");
|
|
|
|
err = synor_perps_set_take_profit(dex, synor_position_get_id(position), "1.80");
|
|
if (err == SYNOR_OK) printf("Take profit set at 1.80\n");
|
|
|
|
// Close position
|
|
printf("\nClosing position...\n");
|
|
synor_close_result_t* close_result = NULL;
|
|
err = synor_perps_close_position(dex, synor_position_get_id(position), &close_result);
|
|
if (err == SYNOR_OK) {
|
|
printf("Position closed:\n");
|
|
printf(" Realized PnL: %s\n", synor_close_result_get_realized_pnl(close_result));
|
|
printf(" Close price: %s\n", synor_close_result_get_close_price(close_result));
|
|
synor_close_result_free(close_result);
|
|
}
|
|
|
|
// Get all positions
|
|
synor_position_list_t* positions = NULL;
|
|
err = synor_perps_get_positions(dex, &positions);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nOpen positions: %zu\n", synor_position_list_count(positions));
|
|
synor_position_list_free(positions);
|
|
}
|
|
|
|
synor_position_free(position);
|
|
printf("\n");
|
|
}
|
|
|
|
void liquidity_example(synor_dex_t* dex) {
|
|
printf("=== Liquidity Provision ===\n");
|
|
|
|
synor_error_t err;
|
|
|
|
// Get available pools
|
|
synor_pool_list_t* pools = NULL;
|
|
err = synor_liquidity_list_pools(dex, &pools);
|
|
if (err == SYNOR_OK) {
|
|
printf("Available pools: %zu\n", synor_pool_list_count(pools));
|
|
for (size_t i = 0; i < 3 && i < synor_pool_list_count(pools); i++) {
|
|
synor_pool_t* pool = synor_pool_list_get(pools, i);
|
|
printf("\n %s:\n", synor_pool_get_name(pool));
|
|
printf(" TVL: $%s\n", synor_pool_get_tvl(pool));
|
|
printf(" APR: %s%%\n", synor_pool_get_apr(pool));
|
|
printf(" Volume 24h: $%s\n", synor_pool_get_volume_24h(pool));
|
|
printf(" Fee tier: %s%%\n", synor_pool_get_fee_tier(pool));
|
|
}
|
|
synor_pool_list_free(pools);
|
|
}
|
|
|
|
// Get pool details
|
|
synor_pool_details_t* pool = NULL;
|
|
err = synor_liquidity_get_pool(dex, "SYN-USDC", &pool);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nSYN-USDC pool details:\n");
|
|
printf(" Token0: %s (%s)\n",
|
|
synor_pool_details_get_token0_symbol(pool),
|
|
synor_pool_details_get_token0_reserve(pool));
|
|
printf(" Token1: %s (%s)\n",
|
|
synor_pool_details_get_token1_symbol(pool),
|
|
synor_pool_details_get_token1_reserve(pool));
|
|
printf(" Price: %s\n", synor_pool_details_get_price(pool));
|
|
printf(" Total LP tokens: %s\n", synor_pool_details_get_total_lp_tokens(pool));
|
|
synor_pool_details_free(pool);
|
|
}
|
|
|
|
// Add liquidity
|
|
printf("\nAdding liquidity...\n");
|
|
synor_add_liquidity_request_t add_req = {
|
|
.pool = "SYN-USDC",
|
|
.amount0 = "100",
|
|
.amount1 = "150",
|
|
.slippage_bps = 50 // 0.5%
|
|
};
|
|
|
|
synor_add_liquidity_result_t* add_result = NULL;
|
|
err = synor_liquidity_add(dex, &add_req, &add_result);
|
|
if (err == SYNOR_OK) {
|
|
printf("Liquidity added:\n");
|
|
printf(" LP tokens received: %s\n", synor_add_result_get_lp_tokens(add_result));
|
|
printf(" Position ID: %s\n", synor_add_result_get_position_id(add_result));
|
|
printf(" Share of pool: %s%%\n", synor_add_result_get_share_of_pool(add_result));
|
|
|
|
// Claim fees
|
|
printf("\nClaiming fees...\n");
|
|
synor_claim_fees_result_t* fees = NULL;
|
|
err = synor_liquidity_claim_fees(dex, synor_add_result_get_position_id(add_result), &fees);
|
|
if (err == SYNOR_OK) {
|
|
printf("Fees claimed:\n");
|
|
printf(" Token0: %s\n", synor_claim_fees_get_amount0(fees));
|
|
printf(" Token1: %s\n", synor_claim_fees_get_amount1(fees));
|
|
synor_claim_fees_result_free(fees);
|
|
}
|
|
|
|
// Remove liquidity
|
|
printf("\nRemoving liquidity...\n");
|
|
synor_remove_liquidity_request_t remove_req = {
|
|
.position_id = synor_add_result_get_position_id(add_result),
|
|
.lp_tokens = synor_add_result_get_lp_tokens(add_result),
|
|
.slippage_bps = 50
|
|
};
|
|
|
|
synor_remove_liquidity_result_t* remove_result = NULL;
|
|
err = synor_liquidity_remove(dex, &remove_req, &remove_result);
|
|
if (err == SYNOR_OK) {
|
|
printf("Liquidity removed:\n");
|
|
printf(" Token0 received: %s\n", synor_remove_result_get_amount0(remove_result));
|
|
printf(" Token1 received: %s\n", synor_remove_result_get_amount1(remove_result));
|
|
synor_remove_liquidity_result_free(remove_result);
|
|
}
|
|
|
|
synor_add_liquidity_result_free(add_result);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
void orderbook_example(synor_dex_t* dex) {
|
|
printf("=== Order Book ===\n");
|
|
|
|
synor_error_t err;
|
|
|
|
// Get order book snapshot
|
|
synor_orderbook_t* orderbook = NULL;
|
|
err = synor_orderbook_get_snapshot(dex, "SYN-USDC", 10, &orderbook);
|
|
if (err != SYNOR_OK) {
|
|
fprintf(stderr, "Failed to get orderbook\n");
|
|
return;
|
|
}
|
|
|
|
printf("Order book for SYN-USDC:\n");
|
|
|
|
printf("\nAsks (sells):\n");
|
|
for (size_t i = 0; i < 5 && i < synor_orderbook_get_ask_count(orderbook); i++) {
|
|
synor_orderbook_entry_t* ask = synor_orderbook_get_ask(orderbook, i);
|
|
printf(" %s @ %s\n",
|
|
synor_orderbook_entry_get_quantity(ask),
|
|
synor_orderbook_entry_get_price(ask));
|
|
}
|
|
|
|
printf("\nBids (buys):\n");
|
|
for (size_t i = 0; i < 5 && i < synor_orderbook_get_bid_count(orderbook); i++) {
|
|
synor_orderbook_entry_t* bid = synor_orderbook_get_bid(orderbook, i);
|
|
printf(" %s @ %s\n",
|
|
synor_orderbook_entry_get_quantity(bid),
|
|
synor_orderbook_entry_get_price(bid));
|
|
}
|
|
|
|
printf("\nSpread: %s (%s%%)\n",
|
|
synor_orderbook_get_spread(orderbook),
|
|
synor_orderbook_get_spread_percent(orderbook));
|
|
printf("Mid price: %s\n", synor_orderbook_get_mid_price(orderbook));
|
|
|
|
synor_orderbook_free(orderbook);
|
|
|
|
// Get recent trades
|
|
synor_trade_list_t* recent_trades = NULL;
|
|
err = synor_orderbook_get_recent_trades(dex, "SYN-USDC", 10, &recent_trades);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nRecent trades:\n");
|
|
for (size_t i = 0; i < 5 && i < synor_trade_list_count(recent_trades); i++) {
|
|
synor_trade_t* trade = synor_trade_list_get(recent_trades, i);
|
|
printf(" %s %s @ %s\n",
|
|
synor_trade_get_side(trade),
|
|
synor_trade_get_quantity(trade),
|
|
synor_trade_get_price(trade));
|
|
}
|
|
synor_trade_list_free(recent_trades);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
void portfolio_example(synor_dex_t* dex) {
|
|
printf("=== Portfolio ===\n");
|
|
|
|
synor_error_t err;
|
|
|
|
// Get portfolio overview
|
|
synor_portfolio_t* portfolio = NULL;
|
|
err = synor_portfolio_get_overview(dex, &portfolio);
|
|
if (err == SYNOR_OK) {
|
|
printf("Portfolio overview:\n");
|
|
printf(" Total value: $%s\n", synor_portfolio_get_total_value(portfolio));
|
|
printf(" Available balance: $%s\n", synor_portfolio_get_available_balance(portfolio));
|
|
printf(" In orders: $%s\n", synor_portfolio_get_in_orders(portfolio));
|
|
printf(" In positions: $%s\n", synor_portfolio_get_in_positions(portfolio));
|
|
printf(" Unrealized PnL: $%s\n", synor_portfolio_get_unrealized_pnl(portfolio));
|
|
synor_portfolio_free(portfolio);
|
|
}
|
|
|
|
// Get balances
|
|
synor_balance_list_t* balances = NULL;
|
|
err = synor_portfolio_get_balances(dex, &balances);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nBalances:\n");
|
|
for (size_t i = 0; i < synor_balance_list_count(balances); i++) {
|
|
synor_balance_t* balance = synor_balance_list_get(balances, i);
|
|
printf(" %s: %s (available: %s, in orders: %s)\n",
|
|
synor_balance_get_asset(balance),
|
|
synor_balance_get_total(balance),
|
|
synor_balance_get_available(balance),
|
|
synor_balance_get_in_orders(balance));
|
|
}
|
|
synor_balance_list_free(balances);
|
|
}
|
|
|
|
// Get trade statistics
|
|
synor_trade_stats_t* stats = NULL;
|
|
err = synor_portfolio_get_stats(dex, &stats);
|
|
if (err == SYNOR_OK) {
|
|
printf("\nTrade statistics:\n");
|
|
printf(" Total trades: %d\n", synor_trade_stats_get_total_trades(stats));
|
|
printf(" Win rate: %s%%\n", synor_trade_stats_get_win_rate(stats));
|
|
printf(" Avg profit: $%s\n", synor_trade_stats_get_avg_profit(stats));
|
|
printf(" Avg loss: $%s\n", synor_trade_stats_get_avg_loss(stats));
|
|
printf(" Best trade: $%s\n", synor_trade_stats_get_best_trade(stats));
|
|
printf(" Worst trade: $%s\n", synor_trade_stats_get_worst_trade(stats));
|
|
synor_trade_stats_free(stats);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
synor_error_t err;
|
|
|
|
// Initialize client
|
|
synor_dex_config_t config = {
|
|
.api_key = getenv("SYNOR_API_KEY") ? getenv("SYNOR_API_KEY") : "your-api-key",
|
|
.endpoint = "https://dex.synor.io/v1",
|
|
.timeout_ms = 30000,
|
|
.retries = 3,
|
|
.debug = false,
|
|
.default_market = "SYN-USDC"
|
|
};
|
|
|
|
synor_dex_t* dex = NULL;
|
|
err = synor_dex_init(&config, &dex);
|
|
if (err != SYNOR_OK) {
|
|
fprintf(stderr, "Failed to initialize DEX client: %s\n", synor_error_string(err));
|
|
return 1;
|
|
}
|
|
|
|
// Check service health
|
|
bool healthy;
|
|
err = synor_dex_health_check(dex, &healthy);
|
|
printf("Service healthy: %s\n\n", healthy ? "true" : "false");
|
|
|
|
// Run examples
|
|
markets_example(dex);
|
|
spot_trading_example(dex);
|
|
perps_trading_example(dex);
|
|
liquidity_example(dex);
|
|
orderbook_example(dex);
|
|
portfolio_example(dex);
|
|
|
|
// Cleanup
|
|
synor_dex_free(dex);
|
|
|
|
return 0;
|
|
}
|