feat(sdk): Add comprehensive examples for C, C++, C#, and Ruby SDKs

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
This commit is contained in:
Gulshan Yadav 2026-01-28 14:44:04 +05:30
parent e169c492aa
commit cf5130d9e4
19 changed files with 7091 additions and 0 deletions

View file

@ -0,0 +1,553 @@
/**
* Synor Compiler SDK Examples for C
*
* Demonstrates smart contract compilation and analysis:
* - WASM contract compilation and optimization
* - ABI extraction and encoding
* - Contract analysis and security scanning
* - Validation and verification
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <synor/compiler.h>
// Helper function to create a minimal valid WASM module for testing
void create_minimal_wasm(uint8_t** wasm, size_t* wasm_len) {
static const uint8_t minimal_wasm[] = {
0x00, 0x61, 0x73, 0x6d, // Magic: \0asm
0x01, 0x00, 0x00, 0x00, // Version: 1
// Type section
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
// Function section
0x03, 0x02, 0x01, 0x00,
// Export section
0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00,
// Code section
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
};
*wasm_len = sizeof(minimal_wasm);
*wasm = (uint8_t*)malloc(*wasm_len);
memcpy(*wasm, minimal_wasm, *wasm_len);
}
void compile_contract_example(synor_compiler_t* compiler) {
printf("=== Contract Compilation ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
synor_compile_options_t options = {
.optimization_level = SYNOR_OPTIMIZATION_SIZE,
.use_wasm_opt = true,
.validate = true,
.extract_metadata = true,
.generate_abi = true,
.strip_options = {
.strip_debug = true,
.strip_producers = true,
.strip_names = true,
.strip_custom = true,
.strip_unused = true
}
};
synor_compile_result_t* result = NULL;
err = synor_compile(compiler, wasm, wasm_len, &options, &result);
free(wasm);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to compile contract\n");
return;
}
printf("Compilation result:\n");
printf(" Contract ID: %s\n", synor_compile_result_get_contract_id(result));
printf(" Code hash: %s\n", synor_compile_result_get_code_hash(result));
printf(" Original size: %zu bytes\n", synor_compile_result_get_original_size(result));
printf(" Optimized size: %zu bytes\n", synor_compile_result_get_optimized_size(result));
printf(" Size reduction: %.1f%%\n", synor_compile_result_get_size_reduction(result));
printf(" Estimated deploy gas: %lu\n", synor_compile_result_get_estimated_deploy_gas(result));
// Get metadata if available
synor_contract_metadata_t* metadata = synor_compile_result_get_metadata(result);
if (metadata) {
printf("\nMetadata:\n");
printf(" Name: %s\n", synor_metadata_get_name(metadata));
printf(" Version: %s\n", synor_metadata_get_version(metadata));
printf(" SDK Version: %s\n", synor_metadata_get_sdk_version(metadata));
}
// Get ABI if available
synor_contract_abi_t* abi = synor_compile_result_get_abi(result);
if (abi) {
printf("\nABI:\n");
printf(" Functions: %zu\n", synor_abi_get_function_count(abi));
printf(" Events: %zu\n", synor_abi_get_event_count(abi));
printf(" Errors: %zu\n", synor_abi_get_error_count(abi));
}
synor_compile_result_free(result);
printf("\n");
}
void compilation_modes_example(synor_compiler_t* compiler) {
printf("=== Compilation Modes ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Development mode: fast compilation, debugging support
printf("Development mode:\n");
synor_compile_result_t* dev_result = NULL;
err = synor_contracts_compile_dev(compiler, wasm, wasm_len, &dev_result);
if (err == SYNOR_OK) {
printf(" Size: %zu bytes\n", synor_compile_result_get_optimized_size(dev_result));
printf(" Optimization: none\n");
}
// Production mode: maximum optimization
printf("\nProduction mode:\n");
synor_compile_result_t* prod_result = NULL;
err = synor_contracts_compile_production(compiler, wasm, wasm_len, &prod_result);
if (err == SYNOR_OK) {
printf(" Size: %zu bytes\n", synor_compile_result_get_optimized_size(prod_result));
printf(" Optimization: aggressive\n");
if (dev_result) {
printf(" Size savings: %zu bytes\n",
synor_compile_result_get_optimized_size(dev_result) -
synor_compile_result_get_optimized_size(prod_result));
}
synor_compile_result_free(prod_result);
}
if (dev_result) synor_compile_result_free(dev_result);
// Custom optimization levels
printf("\nOptimization levels:\n");
synor_optimization_level_t levels[] = {
SYNOR_OPTIMIZATION_NONE,
SYNOR_OPTIMIZATION_BASIC,
SYNOR_OPTIMIZATION_SIZE,
SYNOR_OPTIMIZATION_AGGRESSIVE
};
const char* level_names[] = {"NONE", "BASIC", "SIZE", "AGGRESSIVE"};
for (int i = 0; i < 4; i++) {
synor_compile_options_t options = {
.optimization_level = levels[i]
};
synor_compile_result_t* result = NULL;
err = synor_compile(compiler, wasm, wasm_len, &options, &result);
if (err == SYNOR_OK) {
printf(" %s: %zu bytes\n", level_names[i],
synor_compile_result_get_optimized_size(result));
synor_compile_result_free(result);
}
}
free(wasm);
printf("\n");
}
void abi_example(synor_compiler_t* compiler) {
printf("=== ABI Operations ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Extract ABI from WASM
synor_contract_abi_t* abi = NULL;
err = synor_abi_extract(compiler, wasm, wasm_len, &abi);
free(wasm);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to extract ABI\n");
return;
}
printf("Contract: %s\n", synor_abi_get_name(abi));
printf("Version: %s\n", synor_abi_get_version(abi));
// List functions
size_t func_count = synor_abi_get_function_count(abi);
if (func_count > 0) {
printf("\nFunctions:\n");
for (size_t i = 0; i < func_count; i++) {
synor_abi_function_t* func = synor_abi_get_function(abi, i);
char inputs[256] = "";
size_t input_count = synor_abi_function_get_input_count(func);
for (size_t j = 0; j < input_count; j++) {
synor_abi_param_t* param = synor_abi_function_get_input(func, j);
char temp[64];
snprintf(temp, sizeof(temp), "%s: %s%s",
synor_abi_param_get_name(param),
synor_abi_param_get_type_name(param),
j < input_count - 1 ? ", " : "");
strncat(inputs, temp, sizeof(inputs) - strlen(inputs) - 1);
}
char outputs[128] = "void";
size_t output_count = synor_abi_function_get_output_count(func);
if (output_count > 0) {
outputs[0] = '\0';
for (size_t j = 0; j < output_count; j++) {
synor_abi_param_t* param = synor_abi_function_get_output(func, j);
char temp[64];
snprintf(temp, sizeof(temp), "%s%s",
synor_abi_param_get_type_name(param),
j < output_count - 1 ? ", " : "");
strncat(outputs, temp, sizeof(outputs) - strlen(outputs) - 1);
}
}
char modifiers[32] = "";
if (synor_abi_function_is_view(func)) strcat(modifiers, "view ");
if (synor_abi_function_is_payable(func)) strcat(modifiers, "payable");
printf(" %s(%s) -> %s %s\n",
synor_abi_function_get_name(func), inputs, outputs, modifiers);
printf(" Selector: %s\n", synor_abi_function_get_selector(func));
}
}
// List events
size_t event_count = synor_abi_get_event_count(abi);
if (event_count > 0) {
printf("\nEvents:\n");
for (size_t i = 0; i < event_count; i++) {
synor_abi_event_t* event = synor_abi_get_event(abi, i);
char params[256] = "";
size_t param_count = synor_abi_event_get_param_count(event);
for (size_t j = 0; j < param_count; j++) {
synor_abi_event_param_t* param = synor_abi_event_get_param(event, j);
char temp[64];
snprintf(temp, sizeof(temp), "%s%s: %s%s",
synor_abi_event_param_is_indexed(param) ? "indexed " : "",
synor_abi_event_param_get_name(param),
synor_abi_event_param_get_type_name(param),
j < param_count - 1 ? ", " : "");
strncat(params, temp, sizeof(params) - strlen(params) - 1);
}
printf(" %s(%s)\n", synor_abi_event_get_name(event), params);
printf(" Topic: %s\n", synor_abi_event_get_topic(event));
}
}
// Encode a function call
if (func_count > 0) {
synor_abi_function_t* func = synor_abi_get_function(abi, 0);
const char* args[] = {"arg1", "arg2"};
uint8_t* encoded;
size_t encoded_len;
err = synor_abi_encode_call(compiler, func, args, 2, &encoded, &encoded_len);
if (err == SYNOR_OK) {
printf("\nEncoded call to %s: ", synor_abi_function_get_name(func));
for (size_t i = 0; i < encoded_len && i < 20; i++) {
printf("%02x", encoded[i]);
}
printf("...\n");
// Decode a result
char** decoded;
size_t decoded_count;
err = synor_abi_decode_result(compiler, func, encoded, encoded_len,
&decoded, &decoded_count);
if (err == SYNOR_OK) {
printf("Decoded result: ");
for (size_t i = 0; i < decoded_count; i++) {
printf("%s%s", decoded[i], i < decoded_count - 1 ? ", " : "");
}
printf("\n");
synor_string_array_free(decoded, decoded_count);
}
free(encoded);
}
}
synor_abi_free(abi);
printf("\n");
}
void analysis_example(synor_compiler_t* compiler) {
printf("=== Contract Analysis ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Full analysis
synor_contract_analysis_t* analysis = NULL;
err = synor_analysis_analyze(compiler, wasm, wasm_len, &analysis);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to analyze contract\n");
free(wasm);
return;
}
// Size breakdown
synor_size_breakdown_t* size = synor_analysis_get_size_breakdown(analysis);
if (size) {
printf("Size breakdown:\n");
printf(" Code: %zu bytes\n", synor_size_breakdown_get_code(size));
printf(" Data: %zu bytes\n", synor_size_breakdown_get_data(size));
printf(" Functions: %zu bytes\n", synor_size_breakdown_get_functions(size));
printf(" Memory: %zu bytes\n", synor_size_breakdown_get_memory(size));
printf(" Exports: %zu bytes\n", synor_size_breakdown_get_exports(size));
printf(" Imports: %zu bytes\n", synor_size_breakdown_get_imports(size));
printf(" Total: %zu bytes\n", synor_size_breakdown_get_total(size));
}
// Function analysis
size_t func_count = synor_analysis_get_function_count(analysis);
if (func_count > 0) {
printf("\nFunction analysis:\n");
for (size_t i = 0; i < 5 && i < func_count; i++) {
synor_function_analysis_t* func = synor_analysis_get_function(analysis, i);
printf(" %s:\n", synor_function_analysis_get_name(func));
printf(" Size: %zu bytes\n", synor_function_analysis_get_size(func));
printf(" Instructions: %zu\n", synor_function_analysis_get_instruction_count(func));
printf(" Locals: %zu\n", synor_function_analysis_get_local_count(func));
printf(" Exported: %s\n", synor_function_analysis_is_exported(func) ? "true" : "false");
printf(" Estimated gas: %lu\n", synor_function_analysis_get_estimated_gas(func));
}
}
// Import analysis
size_t import_count = synor_analysis_get_import_count(analysis);
if (import_count > 0) {
printf("\nImports:\n");
for (size_t i = 0; i < import_count; i++) {
synor_import_analysis_t* imp = synor_analysis_get_import(analysis, i);
printf(" %s.%s (%s)\n",
synor_import_analysis_get_module(imp),
synor_import_analysis_get_name(imp),
synor_import_analysis_get_kind(imp));
}
}
// Gas analysis
synor_gas_analysis_t* gas = synor_analysis_get_gas_analysis(analysis);
if (gas) {
printf("\nGas analysis:\n");
printf(" Deployment: %lu\n", synor_gas_analysis_get_deployment_gas(gas));
printf(" Memory init: %lu\n", synor_gas_analysis_get_memory_init_gas(gas));
printf(" Data section: %lu\n", synor_gas_analysis_get_data_section_gas(gas));
}
synor_analysis_free(analysis);
// Extract metadata
synor_contract_metadata_t* metadata = NULL;
err = synor_analysis_extract_metadata(compiler, wasm, wasm_len, &metadata);
if (err == SYNOR_OK) {
printf("\nContract metadata:\n");
printf(" Name: %s\n", synor_metadata_get_name(metadata));
printf(" Version: %s\n", synor_metadata_get_version(metadata));
printf(" Build timestamp: %s\n", synor_metadata_get_build_timestamp(metadata));
synor_metadata_free(metadata);
}
// Estimate deployment gas
uint64_t gas_estimate;
err = synor_analysis_estimate_deploy_gas(compiler, wasm, wasm_len, &gas_estimate);
if (err == SYNOR_OK) {
printf("\nEstimated deployment gas: %lu\n", gas_estimate);
}
free(wasm);
printf("\n");
}
void validation_example(synor_compiler_t* compiler) {
printf("=== Contract Validation ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Full validation
synor_validation_result_t* result = NULL;
err = synor_validation_validate(compiler, wasm, wasm_len, &result);
if (err == SYNOR_OK) {
printf("Valid: %s\n", synor_validation_result_is_valid(result) ? "true" : "false");
printf("Exports: %zu\n", synor_validation_result_get_export_count(result));
printf("Imports: %zu\n", synor_validation_result_get_import_count(result));
printf("Functions: %zu\n", synor_validation_result_get_function_count(result));
printf("Memory pages: %zu\n", synor_validation_result_get_memory_pages(result));
// Print errors
size_t error_count = synor_validation_result_get_error_count(result);
if (error_count > 0) {
printf("\nValidation errors:\n");
for (size_t i = 0; i < error_count; i++) {
synor_validation_error_t* error = synor_validation_result_get_error(result, i);
printf(" [%s] %s\n",
synor_validation_error_get_code(error),
synor_validation_error_get_message(error));
const char* location = synor_validation_error_get_location(error);
if (location) {
printf(" at %s\n", location);
}
}
}
// Print warnings
size_t warning_count = synor_validation_result_get_warning_count(result);
if (warning_count > 0) {
printf("\nWarnings:\n");
for (size_t i = 0; i < warning_count; i++) {
printf(" %s\n", synor_validation_result_get_warning(result, i));
}
}
synor_validation_result_free(result);
}
// Quick validation
bool is_valid;
err = synor_validation_is_valid(compiler, wasm, wasm_len, &is_valid);
printf("\nQuick validation: %s\n", is_valid ? "true" : "false");
// Get validation errors only
synor_validation_error_list_t* errors = NULL;
err = synor_validation_get_errors(compiler, wasm, wasm_len, &errors);
if (err == SYNOR_OK) {
printf("Error count: %zu\n", synor_validation_error_list_count(errors));
synor_validation_error_list_free(errors);
}
// Validate required exports
const char* required[] = {"init", "execute", "query"};
bool has_required;
err = synor_validation_validate_exports(compiler, wasm, wasm_len,
required, 3, &has_required);
printf("Has required exports: %s\n", has_required ? "true" : "false");
// Validate memory constraints
bool memory_valid;
err = synor_validation_validate_memory(compiler, wasm, wasm_len, 16, &memory_valid);
printf("Memory within 16 pages: %s\n", memory_valid ? "true" : "false");
free(wasm);
printf("\n");
}
void security_example(synor_compiler_t* compiler) {
printf("=== Security Scanning ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
synor_security_scan_result_t* security = NULL;
err = synor_analysis_security_scan(compiler, wasm, wasm_len, &security);
free(wasm);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to scan contract\n");
return;
}
printf("Security score: %d/100\n", synor_security_scan_get_score(security));
size_t issue_count = synor_security_scan_get_issue_count(security);
if (issue_count > 0) {
printf("\nSecurity issues:\n");
for (size_t i = 0; i < issue_count; i++) {
synor_security_issue_t* issue = synor_security_scan_get_issue(security, i);
const char* severity = synor_security_issue_get_severity(issue);
const char* icon;
if (strcmp(severity, "critical") == 0) icon = "[CRIT]";
else if (strcmp(severity, "high") == 0) icon = "[HIGH]";
else if (strcmp(severity, "medium") == 0) icon = "[MED]";
else if (strcmp(severity, "low") == 0) icon = "[LOW]";
else icon = "[???]";
printf("%s [%s] %s\n", icon,
synor_security_issue_get_severity(issue),
synor_security_issue_get_type(issue));
printf(" %s\n", synor_security_issue_get_description(issue));
const char* location = synor_security_issue_get_location(issue);
if (location) {
printf(" at %s\n", location);
}
}
} else {
printf("No security issues found!\n");
}
size_t rec_count = synor_security_scan_get_recommendation_count(security);
if (rec_count > 0) {
printf("\nRecommendations:\n");
for (size_t i = 0; i < rec_count; i++) {
printf(" • %s\n", synor_security_scan_get_recommendation(security, i));
}
}
synor_security_scan_result_free(security);
printf("\n");
}
int main(int argc, char** argv) {
synor_error_t err;
// Initialize client
synor_compiler_config_t config = {
.api_key = getenv("SYNOR_API_KEY") ? getenv("SYNOR_API_KEY") : "your-api-key",
.endpoint = "https://compiler.synor.io/v1",
.timeout_ms = 60000,
.retries = 3,
.debug = false,
.default_optimization_level = SYNOR_OPTIMIZATION_SIZE,
.max_contract_size = 256 * 1024,
.use_wasm_opt = true,
.validate = true,
.extract_metadata = true,
.generate_abi = true
};
synor_compiler_t* compiler = NULL;
err = synor_compiler_init(&config, &compiler);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to initialize compiler client: %s\n", synor_error_string(err));
return 1;
}
// Check service health
bool healthy;
err = synor_compiler_health_check(compiler, &healthy);
printf("Service healthy: %s\n\n", healthy ? "true" : "false");
// Run examples
compile_contract_example(compiler);
compilation_modes_example(compiler);
abi_example(compiler);
analysis_example(compiler);
validation_example(compiler);
security_example(compiler);
// Cleanup
synor_compiler_free(compiler);
return 0;
}

View file

@ -0,0 +1,489 @@
/**
* 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;
}

View file

@ -0,0 +1,545 @@
/**
* Synor IBC SDK Examples for C
*
* Demonstrates Inter-Blockchain Communication operations:
* - Cross-chain transfers and messages
* - Channel lifecycle management
* - Packet handling and acknowledgments
* - Relayer operations
* - Connection monitoring
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <synor/ibc.h>
void chains_example(synor_ibc_t* ibc) {
printf("=== Chain Discovery ===\n");
synor_error_t err;
// Get all connected chains
synor_chain_list_t* chains = NULL;
err = synor_chains_list(ibc, &chains);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to get chains\n");
return;
}
printf("Connected chains: %zu\n", synor_chain_list_count(chains));
for (size_t i = 0; i < 5 && i < synor_chain_list_count(chains); i++) {
synor_chain_t* chain = synor_chain_list_get(chains, i);
printf("\n %s:\n", synor_chain_get_id(chain));
printf(" Name: %s\n", synor_chain_get_name(chain));
printf(" Type: %s\n", synor_chain_get_type(chain));
printf(" Status: %s\n", synor_chain_get_status(chain));
printf(" Block height: %lu\n", synor_chain_get_latest_height(chain));
printf(" Light client: %s\n", synor_chain_get_light_client(chain));
}
synor_chain_list_free(chains);
// Get specific chain info
synor_chain_t* synor_chain = NULL;
err = synor_chains_get(ibc, "synor-mainnet-1", &synor_chain);
if (err == SYNOR_OK) {
printf("\nSynor chain details:\n");
printf(" Bech32 prefix: %s\n", synor_chain_get_bech32_prefix(synor_chain));
printf(" Gas price: %s\n", synor_chain_get_gas_price(synor_chain));
char** features;
size_t feature_count;
synor_chain_get_features(synor_chain, &features, &feature_count);
printf(" Supported features: ");
for (size_t i = 0; i < feature_count; i++) {
printf("%s%s", features[i], i < feature_count - 1 ? ", " : "");
}
printf("\n");
synor_string_array_free(features, feature_count);
synor_chain_free(synor_chain);
}
// Get chain connections
synor_connection_list_t* connections = NULL;
err = synor_chains_get_connections(ibc, "synor-mainnet-1", &connections);
if (err == SYNOR_OK) {
printf("\nChain connections: %zu\n", synor_connection_list_count(connections));
for (size_t i = 0; i < 3 && i < synor_connection_list_count(connections); i++) {
synor_connection_t* conn = synor_connection_list_get(connections, i);
printf(" %s -> %s\n",
synor_connection_get_id(conn),
synor_connection_get_counterparty_chain_id(conn));
}
synor_connection_list_free(connections);
}
printf("\n");
}
void channels_example(synor_ibc_t* ibc) {
printf("=== Channel Management ===\n");
synor_error_t err;
// List existing channels
synor_channel_list_t* channels = NULL;
err = synor_channels_list(ibc, &channels);
if (err == SYNOR_OK) {
printf("Active channels: %zu\n", synor_channel_list_count(channels));
for (size_t i = 0; i < 3 && i < synor_channel_list_count(channels); i++) {
synor_channel_t* channel = synor_channel_list_get(channels, i);
printf("\n Channel %s:\n", synor_channel_get_id(channel));
printf(" Port: %s\n", synor_channel_get_port_id(channel));
printf(" State: %s\n", synor_channel_get_state(channel));
printf(" Order: %s\n", synor_channel_get_ordering(channel));
printf(" Counterparty: %s on %s\n",
synor_channel_get_counterparty_channel_id(channel),
synor_channel_get_counterparty_chain_id(channel));
printf(" Version: %s\n", synor_channel_get_version(channel));
}
synor_channel_list_free(channels);
}
// Create a new channel (4-step handshake)
printf("\nInitiating channel creation...\n");
// Step 1: ChanOpenInit
synor_channel_init_request_t init_req = {
.port_id = "transfer",
.counterparty_chain_id = "cosmos-hub-4",
.counterparty_port_id = "transfer",
.version = "ics20-1",
.ordering = SYNOR_CHANNEL_ORDERING_UNORDERED
};
synor_channel_init_result_t* init_result = NULL;
err = synor_channels_open_init(ibc, &init_req, &init_result);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to init channel\n");
return;
}
printf("Channel init:\n");
printf(" Channel ID: %s\n", synor_channel_init_result_get_id(init_result));
printf(" State: %s\n", synor_channel_init_result_get_state(init_result));
printf(" TX hash: %s\n", synor_channel_init_result_get_tx_hash(init_result));
// Step 2: Wait for ChanOpenTry (counterparty)
printf("\nWaiting for counterparty ChanOpenTry...\n");
synor_channel_state_t try_state;
err = synor_channels_wait_for_state(ibc, synor_channel_init_result_get_id(init_result),
SYNOR_CHANNEL_STATE_TRYOPEN, 300, &try_state);
printf("Channel state: %d\n", try_state);
// Step 3: ChanOpenAck
printf("\nSending ChanOpenAck...\n");
synor_channel_ack_request_t ack_req = {
.channel_id = synor_channel_init_result_get_id(init_result),
.counterparty_channel_id = "channel-0",
.counterparty_version = "ics20-1"
};
synor_channel_ack_result_t* ack_result = NULL;
err = synor_channels_open_ack(ibc, &ack_req, &ack_result);
if (err == SYNOR_OK) {
printf("Ack TX: %s\n", synor_channel_ack_result_get_tx_hash(ack_result));
synor_channel_ack_result_free(ack_result);
}
// Step 4: Wait for ChanOpenConfirm (counterparty)
printf("\nWaiting for channel to open...\n");
synor_channel_state_t open_state;
err = synor_channels_wait_for_state(ibc, synor_channel_init_result_get_id(init_result),
SYNOR_CHANNEL_STATE_OPEN, 300, &open_state);
printf("Channel is now: %d\n", open_state);
// Get channel details
synor_channel_t* channel = NULL;
err = synor_channels_get(ibc, synor_channel_init_result_get_id(init_result), &channel);
if (err == SYNOR_OK) {
printf("\nChannel details:\n");
printf(" Sequences - Send: %lu, Recv: %lu, Ack: %lu\n",
synor_channel_get_next_sequence_send(channel),
synor_channel_get_next_sequence_recv(channel),
synor_channel_get_next_sequence_ack(channel));
synor_channel_free(channel);
}
synor_channel_init_result_free(init_result);
printf("\n");
}
void transfer_example(synor_ibc_t* ibc) {
printf("=== Cross-Chain Transfers ===\n");
synor_error_t err;
// Get supported tokens for transfer
synor_transferable_token_list_t* tokens = NULL;
err = synor_transfers_get_supported_tokens(ibc, "cosmos-hub-4", &tokens);
if (err == SYNOR_OK) {
printf("Transferable tokens to Cosmos Hub:\n");
for (size_t i = 0; i < 5 && i < synor_transferable_token_list_count(tokens); i++) {
synor_transferable_token_t* token = synor_transferable_token_list_get(tokens, i);
printf(" %s (%s)\n",
synor_transferable_token_get_symbol(token),
synor_transferable_token_get_denom(token));
}
synor_transferable_token_list_free(tokens);
}
// Initiate a cross-chain transfer
printf("\nInitiating transfer...\n");
synor_transfer_request_t transfer_req = {
.source_channel = "channel-0",
.denom = "usynor",
.amount = "1000000",
.receiver = "cosmos1...",
.timeout_height = 0, // Use timestamp instead
.timeout_timestamp = (uint64_t)(time(NULL) + 600) * 1000000000ULL,
.memo = "IBC transfer from Synor"
};
synor_transfer_result_t* transfer = NULL;
err = synor_transfers_send(ibc, &transfer_req, &transfer);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to send transfer\n");
return;
}
printf("Transfer initiated:\n");
printf(" TX hash: %s\n", synor_transfer_result_get_tx_hash(transfer));
printf(" Sequence: %lu\n", synor_transfer_result_get_sequence(transfer));
printf(" Packet ID: %s\n", synor_transfer_result_get_packet_id(transfer));
printf(" Status: %s\n", synor_transfer_result_get_status(transfer));
// Track transfer progress
printf("\nTracking transfer...\n");
synor_transfer_status_t* status = NULL;
err = synor_transfers_track(ibc, synor_transfer_result_get_packet_id(transfer), &status);
if (err == SYNOR_OK) {
printf("Current status: %s\n", synor_transfer_status_get_state(status));
printf("Source TX: %s\n", synor_transfer_status_get_source_tx_hash(status));
const char* dest_tx = synor_transfer_status_get_dest_tx_hash(status);
if (dest_tx) {
printf("Dest TX: %s\n", dest_tx);
}
synor_transfer_status_free(status);
}
// Wait for completion
printf("\nWaiting for transfer completion...\n");
synor_transfer_status_t* final_status = NULL;
err = synor_transfers_wait_for_completion(ibc, synor_transfer_result_get_packet_id(transfer),
600, &final_status);
if (err == SYNOR_OK) {
printf("Transfer completed:\n");
printf(" Final status: %s\n", synor_transfer_status_get_state(final_status));
printf(" Acknowledgment: %s\n", synor_transfer_status_get_acknowledgment(final_status));
synor_transfer_status_free(final_status);
}
// Get transfer history
synor_transfer_list_t* history = NULL;
err = synor_transfers_get_history(ibc, 10, &history);
if (err == SYNOR_OK) {
printf("\nRecent transfers: %zu\n", synor_transfer_list_count(history));
for (size_t i = 0; i < 3 && i < synor_transfer_list_count(history); i++) {
synor_transfer_t* t = synor_transfer_list_get(history, i);
printf(" %s %s -> %s (%s)\n",
synor_transfer_get_amount(t),
synor_transfer_get_denom(t),
synor_transfer_get_dest_chain(t),
synor_transfer_get_status(t));
}
synor_transfer_list_free(history);
}
synor_transfer_result_free(transfer);
printf("\n");
}
void packet_example(synor_ibc_t* ibc) {
printf("=== Packet Operations ===\n");
synor_error_t err;
// List pending packets
synor_packet_list_t* pending = NULL;
err = synor_packets_list_pending(ibc, "channel-0", &pending);
if (err == SYNOR_OK) {
printf("Pending packets on channel-0: %zu\n", synor_packet_list_count(pending));
for (size_t i = 0; i < 3 && i < synor_packet_list_count(pending); i++) {
synor_packet_t* packet = synor_packet_list_get(pending, i);
printf("\n Packet #%lu:\n", synor_packet_get_sequence(packet));
printf(" Source: %s/%s\n",
synor_packet_get_source_port(packet),
synor_packet_get_source_channel(packet));
printf(" Dest: %s/%s\n",
synor_packet_get_dest_port(packet),
synor_packet_get_dest_channel(packet));
printf(" State: %s\n", synor_packet_get_state(packet));
printf(" Timeout: %lu\n", synor_packet_get_timeout_timestamp(packet));
}
synor_packet_list_free(pending);
}
// Get specific packet
synor_packet_t* packet = NULL;
err = synor_packets_get(ibc, "channel-0", 1, &packet);
if (err == SYNOR_OK) {
printf("\nPacket details:\n");
const char* data_hex = synor_packet_get_data_hex(packet);
printf(" Data (hex): %.40s...\n", data_hex);
printf(" Created: %s\n", synor_packet_get_created_at(packet));
synor_packet_free(packet);
}
// Get packet commitment proof
synor_packet_proof_t* proof = NULL;
err = synor_packets_get_commitment_proof(ibc, "channel-0", 1, &proof);
if (err == SYNOR_OK) {
printf("\nCommitment proof:\n");
printf(" Height: %lu\n", synor_packet_proof_get_height(proof));
printf(" Proof size: %zu bytes\n", synor_packet_proof_get_size(proof));
synor_packet_proof_free(proof);
}
// Get acknowledgment
synor_packet_ack_t* ack = NULL;
err = synor_packets_get_acknowledgment(ibc, "channel-0", 1, &ack);
if (err == SYNOR_OK) {
printf("\nAcknowledgment:\n");
printf(" Result: %s\n", synor_packet_ack_is_success(ack) ? "Success" :
synor_packet_ack_get_error(ack));
printf(" TX hash: %s\n", synor_packet_ack_get_tx_hash(ack));
synor_packet_ack_free(ack);
}
// List timed-out packets
synor_packet_list_t* timed_out = NULL;
err = synor_packets_list_timed_out(ibc, &timed_out);
if (err == SYNOR_OK) {
printf("\nTimed-out packets: %zu\n", synor_packet_list_count(timed_out));
// Timeout a packet manually
if (synor_packet_list_count(timed_out) > 0) {
synor_packet_t* to_timeout = synor_packet_list_get(timed_out, 0);
printf("\nProcessing timeout for packet #%lu\n", synor_packet_get_sequence(to_timeout));
synor_timeout_result_t* timeout = NULL;
err = synor_packets_timeout(ibc, synor_packet_get_source_channel(to_timeout),
synor_packet_get_sequence(to_timeout), &timeout);
if (err == SYNOR_OK) {
printf("Timeout TX: %s\n", synor_timeout_result_get_tx_hash(timeout));
synor_timeout_result_free(timeout);
}
}
synor_packet_list_free(timed_out);
}
printf("\n");
}
void relayer_example(synor_ibc_t* ibc) {
printf("=== Relayer Operations ===\n");
synor_error_t err;
// Get relayer status
synor_relayer_status_t* status = NULL;
err = synor_relayer_get_status(ibc, &status);
if (err == SYNOR_OK) {
printf("Relayer status:\n");
printf(" Running: %s\n", synor_relayer_status_is_running(status) ? "true" : "false");
printf(" Uptime: %s\n", synor_relayer_status_get_uptime(status));
printf(" Packets relayed: %lu\n", synor_relayer_status_get_packets_relayed(status));
printf(" Errors: %lu\n", synor_relayer_status_get_error_count(status));
synor_relayer_status_free(status);
}
// List active paths
synor_relay_path_list_t* paths = NULL;
err = synor_relayer_list_paths(ibc, &paths);
if (err == SYNOR_OK) {
printf("\nActive relay paths: %zu\n", synor_relay_path_list_count(paths));
for (size_t i = 0; i < synor_relay_path_list_count(paths); i++) {
synor_relay_path_t* path = synor_relay_path_list_get(paths, i);
printf("\n %s:\n", synor_relay_path_get_id(path));
printf(" %s <-> %s\n",
synor_relay_path_get_source_chain(path),
synor_relay_path_get_dest_chain(path));
printf(" Channel: %s <-> %s\n",
synor_relay_path_get_source_channel(path),
synor_relay_path_get_dest_channel(path));
printf(" Status: %s\n", synor_relay_path_get_status(path));
printf(" Pending packets: %zu\n", synor_relay_path_get_pending_packets(path));
}
synor_relay_path_list_free(paths);
}
// Configure a new path
printf("\nConfiguring new relay path...\n");
const char* filter_denoms[] = {"usynor", "uosmo"};
synor_path_config_t path_config = {
.source_chain = "synor-mainnet-1",
.dest_chain = "osmosis-1",
.source_channel = "channel-1",
.dest_channel = "channel-100",
.filter_denoms = filter_denoms,
.filter_denoms_count = 2,
.min_relay_amount = "1000",
.max_relay_amount = "1000000000"
};
synor_relay_path_t* new_path = NULL;
err = synor_relayer_add_path(ibc, &path_config, &new_path);
if (err == SYNOR_OK) {
printf("Path created: %s\n", synor_relay_path_get_id(new_path));
// Start relaying on path
printf("\nStarting relayer on path...\n");
err = synor_relayer_start_path(ibc, synor_relay_path_get_id(new_path));
if (err == SYNOR_OK) {
printf("Relayer started\n");
}
// Manually relay pending packets
printf("\nRelaying pending packets...\n");
synor_relay_result_t* relay_result = NULL;
err = synor_relayer_relay_pending(ibc, synor_relay_path_get_id(new_path), &relay_result);
if (err == SYNOR_OK) {
printf("Relayed %zu packets\n", synor_relay_result_get_packet_count(relay_result));
printf("TX hashes: %zu\n", synor_relay_result_get_tx_hash_count(relay_result));
synor_relay_result_free(relay_result);
}
// Get relay history
synor_relay_event_list_t* history = NULL;
err = synor_relayer_get_history(ibc, synor_relay_path_get_id(new_path), 10, &history);
if (err == SYNOR_OK) {
printf("\nRelay history:\n");
for (size_t i = 0; i < 3 && i < synor_relay_event_list_count(history); i++) {
synor_relay_event_t* event = synor_relay_event_list_get(history, i);
printf(" %s: %s - %zu packets\n",
synor_relay_event_get_timestamp(event),
synor_relay_event_get_type(event),
synor_relay_event_get_packet_count(event));
}
synor_relay_event_list_free(history);
}
synor_relay_path_free(new_path);
}
printf("\n");
}
void monitoring_example(synor_ibc_t* ibc) {
printf("=== IBC Monitoring ===\n");
synor_error_t err;
// Get IBC metrics
synor_ibc_metrics_t* metrics = NULL;
err = synor_monitoring_get_metrics(ibc, &metrics);
if (err == SYNOR_OK) {
printf("IBC metrics:\n");
printf(" Total channels: %lu\n", synor_ibc_metrics_get_total_channels(metrics));
printf(" Active channels: %lu\n", synor_ibc_metrics_get_active_channels(metrics));
printf(" Total packets: %lu\n", synor_ibc_metrics_get_total_packets(metrics));
printf(" Pending packets: %lu\n", synor_ibc_metrics_get_pending_packets(metrics));
printf(" Failed packets: %lu\n", synor_ibc_metrics_get_failed_packets(metrics));
printf(" Avg relay time: %lums\n", synor_ibc_metrics_get_avg_relay_time(metrics));
synor_ibc_metrics_free(metrics);
}
// Get chain health
synor_chain_health_list_t* chain_health = NULL;
err = synor_monitoring_get_chain_health(ibc, &chain_health);
if (err == SYNOR_OK) {
printf("\nChain health:\n");
for (size_t i = 0; i < 3 && i < synor_chain_health_list_count(chain_health); i++) {
synor_chain_health_t* health = synor_chain_health_list_get(chain_health, i);
printf(" %s:\n", synor_chain_health_get_chain_id(health));
printf(" Status: %s\n", synor_chain_health_get_status(health));
printf(" Block lag: %lu\n", synor_chain_health_get_block_lag(health));
printf(" Last update: %s\n", synor_chain_health_get_last_update(health));
}
synor_chain_health_list_free(chain_health);
}
// Get channel statistics
synor_channel_stats_t* stats = NULL;
err = synor_monitoring_get_channel_stats(ibc, "channel-0", &stats);
if (err == SYNOR_OK) {
printf("\nChannel-0 statistics:\n");
printf(" Packets sent: %lu\n", synor_channel_stats_get_packets_sent(stats));
printf(" Packets received: %lu\n", synor_channel_stats_get_packets_received(stats));
printf(" Success rate: %s%%\n", synor_channel_stats_get_success_rate(stats));
printf(" Avg confirmation time: %lums\n", synor_channel_stats_get_avg_confirmation_time(stats));
synor_channel_stats_free(stats);
}
// Get alerts
synor_ibc_alert_list_t* alerts = NULL;
err = synor_monitoring_get_alerts(ibc, &alerts);
if (err == SYNOR_OK) {
printf("\nActive alerts: %zu\n", synor_ibc_alert_list_count(alerts));
for (size_t i = 0; i < synor_ibc_alert_list_count(alerts); i++) {
synor_ibc_alert_t* alert = synor_ibc_alert_list_get(alerts, i);
printf(" [%s] %s\n",
synor_ibc_alert_get_severity(alert),
synor_ibc_alert_get_message(alert));
}
synor_ibc_alert_list_free(alerts);
}
printf("\n");
}
int main(int argc, char** argv) {
synor_error_t err;
// Initialize client
synor_ibc_config_t config = {
.api_key = getenv("SYNOR_API_KEY") ? getenv("SYNOR_API_KEY") : "your-api-key",
.endpoint = "https://ibc.synor.io/v1",
.timeout_ms = 30000,
.retries = 3,
.debug = false,
.default_chain = "synor-mainnet-1",
.confirmations = 1
};
synor_ibc_t* ibc = NULL;
err = synor_ibc_init(&config, &ibc);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to initialize IBC client: %s\n", synor_error_string(err));
return 1;
}
// Check service health
bool healthy;
err = synor_ibc_health_check(ibc, &healthy);
printf("Service healthy: %s\n\n", healthy ? "true" : "false");
// Run examples
chains_example(ibc);
channels_example(ibc);
transfer_example(ibc);
packet_example(ibc);
relayer_example(ibc);
monitoring_example(ibc);
// Cleanup
synor_ibc_free(ibc);
return 0;
}

495
sdk/c/examples/zk_example.c Normal file
View file

@ -0,0 +1,495 @@
/**
* Synor ZK SDK Examples for C
*
* Demonstrates zero-knowledge proof operations:
* - Circuit compilation (Circom)
* - Proof generation and verification
* - Multiple proving systems (Groth16, PLONK, STARK)
* - Recursive proof composition
* - Trusted setup ceremonies
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <synor/zk.h>
void circuit_example(synor_zk_t* zk) {
printf("=== Circuit Compilation ===\n");
synor_error_t err;
// Simple Circom circuit: prove knowledge of factors
const char* circom_code =
"pragma circom 2.1.0;\n"
"\n"
"template Multiplier() {\n"
" signal input a;\n"
" signal input b;\n"
" signal output c;\n"
"\n"
" c <== a * b;\n"
"}\n"
"\n"
"component main = Multiplier();\n";
// Compile the circuit
printf("Compiling circuit...\n");
synor_circuit_source_t source = {
.code = circom_code,
.language = SYNOR_CIRCUIT_LANGUAGE_CIRCOM
};
synor_circuit_t* circuit = NULL;
err = synor_circuits_compile(zk, &source, &circuit);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to compile circuit\n");
return;
}
printf("Circuit compiled:\n");
printf(" Circuit ID: %s\n", synor_circuit_get_id(circuit));
printf(" Constraints: %zu\n", synor_circuit_get_constraints(circuit));
printf(" Public inputs: %zu\n", synor_circuit_get_public_inputs(circuit));
printf(" Private inputs: %zu\n", synor_circuit_get_private_inputs(circuit));
printf(" Outputs: %zu\n", synor_circuit_get_outputs(circuit));
// Get circuit info
synor_circuit_info_t* info = NULL;
err = synor_circuits_get(zk, synor_circuit_get_id(circuit), &info);
if (err == SYNOR_OK) {
printf("\nCircuit info:\n");
printf(" Name: %s\n", synor_circuit_info_get_name(info));
printf(" Version: %s\n", synor_circuit_info_get_version(info));
printf(" Wires: %zu\n", synor_circuit_info_get_wire_count(info));
printf(" Labels: %zu\n", synor_circuit_info_get_label_count(info));
synor_circuit_info_free(info);
}
// List available circuits
synor_circuit_list_t* circuits = NULL;
err = synor_circuits_list(zk, &circuits);
if (err == SYNOR_OK) {
printf("\nAvailable circuits: %zu\n", synor_circuit_list_count(circuits));
for (size_t i = 0; i < 3 && i < synor_circuit_list_count(circuits); i++) {
synor_circuit_t* c = synor_circuit_list_get(circuits, i);
printf(" %s: %s (%zu constraints)\n",
synor_circuit_get_id(c),
synor_circuit_get_name(c),
synor_circuit_get_constraints(c));
}
synor_circuit_list_free(circuits);
}
synor_circuit_free(circuit);
printf("\n");
}
void groth16_example(synor_zk_t* zk) {
printf("=== Groth16 Proving System ===\n");
synor_error_t err;
const char* circuit_id = "multiplier-v1";
// Generate proving/verification keys (trusted setup)
printf("Generating keys...\n");
synor_groth16_keys_t* keys = NULL;
err = synor_groth16_setup(zk, circuit_id, &keys);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to generate keys\n");
return;
}
printf("Keys generated:\n");
printf(" Proving key size: %zu bytes\n", synor_groth16_keys_get_pk_size(keys));
printf(" Verification key size: %zu bytes\n", synor_groth16_keys_get_vk_size(keys));
// Prepare witness (private inputs)
synor_witness_t* witness = synor_witness_create();
synor_witness_set(witness, "a", "3");
synor_witness_set(witness, "b", "7");
// Generate proof
printf("\nGenerating proof...\n");
synor_prove_request_t prove_req = {
.circuit_id = circuit_id,
.witness = witness,
.proving_key = synor_groth16_keys_get_pk(keys),
.proving_key_len = synor_groth16_keys_get_pk_size(keys)
};
synor_proof_t* proof = NULL;
err = synor_groth16_prove(zk, &prove_req, &proof);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to generate proof\n");
synor_witness_free(witness);
synor_groth16_keys_free(keys);
return;
}
printf("Proof generated:\n");
printf(" Proof size: %zu bytes\n", synor_proof_get_size(proof));
printf(" Public signals: %zu\n", synor_proof_get_public_signal_count(proof));
printf(" Proving time: %lums\n", synor_proof_get_proving_time_ms(proof));
// Verify proof
printf("\nVerifying proof...\n");
synor_verify_request_t verify_req = {
.proof = synor_proof_get_bytes(proof),
.proof_len = synor_proof_get_size(proof),
.public_signals = synor_proof_get_public_signals(proof),
.public_signal_count = synor_proof_get_public_signal_count(proof),
.verification_key = synor_groth16_keys_get_vk(keys),
.verification_key_len = synor_groth16_keys_get_vk_size(keys)
};
bool verified;
err = synor_groth16_verify(zk, &verify_req, &verified);
printf("Verification result: %s\n", verified ? "true" : "false");
// Export proof for on-chain verification
char* solidity_calldata = NULL;
err = synor_groth16_export_calldata(zk, proof, &solidity_calldata);
if (err == SYNOR_OK && solidity_calldata) {
printf("\nSolidity calldata: %.100s...\n", solidity_calldata);
free(solidity_calldata);
}
synor_proof_free(proof);
synor_witness_free(witness);
synor_groth16_keys_free(keys);
printf("\n");
}
void plonk_example(synor_zk_t* zk) {
printf("=== PLONK Proving System ===\n");
synor_error_t err;
const char* circuit_id = "multiplier-v1";
// PLONK uses universal trusted setup
printf("Getting universal setup...\n");
synor_srs_t* srs = NULL;
err = synor_plonk_get_universal_setup(zk, 14, &srs); // 2^14 constraints
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to get SRS\n");
return;
}
printf("SRS loaded: %zu bytes\n", synor_srs_get_size(srs));
// Generate circuit-specific keys
printf("\nGenerating circuit keys...\n");
synor_plonk_keys_t* keys = NULL;
err = synor_plonk_setup(zk, circuit_id, srs, &keys);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to generate keys\n");
synor_srs_free(srs);
return;
}
printf("Keys generated\n");
// Generate proof
synor_witness_t* witness = synor_witness_create();
synor_witness_set(witness, "a", "5");
synor_witness_set(witness, "b", "9");
printf("\nGenerating PLONK proof...\n");
synor_plonk_prove_request_t prove_req = {
.circuit_id = circuit_id,
.witness = witness,
.proving_key = synor_plonk_keys_get_pk(keys),
.proving_key_len = synor_plonk_keys_get_pk_size(keys)
};
synor_proof_t* proof = NULL;
err = synor_plonk_prove(zk, &prove_req, &proof);
if (err == SYNOR_OK) {
printf("Proof generated:\n");
printf(" Proof size: %zu bytes\n", synor_proof_get_size(proof));
printf(" Proving time: %lums\n", synor_proof_get_proving_time_ms(proof));
// Verify proof
synor_plonk_verify_request_t verify_req = {
.proof = synor_proof_get_bytes(proof),
.proof_len = synor_proof_get_size(proof),
.public_signals = synor_proof_get_public_signals(proof),
.public_signal_count = synor_proof_get_public_signal_count(proof),
.verification_key = synor_plonk_keys_get_vk(keys),
.verification_key_len = synor_plonk_keys_get_vk_size(keys)
};
bool verified;
synor_plonk_verify(zk, &verify_req, &verified);
printf("Verification result: %s\n", verified ? "true" : "false");
synor_proof_free(proof);
}
// Compare with Groth16
printf("\nPLONK advantages:\n");
printf(" - Universal trusted setup\n");
printf(" - Larger proofs (~2.5 KB vs ~200 bytes)\n");
printf(" - Faster proving for some circuits\n");
synor_witness_free(witness);
synor_plonk_keys_free(keys);
synor_srs_free(srs);
printf("\n");
}
void stark_example(synor_zk_t* zk) {
printf("=== STARK Proving System ===\n");
synor_error_t err;
const char* circuit_id = "multiplier-v1";
// STARKs don't need trusted setup
printf("Configuring STARK parameters...\n");
synor_stark_config_t config = {
.field_size = 256,
.hash_function = SYNOR_HASH_FUNCTION_POSEIDON,
.blowup_factor = 8,
.num_queries = 30,
.folding_factor = 8
};
// Generate proof
synor_witness_t* witness = synor_witness_create();
synor_witness_set(witness, "a", "11");
synor_witness_set(witness, "b", "13");
printf("\nGenerating STARK proof...\n");
synor_stark_prove_request_t prove_req = {
.circuit_id = circuit_id,
.witness = witness,
.config = &config
};
synor_stark_proof_t* proof = NULL;
err = synor_stark_prove(zk, &prove_req, &proof);
if (err == SYNOR_OK) {
printf("Proof generated:\n");
printf(" Proof size: %zu bytes\n", synor_stark_proof_get_size(proof));
printf(" Proving time: %lums\n", synor_stark_proof_get_proving_time_ms(proof));
printf(" FRI layers: %zu\n", synor_stark_proof_get_fri_layers(proof));
// Verify proof
printf("\nVerifying STARK proof...\n");
synor_stark_verify_request_t verify_req = {
.proof = synor_stark_proof_get_bytes(proof),
.proof_len = synor_stark_proof_get_size(proof),
.public_signals = synor_stark_proof_get_public_signals(proof),
.public_signal_count = synor_stark_proof_get_public_signal_count(proof),
.config = &config
};
bool verified;
synor_stark_verify(zk, &verify_req, &verified);
printf("Verification result: %s\n", verified ? "true" : "false");
synor_stark_proof_free(proof);
}
// Compare with SNARKs
printf("\nSTARK advantages:\n");
printf(" - No trusted setup needed\n");
printf(" - Post-quantum secure\n");
printf(" - Larger proofs (~100 KB)\n");
printf(" - Faster proving for complex computations\n");
synor_witness_free(witness);
printf("\n");
}
void recursive_example(synor_zk_t* zk) {
printf("=== Recursive Proof Composition ===\n");
synor_error_t err;
// Create inner proofs
printf("Generating inner proofs...\n");
synor_recursive_proof_list_t* inner_proofs = synor_recursive_proof_list_create();
for (int i = 1; i <= 3; i++) {
synor_witness_t* witness = synor_witness_create();
char a_str[16], b_str[16];
snprintf(a_str, sizeof(a_str), "%d", i);
snprintf(b_str, sizeof(b_str), "%d", i + 1);
synor_witness_set(witness, "a", a_str);
synor_witness_set(witness, "b", b_str);
synor_recursive_prove_request_t prove_req = {
.circuit_id = "multiplier-v1",
.witness = witness,
.level = 0
};
synor_recursive_proof_t* proof = NULL;
err = synor_recursive_prove_inner(zk, &prove_req, &proof);
if (err == SYNOR_OK) {
synor_recursive_proof_list_add(inner_proofs, proof);
printf(" Inner proof %d generated\n", i);
}
synor_witness_free(witness);
}
// Aggregate proofs recursively
printf("\nAggregating proofs...\n");
synor_aggregate_request_t aggregate_req = {
.proofs = inner_proofs,
.aggregation_circuit = "recursive-aggregator-v1"
};
synor_aggregated_proof_t* aggregated = NULL;
err = synor_recursive_aggregate(zk, &aggregate_req, &aggregated);
if (err == SYNOR_OK) {
printf("Aggregated proof:\n");
printf(" Proof size: %zu bytes\n", synor_aggregated_proof_get_size(aggregated));
printf(" Proofs aggregated: %zu\n", synor_aggregated_proof_get_count(aggregated));
printf(" Recursion depth: %zu\n", synor_aggregated_proof_get_depth(aggregated));
// Verify aggregated proof
printf("\nVerifying aggregated proof...\n");
bool verified;
err = synor_recursive_verify_aggregated(zk, aggregated, &verified);
printf("Verification result: %s\n", verified ? "true" : "false");
synor_aggregated_proof_free(aggregated);
}
// Use cases
printf("\nRecursive proof use cases:\n");
printf(" - Rollup batch verification\n");
printf(" - Incremental computation proofs\n");
printf(" - Cross-chain state proofs\n");
synor_recursive_proof_list_free(inner_proofs);
printf("\n");
}
void ceremony_example(synor_zk_t* zk) {
printf("=== Trusted Setup Ceremony ===\n");
synor_error_t err;
// List active ceremonies
synor_ceremony_list_t* ceremonies = NULL;
err = synor_ceremony_list(zk, SYNOR_CEREMONY_STATUS_ACTIVE, &ceremonies);
if (err == SYNOR_OK) {
printf("Active ceremonies: %zu\n", synor_ceremony_list_count(ceremonies));
for (size_t i = 0; i < 3 && i < synor_ceremony_list_count(ceremonies); i++) {
synor_ceremony_t* ceremony = synor_ceremony_list_get(ceremonies, i);
printf("\n %s:\n", synor_ceremony_get_id(ceremony));
printf(" Circuit: %s\n", synor_ceremony_get_circuit_id(ceremony));
printf(" Participants: %zu\n", synor_ceremony_get_participant_count(ceremony));
printf(" Current round: %zu\n", synor_ceremony_get_current_round(ceremony));
printf(" Status: %s\n", synor_ceremony_get_status(ceremony));
}
synor_ceremony_list_free(ceremonies);
}
// Create a new ceremony
printf("\nCreating new ceremony...\n");
synor_ceremony_config_t config = {
.circuit_id = "new-circuit-v1",
.min_participants = 10,
.max_participants = 100,
.round_duration = 3600, // 1 hour per round
.verify_contributions = true
};
synor_ceremony_t* new_ceremony = NULL;
err = synor_ceremony_create(zk, &config, &new_ceremony);
if (err == SYNOR_OK) {
printf("Ceremony created:\n");
printf(" Ceremony ID: %s\n", synor_ceremony_get_id(new_ceremony));
printf(" Join URL: %s\n", synor_ceremony_get_join_url(new_ceremony));
// Participate in ceremony
printf("\nParticipating in ceremony...\n");
uint8_t entropy[32];
// In real code, use secure random: arc4random_buf(entropy, sizeof(entropy));
memset(entropy, 0x42, sizeof(entropy)); // Example only
synor_contribution_request_t contrib_req = {
.ceremony_id = synor_ceremony_get_id(new_ceremony),
.entropy = entropy,
.entropy_len = sizeof(entropy)
};
synor_contribution_t* contribution = NULL;
err = synor_ceremony_contribute(zk, &contrib_req, &contribution);
if (err == SYNOR_OK) {
printf("Contribution made:\n");
printf(" Contribution ID: %s\n", synor_contribution_get_id(contribution));
printf(" Position: %zu\n", synor_contribution_get_position(contribution));
printf(" Hash: %s\n", synor_contribution_get_hash(contribution));
// Verify contribution
printf("\nVerifying contribution...\n");
bool valid;
synor_ceremony_verify_contribution(zk, synor_contribution_get_id(contribution), &valid);
printf("Contribution valid: %s\n", valid ? "true" : "false");
synor_contribution_free(contribution);
}
// Get ceremony transcript
synor_transcript_t* transcript = NULL;
err = synor_ceremony_get_transcript(zk, synor_ceremony_get_id(new_ceremony), &transcript);
if (err == SYNOR_OK) {
printf("\nCeremony transcript:\n");
printf(" Total contributions: %zu\n", synor_transcript_get_contribution_count(transcript));
printf(" Start time: %s\n", synor_transcript_get_start_time(transcript));
const char* final_hash = synor_transcript_get_final_hash(transcript);
printf(" Final hash: %s\n", final_hash ? final_hash : "pending");
synor_transcript_free(transcript);
}
synor_ceremony_free(new_ceremony);
}
printf("\n");
}
int main(int argc, char** argv) {
synor_error_t err;
// Initialize client
synor_zk_config_t config = {
.api_key = getenv("SYNOR_API_KEY") ? getenv("SYNOR_API_KEY") : "your-api-key",
.endpoint = "https://zk.synor.io/v1",
.timeout_ms = 120000, // ZK operations can be slow
.retries = 3,
.debug = false,
.default_proving_system = SYNOR_PROVING_SYSTEM_GROTH16,
.prove_timeout_ms = 300000,
.verify_timeout_ms = 30000
};
synor_zk_t* zk = NULL;
err = synor_zk_init(&config, &zk);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to initialize ZK client: %s\n", synor_error_string(err));
return 1;
}
// Check service health
bool healthy;
err = synor_zk_health_check(zk, &healthy);
printf("Service healthy: %s\n\n", healthy ? "true" : "false");
// Run examples
circuit_example(zk);
groth16_example(zk);
plonk_example(zk);
stark_example(zk);
recursive_example(zk);
ceremony_example(zk);
// Cleanup
synor_zk_free(zk);
return 0;
}

View file

@ -0,0 +1,377 @@
/**
* Synor Compiler SDK Examples for C++
*
* Demonstrates smart contract compilation and analysis:
* - WASM contract compilation and optimization
* - ABI extraction and encoding
* - Contract analysis and security scanning
* - Validation and verification
*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <synor/compiler.hpp>
using namespace synor::compiler;
// Helper function to create a minimal valid WASM module for testing
std::vector<uint8_t> create_minimal_wasm() {
return {
0x00, 0x61, 0x73, 0x6d, // Magic: \0asm
0x01, 0x00, 0x00, 0x00, // Version: 1
// Type section
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
// Function section
0x03, 0x02, 0x01, 0x00,
// Export section
0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00,
// Code section
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
};
}
void compile_contract_example(SynorCompiler& compiler) {
std::cout << "=== Contract Compilation ===" << std::endl;
auto wasm = create_minimal_wasm();
auto result = compiler.compile(wasm, {
.optimization_level = OptimizationLevel::Size,
.use_wasm_opt = true,
.validate = true,
.extract_metadata = true,
.generate_abi = true,
.strip_options = {
.strip_debug = true,
.strip_producers = true,
.strip_names = true,
.strip_custom = true,
.strip_unused = true,
.preserve_sections = {}
}
});
std::cout << "Compilation result:" << std::endl;
std::cout << " Contract ID: " << result.contract_id() << std::endl;
std::cout << " Code hash: " << result.code_hash() << std::endl;
std::cout << " Original size: " << result.original_size() << " bytes" << std::endl;
std::cout << " Optimized size: " << result.optimized_size() << " bytes" << std::endl;
std::cout << " Size reduction: " << std::fixed << std::setprecision(1) << result.size_reduction() << "%" << std::endl;
std::cout << " Estimated deploy gas: " << result.estimated_deploy_gas() << std::endl;
if (result.metadata()) {
std::cout << "\nMetadata:" << std::endl;
std::cout << " Name: " << result.metadata()->name() << std::endl;
std::cout << " Version: " << result.metadata()->version() << std::endl;
std::cout << " SDK Version: " << result.metadata()->sdk_version() << std::endl;
}
if (result.abi()) {
std::cout << "\nABI:" << std::endl;
std::cout << " Functions: " << result.abi()->functions().size() << std::endl;
std::cout << " Events: " << result.abi()->events().size() << std::endl;
std::cout << " Errors: " << result.abi()->errors().size() << std::endl;
}
std::cout << std::endl;
}
void compilation_modes_example(SynorCompiler& compiler) {
std::cout << "=== Compilation Modes ===" << std::endl;
auto wasm = create_minimal_wasm();
// Development mode: fast compilation, debugging support
std::cout << "Development mode:" << std::endl;
auto dev_result = compiler.contracts().compile_dev(wasm);
std::cout << " Size: " << dev_result.optimized_size() << " bytes" << std::endl;
std::cout << " Optimization: none" << std::endl;
// Production mode: maximum optimization
std::cout << "\nProduction mode:" << std::endl;
auto prod_result = compiler.contracts().compile_production(wasm);
std::cout << " Size: " << prod_result.optimized_size() << " bytes" << std::endl;
std::cout << " Optimization: aggressive" << std::endl;
std::cout << " Size savings: " << (dev_result.optimized_size() - prod_result.optimized_size()) << " bytes" << std::endl;
// Custom optimization levels
std::cout << "\nOptimization levels:" << std::endl;
std::vector<std::pair<OptimizationLevel, std::string>> levels = {
{OptimizationLevel::None, "NONE"},
{OptimizationLevel::Basic, "BASIC"},
{OptimizationLevel::Size, "SIZE"},
{OptimizationLevel::Aggressive, "AGGRESSIVE"}
};
for (const auto& [level, name] : levels) {
auto result = compiler.compile(wasm, {.optimization_level = level});
std::cout << " " << name << ": " << result.optimized_size() << " bytes" << std::endl;
}
std::cout << std::endl;
}
void abi_example(SynorCompiler& compiler) {
std::cout << "=== ABI Operations ===" << std::endl;
auto wasm = create_minimal_wasm();
// Extract ABI from WASM
auto abi = compiler.abi().extract(wasm);
std::cout << "Contract: " << abi.name() << std::endl;
std::cout << "Version: " << abi.version() << std::endl;
// List functions
if (!abi.functions().empty()) {
std::cout << "\nFunctions:" << std::endl;
for (const auto& func : abi.functions()) {
std::string inputs;
for (size_t i = 0; i < func.inputs().size(); ++i) {
const auto& param = func.inputs()[i];
if (i > 0) inputs += ", ";
inputs += param.name() + ": " + param.type().type_name();
}
std::string outputs;
if (func.outputs().empty()) {
outputs = "void";
} else {
for (size_t i = 0; i < func.outputs().size(); ++i) {
if (i > 0) outputs += ", ";
outputs += func.outputs()[i].type().type_name();
}
}
std::string modifiers;
if (func.view()) modifiers += "view ";
if (func.payable()) modifiers += "payable";
std::cout << " " << func.name() << "(" << inputs << ") -> " << outputs << " " << modifiers << std::endl;
std::cout << " Selector: " << func.selector() << std::endl;
}
}
// List events
if (!abi.events().empty()) {
std::cout << "\nEvents:" << std::endl;
for (const auto& event : abi.events()) {
std::string params;
for (size_t i = 0; i < event.params().size(); ++i) {
const auto& param = event.params()[i];
if (i > 0) params += ", ";
if (param.indexed()) params += "indexed ";
params += param.name() + ": " + param.type().type_name();
}
std::cout << " " << event.name() << "(" << params << ")" << std::endl;
std::cout << " Topic: " << event.topic() << std::endl;
}
}
// Encode a function call
if (!abi.functions().empty()) {
const auto& func = abi.functions().front();
auto encoded = compiler.abi().encode_call(func, {"arg1", "arg2"});
std::cout << "\nEncoded call to " << func.name() << ": " << encoded << std::endl;
// Decode a result
auto decoded = compiler.abi().decode_result(func, encoded);
std::cout << "Decoded result: " << decoded << std::endl;
}
std::cout << std::endl;
}
void analysis_example(SynorCompiler& compiler) {
std::cout << "=== Contract Analysis ===" << std::endl;
auto wasm = create_minimal_wasm();
// Full analysis
auto analysis = compiler.analysis().analyze(wasm);
// Size breakdown
if (analysis.size_breakdown()) {
const auto& size = *analysis.size_breakdown();
std::cout << "Size breakdown:" << std::endl;
std::cout << " Code: " << size.code() << " bytes" << std::endl;
std::cout << " Data: " << size.data() << " bytes" << std::endl;
std::cout << " Functions: " << size.functions() << " bytes" << std::endl;
std::cout << " Memory: " << size.memory() << " bytes" << std::endl;
std::cout << " Exports: " << size.exports() << " bytes" << std::endl;
std::cout << " Imports: " << size.imports() << " bytes" << std::endl;
std::cout << " Total: " << size.total() << " bytes" << std::endl;
}
// Function analysis
if (!analysis.functions().empty()) {
std::cout << "\nFunction analysis:" << std::endl;
for (size_t i = 0; i < std::min(analysis.functions().size(), size_t(5)); ++i) {
const auto& func = analysis.functions()[i];
std::cout << " " << func.name() << ":" << std::endl;
std::cout << " Size: " << func.size() << " bytes" << std::endl;
std::cout << " Instructions: " << func.instruction_count() << std::endl;
std::cout << " Locals: " << func.local_count() << std::endl;
std::cout << " Exported: " << (func.exported() ? "true" : "false") << std::endl;
std::cout << " Estimated gas: " << func.estimated_gas() << std::endl;
}
}
// Import analysis
if (!analysis.imports().empty()) {
std::cout << "\nImports:" << std::endl;
for (const auto& imp : analysis.imports()) {
std::cout << " " << imp.module() << "." << imp.name() << " (" << imp.kind() << ")" << std::endl;
}
}
// Gas analysis
if (analysis.gas_analysis()) {
const auto& gas = *analysis.gas_analysis();
std::cout << "\nGas analysis:" << std::endl;
std::cout << " Deployment: " << gas.deployment_gas() << std::endl;
std::cout << " Memory init: " << gas.memory_init_gas() << std::endl;
std::cout << " Data section: " << gas.data_section_gas() << std::endl;
}
// Extract metadata
auto metadata = compiler.analysis().extract_metadata(wasm);
std::cout << "\nContract metadata:" << std::endl;
std::cout << " Name: " << metadata.name() << std::endl;
std::cout << " Version: " << metadata.version() << std::endl;
std::cout << " Build timestamp: " << metadata.build_timestamp() << std::endl;
// Estimate deployment gas
auto gas_estimate = compiler.analysis().estimate_deploy_gas(wasm);
std::cout << "\nEstimated deployment gas: " << gas_estimate << std::endl;
std::cout << std::endl;
}
void validation_example(SynorCompiler& compiler) {
std::cout << "=== Contract Validation ===" << std::endl;
auto wasm = create_minimal_wasm();
// Full validation
auto result = compiler.validation().validate(wasm);
std::cout << "Valid: " << (result.valid() ? "true" : "false") << std::endl;
std::cout << "Exports: " << result.export_count() << std::endl;
std::cout << "Imports: " << result.import_count() << std::endl;
std::cout << "Functions: " << result.function_count() << std::endl;
std::cout << "Memory pages: " << result.memory_pages() << std::endl;
if (!result.errors().empty()) {
std::cout << "\nValidation errors:" << std::endl;
for (const auto& error : result.errors()) {
std::cout << " [" << error.code() << "] " << error.message() << std::endl;
if (!error.location().empty()) {
std::cout << " at " << error.location() << std::endl;
}
}
}
if (!result.warnings().empty()) {
std::cout << "\nWarnings:" << std::endl;
for (const auto& warning : result.warnings()) {
std::cout << " " << warning << std::endl;
}
}
// Quick validation
bool is_valid = compiler.validation().is_valid(wasm);
std::cout << "\nQuick validation: " << (is_valid ? "true" : "false") << std::endl;
// Get validation errors only
auto errors = compiler.validation().get_errors(wasm);
std::cout << "Error count: " << errors.size() << std::endl;
// Validate required exports
bool has_required = compiler.validation().validate_exports(wasm, {"init", "execute", "query"});
std::cout << "Has required exports: " << (has_required ? "true" : "false") << std::endl;
// Validate memory constraints
bool memory_valid = compiler.validation().validate_memory(wasm, 16);
std::cout << "Memory within 16 pages: " << (memory_valid ? "true" : "false") << std::endl;
std::cout << std::endl;
}
void security_example(SynorCompiler& compiler) {
std::cout << "=== Security Scanning ===" << std::endl;
auto wasm = create_minimal_wasm();
auto security = compiler.analysis().security_scan(wasm);
std::cout << "Security score: " << security.score() << "/100" << std::endl;
if (!security.issues().empty()) {
std::cout << "\nSecurity issues:" << std::endl;
for (const auto& issue : security.issues()) {
std::string icon;
std::string severity = issue.severity();
if (severity == "critical") icon = "[CRIT]";
else if (severity == "high") icon = "[HIGH]";
else if (severity == "medium") icon = "[MED]";
else if (severity == "low") icon = "[LOW]";
else icon = "[???]";
std::cout << icon << " [" << issue.severity() << "] " << issue.type() << std::endl;
std::cout << " " << issue.description() << std::endl;
if (!issue.location().empty()) {
std::cout << " at " << issue.location() << std::endl;
}
}
} else {
std::cout << "No security issues found!" << std::endl;
}
if (!security.recommendations().empty()) {
std::cout << "\nRecommendations:" << std::endl;
for (const auto& rec : security.recommendations()) {
std::cout << "" << rec << std::endl;
}
}
std::cout << std::endl;
}
int main(int argc, char** argv) {
// Initialize client
const char* api_key = std::getenv("SYNOR_API_KEY");
CompilerConfig config{
.api_key = api_key ? api_key : "your-api-key",
.endpoint = "https://compiler.synor.io/v1",
.timeout = std::chrono::seconds(60),
.retries = 3,
.debug = false,
.default_optimization_level = OptimizationLevel::Size,
.max_contract_size = 256 * 1024,
.use_wasm_opt = true,
.validate = true,
.extract_metadata = true,
.generate_abi = true
};
SynorCompiler compiler(config);
try {
// Check service health
bool healthy = compiler.health_check();
std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl;
// Run examples
compile_contract_example(compiler);
compilation_modes_example(compiler);
abi_example(compiler);
analysis_example(compiler);
validation_example(compiler);
security_example(compiler);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

View file

@ -0,0 +1,273 @@
/**
* Synor Crypto SDK Examples for C++
*
* Demonstrates quantum-resistant cryptographic operations:
* - Hybrid Ed25519 + Dilithium3 signatures
* - BIP-39 mnemonic generation and validation
* - Post-quantum algorithms (Falcon, SPHINCS+)
* - Key derivation functions
*/
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdlib>
#include <synor/crypto.hpp>
using namespace synor::crypto;
// Helper function to convert bytes to hex string
std::string bytes_to_hex(const std::vector<uint8_t>& data, size_t max_len = 0) {
std::stringstream ss;
size_t len = max_len > 0 && max_len < data.size() ? max_len : data.size();
for (size_t i = 0; i < len; ++i) {
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]);
}
if (max_len > 0 && max_len < data.size()) {
ss << "...";
}
return ss.str();
}
void mnemonic_example(SynorCrypto& crypto) {
std::cout << "=== Mnemonic Operations ===" << std::endl;
// Generate a 24-word mnemonic (256-bit entropy)
auto mnemonic = crypto.mnemonic().generate(24);
std::cout << "Generated mnemonic: " << mnemonic.phrase() << std::endl;
std::cout << "Word count: " << mnemonic.word_count() << std::endl;
// Validate a mnemonic
auto validation = crypto.mnemonic().validate(mnemonic.phrase());
std::cout << "Valid: " << (validation.is_valid() ? "true" : "false") << std::endl;
if (!validation.is_valid()) {
std::cout << "Error: " << validation.error() << std::endl;
}
// Convert mnemonic to seed
auto seed = crypto.mnemonic().to_seed(mnemonic.phrase(), "optional-passphrase");
std::cout << "Seed (hex): " << bytes_to_hex(seed, 16) << std::endl;
// Word suggestions for autocomplete
auto suggestions = crypto.mnemonic().suggest_words("aban", 5);
std::cout << "Suggestions for 'aban': ";
for (size_t i = 0; i < suggestions.size(); ++i) {
std::cout << suggestions[i] << (i < suggestions.size() - 1 ? ", " : "");
}
std::cout << std::endl << std::endl;
}
void keypair_example(SynorCrypto& crypto) {
std::cout << "=== Keypair Operations ===" << std::endl;
// Generate a random keypair
auto keypair = crypto.keypairs().generate();
std::cout << "Generated hybrid keypair:" << std::endl;
std::cout << " Ed25519 public key size: " << keypair.public_key().ed25519_bytes().size() << " bytes" << std::endl;
std::cout << " Dilithium public key size: " << keypair.public_key().dilithium_bytes().size() << " bytes" << std::endl;
std::cout << " Total public key size: " << keypair.public_key().size() << " bytes" << std::endl;
// Get addresses for different networks
std::cout << "\nAddresses:" << std::endl;
std::cout << " Mainnet: " << keypair.get_address(Network::Mainnet) << std::endl;
std::cout << " Testnet: " << keypair.get_address(Network::Testnet) << std::endl;
std::cout << " Devnet: " << keypair.get_address(Network::Devnet) << std::endl;
// Create keypair from mnemonic (deterministic)
auto mnemonic = crypto.mnemonic().generate(24);
auto keypair2 = crypto.keypairs().from_mnemonic(mnemonic.phrase(), "");
auto addr = keypair2.get_address(Network::Mainnet);
std::cout << "\nKeypair from mnemonic: " << addr.substr(0, 20) << "..." << std::endl;
// Derive child keypair using BIP-44 path
auto path = DerivationPath::external(0, 0); // m/44'/21337'/0'/0/0
std::cout << "Derivation path: " << path.to_string() << std::endl;
std::cout << std::endl;
}
void signing_example(SynorCrypto& crypto) {
std::cout << "=== Hybrid Signing ===" << std::endl;
// Generate keypair
auto keypair = crypto.keypairs().generate();
// Sign a message
std::string message_str = "Hello, quantum-resistant world!";
std::vector<uint8_t> message(message_str.begin(), message_str.end());
auto signature = crypto.signing().sign(keypair, message);
std::cout << "Signature created:" << std::endl;
std::cout << " Ed25519 component: " << signature.ed25519_bytes().size() << " bytes" << std::endl;
std::cout << " Dilithium component: " << signature.dilithium_bytes().size() << " bytes" << std::endl;
std::cout << " Total signature size: " << signature.size() << " bytes" << std::endl;
// Verify the signature
bool valid = crypto.signing().verify(keypair.public_key(), message, signature);
std::cout << "\nVerification result: " << (valid ? "true" : "false") << std::endl;
// Verify with tampered message fails
std::string tampered_str = "Hello, tampered message!";
std::vector<uint8_t> tampered_message(tampered_str.begin(), tampered_str.end());
bool invalid_result = crypto.signing().verify(keypair.public_key(), tampered_message, signature);
std::cout << "Tampered message verification: " << (invalid_result ? "true" : "false") << std::endl;
std::cout << std::endl;
}
void falcon_example(SynorCrypto& crypto) {
std::cout << "=== Falcon Post-Quantum Signatures ===" << std::endl;
// Generate Falcon-512 keypair (128-bit security)
auto falcon512 = crypto.falcon().generate(FalconVariant::Falcon512);
std::cout << "Falcon-512 keypair:" << std::endl;
std::cout << " Public key: " << falcon512.public_key().key_bytes().size() << " bytes" << std::endl;
std::cout << " Security level: 128-bit" << std::endl;
// Generate Falcon-1024 keypair (256-bit security)
auto falcon1024 = crypto.falcon().generate(FalconVariant::Falcon1024);
std::cout << "\nFalcon-1024 keypair:" << std::endl;
std::cout << " Public key: " << falcon1024.public_key().key_bytes().size() << " bytes" << std::endl;
std::cout << " Security level: 256-bit" << std::endl;
// Sign with Falcon-512
std::string message_str = "Post-quantum secure message";
std::vector<uint8_t> message(message_str.begin(), message_str.end());
auto signature = crypto.falcon().sign(falcon512, message);
std::cout << "\nFalcon-512 signature: " << signature.signature_bytes().size() << " bytes" << std::endl;
// Verify
bool valid = crypto.falcon().verify(falcon512.public_key().key_bytes(), message, signature);
std::cout << "Verification: " << (valid ? "true" : "false") << std::endl;
std::cout << std::endl;
}
void sphincs_example(SynorCrypto& crypto) {
std::cout << "=== SPHINCS+ Hash-Based Signatures ===" << std::endl;
// SPHINCS+ variants with different security levels
struct VariantInfo {
SphincsVariant variant;
int security;
int sig_size;
std::string name;
};
std::vector<VariantInfo> variants = {
{SphincsVariant::Shake128s, 128, 7856, "SHAKE128S"},
{SphincsVariant::Shake192s, 192, 16224, "SHAKE192S"},
{SphincsVariant::Shake256s, 256, 29792, "SHAKE256S"},
};
std::string message_str = "Hash-based quantum security";
std::vector<uint8_t> message(message_str.begin(), message_str.end());
for (const auto& v : variants) {
auto keypair = crypto.sphincs().generate(v.variant);
std::cout << "SPHINCS+ " << v.name << ":" << std::endl;
std::cout << " Security level: " << v.security << "-bit" << std::endl;
std::cout << " Expected signature size: " << v.sig_size << " bytes" << std::endl;
// Sign a message
auto signature = crypto.sphincs().sign(keypair, message);
std::cout << " Actual signature size: " << signature.signature_bytes().size() << " bytes" << std::endl;
// Verify
bool valid = crypto.sphincs().verify(keypair.public_key().key_bytes(), message, signature);
std::cout << " Verification: " << (valid ? "true" : "false") << std::endl << std::endl;
}
}
void kdf_example(SynorCrypto& crypto) {
std::cout << "=== Key Derivation Functions ===" << std::endl;
// HKDF (HMAC-based Key Derivation Function)
std::string seed_str = "master-secret-key-material-here";
std::vector<uint8_t> seed(seed_str.begin(), seed_str.end());
std::string salt_str = "application-salt";
std::string info_str = "encryption-key";
DerivationConfig hkdf_config{
.salt = std::vector<uint8_t>(salt_str.begin(), salt_str.end()),
.info = std::vector<uint8_t>(info_str.begin(), info_str.end()),
.output_length = 32
};
auto derived_key = crypto.kdf().derive_key(seed, hkdf_config);
std::cout << "HKDF derived key: " << bytes_to_hex(derived_key) << std::endl;
// PBKDF2 (Password-Based Key Derivation Function)
std::string password_str = "user-password";
std::vector<uint8_t> password(password_str.begin(), password_str.end());
std::string pbkdf2_salt_str = "random-salt-value";
PasswordDerivationConfig pbkdf2_config{
.salt = std::vector<uint8_t>(pbkdf2_salt_str.begin(), pbkdf2_salt_str.end()),
.iterations = 100000,
.output_length = 32
};
auto password_key = crypto.kdf().derive_from_password(password, pbkdf2_config);
std::cout << "PBKDF2 derived key: " << bytes_to_hex(password_key) << std::endl;
std::cout << std::endl;
}
void hash_example(SynorCrypto& crypto) {
std::cout << "=== Hash Functions ===" << std::endl;
std::string data_str = "Data to hash";
std::vector<uint8_t> data(data_str.begin(), data_str.end());
// SHA3-256 (FIPS 202)
auto sha3 = crypto.hash().sha3_256(data);
std::cout << "SHA3-256: " << sha3.hex() << std::endl;
// BLAKE3 (fast, parallel)
auto blake3 = crypto.hash().blake3(data);
std::cout << "BLAKE3: " << blake3.hex() << std::endl;
// Keccak-256 (Ethereum compatible)
auto keccak = crypto.hash().keccak256(data);
std::cout << "Keccak: " << keccak.hex() << std::endl;
std::cout << std::endl;
}
int main(int argc, char** argv) {
// Initialize client
const char* api_key = std::getenv("SYNOR_API_KEY");
CryptoConfig config{
.api_key = api_key ? api_key : "your-api-key",
.endpoint = "https://crypto.synor.io/v1",
.timeout = std::chrono::seconds(30),
.retries = 3,
.debug = false,
.default_network = Network::Mainnet
};
SynorCrypto crypto(config);
try {
// Check service health
bool healthy = crypto.health_check();
std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl;
// Run examples
mnemonic_example(crypto);
keypair_example(crypto);
signing_example(crypto);
falcon_example(crypto);
sphincs_example(crypto);
kdf_example(crypto);
hash_example(crypto);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

View file

@ -0,0 +1,358 @@
/**
* 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 <iostream>
#include <iomanip>
#include <cstdlib>
#include <synor/dex.hpp>
using namespace synor::dex;
void markets_example(SynorDex& dex) {
std::cout << "=== Markets ===" << std::endl;
// Get all markets
auto markets = dex.markets().list();
std::cout << "Available markets: " << markets.size() << std::endl;
for (size_t i = 0; i < std::min(markets.size(), size_t(5)); ++i) {
const auto& market = markets[i];
std::cout << "\n " << market.symbol() << ":" << std::endl;
std::cout << " Base: " << market.base_asset() << ", Quote: " << market.quote_asset() << std::endl;
std::cout << " Price: " << market.last_price() << std::endl;
std::cout << " 24h Volume: " << market.volume_24h() << std::endl;
std::cout << " 24h Change: " << market.change_24h() << "%" << std::endl;
std::cout << " Status: " << market.status() << std::endl;
}
// Get specific market
auto market = dex.markets().get("SYN-USDC");
std::cout << "\nSYN-USDC details:" << std::endl;
std::cout << " Min order size: " << market.min_order_size() << std::endl;
std::cout << " Tick size: " << market.tick_size() << std::endl;
std::cout << " Maker fee: " << market.maker_fee() << "%" << std::endl;
std::cout << " Taker fee: " << market.taker_fee() << "%" << std::endl;
// Get market statistics
auto stats = dex.markets().get_stats("SYN-USDC");
std::cout << "\nMarket statistics:" << std::endl;
std::cout << " High 24h: " << stats.high_24h() << std::endl;
std::cout << " Low 24h: " << stats.low_24h() << std::endl;
std::cout << " Open interest: " << stats.open_interest() << std::endl;
std::cout << " Funding rate: " << stats.funding_rate() << "%" << std::endl;
std::cout << std::endl;
}
void spot_trading_example(SynorDex& dex) {
std::cout << "=== Spot Trading ===" << std::endl;
// Place a limit order
std::cout << "Placing limit buy order..." << std::endl;
auto limit_order = dex.spot().place_order({
.market = "SYN-USDC",
.side = OrderSide::Buy,
.order_type = OrderType::Limit,
.price = "1.50",
.quantity = "100",
.time_in_force = TimeInForce::GTC
});
std::cout << "Limit order placed:" << std::endl;
std::cout << " Order ID: " << limit_order.order_id() << std::endl;
std::cout << " Status: " << limit_order.status() << std::endl;
std::cout << " Price: " << limit_order.price() << std::endl;
std::cout << " Quantity: " << limit_order.quantity() << std::endl;
// Place a market order
std::cout << "\nPlacing market sell order..." << std::endl;
auto market_order = dex.spot().place_order({
.market = "SYN-USDC",
.side = OrderSide::Sell,
.order_type = OrderType::Market,
.quantity = "50"
});
std::cout << "Market order executed:" << std::endl;
std::cout << " Order ID: " << market_order.order_id() << std::endl;
std::cout << " Status: " << market_order.status() << std::endl;
std::cout << " Filled: " << market_order.filled_quantity() << std::endl;
std::cout << " Avg price: " << market_order.average_price() << std::endl;
// Get order status
auto status = dex.spot().get_order(limit_order.order_id());
std::cout << "\nOrder status:" << std::endl;
std::cout << " Status: " << status.status() << std::endl;
std::cout << " Filled: " << status.filled_quantity() << " / " << status.quantity() << std::endl;
std::cout << " Remaining: " << status.remaining_quantity() << std::endl;
// Cancel order
std::cout << "\nCancelling order..." << std::endl;
dex.spot().cancel_order(limit_order.order_id());
std::cout << "Order cancelled successfully" << std::endl;
// Get open orders
auto open_orders = dex.spot().get_open_orders("SYN-USDC");
std::cout << "\nOpen orders: " << open_orders.size() << std::endl;
// Get trade history
auto trades = dex.spot().get_trade_history("SYN-USDC", 10);
std::cout << "\nRecent trades: " << trades.size() << std::endl;
for (size_t i = 0; i < std::min(trades.size(), size_t(3)); ++i) {
const auto& trade = trades[i];
std::cout << " " << trade.side() << " " << trade.quantity()
<< " @ " << trade.price() << " (" << trade.timestamp() << ")" << std::endl;
}
std::cout << std::endl;
}
void perps_trading_example(SynorDex& dex) {
std::cout << "=== Perpetual Futures Trading ===" << std::endl;
// Get available perps markets
auto perps_markets = dex.perps().list_markets();
std::cout << "Available perps markets: " << perps_markets.size() << std::endl;
for (size_t i = 0; i < std::min(perps_markets.size(), size_t(3)); ++i) {
const auto& market = perps_markets[i];
std::cout << " " << market.symbol() << ": " << market.mark_price()
<< " (funding: " << market.funding_rate() << "%)" << std::endl;
}
// Open a long position
std::cout << "\nOpening long position..." << std::endl;
auto position = dex.perps().open_position({
.market = "SYN-USDC-PERP",
.side = OrderSide::Buy,
.order_type = OrderType::Limit,
.price = "1.50",
.size = "1000",
.leverage = 10,
.reduce_only = false
});
std::cout << "Position opened:" << std::endl;
std::cout << " Position ID: " << position.position_id() << std::endl;
std::cout << " Size: " << position.size() << std::endl;
std::cout << " Entry price: " << position.entry_price() << std::endl;
std::cout << " Leverage: " << position.leverage() << "x" << std::endl;
std::cout << " Liquidation price: " << position.liquidation_price() << std::endl;
// Get position details
auto details = dex.perps().get_position(position.position_id());
std::cout << "\nPosition details:" << std::endl;
std::cout << " Unrealized PnL: " << details.unrealized_pnl() << std::endl;
std::cout << " Margin: " << details.margin() << std::endl;
std::cout << " Margin ratio: " << details.margin_ratio() << "%" << std::endl;
// Set stop loss and take profit
std::cout << "\nSetting stop loss and take profit..." << std::endl;
dex.perps().set_stop_loss(position.position_id(), "1.40");
std::cout << "Stop loss set at 1.40" << std::endl;
dex.perps().set_take_profit(position.position_id(), "1.80");
std::cout << "Take profit set at 1.80" << std::endl;
// Close position
std::cout << "\nClosing position..." << std::endl;
auto close_result = dex.perps().close_position(position.position_id());
std::cout << "Position closed:" << std::endl;
std::cout << " Realized PnL: " << close_result.realized_pnl() << std::endl;
std::cout << " Close price: " << close_result.close_price() << std::endl;
// Get all positions
auto positions = dex.perps().get_positions();
std::cout << "\nOpen positions: " << positions.size() << std::endl;
// Get funding history
auto funding = dex.perps().get_funding_history("SYN-USDC-PERP", 10);
std::cout << "Funding payments: " << funding.size() << std::endl;
std::cout << std::endl;
}
void liquidity_example(SynorDex& dex) {
std::cout << "=== Liquidity Provision ===" << std::endl;
// Get available pools
auto pools = dex.liquidity().list_pools();
std::cout << "Available pools: " << pools.size() << std::endl;
for (size_t i = 0; i < std::min(pools.size(), size_t(3)); ++i) {
const auto& pool = pools[i];
std::cout << "\n " << pool.name() << ":" << std::endl;
std::cout << " TVL: $" << pool.tvl() << std::endl;
std::cout << " APR: " << pool.apr() << "%" << std::endl;
std::cout << " Volume 24h: $" << pool.volume_24h() << std::endl;
std::cout << " Fee tier: " << pool.fee_tier() << "%" << std::endl;
}
// Get pool details
auto pool = dex.liquidity().get_pool("SYN-USDC");
std::cout << "\nSYN-USDC pool details:" << std::endl;
std::cout << " Token0: " << pool.token0().symbol() << " (" << pool.token0_reserve() << ")" << std::endl;
std::cout << " Token1: " << pool.token1().symbol() << " (" << pool.token1_reserve() << ")" << std::endl;
std::cout << " Price: " << pool.price() << std::endl;
std::cout << " Total LP tokens: " << pool.total_lp_tokens() << std::endl;
// Add liquidity
std::cout << "\nAdding liquidity..." << std::endl;
auto add_result = dex.liquidity().add_liquidity({
.pool = "SYN-USDC",
.amount0 = "100",
.amount1 = "150",
.slippage_bps = 50 // 0.5%
});
std::cout << "Liquidity added:" << std::endl;
std::cout << " LP tokens received: " << add_result.lp_tokens() << std::endl;
std::cout << " Position ID: " << add_result.position_id() << std::endl;
std::cout << " Share of pool: " << add_result.share_of_pool() << "%" << std::endl;
// Get LP positions
auto lp_positions = dex.liquidity().get_positions();
std::cout << "\nLP positions: " << lp_positions.size() << std::endl;
for (const auto& pos : lp_positions) {
std::cout << " " << pos.pool() << ": " << pos.lp_tokens()
<< " LP tokens (value: $" << pos.value() << ")" << std::endl;
}
// Claim fees
std::cout << "\nClaiming fees..." << std::endl;
auto fees = dex.liquidity().claim_fees(add_result.position_id());
std::cout << "Fees claimed:" << std::endl;
std::cout << " Token0: " << fees.amount0() << std::endl;
std::cout << " Token1: " << fees.amount1() << std::endl;
// Remove liquidity
std::cout << "\nRemoving liquidity..." << std::endl;
auto remove_result = dex.liquidity().remove_liquidity({
.position_id = add_result.position_id(),
.lp_tokens = add_result.lp_tokens(),
.slippage_bps = 50
});
std::cout << "Liquidity removed:" << std::endl;
std::cout << " Token0 received: " << remove_result.amount0() << std::endl;
std::cout << " Token1 received: " << remove_result.amount1() << std::endl;
std::cout << std::endl;
}
void orderbook_example(SynorDex& dex) {
std::cout << "=== Order Book ===" << std::endl;
// Get order book snapshot
auto orderbook = dex.orderbook().get_snapshot("SYN-USDC", 10);
std::cout << "Order book for SYN-USDC:" << std::endl;
std::cout << "\nAsks (sells):" << std::endl;
for (size_t i = 0; i < std::min(orderbook.asks().size(), size_t(5)); ++i) {
const auto& ask = orderbook.asks()[i];
std::cout << " " << ask.quantity() << " @ " << ask.price() << std::endl;
}
std::cout << "\nBids (buys):" << std::endl;
for (size_t i = 0; i < std::min(orderbook.bids().size(), size_t(5)); ++i) {
const auto& bid = orderbook.bids()[i];
std::cout << " " << bid.quantity() << " @ " << bid.price() << std::endl;
}
std::cout << "\nSpread: " << orderbook.spread() << " (" << orderbook.spread_percent() << "%)" << std::endl;
std::cout << "Mid price: " << orderbook.mid_price() << std::endl;
// Get recent trades
auto recent_trades = dex.orderbook().get_recent_trades("SYN-USDC", 10);
std::cout << "\nRecent trades:" << std::endl;
for (size_t i = 0; i < std::min(recent_trades.size(), size_t(5)); ++i) {
const auto& trade = recent_trades[i];
std::cout << " " << trade.side() << " " << trade.quantity() << " @ " << trade.price() << std::endl;
}
std::cout << std::endl;
}
void portfolio_example(SynorDex& dex) {
std::cout << "=== Portfolio ===" << std::endl;
// Get portfolio overview
auto portfolio = dex.portfolio().get_overview();
std::cout << "Portfolio overview:" << std::endl;
std::cout << " Total value: $" << portfolio.total_value() << std::endl;
std::cout << " Available balance: $" << portfolio.available_balance() << std::endl;
std::cout << " In orders: $" << portfolio.in_orders() << std::endl;
std::cout << " In positions: $" << portfolio.in_positions() << std::endl;
std::cout << " Unrealized PnL: $" << portfolio.unrealized_pnl() << std::endl;
// Get balances
auto balances = dex.portfolio().get_balances();
std::cout << "\nBalances:" << std::endl;
for (const auto& balance : balances) {
std::cout << " " << balance.asset() << ": " << balance.total()
<< " (available: " << balance.available()
<< ", in orders: " << balance.in_orders() << ")" << std::endl;
}
// Get PnL history
auto pnl_history = dex.portfolio().get_pnl_history(30);
std::cout << "\nPnL history (last " << pnl_history.size() << " days):" << std::endl;
if (!pnl_history.empty()) {
std::cout << " Total PnL: $" << pnl_history.back().cumulative_pnl() << std::endl;
}
// Get trade statistics
auto stats = dex.portfolio().get_stats();
std::cout << "\nTrade statistics:" << std::endl;
std::cout << " Total trades: " << stats.total_trades() << std::endl;
std::cout << " Win rate: " << stats.win_rate() << "%" << std::endl;
std::cout << " Avg profit: $" << stats.avg_profit() << std::endl;
std::cout << " Avg loss: $" << stats.avg_loss() << std::endl;
std::cout << " Best trade: $" << stats.best_trade() << std::endl;
std::cout << " Worst trade: $" << stats.worst_trade() << std::endl;
std::cout << std::endl;
}
int main(int argc, char** argv) {
// Initialize client
const char* api_key = std::getenv("SYNOR_API_KEY");
DexConfig config{
.api_key = api_key ? api_key : "your-api-key",
.endpoint = "https://dex.synor.io/v1",
.timeout = std::chrono::seconds(30),
.retries = 3,
.debug = false,
.default_market = "SYN-USDC"
};
SynorDex dex(config);
try {
// Check service health
bool healthy = dex.health_check();
std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl;
// Run examples
markets_example(dex);
spot_trading_example(dex);
perps_trading_example(dex);
liquidity_example(dex);
orderbook_example(dex);
portfolio_example(dex);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

View file

@ -0,0 +1,389 @@
/**
* Synor IBC SDK Examples for C++
*
* Demonstrates Inter-Blockchain Communication operations:
* - Cross-chain transfers and messages
* - Channel lifecycle management
* - Packet handling and acknowledgments
* - Relayer operations
* - Connection monitoring
*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <chrono>
#include <synor/ibc.hpp>
using namespace synor::ibc;
void chains_example(SynorIbc& ibc) {
std::cout << "=== Chain Discovery ===" << std::endl;
// Get all connected chains
auto chains = ibc.chains().list();
std::cout << "Connected chains: " << chains.size() << std::endl;
for (size_t i = 0; i < std::min(chains.size(), size_t(5)); ++i) {
const auto& chain = chains[i];
std::cout << "\n " << chain.chain_id() << ":" << std::endl;
std::cout << " Name: " << chain.name() << std::endl;
std::cout << " Type: " << chain.chain_type() << std::endl;
std::cout << " Status: " << chain.status() << std::endl;
std::cout << " Block height: " << chain.latest_height() << std::endl;
std::cout << " Light client: " << chain.light_client() << std::endl;
}
// Get specific chain info
auto synor_chain = ibc.chains().get("synor-mainnet-1");
std::cout << "\nSynor chain details:" << std::endl;
std::cout << " Bech32 prefix: " << synor_chain.bech32_prefix() << std::endl;
std::cout << " Gas price: " << synor_chain.gas_price() << std::endl;
auto features = synor_chain.features();
std::cout << " Supported features: ";
for (size_t i = 0; i < features.size(); ++i) {
std::cout << features[i] << (i < features.size() - 1 ? ", " : "");
}
std::cout << std::endl;
// Get chain connections
auto connections = ibc.chains().get_connections("synor-mainnet-1");
std::cout << "\nChain connections: " << connections.size() << std::endl;
for (size_t i = 0; i < std::min(connections.size(), size_t(3)); ++i) {
const auto& conn = connections[i];
std::cout << " " << conn.connection_id() << " -> " << conn.counterparty_chain_id() << std::endl;
}
std::cout << std::endl;
}
void channels_example(SynorIbc& ibc) {
std::cout << "=== Channel Management ===" << std::endl;
// List existing channels
auto channels = ibc.channels().list();
std::cout << "Active channels: " << channels.size() << std::endl;
for (size_t i = 0; i < std::min(channels.size(), size_t(3)); ++i) {
const auto& channel = channels[i];
std::cout << "\n Channel " << channel.channel_id() << ":" << std::endl;
std::cout << " Port: " << channel.port_id() << std::endl;
std::cout << " State: " << channel.state() << std::endl;
std::cout << " Order: " << channel.ordering() << std::endl;
std::cout << " Counterparty: " << channel.counterparty_channel_id()
<< " on " << channel.counterparty_chain_id() << std::endl;
std::cout << " Version: " << channel.version() << std::endl;
}
// Create a new channel (4-step handshake)
std::cout << "\nInitiating channel creation..." << std::endl;
// Step 1: ChanOpenInit
auto init_result = ibc.channels().open_init({
.port_id = "transfer",
.counterparty_chain_id = "cosmos-hub-4",
.counterparty_port_id = "transfer",
.version = "ics20-1",
.ordering = ChannelOrdering::Unordered
});
std::cout << "Channel init:" << std::endl;
std::cout << " Channel ID: " << init_result.channel_id() << std::endl;
std::cout << " State: " << init_result.state() << std::endl;
std::cout << " TX hash: " << init_result.tx_hash() << std::endl;
// Step 2: Wait for ChanOpenTry (counterparty)
std::cout << "\nWaiting for counterparty ChanOpenTry..." << std::endl;
auto try_state = ibc.channels().wait_for_state(
init_result.channel_id(),
ChannelState::TryOpen,
std::chrono::minutes(5)
);
std::cout << "Channel state: " << try_state << std::endl;
// Step 3: ChanOpenAck
std::cout << "\nSending ChanOpenAck..." << std::endl;
auto ack_result = ibc.channels().open_ack({
.channel_id = init_result.channel_id(),
.counterparty_channel_id = "channel-0",
.counterparty_version = "ics20-1"
});
std::cout << "Ack TX: " << ack_result.tx_hash() << std::endl;
// Step 4: Wait for ChanOpenConfirm (counterparty)
std::cout << "\nWaiting for channel to open..." << std::endl;
auto open_state = ibc.channels().wait_for_state(
init_result.channel_id(),
ChannelState::Open,
std::chrono::minutes(5)
);
std::cout << "Channel is now: " << open_state << std::endl;
// Get channel details
auto channel = ibc.channels().get(init_result.channel_id());
std::cout << "\nChannel details:" << std::endl;
std::cout << " Sequences - Send: " << channel.next_sequence_send()
<< ", Recv: " << channel.next_sequence_recv()
<< ", Ack: " << channel.next_sequence_ack() << std::endl;
std::cout << std::endl;
}
void transfer_example(SynorIbc& ibc) {
std::cout << "=== Cross-Chain Transfers ===" << std::endl;
// Get supported tokens for transfer
auto tokens = ibc.transfers().get_supported_tokens("cosmos-hub-4");
std::cout << "Transferable tokens to Cosmos Hub:" << std::endl;
for (size_t i = 0; i < std::min(tokens.size(), size_t(5)); ++i) {
const auto& token = tokens[i];
std::cout << " " << token.symbol() << " (" << token.denom() << ")" << std::endl;
}
// Initiate a cross-chain transfer
std::cout << "\nInitiating transfer..." << std::endl;
auto now = std::chrono::system_clock::now();
auto timeout = std::chrono::duration_cast<std::chrono::nanoseconds>(
(now + std::chrono::seconds(600)).time_since_epoch()
).count();
auto transfer = ibc.transfers().send({
.source_channel = "channel-0",
.denom = "usynor",
.amount = "1000000",
.receiver = "cosmos1...",
.timeout_height = 0, // Use timestamp instead
.timeout_timestamp = static_cast<uint64_t>(timeout),
.memo = "IBC transfer from Synor"
});
std::cout << "Transfer initiated:" << std::endl;
std::cout << " TX hash: " << transfer.tx_hash() << std::endl;
std::cout << " Sequence: " << transfer.sequence() << std::endl;
std::cout << " Packet ID: " << transfer.packet_id() << std::endl;
std::cout << " Status: " << transfer.status() << std::endl;
// Track transfer progress
std::cout << "\nTracking transfer..." << std::endl;
auto status = ibc.transfers().track(transfer.packet_id());
std::cout << "Current status: " << status.state() << std::endl;
std::cout << "Source TX: " << status.source_tx_hash() << std::endl;
if (!status.dest_tx_hash().empty()) {
std::cout << "Dest TX: " << status.dest_tx_hash() << std::endl;
}
// Wait for completion
std::cout << "\nWaiting for transfer completion..." << std::endl;
auto final_status = ibc.transfers().wait_for_completion(
transfer.packet_id(),
std::chrono::minutes(10)
);
std::cout << "Transfer completed:" << std::endl;
std::cout << " Final status: " << final_status.state() << std::endl;
std::cout << " Acknowledgment: " << final_status.acknowledgment() << std::endl;
// Get transfer history
auto history = ibc.transfers().get_history(10);
std::cout << "\nRecent transfers: " << history.size() << std::endl;
for (size_t i = 0; i < std::min(history.size(), size_t(3)); ++i) {
const auto& t = history[i];
std::cout << " " << t.amount() << " " << t.denom()
<< " -> " << t.dest_chain() << " (" << t.status() << ")" << std::endl;
}
std::cout << std::endl;
}
void packet_example(SynorIbc& ibc) {
std::cout << "=== Packet Operations ===" << std::endl;
// List pending packets
auto pending = ibc.packets().list_pending("channel-0");
std::cout << "Pending packets on channel-0: " << pending.size() << std::endl;
for (size_t i = 0; i < std::min(pending.size(), size_t(3)); ++i) {
const auto& packet = pending[i];
std::cout << "\n Packet #" << packet.sequence() << ":" << std::endl;
std::cout << " Source: " << packet.source_port() << "/" << packet.source_channel() << std::endl;
std::cout << " Dest: " << packet.dest_port() << "/" << packet.dest_channel() << std::endl;
std::cout << " State: " << packet.state() << std::endl;
std::cout << " Timeout: " << packet.timeout_timestamp() << std::endl;
}
// Get specific packet
auto packet = ibc.packets().get("channel-0", 1);
std::cout << "\nPacket details:" << std::endl;
std::cout << " Data (hex): " << packet.data_hex().substr(0, 40) << "..." << std::endl;
std::cout << " Created: " << packet.created_at() << std::endl;
// Get packet commitment proof
auto proof = ibc.packets().get_commitment_proof("channel-0", 1);
std::cout << "\nCommitment proof:" << std::endl;
std::cout << " Height: " << proof.proof_height() << std::endl;
std::cout << " Proof size: " << proof.proof().size() << " bytes" << std::endl;
// Get acknowledgment
auto ack = ibc.packets().get_acknowledgment("channel-0", 1);
std::cout << "\nAcknowledgment:" << std::endl;
std::cout << " Result: " << (ack.success() ? "Success" : std::string("Error: ") + ack.error()) << std::endl;
std::cout << " TX hash: " << ack.tx_hash() << std::endl;
// List timed-out packets
auto timed_out = ibc.packets().list_timed_out();
std::cout << "\nTimed-out packets: " << timed_out.size() << std::endl;
// Timeout a packet manually
if (!timed_out.empty()) {
const auto& to_timeout = timed_out.front();
std::cout << "\nProcessing timeout for packet #" << to_timeout.sequence() << std::endl;
auto timeout = ibc.packets().timeout(to_timeout.source_channel(), to_timeout.sequence());
std::cout << "Timeout TX: " << timeout.tx_hash() << std::endl;
}
std::cout << std::endl;
}
void relayer_example(SynorIbc& ibc) {
std::cout << "=== Relayer Operations ===" << std::endl;
// Get relayer status
auto status = ibc.relayer().get_status();
std::cout << "Relayer status:" << std::endl;
std::cout << " Running: " << (status.running() ? "true" : "false") << std::endl;
std::cout << " Uptime: " << status.uptime() << std::endl;
std::cout << " Packets relayed: " << status.packets_relayed() << std::endl;
std::cout << " Errors: " << status.error_count() << std::endl;
// List active paths
auto paths = ibc.relayer().list_paths();
std::cout << "\nActive relay paths: " << paths.size() << std::endl;
for (const auto& path : paths) {
std::cout << "\n " << path.path_id() << ":" << std::endl;
std::cout << " " << path.source_chain() << " <-> " << path.dest_chain() << std::endl;
std::cout << " Channel: " << path.source_channel() << " <-> " << path.dest_channel() << std::endl;
std::cout << " Status: " << path.status() << std::endl;
std::cout << " Pending packets: " << path.pending_packets() << std::endl;
}
// Configure a new path
std::cout << "\nConfiguring new relay path..." << std::endl;
auto new_path = ibc.relayer().add_path({
.source_chain = "synor-mainnet-1",
.dest_chain = "osmosis-1",
.source_channel = "channel-1",
.dest_channel = "channel-100",
.filter_denoms = {"usynor", "uosmo"},
.min_relay_amount = "1000",
.max_relay_amount = "1000000000"
});
std::cout << "Path created: " << new_path.path_id() << std::endl;
// Start relaying on path
std::cout << "\nStarting relayer on path..." << std::endl;
ibc.relayer().start_path(new_path.path_id());
std::cout << "Relayer started" << std::endl;
// Manually relay pending packets
std::cout << "\nRelaying pending packets..." << std::endl;
auto relay_result = ibc.relayer().relay_pending(new_path.path_id());
std::cout << "Relayed " << relay_result.packet_count() << " packets" << std::endl;
std::cout << "TX hashes: " << relay_result.tx_hashes().size() << std::endl;
// Get relay history
auto history = ibc.relayer().get_history(new_path.path_id(), 10);
std::cout << "\nRelay history:" << std::endl;
for (size_t i = 0; i < std::min(history.size(), size_t(3)); ++i) {
const auto& event = history[i];
std::cout << " " << event.timestamp() << ": " << event.event_type()
<< " - " << event.packet_count() << " packets" << std::endl;
}
std::cout << std::endl;
}
void monitoring_example(SynorIbc& ibc) {
std::cout << "=== IBC Monitoring ===" << std::endl;
// Get IBC metrics
auto metrics = ibc.monitoring().get_metrics();
std::cout << "IBC metrics:" << std::endl;
std::cout << " Total channels: " << metrics.total_channels() << std::endl;
std::cout << " Active channels: " << metrics.active_channels() << std::endl;
std::cout << " Total packets: " << metrics.total_packets() << std::endl;
std::cout << " Pending packets: " << metrics.pending_packets() << std::endl;
std::cout << " Failed packets: " << metrics.failed_packets() << std::endl;
std::cout << " Avg relay time: " << metrics.avg_relay_time() << "ms" << std::endl;
// Get chain health
auto chain_health = ibc.monitoring().get_chain_health();
std::cout << "\nChain health:" << std::endl;
for (size_t i = 0; i < std::min(chain_health.size(), size_t(3)); ++i) {
const auto& health = chain_health[i];
std::cout << " " << health.chain_id() << ":" << std::endl;
std::cout << " Status: " << health.status() << std::endl;
std::cout << " Block lag: " << health.block_lag() << std::endl;
std::cout << " Last update: " << health.last_update() << std::endl;
}
// Get channel statistics
auto stats = ibc.monitoring().get_channel_stats("channel-0");
std::cout << "\nChannel-0 statistics:" << std::endl;
std::cout << " Packets sent: " << stats.packets_sent() << std::endl;
std::cout << " Packets received: " << stats.packets_received() << std::endl;
std::cout << " Success rate: " << stats.success_rate() << "%" << std::endl;
std::cout << " Avg confirmation time: " << stats.avg_confirmation_time() << "ms" << std::endl;
// Subscribe to IBC events
std::cout << "\nSubscribing to IBC events..." << std::endl;
ibc.monitoring().subscribe([](const IbcEvent& event) {
std::cout << "Event: " << event.type() << " on " << event.channel_id() << std::endl;
});
// Get alerts
auto alerts = ibc.monitoring().get_alerts();
std::cout << "\nActive alerts: " << alerts.size() << std::endl;
for (const auto& alert : alerts) {
std::cout << " [" << alert.severity() << "] " << alert.message() << std::endl;
}
std::cout << std::endl;
}
int main(int argc, char** argv) {
// Initialize client
const char* api_key = std::getenv("SYNOR_API_KEY");
IbcConfig config{
.api_key = api_key ? api_key : "your-api-key",
.endpoint = "https://ibc.synor.io/v1",
.timeout = std::chrono::seconds(30),
.retries = 3,
.debug = false,
.default_chain = "synor-mainnet-1",
.confirmations = 1
};
SynorIbc ibc(config);
try {
// Check service health
bool healthy = ibc.health_check();
std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl;
// Run examples
chains_example(ibc);
channels_example(ibc);
transfer_example(ibc);
packet_example(ibc);
relayer_example(ibc);
monitoring_example(ibc);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

View file

@ -0,0 +1,359 @@
/**
* Synor ZK SDK Examples for C++
*
* Demonstrates zero-knowledge proof operations:
* - Circuit compilation (Circom)
* - Proof generation and verification
* - Multiple proving systems (Groth16, PLONK, STARK)
* - Recursive proof composition
* - Trusted setup ceremonies
*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <random>
#include <synor/zk.hpp>
using namespace synor::zk;
void circuit_example(SynorZk& zk) {
std::cout << "=== Circuit Compilation ===" << std::endl;
// Simple Circom circuit: prove knowledge of factors
std::string circom_code = R"(
pragma circom 2.1.0;
template Multiplier() {
signal input a;
signal input b;
signal output c;
c <== a * b;
}
component main = Multiplier();
)";
// Compile the circuit
std::cout << "Compiling circuit..." << std::endl;
auto circuit = zk.circuits().compile({
.code = circom_code,
.language = CircuitLanguage::Circom
});
std::cout << "Circuit compiled:" << std::endl;
std::cout << " Circuit ID: " << circuit.circuit_id() << std::endl;
std::cout << " Constraints: " << circuit.constraints() << std::endl;
std::cout << " Public inputs: " << circuit.public_inputs() << std::endl;
std::cout << " Private inputs: " << circuit.private_inputs() << std::endl;
std::cout << " Outputs: " << circuit.outputs() << std::endl;
// Get circuit info
auto info = zk.circuits().get(circuit.circuit_id());
std::cout << "\nCircuit info:" << std::endl;
std::cout << " Name: " << info.name() << std::endl;
std::cout << " Version: " << info.version() << std::endl;
std::cout << " Wires: " << info.wire_count() << std::endl;
std::cout << " Labels: " << info.label_count() << std::endl;
// List available circuits
auto circuits = zk.circuits().list();
std::cout << "\nAvailable circuits: " << circuits.size() << std::endl;
for (size_t i = 0; i < std::min(circuits.size(), size_t(3)); ++i) {
const auto& c = circuits[i];
std::cout << " " << c.circuit_id() << ": " << c.name()
<< " (" << c.constraints() << " constraints)" << std::endl;
}
std::cout << std::endl;
}
void groth16_example(SynorZk& zk) {
std::cout << "=== Groth16 Proving System ===" << std::endl;
std::string circuit_id = "multiplier-v1";
// Generate proving/verification keys (trusted setup)
std::cout << "Generating keys..." << std::endl;
auto keys = zk.groth16().setup(circuit_id);
std::cout << "Keys generated:" << std::endl;
std::cout << " Proving key size: " << keys.proving_key().size() << " bytes" << std::endl;
std::cout << " Verification key size: " << keys.verification_key().size() << " bytes" << std::endl;
// Prepare witness (private inputs)
std::map<std::string, std::string> witness = {
{"a", "3"},
{"b", "7"}
};
// Generate proof
std::cout << "\nGenerating proof..." << std::endl;
auto proof = zk.groth16().prove({
.circuit_id = circuit_id,
.witness = witness,
.proving_key = keys.proving_key()
});
std::cout << "Proof generated:" << std::endl;
std::cout << " Proof size: " << proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Public signals: " << proof.public_signals().size() << std::endl;
std::cout << " Proving time: " << proof.proving_time_ms() << "ms" << std::endl;
// Verify proof
std::cout << "\nVerifying proof..." << std::endl;
bool verified = zk.groth16().verify({
.proof = proof.proof_bytes(),
.public_signals = proof.public_signals(),
.verification_key = keys.verification_key()
});
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Export proof for on-chain verification
auto solidity_calldata = zk.groth16().export_calldata(proof);
std::cout << "\nSolidity calldata: " << solidity_calldata.substr(0, 100) << "..." << std::endl;
std::cout << std::endl;
}
void plonk_example(SynorZk& zk) {
std::cout << "=== PLONK Proving System ===" << std::endl;
std::string circuit_id = "multiplier-v1";
// PLONK uses universal trusted setup
std::cout << "Getting universal setup..." << std::endl;
auto srs = zk.plonk().get_universal_setup(14); // 2^14 constraints
std::cout << "SRS loaded: " << srs.size() << " bytes" << std::endl;
// Generate circuit-specific keys
std::cout << "\nGenerating circuit keys..." << std::endl;
auto keys = zk.plonk().setup(circuit_id, srs);
std::cout << "Keys generated" << std::endl;
// Generate proof
std::map<std::string, std::string> witness = {{"a", "5"}, {"b", "9"}};
std::cout << "\nGenerating PLONK proof..." << std::endl;
auto proof = zk.plonk().prove({
.circuit_id = circuit_id,
.witness = witness,
.proving_key = keys.proving_key()
});
std::cout << "Proof generated:" << std::endl;
std::cout << " Proof size: " << proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Proving time: " << proof.proving_time_ms() << "ms" << std::endl;
// Verify proof
bool verified = zk.plonk().verify({
.proof = proof.proof_bytes(),
.public_signals = proof.public_signals(),
.verification_key = keys.verification_key()
});
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Compare with Groth16
std::cout << "\nPLONK advantages:" << std::endl;
std::cout << " - Universal trusted setup" << std::endl;
std::cout << " - Larger proofs (~2.5 KB vs ~200 bytes)" << std::endl;
std::cout << " - Faster proving for some circuits" << std::endl;
std::cout << std::endl;
}
void stark_example(SynorZk& zk) {
std::cout << "=== STARK Proving System ===" << std::endl;
std::string circuit_id = "multiplier-v1";
// STARKs don't need trusted setup
std::cout << "Configuring STARK parameters..." << std::endl;
StarkConfig config{
.field_size = 256,
.hash_function = HashFunction::Poseidon,
.blowup_factor = 8,
.num_queries = 30,
.folding_factor = 8
};
// Generate proof
std::map<std::string, std::string> witness = {{"a", "11"}, {"b", "13"}};
std::cout << "\nGenerating STARK proof..." << std::endl;
auto proof = zk.stark().prove({
.circuit_id = circuit_id,
.witness = witness,
.config = config
});
std::cout << "Proof generated:" << std::endl;
std::cout << " Proof size: " << proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Proving time: " << proof.proving_time_ms() << "ms" << std::endl;
std::cout << " FRI layers: " << proof.fri_layers() << std::endl;
// Verify proof
std::cout << "\nVerifying STARK proof..." << std::endl;
bool verified = zk.stark().verify({
.proof = proof.proof_bytes(),
.public_signals = proof.public_signals(),
.config = config
});
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Compare with SNARKs
std::cout << "\nSTARK advantages:" << std::endl;
std::cout << " - No trusted setup needed" << std::endl;
std::cout << " - Post-quantum secure" << std::endl;
std::cout << " - Larger proofs (~100 KB)" << std::endl;
std::cout << " - Faster proving for complex computations" << std::endl;
std::cout << std::endl;
}
void recursive_example(SynorZk& zk) {
std::cout << "=== Recursive Proof Composition ===" << std::endl;
// Create inner proofs
std::cout << "Generating inner proofs..." << std::endl;
std::vector<RecursiveProof> inner_proofs;
for (int i = 1; i <= 3; ++i) {
std::map<std::string, std::string> witness = {
{"a", std::to_string(i)},
{"b", std::to_string(i + 1)}
};
auto proof = zk.recursive().prove_inner({
.circuit_id = "multiplier-v1",
.witness = witness,
.level = 0
});
inner_proofs.push_back(proof);
std::cout << " Inner proof " << i << " generated" << std::endl;
}
// Aggregate proofs recursively
std::cout << "\nAggregating proofs..." << std::endl;
auto aggregated_proof = zk.recursive().aggregate({
.proofs = inner_proofs,
.aggregation_circuit = "recursive-aggregator-v1"
});
std::cout << "Aggregated proof:" << std::endl;
std::cout << " Proof size: " << aggregated_proof.proof_bytes().size() << " bytes" << std::endl;
std::cout << " Proofs aggregated: " << aggregated_proof.proofs_aggregated() << std::endl;
std::cout << " Recursion depth: " << aggregated_proof.recursion_depth() << std::endl;
// Verify aggregated proof (verifies all inner proofs at once)
std::cout << "\nVerifying aggregated proof..." << std::endl;
bool verified = zk.recursive().verify_aggregated(aggregated_proof);
std::cout << "Verification result: " << (verified ? "true" : "false") << std::endl;
// Use cases
std::cout << "\nRecursive proof use cases:" << std::endl;
std::cout << " - Rollup batch verification" << std::endl;
std::cout << " - Incremental computation proofs" << std::endl;
std::cout << " - Cross-chain state proofs" << std::endl;
std::cout << std::endl;
}
void ceremony_example(SynorZk& zk) {
std::cout << "=== Trusted Setup Ceremony ===" << std::endl;
// List active ceremonies
auto ceremonies = zk.ceremony().list(CeremonyStatus::Active);
std::cout << "Active ceremonies: " << ceremonies.size() << std::endl;
for (size_t i = 0; i < std::min(ceremonies.size(), size_t(3)); ++i) {
const auto& ceremony = ceremonies[i];
std::cout << "\n " << ceremony.ceremony_id() << ":" << std::endl;
std::cout << " Circuit: " << ceremony.circuit_id() << std::endl;
std::cout << " Participants: " << ceremony.participant_count() << std::endl;
std::cout << " Current round: " << ceremony.current_round() << std::endl;
std::cout << " Status: " << ceremony.status() << std::endl;
}
// Create a new ceremony
std::cout << "\nCreating new ceremony..." << std::endl;
auto new_ceremony = zk.ceremony().create({
.circuit_id = "new-circuit-v1",
.min_participants = 10,
.max_participants = 100,
.round_duration = 3600, // 1 hour per round
.verify_contributions = true
});
std::cout << "Ceremony created:" << std::endl;
std::cout << " Ceremony ID: " << new_ceremony.ceremony_id() << std::endl;
std::cout << " Join URL: " << new_ceremony.join_url() << std::endl;
// Participate in a ceremony
std::cout << "\nParticipating in ceremony..." << std::endl;
// Generate entropy
std::vector<uint8_t> entropy(32);
std::random_device rd;
std::generate(entropy.begin(), entropy.end(), std::ref(rd));
auto contribution = zk.ceremony().contribute({
.ceremony_id = new_ceremony.ceremony_id(),
.entropy = entropy
});
std::cout << "Contribution made:" << std::endl;
std::cout << " Contribution ID: " << contribution.contribution_id() << std::endl;
std::cout << " Position: " << contribution.position() << std::endl;
std::cout << " Hash: " << contribution.hash() << std::endl;
// Verify a contribution
std::cout << "\nVerifying contribution..." << std::endl;
bool valid = zk.ceremony().verify_contribution(contribution.contribution_id());
std::cout << "Contribution valid: " << (valid ? "true" : "false") << std::endl;
// Get ceremony transcript (for auditability)
auto transcript = zk.ceremony().get_transcript(new_ceremony.ceremony_id());
std::cout << "\nCeremony transcript:" << std::endl;
std::cout << " Total contributions: " << transcript.contributions().size() << std::endl;
std::cout << " Start time: " << transcript.start_time() << std::endl;
std::cout << " Final hash: " << (transcript.final_hash().empty() ? "pending" : transcript.final_hash()) << std::endl;
std::cout << std::endl;
}
int main(int argc, char** argv) {
// Initialize client
const char* api_key = std::getenv("SYNOR_API_KEY");
ZkConfig config{
.api_key = api_key ? api_key : "your-api-key",
.endpoint = "https://zk.synor.io/v1",
.timeout = std::chrono::seconds(120), // ZK operations can be slow
.retries = 3,
.debug = false,
.default_proving_system = ProvingSystem::Groth16,
.prove_timeout = std::chrono::seconds(300),
.verify_timeout = std::chrono::seconds(30)
};
SynorZk zk(config);
try {
// Check service health
bool healthy = zk.health_check();
std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl;
// Run examples
circuit_example(zk);
groth16_example(zk);
plonk_example(zk);
stark_example(zk);
recursive_example(zk);
ceremony_example(zk);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

View file

@ -0,0 +1,415 @@
/**
* Synor Compiler SDK Examples for C#
*
* Demonstrates smart contract compilation and analysis:
* - WASM contract compilation and optimization
* - ABI extraction and encoding
* - Contract analysis and security scanning
* - Validation and verification
*/
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Synor.Compiler;
namespace Synor.Examples;
public class CompilerExample
{
private readonly SynorCompiler _compiler;
public CompilerExample(SynorCompiler compiler)
{
_compiler = compiler;
}
/// <summary>
/// Creates a minimal valid WASM module for testing
/// </summary>
private static byte[] CreateMinimalWasm()
{
return new byte[]
{
0x00, 0x61, 0x73, 0x6d, // Magic: \0asm
0x01, 0x00, 0x00, 0x00, // Version: 1
// Type section
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
// Function section
0x03, 0x02, 0x01, 0x00,
// Export section
0x07, 0x08, 0x01, 0x04, (byte)'a', (byte)'d', (byte)'d', 0x00, 0x00,
// Code section
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
};
}
public async Task RunCompileContractExample()
{
Console.WriteLine("=== Contract Compilation ===");
var wasm = CreateMinimalWasm();
var result = await _compiler.CompileAsync(wasm, new CompileOptions
{
OptimizationLevel = OptimizationLevel.Size,
UseWasmOpt = true,
Validate = true,
ExtractMetadata = true,
GenerateAbi = true,
StripOptions = new StripOptions
{
StripDebug = true,
StripProducers = true,
StripNames = true,
StripCustom = true,
StripUnused = true,
PreserveSections = new List<string>()
}
});
Console.WriteLine("Compilation result:");
Console.WriteLine($" Contract ID: {result.ContractId}");
Console.WriteLine($" Code hash: {result.CodeHash}");
Console.WriteLine($" Original size: {result.OriginalSize} bytes");
Console.WriteLine($" Optimized size: {result.OptimizedSize} bytes");
Console.WriteLine($" Size reduction: {result.SizeReduction:F1}%");
Console.WriteLine($" Estimated deploy gas: {result.EstimatedDeployGas}");
if (result.Metadata != null)
{
Console.WriteLine("\nMetadata:");
Console.WriteLine($" Name: {result.Metadata.Name}");
Console.WriteLine($" Version: {result.Metadata.Version}");
Console.WriteLine($" SDK Version: {result.Metadata.SdkVersion}");
}
if (result.Abi != null)
{
Console.WriteLine("\nABI:");
Console.WriteLine($" Functions: {result.Abi.Functions.Count}");
Console.WriteLine($" Events: {result.Abi.Events.Count}");
Console.WriteLine($" Errors: {result.Abi.Errors.Count}");
}
Console.WriteLine();
}
public async Task RunCompilationModesExample()
{
Console.WriteLine("=== Compilation Modes ===");
var wasm = CreateMinimalWasm();
// Development mode: fast compilation, debugging support
Console.WriteLine("Development mode:");
var devResult = await _compiler.Contracts.CompileDevAsync(wasm);
Console.WriteLine($" Size: {devResult.OptimizedSize} bytes");
Console.WriteLine(" Optimization: none");
// Production mode: maximum optimization
Console.WriteLine("\nProduction mode:");
var prodResult = await _compiler.Contracts.CompileProductionAsync(wasm);
Console.WriteLine($" Size: {prodResult.OptimizedSize} bytes");
Console.WriteLine(" Optimization: aggressive");
Console.WriteLine($" Size savings: {devResult.OptimizedSize - prodResult.OptimizedSize} bytes");
// Custom optimization levels
Console.WriteLine("\nOptimization levels:");
var levels = new (OptimizationLevel Level, string Name)[]
{
(OptimizationLevel.None, "NONE"),
(OptimizationLevel.Basic, "BASIC"),
(OptimizationLevel.Size, "SIZE"),
(OptimizationLevel.Aggressive, "AGGRESSIVE")
};
foreach (var (level, name) in levels)
{
var result = await _compiler.CompileAsync(wasm, new CompileOptions
{
OptimizationLevel = level
});
Console.WriteLine($" {name}: {result.OptimizedSize} bytes");
}
Console.WriteLine();
}
public async Task RunAbiExample()
{
Console.WriteLine("=== ABI Operations ===");
var wasm = CreateMinimalWasm();
// Extract ABI from WASM
var abi = await _compiler.Abi.ExtractAsync(wasm);
Console.WriteLine($"Contract: {abi.Name}");
Console.WriteLine($"Version: {abi.Version}");
// List functions
if (abi.Functions.Count > 0)
{
Console.WriteLine("\nFunctions:");
foreach (var func in abi.Functions)
{
var inputs = string.Join(", ", func.Inputs.ConvertAll(p => $"{p.Name}: {p.Type.TypeName}"));
var outputs = func.Outputs.Count == 0
? "void"
: string.Join(", ", func.Outputs.ConvertAll(o => o.Type.TypeName));
var modifiers = new List<string>();
if (func.View) modifiers.Add("view");
if (func.Payable) modifiers.Add("payable");
var modifierStr = modifiers.Count > 0 ? string.Join(" ", modifiers) : "";
Console.WriteLine($" {func.Name}({inputs}) -> {outputs} {modifierStr}");
Console.WriteLine($" Selector: {func.Selector}");
}
}
// List events
if (abi.Events.Count > 0)
{
Console.WriteLine("\nEvents:");
foreach (var evt in abi.Events)
{
var paramParts = new List<string>();
foreach (var param in evt.Params)
{
var prefix = param.Indexed ? "indexed " : "";
paramParts.Add($"{prefix}{param.Name}: {param.Type.TypeName}");
}
Console.WriteLine($" {evt.Name}({string.Join(", ", paramParts)})");
Console.WriteLine($" Topic: {evt.Topic}");
}
}
// Encode a function call
if (abi.Functions.Count > 0)
{
var func = abi.Functions[0];
var encoded = await _compiler.Abi.EncodeCallAsync(func, new[] { "arg1", "arg2" });
Console.WriteLine($"\nEncoded call to {func.Name}: {encoded}");
// Decode a result
var decoded = await _compiler.Abi.DecodeResultAsync(func, encoded);
Console.WriteLine($"Decoded result: {decoded}");
}
Console.WriteLine();
}
public async Task RunAnalysisExample()
{
Console.WriteLine("=== Contract Analysis ===");
var wasm = CreateMinimalWasm();
// Full analysis
var analysis = await _compiler.Analysis.AnalyzeAsync(wasm);
// Size breakdown
if (analysis.SizeBreakdown != null)
{
var size = analysis.SizeBreakdown;
Console.WriteLine("Size breakdown:");
Console.WriteLine($" Code: {size.Code} bytes");
Console.WriteLine($" Data: {size.Data} bytes");
Console.WriteLine($" Functions: {size.Functions} bytes");
Console.WriteLine($" Memory: {size.Memory} bytes");
Console.WriteLine($" Exports: {size.Exports} bytes");
Console.WriteLine($" Imports: {size.Imports} bytes");
Console.WriteLine($" Total: {size.Total} bytes");
}
// Function analysis
if (analysis.Functions.Count > 0)
{
Console.WriteLine("\nFunction analysis:");
foreach (var func in analysis.Functions.GetRange(0, Math.Min(analysis.Functions.Count, 5)))
{
Console.WriteLine($" {func.Name}:");
Console.WriteLine($" Size: {func.Size} bytes");
Console.WriteLine($" Instructions: {func.InstructionCount}");
Console.WriteLine($" Locals: {func.LocalCount}");
Console.WriteLine($" Exported: {func.Exported}");
Console.WriteLine($" Estimated gas: {func.EstimatedGas}");
}
}
// Import analysis
if (analysis.Imports.Count > 0)
{
Console.WriteLine("\nImports:");
foreach (var imp in analysis.Imports)
{
Console.WriteLine($" {imp.Module}.{imp.Name} ({imp.Kind})");
}
}
// Gas analysis
if (analysis.GasAnalysis != null)
{
var gas = analysis.GasAnalysis;
Console.WriteLine("\nGas analysis:");
Console.WriteLine($" Deployment: {gas.DeploymentGas}");
Console.WriteLine($" Memory init: {gas.MemoryInitGas}");
Console.WriteLine($" Data section: {gas.DataSectionGas}");
}
// Extract metadata
var metadata = await _compiler.Analysis.ExtractMetadataAsync(wasm);
Console.WriteLine("\nContract metadata:");
Console.WriteLine($" Name: {metadata.Name}");
Console.WriteLine($" Version: {metadata.Version}");
Console.WriteLine($" Build timestamp: {metadata.BuildTimestamp}");
// Estimate deployment gas
var gasEstimate = await _compiler.Analysis.EstimateDeployGasAsync(wasm);
Console.WriteLine($"\nEstimated deployment gas: {gasEstimate}");
Console.WriteLine();
}
public async Task RunValidationExample()
{
Console.WriteLine("=== Contract Validation ===");
var wasm = CreateMinimalWasm();
// Full validation
var result = await _compiler.Validation.ValidateAsync(wasm);
Console.WriteLine($"Valid: {result.Valid}");
Console.WriteLine($"Exports: {result.ExportCount}");
Console.WriteLine($"Imports: {result.ImportCount}");
Console.WriteLine($"Functions: {result.FunctionCount}");
Console.WriteLine($"Memory pages: {result.MemoryPages}");
if (result.Errors.Count > 0)
{
Console.WriteLine("\nValidation errors:");
foreach (var error in result.Errors)
{
Console.WriteLine($" [{error.Code}] {error.Message}");
if (!string.IsNullOrEmpty(error.Location))
{
Console.WriteLine($" at {error.Location}");
}
}
}
if (result.Warnings.Count > 0)
{
Console.WriteLine("\nWarnings:");
foreach (var warning in result.Warnings)
{
Console.WriteLine($" {warning}");
}
}
// Quick validation
var isValid = await _compiler.Validation.IsValidAsync(wasm);
Console.WriteLine($"\nQuick validation: {isValid}");
// Get validation errors only
var errors = await _compiler.Validation.GetErrorsAsync(wasm);
Console.WriteLine($"Error count: {errors.Count}");
// Validate required exports
var hasRequired = await _compiler.Validation.ValidateExportsAsync(wasm, new[] { "init", "execute", "query" });
Console.WriteLine($"Has required exports: {hasRequired}");
// Validate memory constraints
var memoryValid = await _compiler.Validation.ValidateMemoryAsync(wasm, 16);
Console.WriteLine($"Memory within 16 pages: {memoryValid}");
Console.WriteLine();
}
public async Task RunSecurityExample()
{
Console.WriteLine("=== Security Scanning ===");
var wasm = CreateMinimalWasm();
var security = await _compiler.Analysis.SecurityScanAsync(wasm);
Console.WriteLine($"Security score: {security.Score}/100");
if (security.Issues.Count > 0)
{
Console.WriteLine("\nSecurity issues:");
foreach (var issue in security.Issues)
{
var icon = issue.Severity switch
{
"critical" => "[CRIT]",
"high" => "[HIGH]",
"medium" => "[MED]",
"low" => "[LOW]",
_ => "[???]"
};
Console.WriteLine($"{icon} [{issue.Severity}] {issue.Type}");
Console.WriteLine($" {issue.Description}");
if (!string.IsNullOrEmpty(issue.Location))
{
Console.WriteLine($" at {issue.Location}");
}
}
}
else
{
Console.WriteLine("No security issues found!");
}
if (security.Recommendations.Count > 0)
{
Console.WriteLine("\nRecommendations:");
foreach (var rec in security.Recommendations)
{
Console.WriteLine($" • {rec}");
}
}
Console.WriteLine();
}
public static async Task Main(string[] args)
{
// Initialize client
var apiKey = Environment.GetEnvironmentVariable("SYNOR_API_KEY") ?? "your-api-key";
var config = new CompilerConfig
{
ApiKey = apiKey,
Endpoint = "https://compiler.synor.io/v1",
Timeout = TimeSpan.FromSeconds(60),
Retries = 3,
Debug = false,
DefaultOptimizationLevel = OptimizationLevel.Size,
MaxContractSize = 256 * 1024,
UseWasmOpt = true,
Validate = true,
ExtractMetadata = true,
GenerateAbi = true
};
var compiler = new SynorCompiler(config);
var example = new CompilerExample(compiler);
try
{
// Check service health
var healthy = await compiler.HealthCheckAsync();
Console.WriteLine($"Service healthy: {healthy}\n");
// Run examples
await example.RunCompileContractExample();
await example.RunCompilationModesExample();
await example.RunAbiExample();
await example.RunAnalysisExample();
await example.RunValidationExample();
await example.RunSecurityExample();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
Environment.Exit(1);
}
}
}

View file

@ -0,0 +1,272 @@
/**
* Synor Crypto SDK Examples for C#
*
* Demonstrates quantum-resistant cryptographic operations:
* - Hybrid Ed25519 + Dilithium3 signatures
* - BIP-39 mnemonic generation and validation
* - Post-quantum algorithms (Falcon, SPHINCS+)
* - Key derivation functions
*/
using System;
using System.Text;
using System.Threading.Tasks;
using Synor.Crypto;
namespace Synor.Examples;
public class CryptoExample
{
private readonly SynorCrypto _crypto;
public CryptoExample(SynorCrypto crypto)
{
_crypto = crypto;
}
public async Task RunMnemonicExample()
{
Console.WriteLine("=== Mnemonic Operations ===");
// Generate a 24-word mnemonic (256-bit entropy)
var mnemonic = await _crypto.Mnemonic.GenerateAsync(24);
Console.WriteLine($"Generated mnemonic: {mnemonic.Phrase}");
Console.WriteLine($"Word count: {mnemonic.WordCount}");
// Validate a mnemonic
var validation = await _crypto.Mnemonic.ValidateAsync(mnemonic.Phrase);
Console.WriteLine($"Valid: {validation.IsValid}");
if (!validation.IsValid)
{
Console.WriteLine($"Error: {validation.Error}");
}
// Convert mnemonic to seed
var seed = await _crypto.Mnemonic.ToSeedAsync(mnemonic.Phrase, "optional-passphrase");
Console.WriteLine($"Seed (hex): {BytesToHex(seed, 16)}...");
// Word suggestions for autocomplete
var suggestions = await _crypto.Mnemonic.SuggestWordsAsync("aban", 5);
Console.WriteLine($"Suggestions for 'aban': {string.Join(", ", suggestions)}");
Console.WriteLine();
}
public async Task RunKeypairExample()
{
Console.WriteLine("=== Keypair Operations ===");
// Generate a random keypair
var keypair = await _crypto.Keypairs.GenerateAsync();
Console.WriteLine("Generated hybrid keypair:");
Console.WriteLine($" Ed25519 public key size: {keypair.PublicKey.Ed25519Bytes.Length} bytes");
Console.WriteLine($" Dilithium public key size: {keypair.PublicKey.DilithiumBytes.Length} bytes");
Console.WriteLine($" Total public key size: {keypair.PublicKey.Size} bytes");
// Get addresses for different networks
Console.WriteLine("\nAddresses:");
Console.WriteLine($" Mainnet: {keypair.GetAddress(Network.Mainnet)}");
Console.WriteLine($" Testnet: {keypair.GetAddress(Network.Testnet)}");
Console.WriteLine($" Devnet: {keypair.GetAddress(Network.Devnet)}");
// Create keypair from mnemonic (deterministic)
var mnemonic = await _crypto.Mnemonic.GenerateAsync(24);
var keypair2 = await _crypto.Keypairs.FromMnemonicAsync(mnemonic.Phrase);
var addr = keypair2.GetAddress(Network.Mainnet);
Console.WriteLine($"\nKeypair from mnemonic: {addr[..20]}...");
// Derive child keypair using BIP-44 path
var path = DerivationPath.External(0, 0); // m/44'/21337'/0'/0/0
Console.WriteLine($"Derivation path: {path}");
Console.WriteLine();
}
public async Task RunSigningExample()
{
Console.WriteLine("=== Hybrid Signing ===");
// Generate keypair
var keypair = await _crypto.Keypairs.GenerateAsync();
// Sign a message
var message = Encoding.UTF8.GetBytes("Hello, quantum-resistant world!");
var signature = await _crypto.Signing.SignAsync(keypair, message);
Console.WriteLine("Signature created:");
Console.WriteLine($" Ed25519 component: {signature.Ed25519Bytes.Length} bytes");
Console.WriteLine($" Dilithium component: {signature.DilithiumBytes.Length} bytes");
Console.WriteLine($" Total signature size: {signature.Size} bytes");
// Verify the signature
var valid = await _crypto.Signing.VerifyAsync(keypair.PublicKey, message, signature);
Console.WriteLine($"\nVerification result: {valid}");
// Verify with tampered message fails
var tamperedMessage = Encoding.UTF8.GetBytes("Hello, tampered message!");
var invalidResult = await _crypto.Signing.VerifyAsync(keypair.PublicKey, tamperedMessage, signature);
Console.WriteLine($"Tampered message verification: {invalidResult}");
Console.WriteLine();
}
public async Task RunFalconExample()
{
Console.WriteLine("=== Falcon Post-Quantum Signatures ===");
// Generate Falcon-512 keypair (128-bit security)
var falcon512 = await _crypto.Falcon.GenerateAsync(FalconVariant.Falcon512);
Console.WriteLine("Falcon-512 keypair:");
Console.WriteLine($" Public key: {falcon512.PublicKey.KeyBytes.Length} bytes");
Console.WriteLine(" Security level: 128-bit");
// Generate Falcon-1024 keypair (256-bit security)
var falcon1024 = await _crypto.Falcon.GenerateAsync(FalconVariant.Falcon1024);
Console.WriteLine("\nFalcon-1024 keypair:");
Console.WriteLine($" Public key: {falcon1024.PublicKey.KeyBytes.Length} bytes");
Console.WriteLine(" Security level: 256-bit");
// Sign with Falcon-512
var message = Encoding.UTF8.GetBytes("Post-quantum secure message");
var signature = await _crypto.Falcon.SignAsync(falcon512, message);
Console.WriteLine($"\nFalcon-512 signature: {signature.SignatureBytes.Length} bytes");
// Verify
var valid = await _crypto.Falcon.VerifyAsync(falcon512.PublicKey.KeyBytes, message, signature);
Console.WriteLine($"Verification: {valid}");
Console.WriteLine();
}
public async Task RunSphincsExample()
{
Console.WriteLine("=== SPHINCS+ Hash-Based Signatures ===");
// SPHINCS+ variants with different security levels
var variants = new (SphincsVariant Variant, int Security, int SigSize, string Name)[]
{
(SphincsVariant.Shake128s, 128, 7856, "SHAKE128S"),
(SphincsVariant.Shake192s, 192, 16224, "SHAKE192S"),
(SphincsVariant.Shake256s, 256, 29792, "SHAKE256S"),
};
var message = Encoding.UTF8.GetBytes("Hash-based quantum security");
foreach (var (variant, security, sigSize, name) in variants)
{
var keypair = await _crypto.Sphincs.GenerateAsync(variant);
Console.WriteLine($"SPHINCS+ {name}:");
Console.WriteLine($" Security level: {security}-bit");
Console.WriteLine($" Expected signature size: {sigSize} bytes");
// Sign a message
var signature = await _crypto.Sphincs.SignAsync(keypair, message);
Console.WriteLine($" Actual signature size: {signature.SignatureBytes.Length} bytes");
// Verify
var valid = await _crypto.Sphincs.VerifyAsync(keypair.PublicKey.KeyBytes, message, signature);
Console.WriteLine($" Verification: {valid}");
Console.WriteLine();
}
}
public async Task RunKdfExample()
{
Console.WriteLine("=== Key Derivation Functions ===");
// HKDF (HMAC-based Key Derivation Function)
var seed = Encoding.UTF8.GetBytes("master-secret-key-material-here");
var hkdfConfig = new DerivationConfig
{
Salt = Encoding.UTF8.GetBytes("application-salt"),
Info = Encoding.UTF8.GetBytes("encryption-key"),
OutputLength = 32
};
var derivedKey = await _crypto.Kdf.DeriveKeyAsync(seed, hkdfConfig);
Console.WriteLine($"HKDF derived key: {BytesToHex(derivedKey)}");
// PBKDF2 (Password-Based Key Derivation Function)
var password = Encoding.UTF8.GetBytes("user-password");
var pbkdf2Config = new PasswordDerivationConfig
{
Salt = Encoding.UTF8.GetBytes("random-salt-value"),
Iterations = 100000,
OutputLength = 32
};
var passwordKey = await _crypto.Kdf.DeriveFromPasswordAsync(password, pbkdf2Config);
Console.WriteLine($"PBKDF2 derived key: {BytesToHex(passwordKey)}");
Console.WriteLine();
}
public async Task RunHashExample()
{
Console.WriteLine("=== Hash Functions ===");
var data = Encoding.UTF8.GetBytes("Data to hash");
// SHA3-256 (FIPS 202)
var sha3 = await _crypto.Hash.Sha3_256Async(data);
Console.WriteLine($"SHA3-256: {sha3.Hex}");
// BLAKE3 (fast, parallel)
var blake3 = await _crypto.Hash.Blake3Async(data);
Console.WriteLine($"BLAKE3: {blake3.Hex}");
// Keccak-256 (Ethereum compatible)
var keccak = await _crypto.Hash.Keccak256Async(data);
Console.WriteLine($"Keccak: {keccak.Hex}");
Console.WriteLine();
}
private static string BytesToHex(byte[] data, int? maxLen = null)
{
var len = maxLen ?? data.Length;
var sb = new StringBuilder(len * 2);
for (var i = 0; i < Math.Min(len, data.Length); i++)
{
sb.AppendFormat("{0:x2}", data[i]);
}
if (maxLen.HasValue && maxLen.Value < data.Length)
{
sb.Append("...");
}
return sb.ToString();
}
public static async Task Main(string[] args)
{
// Initialize client
var apiKey = Environment.GetEnvironmentVariable("SYNOR_API_KEY") ?? "your-api-key";
var config = new CryptoConfig
{
ApiKey = apiKey,
Endpoint = "https://crypto.synor.io/v1",
Timeout = TimeSpan.FromSeconds(30),
Retries = 3,
Debug = false,
DefaultNetwork = Network.Mainnet
};
var crypto = new SynorCrypto(config);
var example = new CryptoExample(crypto);
try
{
// Check service health
var healthy = await crypto.HealthCheckAsync();
Console.WriteLine($"Service healthy: {healthy}\n");
// Run examples
await example.RunMnemonicExample();
await example.RunKeypairExample();
await example.RunSigningExample();
await example.RunFalconExample();
await example.RunSphincsExample();
await example.RunKdfExample();
await example.RunHashExample();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
Environment.Exit(1);
}
}
}

View file

@ -0,0 +1,324 @@
/**
* 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);
}
}
}

View file

@ -0,0 +1,326 @@
/**
* Synor IBC SDK Examples for C#
*
* Demonstrates Inter-Blockchain Communication operations:
* - Chain and channel management
* - Cross-chain token transfers
* - Packet lifecycle handling
* - Relayer operations
* - Connection monitoring
*/
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Synor.Ibc;
namespace Synor.Examples;
public class IbcExample
{
private readonly SynorIbc _ibc;
public IbcExample(SynorIbc ibc)
{
_ibc = ibc;
}
public async Task RunChainsExample()
{
Console.WriteLine("=== Chain Information ===");
// List connected chains
var chains = await _ibc.Chains.ListAsync();
Console.WriteLine($"Connected chains: {chains.Count}");
foreach (var chain in chains.GetRange(0, Math.Min(chains.Count, 5)))
{
Console.WriteLine($" {chain.ChainId}: {chain.Name} ({chain.Status})");
}
// Get specific chain info
var cosmosHub = await _ibc.Chains.GetAsync("cosmoshub-4");
Console.WriteLine($"\n{cosmosHub.Name}:");
Console.WriteLine($" Chain ID: {cosmosHub.ChainId}");
Console.WriteLine($" RPC endpoint: {cosmosHub.RpcEndpoint}");
Console.WriteLine($" Block height: {cosmosHub.LatestHeight}");
Console.WriteLine($" Active channels: {cosmosHub.ActiveChannels}");
// Get chain clients
var clients = await _ibc.Chains.GetClientsAsync("cosmoshub-4");
Console.WriteLine($"\nIBC clients: {clients.Count}");
foreach (var client in clients.GetRange(0, Math.Min(clients.Count, 3)))
{
Console.WriteLine($" {client.ClientId}: {client.ChainId} ({client.ClientType})");
}
Console.WriteLine();
}
public async Task RunChannelsExample()
{
Console.WriteLine("=== Channel Management ===");
// List channels
var channels = await _ibc.Channels.ListAsync();
Console.WriteLine($"IBC channels: {channels.Count}");
foreach (var channel in channels.GetRange(0, Math.Min(channels.Count, 5)))
{
Console.WriteLine($" {channel.ChannelId}: {channel.SourceChain} <-> {channel.DestChain} ({channel.State})");
}
// Get channel details
var channelId = "channel-0";
var channel = await _ibc.Channels.GetAsync(channelId);
Console.WriteLine($"\nChannel {channelId}:");
Console.WriteLine($" State: {channel.State}");
Console.WriteLine($" Port: {channel.PortId}");
Console.WriteLine($" Counterparty: {channel.CounterpartyChannelId}");
Console.WriteLine($" Connection: {channel.ConnectionId}");
Console.WriteLine($" Ordering: {channel.Ordering}");
Console.WriteLine($" Version: {channel.Version}");
// Create a new channel (4-step handshake)
Console.WriteLine("\nInitiating channel creation...");
var initResult = await _ibc.Channels.InitAsync(new ChannelInitRequest
{
SourceChain = "synor-mainnet",
DestChain = "osmosis-1",
PortId = "transfer",
Version = "ics20-1"
});
Console.WriteLine($" ChanOpenInit sent: {initResult.ChannelId}");
// In production, the following steps happen through relayers:
// ChanOpenTry -> ChanOpenAck -> ChanOpenConfirm
// Get channel statistics
var stats = await _ibc.Channels.GetStatsAsync(channelId);
Console.WriteLine($"\nChannel statistics:");
Console.WriteLine($" Packets sent: {stats.PacketsSent}");
Console.WriteLine($" Packets received: {stats.PacketsReceived}");
Console.WriteLine($" Packets acknowledged: {stats.PacketsAcknowledged}");
Console.WriteLine($" Packets timed out: {stats.PacketsTimedOut}");
Console.WriteLine();
}
public async Task RunTransferExample()
{
Console.WriteLine("=== Cross-Chain Transfers ===");
// Get transfer routes
Console.WriteLine("Available transfer routes:");
var routes = await _ibc.Transfers.GetRoutesAsync("ATOM", "synor-mainnet");
foreach (var route in routes)
{
Console.WriteLine($" {route.SourceChain} -> {route.DestChain}: {route.ChannelId}");
Console.WriteLine($" Estimated time: {route.EstimatedTime}");
Console.WriteLine($" Fee: {route.Fee} {route.FeeAsset}");
}
// Initiate a transfer
Console.WriteLine("\nInitiating transfer...");
var transfer = await _ibc.Transfers.SendAsync(new TransferRequest
{
SourceChain = "cosmoshub-4",
DestChain = "synor-mainnet",
ChannelId = "channel-0",
Asset = "uatom",
Amount = "1000000", // 1 ATOM
Sender = "cosmos1abc...",
Receiver = "synor1xyz...",
Timeout = TimeSpan.FromMinutes(30),
Memo = "IBC transfer test"
});
Console.WriteLine($"Transfer initiated:");
Console.WriteLine($" Transfer ID: {transfer.TransferId}");
Console.WriteLine($" Sequence: {transfer.Sequence}");
Console.WriteLine($" Status: {transfer.Status}");
// Track transfer status
Console.WriteLine("\nTracking transfer...");
var status = await _ibc.Transfers.GetStatusAsync(transfer.TransferId);
Console.WriteLine($" Current status: {status.Status}");
Console.WriteLine($" Source tx: {status.SourceTxHash}");
if (!string.IsNullOrEmpty(status.DestTxHash))
{
Console.WriteLine($" Dest tx: {status.DestTxHash}");
}
// Get transfer history
var history = await _ibc.Transfers.GetHistoryAsync(new TransferHistoryFilter
{
Limit = 5
});
Console.WriteLine($"\nRecent transfers: {history.Count}");
foreach (var tx in history)
{
Console.WriteLine($" {tx.TransferId}: {tx.Amount} {tx.Asset} ({tx.Status})");
}
Console.WriteLine();
}
public async Task RunPacketExample()
{
Console.WriteLine("=== Packet Handling ===");
// Get pending packets
var pendingPackets = await _ibc.Packets.GetPendingAsync("channel-0");
Console.WriteLine($"Pending packets: {pendingPackets.Count}");
foreach (var packet in pendingPackets.GetRange(0, Math.Min(pendingPackets.Count, 5)))
{
Console.WriteLine($" Seq {packet.Sequence}: {packet.SourcePort} -> {packet.DestPort}");
}
// Get packet details
if (pendingPackets.Count > 0)
{
var packet = await _ibc.Packets.GetAsync("channel-0", pendingPackets[0].Sequence);
Console.WriteLine($"\nPacket {packet.Sequence}:");
Console.WriteLine($" Source: {packet.SourcePort}/{packet.SourceChannel}");
Console.WriteLine($" Dest: {packet.DestPort}/{packet.DestChannel}");
Console.WriteLine($" Timeout height: {packet.TimeoutHeight}");
Console.WriteLine($" Timeout timestamp: {packet.TimeoutTimestamp}");
Console.WriteLine($" Data: {Convert.ToHexString(packet.Data)[..Math.Min(packet.Data.Length * 2, 64)]}...");
}
// Query packet commitments
var commitments = await _ibc.Packets.GetCommitmentsAsync("channel-0");
Console.WriteLine($"\nPacket commitments: {commitments.Count}");
// Query unreceived packets
var unreceived = await _ibc.Packets.GetUnreceivedAsync("channel-0", new ulong[] { 1, 2, 3, 4, 5 });
Console.WriteLine($"Unreceived packets: {string.Join(", ", unreceived)}");
// Query acknowledgements
var acks = await _ibc.Packets.GetAcknowledgementsAsync("channel-0");
Console.WriteLine($"Packet acknowledgements: {acks.Count}");
Console.WriteLine();
}
public async Task RunRelayerExample()
{
Console.WriteLine("=== Relayer Operations ===");
// Get relayer status
var relayers = await _ibc.Relayer.ListAsync();
Console.WriteLine($"Active relayers: {relayers.Count}");
foreach (var relayer in relayers.GetRange(0, Math.Min(relayers.Count, 3)))
{
Console.WriteLine($" {relayer.Address}: {relayer.PacketsRelayed} packets ({relayer.Status})");
}
// Register as a relayer
Console.WriteLine("\nRegistering as relayer...");
var registration = await _ibc.Relayer.RegisterAsync(new RelayerRegistration
{
Address = "synor1relayer...",
Chains = new List<string> { "synor-mainnet", "cosmoshub-4", "osmosis-1" },
Commission = 0.1m // 0.1%
});
Console.WriteLine($" Registered: {registration.RelayerId}");
// Start relaying
Console.WriteLine("\nStarting packet relay...");
var relayConfig = new RelayConfig
{
Channels = new List<string> { "channel-0", "channel-1" },
BatchSize = 10,
PollInterval = TimeSpan.FromSeconds(5)
};
// In production, this would run continuously
var pendingCount = await _ibc.Relayer.GetPendingCountAsync(relayConfig.Channels);
Console.WriteLine($" Pending packets to relay: {pendingCount}");
// Relay a batch
var relayResult = await _ibc.Relayer.RelayBatchAsync("channel-0", 5);
Console.WriteLine($" Relayed: {relayResult.PacketsRelayed}");
Console.WriteLine($" Fees earned: {relayResult.FeesEarned}");
// Get relayer earnings
var earnings = await _ibc.Relayer.GetEarningsAsync("synor1relayer...");
Console.WriteLine($"\nRelayer earnings:");
Console.WriteLine($" Total earned: {earnings.TotalEarned}");
Console.WriteLine($" Packets relayed: {earnings.PacketsRelayed}");
Console.WriteLine($" Success rate: {earnings.SuccessRate:F1}%");
Console.WriteLine();
}
public async Task RunMonitoringExample()
{
Console.WriteLine("=== Connection Monitoring ===");
// Get connection health
var connections = await _ibc.Monitoring.GetConnectionsAsync();
Console.WriteLine("Connection health:");
foreach (var conn in connections)
{
var healthIcon = conn.Healthy ? "✓" : "✗";
Console.WriteLine($" [{healthIcon}] {conn.ConnectionId}: {conn.ChainA} <-> {conn.ChainB}");
Console.WriteLine($" Latency: {conn.Latency}ms, Uptime: {conn.Uptime:F1}%");
}
// Get channel metrics
var metrics = await _ibc.Monitoring.GetChannelMetricsAsync("channel-0");
Console.WriteLine($"\nChannel metrics:");
Console.WriteLine($" Throughput: {metrics.PacketsPerHour}/hour");
Console.WriteLine($" Avg latency: {metrics.AvgLatencyMs}ms");
Console.WriteLine($" Success rate: {metrics.SuccessRate:F1}%");
Console.WriteLine($" Volume 24h: {metrics.Volume24h}");
// Subscribe to events (in production)
Console.WriteLine("\nEvent subscription example:");
Console.WriteLine(" Subscribing to packet events...");
// await _ibc.Monitoring.SubscribeAsync("channel-0", (evt) => {
// Console.WriteLine($" Event: {evt.Type} - {evt.Data}");
// });
// Get alerts
var alerts = await _ibc.Monitoring.GetAlertsAsync();
Console.WriteLine($"\nActive alerts: {alerts.Count}");
foreach (var alert in alerts)
{
Console.WriteLine($" [{alert.Severity}] {alert.Message}");
Console.WriteLine($" Channel: {alert.ChannelId}, Time: {alert.Timestamp}");
}
Console.WriteLine();
}
public static async Task Main(string[] args)
{
// Initialize client
var apiKey = Environment.GetEnvironmentVariable("SYNOR_API_KEY") ?? "your-api-key";
var config = new IbcConfig
{
ApiKey = apiKey,
Endpoint = "https://ibc.synor.io/v1",
Timeout = TimeSpan.FromSeconds(60),
Retries = 3,
Debug = false,
DefaultTimeout = TimeSpan.FromMinutes(30)
};
var ibc = new SynorIbc(config);
var example = new IbcExample(ibc);
try
{
// Check service health
var healthy = await ibc.HealthCheckAsync();
Console.WriteLine($"Service healthy: {healthy}\n");
// Run examples
await example.RunChainsExample();
await example.RunChannelsExample();
await example.RunTransferExample();
await example.RunPacketExample();
await example.RunRelayerExample();
await example.RunMonitoringExample();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
Environment.Exit(1);
}
}
}

View file

@ -0,0 +1,399 @@
/**
* Synor ZK SDK Examples for C#
*
* Demonstrates zero-knowledge proof operations:
* - Circuit compilation (Circom)
* - Proof generation and verification
* - Multiple proving systems (Groth16, PLONK, STARK)
* - Recursive proof composition
* - Trusted setup ceremonies
*/
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Synor.Zk;
namespace Synor.Examples;
public class ZkExample
{
private readonly SynorZk _zk;
public ZkExample(SynorZk zk)
{
_zk = zk;
}
public async Task RunCircuitExample()
{
Console.WriteLine("=== Circuit Compilation ===");
// Simple Circom circuit: prove knowledge of factors
var circomCode = @"
pragma circom 2.1.0;
template Multiplier() {
signal input a;
signal input b;
signal output c;
c <== a * b;
}
component main = Multiplier();
";
// Compile the circuit
Console.WriteLine("Compiling circuit...");
var circuit = await _zk.Circuits.CompileAsync(new CompileRequest
{
Code = circomCode,
Language = CircuitLanguage.Circom
});
Console.WriteLine("Circuit compiled:");
Console.WriteLine($" Circuit ID: {circuit.CircuitId}");
Console.WriteLine($" Constraints: {circuit.Constraints}");
Console.WriteLine($" Public inputs: {circuit.PublicInputs}");
Console.WriteLine($" Private inputs: {circuit.PrivateInputs}");
Console.WriteLine($" Outputs: {circuit.Outputs}");
// Get circuit info
var info = await _zk.Circuits.GetAsync(circuit.CircuitId);
Console.WriteLine("\nCircuit info:");
Console.WriteLine($" Name: {info.Name}");
Console.WriteLine($" Version: {info.Version}");
Console.WriteLine($" Wires: {info.WireCount}");
Console.WriteLine($" Labels: {info.LabelCount}");
// List available circuits
var circuits = await _zk.Circuits.ListAsync();
Console.WriteLine($"\nAvailable circuits: {circuits.Count}");
foreach (var c in circuits.GetRange(0, Math.Min(circuits.Count, 3)))
{
Console.WriteLine($" {c.CircuitId}: {c.Name} ({c.Constraints} constraints)");
}
Console.WriteLine();
}
public async Task RunGroth16Example()
{
Console.WriteLine("=== Groth16 Proving System ===");
var circuitId = "multiplier-v1";
// Generate proving/verification keys (trusted setup)
Console.WriteLine("Generating keys...");
var keys = await _zk.Groth16.SetupAsync(circuitId);
Console.WriteLine("Keys generated:");
Console.WriteLine($" Proving key size: {keys.ProvingKey.Length} bytes");
Console.WriteLine($" Verification key size: {keys.VerificationKey.Length} bytes");
// Prepare witness (private inputs)
var witness = new Dictionary<string, string>
{
["a"] = "3",
["b"] = "7"
};
// Generate proof
Console.WriteLine("\nGenerating proof...");
var proof = await _zk.Groth16.ProveAsync(new ProveRequest
{
CircuitId = circuitId,
Witness = witness,
ProvingKey = keys.ProvingKey
});
Console.WriteLine("Proof generated:");
Console.WriteLine($" Proof size: {proof.ProofBytes.Length} bytes");
Console.WriteLine($" Public signals: {proof.PublicSignals.Count}");
Console.WriteLine($" Proving time: {proof.ProvingTimeMs}ms");
// Verify proof
Console.WriteLine("\nVerifying proof...");
var verified = await _zk.Groth16.VerifyAsync(new VerifyRequest
{
Proof = proof.ProofBytes,
PublicSignals = proof.PublicSignals,
VerificationKey = keys.VerificationKey
});
Console.WriteLine($"Verification result: {verified}");
// Export proof for on-chain verification
var solidityCalldata = await _zk.Groth16.ExportCalldataAsync(proof);
Console.WriteLine($"\nSolidity calldata: {solidityCalldata[..Math.Min(solidityCalldata.Length, 100)]}...");
Console.WriteLine();
}
public async Task RunPlonkExample()
{
Console.WriteLine("=== PLONK Proving System ===");
var circuitId = "multiplier-v1";
// PLONK uses universal trusted setup
Console.WriteLine("Getting universal setup...");
var srs = await _zk.Plonk.GetUniversalSetupAsync(14); // 2^14 constraints
Console.WriteLine($"SRS loaded: {srs.Length} bytes");
// Generate circuit-specific keys
Console.WriteLine("\nGenerating circuit keys...");
var keys = await _zk.Plonk.SetupAsync(circuitId, srs);
Console.WriteLine("Keys generated");
// Generate proof
var witness = new Dictionary<string, string>
{
["a"] = "5",
["b"] = "9"
};
Console.WriteLine("\nGenerating PLONK proof...");
var proof = await _zk.Plonk.ProveAsync(new ProveRequest
{
CircuitId = circuitId,
Witness = witness,
ProvingKey = keys.ProvingKey
});
Console.WriteLine("Proof generated:");
Console.WriteLine($" Proof size: {proof.ProofBytes.Length} bytes");
Console.WriteLine($" Proving time: {proof.ProvingTimeMs}ms");
// Verify proof
var verified = await _zk.Plonk.VerifyAsync(new VerifyRequest
{
Proof = proof.ProofBytes,
PublicSignals = proof.PublicSignals,
VerificationKey = keys.VerificationKey
});
Console.WriteLine($"Verification result: {verified}");
// Compare with Groth16
Console.WriteLine("\nPLONK advantages:");
Console.WriteLine(" - Universal trusted setup");
Console.WriteLine(" - Larger proofs (~2.5 KB vs ~200 bytes)");
Console.WriteLine(" - Faster proving for some circuits");
Console.WriteLine();
}
public async Task RunStarkExample()
{
Console.WriteLine("=== STARK Proving System ===");
var circuitId = "multiplier-v1";
// STARKs don't need trusted setup
Console.WriteLine("Configuring STARK parameters...");
var config = new StarkConfig
{
FieldSize = 256,
HashFunction = HashFunction.Poseidon,
BlowupFactor = 8,
NumQueries = 30,
FoldingFactor = 8
};
// Generate proof
var witness = new Dictionary<string, string>
{
["a"] = "11",
["b"] = "13"
};
Console.WriteLine("\nGenerating STARK proof...");
var proof = await _zk.Stark.ProveAsync(new StarkProveRequest
{
CircuitId = circuitId,
Witness = witness,
Config = config
});
Console.WriteLine("Proof generated:");
Console.WriteLine($" Proof size: {proof.ProofBytes.Length} bytes");
Console.WriteLine($" Proving time: {proof.ProvingTimeMs}ms");
Console.WriteLine($" FRI layers: {proof.FriLayers}");
// Verify proof
Console.WriteLine("\nVerifying STARK proof...");
var verified = await _zk.Stark.VerifyAsync(new StarkVerifyRequest
{
Proof = proof.ProofBytes,
PublicSignals = proof.PublicSignals,
Config = config
});
Console.WriteLine($"Verification result: {verified}");
// Compare with SNARKs
Console.WriteLine("\nSTARK advantages:");
Console.WriteLine(" - No trusted setup needed");
Console.WriteLine(" - Post-quantum secure");
Console.WriteLine(" - Larger proofs (~100 KB)");
Console.WriteLine(" - Faster proving for complex computations");
Console.WriteLine();
}
public async Task RunRecursiveExample()
{
Console.WriteLine("=== Recursive Proof Composition ===");
// Create inner proofs
Console.WriteLine("Generating inner proofs...");
var innerProofs = new List<RecursiveProof>();
for (var i = 1; i <= 3; i++)
{
var witness = new Dictionary<string, string>
{
["a"] = i.ToString(),
["b"] = (i + 1).ToString()
};
var proof = await _zk.Recursive.ProveInnerAsync(new RecursiveProveRequest
{
CircuitId = "multiplier-v1",
Witness = witness,
Level = 0
});
innerProofs.Add(proof);
Console.WriteLine($" Inner proof {i} generated");
}
// Aggregate proofs recursively
Console.WriteLine("\nAggregating proofs...");
var aggregatedProof = await _zk.Recursive.AggregateAsync(new AggregateRequest
{
Proofs = innerProofs,
AggregationCircuit = "recursive-aggregator-v1"
});
Console.WriteLine("Aggregated proof:");
Console.WriteLine($" Proof size: {aggregatedProof.ProofBytes.Length} bytes");
Console.WriteLine($" Proofs aggregated: {aggregatedProof.ProofsAggregated}");
Console.WriteLine($" Recursion depth: {aggregatedProof.RecursionDepth}");
// Verify aggregated proof (verifies all inner proofs at once)
Console.WriteLine("\nVerifying aggregated proof...");
var verified = await _zk.Recursive.VerifyAggregatedAsync(aggregatedProof);
Console.WriteLine($"Verification result: {verified}");
// Use cases
Console.WriteLine("\nRecursive proof use cases:");
Console.WriteLine(" - Rollup batch verification");
Console.WriteLine(" - Incremental computation proofs");
Console.WriteLine(" - Cross-chain state proofs");
Console.WriteLine();
}
public async Task RunCeremonyExample()
{
Console.WriteLine("=== Trusted Setup Ceremony ===");
// List active ceremonies
var ceremonies = await _zk.Ceremony.ListAsync(CeremonyStatus.Active);
Console.WriteLine($"Active ceremonies: {ceremonies.Count}");
foreach (var ceremony in ceremonies.GetRange(0, Math.Min(ceremonies.Count, 3)))
{
Console.WriteLine($"\n {ceremony.CeremonyId}:");
Console.WriteLine($" Circuit: {ceremony.CircuitId}");
Console.WriteLine($" Participants: {ceremony.ParticipantCount}");
Console.WriteLine($" Current round: {ceremony.CurrentRound}");
Console.WriteLine($" Status: {ceremony.Status}");
}
// Create a new ceremony
Console.WriteLine("\nCreating new ceremony...");
var newCeremony = await _zk.Ceremony.CreateAsync(new CreateCeremonyRequest
{
CircuitId = "new-circuit-v1",
MinParticipants = 10,
MaxParticipants = 100,
RoundDuration = 3600, // 1 hour per round
VerifyContributions = true
});
Console.WriteLine("Ceremony created:");
Console.WriteLine($" Ceremony ID: {newCeremony.CeremonyId}");
Console.WriteLine($" Join URL: {newCeremony.JoinUrl}");
// Participate in a ceremony
Console.WriteLine("\nParticipating in ceremony...");
// Generate entropy
var entropy = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(entropy);
}
var contribution = await _zk.Ceremony.ContributeAsync(new ContributeRequest
{
CeremonyId = newCeremony.CeremonyId,
Entropy = entropy
});
Console.WriteLine("Contribution made:");
Console.WriteLine($" Contribution ID: {contribution.ContributionId}");
Console.WriteLine($" Position: {contribution.Position}");
Console.WriteLine($" Hash: {contribution.Hash}");
// Verify a contribution
Console.WriteLine("\nVerifying contribution...");
var valid = await _zk.Ceremony.VerifyContributionAsync(contribution.ContributionId);
Console.WriteLine($"Contribution valid: {valid}");
// Get ceremony transcript (for auditability)
var transcript = await _zk.Ceremony.GetTranscriptAsync(newCeremony.CeremonyId);
Console.WriteLine("\nCeremony transcript:");
Console.WriteLine($" Total contributions: {transcript.Contributions.Count}");
Console.WriteLine($" Start time: {transcript.StartTime}");
Console.WriteLine($" Final hash: {(string.IsNullOrEmpty(transcript.FinalHash) ? "pending" : transcript.FinalHash)}");
Console.WriteLine();
}
public static async Task Main(string[] args)
{
// Initialize client
var apiKey = Environment.GetEnvironmentVariable("SYNOR_API_KEY") ?? "your-api-key";
var config = new ZkConfig
{
ApiKey = apiKey,
Endpoint = "https://zk.synor.io/v1",
Timeout = TimeSpan.FromSeconds(120), // ZK operations can be slow
Retries = 3,
Debug = false,
DefaultProvingSystem = ProvingSystem.Groth16,
ProveTimeout = TimeSpan.FromSeconds(300),
VerifyTimeout = TimeSpan.FromSeconds(30)
};
var zk = new SynorZk(config);
var example = new ZkExample(zk);
try
{
// Check service health
var healthy = await zk.HealthCheckAsync();
Console.WriteLine($"Service healthy: {healthy}\n");
// Run examples
await example.RunCircuitExample();
await example.RunGroth16Example();
await example.RunPlonkExample();
await example.RunStarkExample();
await example.RunRecursiveExample();
await example.RunCeremonyExample();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
Environment.Exit(1);
}
}
}

View file

@ -0,0 +1,353 @@
# frozen_string_literal: true
#
# Synor Compiler SDK Examples for Ruby
#
# Demonstrates smart contract compilation and analysis:
# - WASM contract compilation and optimization
# - ABI extraction and encoding
# - Contract analysis and security scanning
# - Validation and verification
#
require 'synor/compiler'
class CompilerExample
def initialize(compiler)
@compiler = compiler
end
# Creates a minimal valid WASM module for testing
def create_minimal_wasm
[
0x00, 0x61, 0x73, 0x6d, # Magic: \0asm
0x01, 0x00, 0x00, 0x00, # Version: 1
# Type section
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
# Function section
0x03, 0x02, 0x01, 0x00,
# Export section
0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00, # "add"
# Code section
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
].pack('C*')
end
def run_compile_contract_example
puts '=== Contract Compilation ==='
wasm = create_minimal_wasm
result = @compiler.compile(wasm,
optimization_level: :size,
use_wasm_opt: true,
validate: true,
extract_metadata: true,
generate_abi: true,
strip_options: {
strip_debug: true,
strip_producers: true,
strip_names: true,
strip_custom: true,
strip_unused: true,
preserve_sections: []
}
)
puts 'Compilation result:'
puts " Contract ID: #{result.contract_id}"
puts " Code hash: #{result.code_hash}"
puts " Original size: #{result.original_size} bytes"
puts " Optimized size: #{result.optimized_size} bytes"
puts " Size reduction: #{format('%.1f', result.size_reduction)}%"
puts " Estimated deploy gas: #{result.estimated_deploy_gas}"
if result.metadata
puts "\nMetadata:"
puts " Name: #{result.metadata.name}"
puts " Version: #{result.metadata.version}"
puts " SDK Version: #{result.metadata.sdk_version}"
end
if result.abi
puts "\nABI:"
puts " Functions: #{result.abi.functions.length}"
puts " Events: #{result.abi.events.length}"
puts " Errors: #{result.abi.errors.length}"
end
puts
end
def run_compilation_modes_example
puts '=== Compilation Modes ==='
wasm = create_minimal_wasm
# Development mode: fast compilation, debugging support
puts 'Development mode:'
dev_result = @compiler.contracts.compile_dev(wasm)
puts " Size: #{dev_result.optimized_size} bytes"
puts ' Optimization: none'
# Production mode: maximum optimization
puts "\nProduction mode:"
prod_result = @compiler.contracts.compile_production(wasm)
puts " Size: #{prod_result.optimized_size} bytes"
puts ' Optimization: aggressive'
puts " Size savings: #{dev_result.optimized_size - prod_result.optimized_size} bytes"
# Custom optimization levels
puts "\nOptimization levels:"
levels = [
{ level: :none, name: 'NONE' },
{ level: :basic, name: 'BASIC' },
{ level: :size, name: 'SIZE' },
{ level: :aggressive, name: 'AGGRESSIVE' }
]
levels.each do |l|
result = @compiler.compile(wasm, optimization_level: l[:level])
puts " #{l[:name]}: #{result.optimized_size} bytes"
end
puts
end
def run_abi_example
puts '=== ABI Operations ==='
wasm = create_minimal_wasm
# Extract ABI from WASM
abi = @compiler.abi.extract(wasm)
puts "Contract: #{abi.name}"
puts "Version: #{abi.version}"
# List functions
if abi.functions.any?
puts "\nFunctions:"
abi.functions.each do |func|
inputs = func.inputs.map { |p| "#{p.name}: #{p.type.type_name}" }.join(', ')
outputs = func.outputs.empty? ? 'void' : func.outputs.map { |o| o.type.type_name }.join(', ')
modifiers = []
modifiers << 'view' if func.view?
modifiers << 'payable' if func.payable?
modifier_str = modifiers.join(' ')
puts " #{func.name}(#{inputs}) -> #{outputs} #{modifier_str}"
puts " Selector: #{func.selector}"
end
end
# List events
if abi.events.any?
puts "\nEvents:"
abi.events.each do |event|
params = event.params.map do |param|
prefix = param.indexed? ? 'indexed ' : ''
"#{prefix}#{param.name}: #{param.type.type_name}"
end.join(', ')
puts " #{event.name}(#{params})"
puts " Topic: #{event.topic}"
end
end
# Encode a function call
if abi.functions.any?
func = abi.functions.first
encoded = @compiler.abi.encode_call(func, %w[arg1 arg2])
puts "\nEncoded call to #{func.name}: #{encoded}"
# Decode a result
decoded = @compiler.abi.decode_result(func, encoded)
puts "Decoded result: #{decoded}"
end
puts
end
def run_analysis_example
puts '=== Contract Analysis ==='
wasm = create_minimal_wasm
# Full analysis
analysis = @compiler.analysis.analyze(wasm)
# Size breakdown
if analysis.size_breakdown
size = analysis.size_breakdown
puts 'Size breakdown:'
puts " Code: #{size.code} bytes"
puts " Data: #{size.data} bytes"
puts " Functions: #{size.functions} bytes"
puts " Memory: #{size.memory} bytes"
puts " Exports: #{size.exports} bytes"
puts " Imports: #{size.imports} bytes"
puts " Total: #{size.total} bytes"
end
# Function analysis
if analysis.functions.any?
puts "\nFunction analysis:"
analysis.functions.first(5).each do |func|
puts " #{func.name}:"
puts " Size: #{func.size} bytes"
puts " Instructions: #{func.instruction_count}"
puts " Locals: #{func.local_count}"
puts " Exported: #{func.exported?}"
puts " Estimated gas: #{func.estimated_gas}"
end
end
# Import analysis
if analysis.imports.any?
puts "\nImports:"
analysis.imports.each do |imp|
puts " #{imp.module}.#{imp.name} (#{imp.kind})"
end
end
# Gas analysis
if analysis.gas_analysis
gas = analysis.gas_analysis
puts "\nGas analysis:"
puts " Deployment: #{gas.deployment_gas}"
puts " Memory init: #{gas.memory_init_gas}"
puts " Data section: #{gas.data_section_gas}"
end
# Extract metadata
metadata = @compiler.analysis.extract_metadata(wasm)
puts "\nContract metadata:"
puts " Name: #{metadata.name}"
puts " Version: #{metadata.version}"
puts " Build timestamp: #{metadata.build_timestamp}"
# Estimate deployment gas
gas_estimate = @compiler.analysis.estimate_deploy_gas(wasm)
puts "\nEstimated deployment gas: #{gas_estimate}"
puts
end
def run_validation_example
puts '=== Contract Validation ==='
wasm = create_minimal_wasm
# Full validation
result = @compiler.validation.validate(wasm)
puts "Valid: #{result.valid?}"
puts "Exports: #{result.export_count}"
puts "Imports: #{result.import_count}"
puts "Functions: #{result.function_count}"
puts "Memory pages: #{result.memory_pages}"
if result.errors.any?
puts "\nValidation errors:"
result.errors.each do |error|
puts " [#{error.code}] #{error.message}"
puts " at #{error.location}" if error.location
end
end
if result.warnings.any?
puts "\nWarnings:"
result.warnings.each do |warning|
puts " #{warning}"
end
end
# Quick validation
is_valid = @compiler.validation.valid?(wasm)
puts "\nQuick validation: #{is_valid}"
# Get validation errors only
errors = @compiler.validation.get_errors(wasm)
puts "Error count: #{errors.length}"
# Validate required exports
has_required = @compiler.validation.validate_exports(wasm, %w[init execute query])
puts "Has required exports: #{has_required}"
# Validate memory constraints
memory_valid = @compiler.validation.validate_memory(wasm, 16)
puts "Memory within 16 pages: #{memory_valid}"
puts
end
def run_security_example
puts '=== Security Scanning ==='
wasm = create_minimal_wasm
security = @compiler.analysis.security_scan(wasm)
puts "Security score: #{security.score}/100"
if security.issues.any?
puts "\nSecurity issues:"
security.issues.each do |issue|
icon = case issue.severity
when 'critical' then '[CRIT]'
when 'high' then '[HIGH]'
when 'medium' then '[MED]'
when 'low' then '[LOW]'
else '[???]'
end
puts "#{icon} [#{issue.severity}] #{issue.type}"
puts " #{issue.description}"
puts " at #{issue.location}" if issue.location
end
else
puts 'No security issues found!'
end
if security.recommendations.any?
puts "\nRecommendations:"
security.recommendations.each do |rec|
puts "#{rec}"
end
end
puts
end
end
# Main execution
if __FILE__ == $PROGRAM_NAME
# Initialize client
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
config = Synor::Compiler::Config.new(
api_key: api_key,
endpoint: 'https://compiler.synor.io/v1',
timeout: 60,
retries: 3,
debug: false,
default_optimization_level: :size,
max_contract_size: 256 * 1024,
use_wasm_opt: true,
validate: true,
extract_metadata: true,
generate_abi: true
)
compiler = Synor::Compiler::Client.new(config)
example = CompilerExample.new(compiler)
begin
# Check service health
healthy = compiler.health_check
puts "Service healthy: #{healthy}\n\n"
# Run examples
example.run_compile_contract_example
example.run_compilation_modes_example
example.run_abi_example
example.run_analysis_example
example.run_validation_example
example.run_security_example
rescue StandardError => e
warn "Error: #{e.message}"
exit 1
end
end

View file

@ -0,0 +1,241 @@
# frozen_string_literal: true
#
# Synor Crypto SDK Examples for Ruby
#
# Demonstrates quantum-resistant cryptographic operations:
# - Hybrid Ed25519 + Dilithium3 signatures
# - BIP-39 mnemonic generation and validation
# - Post-quantum algorithms (Falcon, SPHINCS+)
# - Key derivation functions
#
require 'synor/crypto'
class CryptoExample
def initialize(crypto)
@crypto = crypto
end
def run_mnemonic_example
puts '=== Mnemonic Operations ==='
# Generate a 24-word mnemonic (256-bit entropy)
mnemonic = @crypto.mnemonic.generate(24)
puts "Generated mnemonic: #{mnemonic.phrase}"
puts "Word count: #{mnemonic.word_count}"
# Validate a mnemonic
validation = @crypto.mnemonic.validate(mnemonic.phrase)
puts "Valid: #{validation.valid?}"
puts "Error: #{validation.error}" unless validation.valid?
# Convert mnemonic to seed
seed = @crypto.mnemonic.to_seed(mnemonic.phrase, 'optional-passphrase')
puts "Seed (hex): #{bytes_to_hex(seed, 16)}..."
# Word suggestions for autocomplete
suggestions = @crypto.mnemonic.suggest_words('aban', 5)
puts "Suggestions for 'aban': #{suggestions.join(', ')}"
puts
end
def run_keypair_example
puts '=== Keypair Operations ==='
# Generate a random keypair
keypair = @crypto.keypairs.generate
puts 'Generated hybrid keypair:'
puts " Ed25519 public key size: #{keypair.public_key.ed25519_bytes.length} bytes"
puts " Dilithium public key size: #{keypair.public_key.dilithium_bytes.length} bytes"
puts " Total public key size: #{keypair.public_key.size} bytes"
# Get addresses for different networks
puts "\nAddresses:"
puts " Mainnet: #{keypair.get_address(:mainnet)}"
puts " Testnet: #{keypair.get_address(:testnet)}"
puts " Devnet: #{keypair.get_address(:devnet)}"
# Create keypair from mnemonic (deterministic)
mnemonic = @crypto.mnemonic.generate(24)
keypair2 = @crypto.keypairs.from_mnemonic(mnemonic.phrase)
addr = keypair2.get_address(:mainnet)
puts "\nKeypair from mnemonic: #{addr[0, 20]}..."
# Derive child keypair using BIP-44 path
path = Synor::Crypto::DerivationPath.external(0, 0) # m/44'/21337'/0'/0/0
puts "Derivation path: #{path}"
puts
end
def run_signing_example
puts '=== Hybrid Signing ==='
# Generate keypair
keypair = @crypto.keypairs.generate
# Sign a message
message = 'Hello, quantum-resistant world!'.bytes
signature = @crypto.signing.sign(keypair, message)
puts 'Signature created:'
puts " Ed25519 component: #{signature.ed25519_bytes.length} bytes"
puts " Dilithium component: #{signature.dilithium_bytes.length} bytes"
puts " Total signature size: #{signature.size} bytes"
# Verify the signature
valid = @crypto.signing.verify(keypair.public_key, message, signature)
puts "\nVerification result: #{valid}"
# Verify with tampered message fails
tampered_message = 'Hello, tampered message!'.bytes
invalid_result = @crypto.signing.verify(keypair.public_key, tampered_message, signature)
puts "Tampered message verification: #{invalid_result}"
puts
end
def run_falcon_example
puts '=== Falcon Post-Quantum Signatures ==='
# Generate Falcon-512 keypair (128-bit security)
falcon512 = @crypto.falcon.generate(:falcon512)
puts 'Falcon-512 keypair:'
puts " Public key: #{falcon512.public_key.key_bytes.length} bytes"
puts ' Security level: 128-bit'
# Generate Falcon-1024 keypair (256-bit security)
falcon1024 = @crypto.falcon.generate(:falcon1024)
puts "\nFalcon-1024 keypair:"
puts " Public key: #{falcon1024.public_key.key_bytes.length} bytes"
puts ' Security level: 256-bit'
# Sign with Falcon-512
message = 'Post-quantum secure message'.bytes
signature = @crypto.falcon.sign(falcon512, message)
puts "\nFalcon-512 signature: #{signature.signature_bytes.length} bytes"
# Verify
valid = @crypto.falcon.verify(falcon512.public_key.key_bytes, message, signature)
puts "Verification: #{valid}"
puts
end
def run_sphincs_example
puts '=== SPHINCS+ Hash-Based Signatures ==='
# SPHINCS+ variants with different security levels
variants = [
{ variant: :shake128s, security: 128, sig_size: 7856, name: 'SHAKE128S' },
{ variant: :shake192s, security: 192, sig_size: 16_224, name: 'SHAKE192S' },
{ variant: :shake256s, security: 256, sig_size: 29_792, name: 'SHAKE256S' }
]
message = 'Hash-based quantum security'.bytes
variants.each do |v|
keypair = @crypto.sphincs.generate(v[:variant])
puts "SPHINCS+ #{v[:name]}:"
puts " Security level: #{v[:security]}-bit"
puts " Expected signature size: #{v[:sig_size]} bytes"
# Sign a message
signature = @crypto.sphincs.sign(keypair, message)
puts " Actual signature size: #{signature.signature_bytes.length} bytes"
# Verify
valid = @crypto.sphincs.verify(keypair.public_key.key_bytes, message, signature)
puts " Verification: #{valid}"
puts
end
end
def run_kdf_example
puts '=== Key Derivation Functions ==='
# HKDF (HMAC-based Key Derivation Function)
seed = 'master-secret-key-material-here'.bytes
hkdf_config = {
salt: 'application-salt'.bytes,
info: 'encryption-key'.bytes,
output_length: 32
}
derived_key = @crypto.kdf.derive_key(seed, hkdf_config)
puts "HKDF derived key: #{bytes_to_hex(derived_key)}"
# PBKDF2 (Password-Based Key Derivation Function)
password = 'user-password'.bytes
pbkdf2_config = {
salt: 'random-salt-value'.bytes,
iterations: 100_000,
output_length: 32
}
password_key = @crypto.kdf.derive_from_password(password, pbkdf2_config)
puts "PBKDF2 derived key: #{bytes_to_hex(password_key)}"
puts
end
def run_hash_example
puts '=== Hash Functions ==='
data = 'Data to hash'.bytes
# SHA3-256 (FIPS 202)
sha3 = @crypto.hash.sha3_256(data)
puts "SHA3-256: #{sha3.hex}"
# BLAKE3 (fast, parallel)
blake3 = @crypto.hash.blake3(data)
puts "BLAKE3: #{blake3.hex}"
# Keccak-256 (Ethereum compatible)
keccak = @crypto.hash.keccak256(data)
puts "Keccak: #{keccak.hex}"
puts
end
private
def bytes_to_hex(data, max_len = nil)
len = max_len || data.length
hex = data[0, len].map { |b| format('%02x', b) }.join
hex += '...' if max_len && max_len < data.length
hex
end
end
# Main execution
if __FILE__ == $PROGRAM_NAME
# Initialize client
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
config = Synor::Crypto::Config.new(
api_key: api_key,
endpoint: 'https://crypto.synor.io/v1',
timeout: 30,
retries: 3,
debug: false,
default_network: :mainnet
)
crypto = Synor::Crypto::Client.new(config)
example = CryptoExample.new(crypto)
begin
# Check service health
healthy = crypto.health_check
puts "Service healthy: #{healthy}\n\n"
# Run examples
example.run_mnemonic_example
example.run_keypair_example
example.run_signing_example
example.run_falcon_example
example.run_sphincs_example
example.run_kdf_example
example.run_hash_example
rescue StandardError => e
warn "Error: #{e.message}"
exit 1
end
end

View file

@ -0,0 +1,288 @@
# 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

View file

@ -0,0 +1,290 @@
# frozen_string_literal: true
#
# Synor IBC SDK Examples for Ruby
#
# Demonstrates Inter-Blockchain Communication operations:
# - Chain and channel management
# - Cross-chain token transfers
# - Packet lifecycle handling
# - Relayer operations
# - Connection monitoring
#
require 'synor/ibc'
class IbcExample
def initialize(ibc)
@ibc = ibc
end
def run_chains_example
puts '=== Chain Information ==='
# List connected chains
chains = @ibc.chains.list
puts "Connected chains: #{chains.length}"
chains.first(5).each do |chain|
puts " #{chain.chain_id}: #{chain.name} (#{chain.status})"
end
# Get specific chain info
cosmos_hub = @ibc.chains.get('cosmoshub-4')
puts "\n#{cosmos_hub.name}:"
puts " Chain ID: #{cosmos_hub.chain_id}"
puts " RPC endpoint: #{cosmos_hub.rpc_endpoint}"
puts " Block height: #{cosmos_hub.latest_height}"
puts " Active channels: #{cosmos_hub.active_channels}"
# Get chain clients
clients = @ibc.chains.get_clients('cosmoshub-4')
puts "\nIBC clients: #{clients.length}"
clients.first(3).each do |client|
puts " #{client.client_id}: #{client.chain_id} (#{client.client_type})"
end
puts
end
def run_channels_example
puts '=== Channel Management ==='
# List channels
channels = @ibc.channels.list
puts "IBC channels: #{channels.length}"
channels.first(5).each do |channel|
puts " #{channel.channel_id}: #{channel.source_chain} <-> #{channel.dest_chain} (#{channel.state})"
end
# Get channel details
channel_id = 'channel-0'
channel = @ibc.channels.get(channel_id)
puts "\nChannel #{channel_id}:"
puts " State: #{channel.state}"
puts " Port: #{channel.port_id}"
puts " Counterparty: #{channel.counterparty_channel_id}"
puts " Connection: #{channel.connection_id}"
puts " Ordering: #{channel.ordering}"
puts " Version: #{channel.version}"
# Create a new channel (4-step handshake)
puts "\nInitiating channel creation..."
init_result = @ibc.channels.init(
source_chain: 'synor-mainnet',
dest_chain: 'osmosis-1',
port_id: 'transfer',
version: 'ics20-1'
)
puts " ChanOpenInit sent: #{init_result.channel_id}"
# In production, the following steps happen through relayers:
# ChanOpenTry -> ChanOpenAck -> ChanOpenConfirm
# Get channel statistics
stats = @ibc.channels.get_stats(channel_id)
puts "\nChannel statistics:"
puts " Packets sent: #{stats.packets_sent}"
puts " Packets received: #{stats.packets_received}"
puts " Packets acknowledged: #{stats.packets_acknowledged}"
puts " Packets timed out: #{stats.packets_timed_out}"
puts
end
def run_transfer_example
puts '=== Cross-Chain Transfers ==='
# Get transfer routes
puts 'Available transfer routes:'
routes = @ibc.transfers.get_routes('ATOM', 'synor-mainnet')
routes.each do |route|
puts " #{route.source_chain} -> #{route.dest_chain}: #{route.channel_id}"
puts " Estimated time: #{route.estimated_time}"
puts " Fee: #{route.fee} #{route.fee_asset}"
end
# Initiate a transfer
puts "\nInitiating transfer..."
transfer = @ibc.transfers.send(
source_chain: 'cosmoshub-4',
dest_chain: 'synor-mainnet',
channel_id: 'channel-0',
asset: 'uatom',
amount: '1000000', # 1 ATOM
sender: 'cosmos1abc...',
receiver: 'synor1xyz...',
timeout: 1800, # 30 minutes in seconds
memo: 'IBC transfer test'
)
puts 'Transfer initiated:'
puts " Transfer ID: #{transfer.transfer_id}"
puts " Sequence: #{transfer.sequence}"
puts " Status: #{transfer.status}"
# Track transfer status
puts "\nTracking transfer..."
status = @ibc.transfers.get_status(transfer.transfer_id)
puts " Current status: #{status.status}"
puts " Source tx: #{status.source_tx_hash}"
puts " Dest tx: #{status.dest_tx_hash}" if status.dest_tx_hash
# Get transfer history
history = @ibc.transfers.get_history(limit: 5)
puts "\nRecent transfers: #{history.length}"
history.each do |tx|
puts " #{tx.transfer_id}: #{tx.amount} #{tx.asset} (#{tx.status})"
end
puts
end
def run_packet_example
puts '=== Packet Handling ==='
# Get pending packets
pending_packets = @ibc.packets.get_pending('channel-0')
puts "Pending packets: #{pending_packets.length}"
pending_packets.first(5).each do |packet|
puts " Seq #{packet.sequence}: #{packet.source_port} -> #{packet.dest_port}"
end
# Get packet details
if pending_packets.any?
packet = @ibc.packets.get('channel-0', pending_packets.first.sequence)
puts "\nPacket #{packet.sequence}:"
puts " Source: #{packet.source_port}/#{packet.source_channel}"
puts " Dest: #{packet.dest_port}/#{packet.dest_channel}"
puts " Timeout height: #{packet.timeout_height}"
puts " Timeout timestamp: #{packet.timeout_timestamp}"
data_hex = packet.data.unpack1('H*')
puts " Data: #{data_hex[0, 64]}..."
end
# Query packet commitments
commitments = @ibc.packets.get_commitments('channel-0')
puts "\nPacket commitments: #{commitments.length}"
# Query unreceived packets
unreceived = @ibc.packets.get_unreceived('channel-0', [1, 2, 3, 4, 5])
puts "Unreceived packets: #{unreceived.join(', ')}"
# Query acknowledgements
acks = @ibc.packets.get_acknowledgements('channel-0')
puts "Packet acknowledgements: #{acks.length}"
puts
end
def run_relayer_example
puts '=== Relayer Operations ==='
# Get relayer status
relayers = @ibc.relayer.list
puts "Active relayers: #{relayers.length}"
relayers.first(3).each do |relayer|
puts " #{relayer.address}: #{relayer.packets_relayed} packets (#{relayer.status})"
end
# Register as a relayer
puts "\nRegistering as relayer..."
registration = @ibc.relayer.register(
address: 'synor1relayer...',
chains: %w[synor-mainnet cosmoshub-4 osmosis-1],
commission: 0.1 # 0.1%
)
puts " Registered: #{registration.relayer_id}"
# Start relaying
puts "\nStarting packet relay..."
relay_config = {
channels: %w[channel-0 channel-1],
batch_size: 10,
poll_interval: 5
}
# In production, this would run continuously
pending_count = @ibc.relayer.get_pending_count(relay_config[:channels])
puts " Pending packets to relay: #{pending_count}"
# Relay a batch
relay_result = @ibc.relayer.relay_batch('channel-0', 5)
puts " Relayed: #{relay_result.packets_relayed}"
puts " Fees earned: #{relay_result.fees_earned}"
# Get relayer earnings
earnings = @ibc.relayer.get_earnings('synor1relayer...')
puts "\nRelayer earnings:"
puts " Total earned: #{earnings.total_earned}"
puts " Packets relayed: #{earnings.packets_relayed}"
puts " Success rate: #{format('%.1f', earnings.success_rate)}%"
puts
end
def run_monitoring_example
puts '=== Connection Monitoring ==='
# Get connection health
connections = @ibc.monitoring.get_connections
puts 'Connection health:'
connections.each do |conn|
health_icon = conn.healthy? ? '✓' : '✗'
puts " [#{health_icon}] #{conn.connection_id}: #{conn.chain_a} <-> #{conn.chain_b}"
puts " Latency: #{conn.latency}ms, Uptime: #{format('%.1f', conn.uptime)}%"
end
# Get channel metrics
metrics = @ibc.monitoring.get_channel_metrics('channel-0')
puts "\nChannel metrics:"
puts " Throughput: #{metrics.packets_per_hour}/hour"
puts " Avg latency: #{metrics.avg_latency_ms}ms"
puts " Success rate: #{format('%.1f', metrics.success_rate)}%"
puts " Volume 24h: #{metrics.volume_24h}"
# Subscribe to events (in production)
puts "\nEvent subscription example:"
puts ' Subscribing to packet events...'
# @ibc.monitoring.subscribe('channel-0') do |event|
# puts " Event: #{event.type} - #{event.data}"
# end
# Get alerts
alerts = @ibc.monitoring.get_alerts
puts "\nActive alerts: #{alerts.length}"
alerts.each do |alert|
puts " [#{alert.severity}] #{alert.message}"
puts " Channel: #{alert.channel_id}, Time: #{alert.timestamp}"
end
puts
end
end
# Main execution
if __FILE__ == $PROGRAM_NAME
# Initialize client
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
config = Synor::Ibc::Config.new(
api_key: api_key,
endpoint: 'https://ibc.synor.io/v1',
timeout: 60,
retries: 3,
debug: false,
default_timeout: 1800 # 30 minutes
)
ibc = Synor::Ibc::Client.new(config)
example = IbcExample.new(ibc)
begin
# Check service health
healthy = ibc.health_check
puts "Service healthy: #{healthy}\n\n"
# Run examples
example.run_chains_example
example.run_channels_example
example.run_transfer_example
example.run_packet_example
example.run_relayer_example
example.run_monitoring_example
rescue StandardError => e
warn "Error: #{e.message}"
exit 1
end
end

View file

@ -0,0 +1,345 @@
# frozen_string_literal: true
#
# Synor ZK SDK Examples for Ruby
#
# Demonstrates zero-knowledge proof operations:
# - Circuit compilation (Circom)
# - Proof generation and verification
# - Multiple proving systems (Groth16, PLONK, STARK)
# - Recursive proof composition
# - Trusted setup ceremonies
#
require 'securerandom'
require 'synor/zk'
class ZkExample
def initialize(zk)
@zk = zk
end
def run_circuit_example
puts '=== Circuit Compilation ==='
# Simple Circom circuit: prove knowledge of factors
circom_code = <<~CIRCOM
pragma circom 2.1.0;
template Multiplier() {
signal input a;
signal input b;
signal output c;
c <== a * b;
}
component main = Multiplier();
CIRCOM
# Compile the circuit
puts 'Compiling circuit...'
circuit = @zk.circuits.compile(
code: circom_code,
language: :circom
)
puts 'Circuit compiled:'
puts " Circuit ID: #{circuit.circuit_id}"
puts " Constraints: #{circuit.constraints}"
puts " Public inputs: #{circuit.public_inputs}"
puts " Private inputs: #{circuit.private_inputs}"
puts " Outputs: #{circuit.outputs}"
# Get circuit info
info = @zk.circuits.get(circuit.circuit_id)
puts "\nCircuit info:"
puts " Name: #{info.name}"
puts " Version: #{info.version}"
puts " Wires: #{info.wire_count}"
puts " Labels: #{info.label_count}"
# List available circuits
circuits = @zk.circuits.list
puts "\nAvailable circuits: #{circuits.length}"
circuits.first(3).each do |c|
puts " #{c.circuit_id}: #{c.name} (#{c.constraints} constraints)"
end
puts
end
def run_groth16_example
puts '=== Groth16 Proving System ==='
circuit_id = 'multiplier-v1'
# Generate proving/verification keys (trusted setup)
puts 'Generating keys...'
keys = @zk.groth16.setup(circuit_id)
puts 'Keys generated:'
puts " Proving key size: #{keys.proving_key.length} bytes"
puts " Verification key size: #{keys.verification_key.length} bytes"
# Prepare witness (private inputs)
witness = { 'a' => '3', 'b' => '7' }
# Generate proof
puts "\nGenerating proof..."
proof = @zk.groth16.prove(
circuit_id: circuit_id,
witness: witness,
proving_key: keys.proving_key
)
puts 'Proof generated:'
puts " Proof size: #{proof.proof_bytes.length} bytes"
puts " Public signals: #{proof.public_signals.length}"
puts " Proving time: #{proof.proving_time_ms}ms"
# Verify proof
puts "\nVerifying proof..."
verified = @zk.groth16.verify(
proof: proof.proof_bytes,
public_signals: proof.public_signals,
verification_key: keys.verification_key
)
puts "Verification result: #{verified}"
# Export proof for on-chain verification
solidity_calldata = @zk.groth16.export_calldata(proof)
puts "\nSolidity calldata: #{solidity_calldata[0, 100]}..."
puts
end
def run_plonk_example
puts '=== PLONK Proving System ==='
circuit_id = 'multiplier-v1'
# PLONK uses universal trusted setup
puts 'Getting universal setup...'
srs = @zk.plonk.get_universal_setup(14) # 2^14 constraints
puts "SRS loaded: #{srs.length} bytes"
# Generate circuit-specific keys
puts "\nGenerating circuit keys..."
keys = @zk.plonk.setup(circuit_id, srs)
puts 'Keys generated'
# Generate proof
witness = { 'a' => '5', 'b' => '9' }
puts "\nGenerating PLONK proof..."
proof = @zk.plonk.prove(
circuit_id: circuit_id,
witness: witness,
proving_key: keys.proving_key
)
puts 'Proof generated:'
puts " Proof size: #{proof.proof_bytes.length} bytes"
puts " Proving time: #{proof.proving_time_ms}ms"
# Verify proof
verified = @zk.plonk.verify(
proof: proof.proof_bytes,
public_signals: proof.public_signals,
verification_key: keys.verification_key
)
puts "Verification result: #{verified}"
# Compare with Groth16
puts "\nPLONK advantages:"
puts ' - Universal trusted setup'
puts ' - Larger proofs (~2.5 KB vs ~200 bytes)'
puts ' - Faster proving for some circuits'
puts
end
def run_stark_example
puts '=== STARK Proving System ==='
circuit_id = 'multiplier-v1'
# STARKs don't need trusted setup
puts 'Configuring STARK parameters...'
config = {
field_size: 256,
hash_function: :poseidon,
blowup_factor: 8,
num_queries: 30,
folding_factor: 8
}
# Generate proof
witness = { 'a' => '11', 'b' => '13' }
puts "\nGenerating STARK proof..."
proof = @zk.stark.prove(
circuit_id: circuit_id,
witness: witness,
config: config
)
puts 'Proof generated:'
puts " Proof size: #{proof.proof_bytes.length} bytes"
puts " Proving time: #{proof.proving_time_ms}ms"
puts " FRI layers: #{proof.fri_layers}"
# Verify proof
puts "\nVerifying STARK proof..."
verified = @zk.stark.verify(
proof: proof.proof_bytes,
public_signals: proof.public_signals,
config: config
)
puts "Verification result: #{verified}"
# Compare with SNARKs
puts "\nSTARK advantages:"
puts ' - No trusted setup needed'
puts ' - Post-quantum secure'
puts ' - Larger proofs (~100 KB)'
puts ' - Faster proving for complex computations'
puts
end
def run_recursive_example
puts '=== Recursive Proof Composition ==='
# Create inner proofs
puts 'Generating inner proofs...'
inner_proofs = []
(1..3).each do |i|
witness = { 'a' => i.to_s, 'b' => (i + 1).to_s }
proof = @zk.recursive.prove_inner(
circuit_id: 'multiplier-v1',
witness: witness,
level: 0
)
inner_proofs << proof
puts " Inner proof #{i} generated"
end
# Aggregate proofs recursively
puts "\nAggregating proofs..."
aggregated_proof = @zk.recursive.aggregate(
proofs: inner_proofs,
aggregation_circuit: 'recursive-aggregator-v1'
)
puts 'Aggregated proof:'
puts " Proof size: #{aggregated_proof.proof_bytes.length} bytes"
puts " Proofs aggregated: #{aggregated_proof.proofs_aggregated}"
puts " Recursion depth: #{aggregated_proof.recursion_depth}"
# Verify aggregated proof (verifies all inner proofs at once)
puts "\nVerifying aggregated proof..."
verified = @zk.recursive.verify_aggregated(aggregated_proof)
puts "Verification result: #{verified}"
# Use cases
puts "\nRecursive proof use cases:"
puts ' - Rollup batch verification'
puts ' - Incremental computation proofs'
puts ' - Cross-chain state proofs'
puts
end
def run_ceremony_example
puts '=== Trusted Setup Ceremony ==='
# List active ceremonies
ceremonies = @zk.ceremony.list(:active)
puts "Active ceremonies: #{ceremonies.length}"
ceremonies.first(3).each do |ceremony|
puts "\n #{ceremony.ceremony_id}:"
puts " Circuit: #{ceremony.circuit_id}"
puts " Participants: #{ceremony.participant_count}"
puts " Current round: #{ceremony.current_round}"
puts " Status: #{ceremony.status}"
end
# Create a new ceremony
puts "\nCreating new ceremony..."
new_ceremony = @zk.ceremony.create(
circuit_id: 'new-circuit-v1',
min_participants: 10,
max_participants: 100,
round_duration: 3600, # 1 hour per round
verify_contributions: true
)
puts 'Ceremony created:'
puts " Ceremony ID: #{new_ceremony.ceremony_id}"
puts " Join URL: #{new_ceremony.join_url}"
# Participate in a ceremony
puts "\nParticipating in ceremony..."
# Generate entropy
entropy = SecureRandom.random_bytes(32)
contribution = @zk.ceremony.contribute(
ceremony_id: new_ceremony.ceremony_id,
entropy: entropy
)
puts 'Contribution made:'
puts " Contribution ID: #{contribution.contribution_id}"
puts " Position: #{contribution.position}"
puts " Hash: #{contribution.hash}"
# Verify a contribution
puts "\nVerifying contribution..."
valid = @zk.ceremony.verify_contribution(contribution.contribution_id)
puts "Contribution valid: #{valid}"
# Get ceremony transcript (for auditability)
transcript = @zk.ceremony.get_transcript(new_ceremony.ceremony_id)
puts "\nCeremony transcript:"
puts " Total contributions: #{transcript.contributions.length}"
puts " Start time: #{transcript.start_time}"
puts " Final hash: #{transcript.final_hash.empty? ? 'pending' : transcript.final_hash}"
puts
end
end
# Main execution
if __FILE__ == $PROGRAM_NAME
# Initialize client
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
config = Synor::Zk::Config.new(
api_key: api_key,
endpoint: 'https://zk.synor.io/v1',
timeout: 120, # ZK operations can be slow
retries: 3,
debug: false,
default_proving_system: :groth16,
prove_timeout: 300,
verify_timeout: 30
)
zk = Synor::Zk::Client.new(config)
example = ZkExample.new(zk)
begin
# Check service health
healthy = zk.health_check
puts "Service healthy: #{healthy}\n\n"
# Run examples
example.run_circuit_example
example.run_groth16_example
example.run_plonk_example
example.run_stark_example
example.run_recursive_example
example.run_ceremony_example
rescue StandardError => e
warn "Error: #{e.message}"
exit 1
end
end