From 9416d76108f36d6ad3b8fb30aee4dda3aa29d44f Mon Sep 17 00:00:00 2001 From: Gulshan Yadav Date: Wed, 28 Jan 2026 14:15:51 +0530 Subject: [PATCH] Add IBC and ZK SDK examples for Rust - Introduced `ibc_example.rs` demonstrating Inter-Blockchain Communication operations including cross-chain transfers, channel management, packet handling, and relayer operations. - Introduced `zk_example.rs` showcasing Zero-Knowledge proof operations such as circuit compilation, proof generation and verification, and on-chain verification with multiple proving systems. --- .../extension_discovery/vs_code.json | 2 +- sdk/flutter/example/compiler_example.dart | 359 ++++++++++ sdk/flutter/example/crypto_example.dart | 247 +++++++ sdk/flutter/example/dex_example.dart | 349 +++++++++ sdk/flutter/example/ibc_example.dart | 355 ++++++++++ sdk/flutter/example/zk_example.dart | 504 +++++++++++++ sdk/go/examples/compiler_example.go | 465 ++++++++++++ sdk/go/examples/crypto_example.go | 344 +++++++++ sdk/go/examples/dex_example.go | 506 +++++++++++++ sdk/go/examples/ibc_example.go | 509 ++++++++++++++ sdk/go/examples/zk_example.go | 662 ++++++++++++++++++ sdk/java/examples/CryptoExample.java | 249 +++++++ sdk/js/examples/compiler_example.ts | 393 +++++++++++ sdk/js/examples/crypto_example.ts | 279 ++++++++ sdk/js/examples/dex_example.ts | 488 +++++++++++++ sdk/js/examples/ibc_example.ts | 380 ++++++++++ sdk/js/examples/zk_example.ts | 537 ++++++++++++++ sdk/python/examples/compiler_example.py | 354 ++++++++++ sdk/python/examples/crypto_example.py | 265 +++++++ sdk/python/examples/dex_example.py | 450 ++++++++++++ sdk/python/examples/ibc_example.py | 358 ++++++++++ sdk/python/examples/zk_example.py | 521 ++++++++++++++ sdk/rust/examples/compiler_example.rs | 435 ++++++++++++ sdk/rust/examples/crypto_example.rs | 279 ++++++++ sdk/rust/examples/dex_example.rs | 387 ++++++++++ sdk/rust/examples/ibc_example.rs | 407 +++++++++++ sdk/rust/examples/zk_example.rs | 607 ++++++++++++++++ 27 files changed, 10690 insertions(+), 1 deletion(-) create mode 100644 sdk/flutter/example/compiler_example.dart create mode 100644 sdk/flutter/example/crypto_example.dart create mode 100644 sdk/flutter/example/dex_example.dart create mode 100644 sdk/flutter/example/ibc_example.dart create mode 100644 sdk/flutter/example/zk_example.dart create mode 100644 sdk/go/examples/compiler_example.go create mode 100644 sdk/go/examples/crypto_example.go create mode 100644 sdk/go/examples/dex_example.go create mode 100644 sdk/go/examples/ibc_example.go create mode 100644 sdk/go/examples/zk_example.go create mode 100644 sdk/java/examples/CryptoExample.java create mode 100644 sdk/js/examples/compiler_example.ts create mode 100644 sdk/js/examples/crypto_example.ts create mode 100644 sdk/js/examples/dex_example.ts create mode 100644 sdk/js/examples/ibc_example.ts create mode 100644 sdk/js/examples/zk_example.ts create mode 100644 sdk/python/examples/compiler_example.py create mode 100644 sdk/python/examples/crypto_example.py create mode 100644 sdk/python/examples/dex_example.py create mode 100644 sdk/python/examples/ibc_example.py create mode 100644 sdk/python/examples/zk_example.py create mode 100644 sdk/rust/examples/compiler_example.rs create mode 100644 sdk/rust/examples/crypto_example.rs create mode 100644 sdk/rust/examples/dex_example.rs create mode 100644 sdk/rust/examples/ibc_example.rs create mode 100644 sdk/rust/examples/zk_example.rs diff --git a/sdk/flutter/.dart_tool/extension_discovery/vs_code.json b/sdk/flutter/.dart_tool/extension_discovery/vs_code.json index 17c2a92..b3f4b9c 100644 --- a/sdk/flutter/.dart_tool/extension_discovery/vs_code.json +++ b/sdk/flutter/.dart_tool/extension_discovery/vs_code.json @@ -1 +1 @@ -{"version":2,"entries":[{"package":"synor_compute","rootUri":"../","packageUri":"lib/"}]} \ No newline at end of file +{"version":2,"entries":[{"package":"synor_sdk","rootUri":"../","packageUri":"lib/"}]} \ No newline at end of file diff --git a/sdk/flutter/example/compiler_example.dart b/sdk/flutter/example/compiler_example.dart new file mode 100644 index 0000000..27ac7d6 --- /dev/null +++ b/sdk/flutter/example/compiler_example.dart @@ -0,0 +1,359 @@ +/// Synor Compiler SDK Examples for Flutter/Dart +/// +/// Demonstrates smart contract compilation and analysis: +/// - WASM contract compilation and optimization +/// - ABI extraction and encoding +/// - Contract analysis and security scanning +/// - Validation and verification + +import 'dart:io'; +import 'dart:typed_data'; +import 'package:synor_compiler/synor_compiler.dart'; + +Future main() async { + // Initialize client + final config = CompilerConfig( + apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key', + endpoint: 'https://compiler.synor.io/v1', + timeout: const Duration(seconds: 60), + retries: 3, + debug: false, + defaultOptimizationLevel: OptimizationLevel.size, + maxContractSize: 256 * 1024, + useWasmOpt: true, + validate: true, + extractMetadata: true, + generateAbi: true, + ); + + final compiler = SynorCompiler(config); + + try { + // Check service health + final healthy = await compiler.healthCheck(); + print('Service healthy: $healthy\n'); + + // Run examples + await compileContractExample(compiler); + await compilationModesExample(compiler); + await abiExample(compiler); + await analysisExample(compiler); + await validationExample(compiler); + await securityExample(compiler); + } finally { + await compiler.close(); + } +} + +/// Create a minimal valid WASM module for testing. +Uint8List createMinimalWasm() { + return Uint8List.fromList([ + 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, + ]); +} + +Future compileContractExample(SynorCompiler compiler) async { + print('=== Contract Compilation ==='); + + final wasm = createMinimalWasm(); + + final result = await compiler.compile( + wasm, + options: CompileOptions( + optimizationLevel: OptimizationLevel.size, + useWasmOpt: true, + validate: true, + extractMetadata: true, + generateAbi: true, + stripOptions: StripOptions( + stripDebug: true, + stripProducers: true, + stripNames: true, + stripCustom: true, + stripUnused: true, + preserveSections: [], + ), + ), + ); + + print('Compilation result:'); + print(' Contract ID: ${result.contractId}'); + print(' Code hash: ${result.codeHash}'); + print(' Original size: ${result.originalSize} bytes'); + print(' Optimized size: ${result.optimizedSize} bytes'); + print(' Size reduction: ${result.sizeReduction.toStringAsFixed(1)}%'); + print(' Estimated deploy gas: ${result.estimatedDeployGas}'); + + if (result.metadata != null) { + print('\nMetadata:'); + print(' Name: ${result.metadata!.name}'); + print(' Version: ${result.metadata!.version}'); + print(' SDK Version: ${result.metadata!.sdkVersion}'); + } + + if (result.abi != null) { + print('\nABI:'); + print(' Functions: ${result.abi!.functions?.length ?? 0}'); + print(' Events: ${result.abi!.events?.length ?? 0}'); + print(' Errors: ${result.abi!.errors?.length ?? 0}'); + } + + print(''); +} + +Future compilationModesExample(SynorCompiler compiler) async { + print('=== Compilation Modes ==='); + + final wasm = createMinimalWasm(); + + // Development mode: fast compilation, debugging support + print('Development mode:'); + final devResult = await compiler.contracts.compileDev(wasm); + print(' Size: ${devResult.optimizedSize} bytes'); + print(' Optimization: none'); + + // Production mode: maximum optimization + print('\nProduction mode:'); + final prodResult = await compiler.contracts.compileProduction(wasm); + print(' Size: ${prodResult.optimizedSize} bytes'); + print(' Optimization: aggressive'); + print(' Size savings: ${devResult.optimizedSize - prodResult.optimizedSize} bytes'); + + // Custom optimization levels + print('\nOptimization levels:'); + final levels = [ + OptimizationLevel.none, + OptimizationLevel.basic, + OptimizationLevel.size, + OptimizationLevel.aggressive, + ]; + + for (final level in levels) { + final result = await compiler.compile( + wasm, + options: CompileOptions(optimizationLevel: level), + ); + print(' $level: ${result.optimizedSize} bytes'); + } + + print(''); +} + +Future abiExample(SynorCompiler compiler) async { + print('=== ABI Operations ==='); + + final wasm = createMinimalWasm(); + + // Extract ABI from WASM + final abi = await compiler.abi.extract(wasm); + print('Contract: ${abi.name}'); + print('Version: ${abi.version}'); + + // List functions + if (abi.functions != null && abi.functions!.isNotEmpty) { + print('\nFunctions:'); + for (final func in abi.functions!) { + final inputs = func.inputs + ?.map((i) => '${i.name}: ${i.type.typeName}') + .join(', ') ?? + ''; + final outputs = func.outputs?.map((o) => o.type.typeName).join(', ') ?? 'void'; + final modifiers = [ + if (func.view) 'view', + if (func.payable) 'payable', + ].join(' '); + print(' ${func.name}($inputs) -> $outputs $modifiers'); + print(' Selector: ${func.selector}'); + } + } + + // List events + if (abi.events != null && abi.events!.isNotEmpty) { + print('\nEvents:'); + for (final event in abi.events!) { + final params = event.params + ?.map((p) => + '${p.indexed ? "indexed " : ""}${p.name}: ${p.type.typeName}') + .join(', ') ?? + ''; + print(' ${event.name}($params)'); + print(' Topic: ${event.topic}'); + } + } + + // Encode a function call + if (abi.functions != null && abi.functions!.isNotEmpty) { + final func = abi.functions!.first; + final encoded = await compiler.abi.encodeCall(func, ['arg1', 'arg2']); + print('\nEncoded call to ${func.name}: $encoded'); + + // Decode a result + final decoded = await compiler.abi.decodeResult(func, encoded); + print('Decoded result: $decoded'); + } + + print(''); +} + +Future analysisExample(SynorCompiler compiler) async { + print('=== Contract Analysis ==='); + + final wasm = createMinimalWasm(); + + // Full analysis + final analysis = await compiler.analysis.analyze(wasm); + + // Size breakdown + if (analysis.sizeBreakdown != null) { + print('Size breakdown:'); + print(' Code: ${analysis.sizeBreakdown!.code} bytes'); + print(' Data: ${analysis.sizeBreakdown!.data} bytes'); + print(' Functions: ${analysis.sizeBreakdown!.functions} bytes'); + print(' Memory: ${analysis.sizeBreakdown!.memory} bytes'); + print(' Exports: ${analysis.sizeBreakdown!.exports} bytes'); + print(' Imports: ${analysis.sizeBreakdown!.imports} bytes'); + print(' Total: ${analysis.sizeBreakdown!.total} bytes'); + } + + // Function analysis + if (analysis.functions != null && analysis.functions!.isNotEmpty) { + print('\nFunction analysis:'); + for (final func in analysis.functions!.take(5)) { + print(' ${func.name}:'); + print(' Size: ${func.size} bytes'); + print(' Instructions: ${func.instructionCount}'); + print(' Locals: ${func.localCount}'); + print(' Exported: ${func.exported}'); + print(' Estimated gas: ${func.estimatedGas}'); + } + } + + // Import analysis + if (analysis.imports != null && analysis.imports!.isNotEmpty) { + print('\nImports:'); + for (final imp in analysis.imports!) { + print(' ${imp.module}.${imp.name} (${imp.kind})'); + } + } + + // Gas analysis + if (analysis.gasAnalysis != null) { + print('\nGas analysis:'); + print(' Deployment: ${analysis.gasAnalysis!.deploymentGas}'); + print(' Memory init: ${analysis.gasAnalysis!.memoryInitGas}'); + print(' Data section: ${analysis.gasAnalysis!.dataSectionGas}'); + } + + // Extract metadata + final metadata = await compiler.analysis.extractMetadata(wasm); + print('\nContract metadata:'); + print(' Name: ${metadata.name}'); + print(' Version: ${metadata.version}'); + print(' Build timestamp: ${metadata.buildTimestamp}'); + + // Estimate deployment gas + final gas = await compiler.analysis.estimateDeployGas(wasm); + print('\nEstimated deployment gas: $gas'); + + print(''); +} + +Future validationExample(SynorCompiler compiler) async { + print('=== Contract Validation ==='); + + final wasm = createMinimalWasm(); + + // Full validation + final result = await compiler.validation.validate(wasm); + print('Valid: ${result.valid}'); + print('Exports: ${result.exportCount}'); + print('Imports: ${result.importCount}'); + print('Functions: ${result.functionCount}'); + print('Memory pages: ${result.memoryPages}'); + + if (result.errors != null && result.errors!.isNotEmpty) { + print('\nValidation errors:'); + for (final error in result.errors!) { + print(' [${error.code}] ${error.message}'); + if (error.location != null) { + print(' at ${error.location}'); + } + } + } + + if (result.warnings != null && result.warnings!.isNotEmpty) { + print('\nWarnings:'); + for (final warning in result.warnings!) { + print(' $warning'); + } + } + + // Quick validation + final isValid = await compiler.validation.isValid(wasm); + print('\nQuick validation: $isValid'); + + // Get validation errors only + final errors = await compiler.validation.getErrors(wasm); + print('Error count: ${errors.length}'); + + // Validate required exports + final hasRequired = await compiler.validation.validateExports( + wasm, + ['init', 'execute', 'query'], + ); + print('Has required exports: $hasRequired'); + + // Validate memory constraints + final memoryValid = await compiler.validation.validateMemory(wasm, 16); + print('Memory within 16 pages: $memoryValid'); + + print(''); +} + +Future securityExample(SynorCompiler compiler) async { + print('=== Security Scanning ==='); + + final wasm = createMinimalWasm(); + + final security = await compiler.analysis.securityScan(wasm); + + print('Security score: ${security.score}/100'); + + if (security.issues != null && security.issues!.isNotEmpty) { + print('\nSecurity issues:'); + final severityIcons = { + 'critical': '[CRIT]', + 'high': '[HIGH]', + 'medium': '[MED]', + 'low': '[LOW]', + }; + for (final issue in security.issues!) { + final icon = severityIcons[issue.severity] ?? '[???]'; + print('$icon [${issue.severity.toUpperCase()}] ${issue.type}'); + print(' ${issue.description}'); + if (issue.location != null) { + print(' at ${issue.location}'); + } + } + } else { + print('No security issues found!'); + } + + if (security.recommendations != null && security.recommendations!.isNotEmpty) { + print('\nRecommendations:'); + for (final rec in security.recommendations!) { + print(' • $rec'); + } + } + + print(''); +} diff --git a/sdk/flutter/example/crypto_example.dart b/sdk/flutter/example/crypto_example.dart new file mode 100644 index 0000000..aa00acc --- /dev/null +++ b/sdk/flutter/example/crypto_example.dart @@ -0,0 +1,247 @@ +/// Synor Crypto SDK Examples for Flutter/Dart +/// +/// Demonstrates quantum-resistant cryptographic operations: +/// - Hybrid Ed25519 + Dilithium3 signatures +/// - BIP-39 mnemonic generation and validation +/// - Post-quantum algorithms (Falcon, SPHINCS+) +/// - Key derivation functions + +import 'dart:io'; +import 'package:synor_crypto/synor_crypto.dart'; + +Future main() async { + // Initialize client + final config = CryptoConfig( + apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key', + endpoint: 'https://crypto.synor.io/v1', + timeout: const Duration(seconds: 30), + retries: 3, + debug: false, + defaultNetwork: Network.mainnet, + ); + + final crypto = SynorCrypto(config); + + try { + // Check service health + final healthy = await crypto.healthCheck(); + print('Service healthy: $healthy\n'); + + // Run examples + await mnemonicExample(crypto); + await keypairExample(crypto); + await signingExample(crypto); + await falconExample(crypto); + await sphincsExample(crypto); + await kdfExample(crypto); + await hashExample(crypto); + } finally { + await crypto.close(); + } +} + +Future mnemonicExample(SynorCrypto crypto) async { + print('=== Mnemonic Operations ==='); + + // Generate a 24-word mnemonic (256-bit entropy) + final mnemonic = await crypto.mnemonic.generate(24); + print('Generated mnemonic: ${mnemonic.phrase}'); + print('Word count: ${mnemonic.wordCount}'); + + // Validate a mnemonic + final validation = await crypto.mnemonic.validate(mnemonic.phrase); + print('Valid: ${validation.valid}'); + if (!validation.valid) { + print('Error: ${validation.error}'); + } + + // Convert mnemonic to seed + final seed = await crypto.mnemonic.toSeed( + mnemonic.phrase, + passphrase: 'optional-passphrase', + ); + print('Seed (hex): ${seed.toHex().substring(0, 32)}...'); + + // Word suggestions for autocomplete + final suggestions = await crypto.mnemonic.suggestWords('aban', limit: 5); + print('Suggestions for "aban": ${suggestions.join(", ")}'); + + print(''); +} + +Future keypairExample(SynorCrypto crypto) async { + print('=== Keypair Operations ==='); + + // Generate a random keypair + final keypair = await crypto.keypairs.generate(); + print('Generated hybrid keypair:'); + print(' Ed25519 public key size: ${keypair.publicKey.ed25519Bytes.length} bytes'); + print(' Dilithium public key size: ${keypair.publicKey.dilithiumBytes.length} bytes'); + print(' Total public key size: ${keypair.publicKey.size} bytes'); + + // Get addresses for different networks + print('\nAddresses:'); + print(' Mainnet: ${keypair.getAddress(Network.mainnet)}'); + print(' Testnet: ${keypair.getAddress(Network.testnet)}'); + print(' Devnet: ${keypair.getAddress(Network.devnet)}'); + + // Create keypair from mnemonic (deterministic) + final mnemonic = await crypto.mnemonic.generate(24); + final keypair2 = await crypto.keypairs.fromMnemonic(mnemonic.phrase, ''); + final addr = keypair2.getAddress(Network.mainnet); + print('\nKeypair from mnemonic: ${addr.substring(0, 20)}...'); + + // Derive child keypair using BIP-44 path + final path = DerivationPath.external(0, 0); // m/44'/21337'/0'/0/0 + print('Derivation path: $path'); + + print(''); +} + +Future signingExample(SynorCrypto crypto) async { + print('=== Hybrid Signing ==='); + + // Generate keypair + final keypair = await crypto.keypairs.generate(); + + // Sign a message + final message = 'Hello, quantum-resistant world!'.codeUnits; + final signature = await crypto.signing.sign(keypair, message); + + print('Signature created:'); + print(' Ed25519 component: ${signature.ed25519Bytes.length} bytes'); + print(' Dilithium component: ${signature.dilithiumBytes.length} bytes'); + print(' Total signature size: ${signature.size} bytes'); + + // Verify the signature + final valid = await crypto.signing.verify(keypair.publicKey, message, signature); + print('\nVerification result: $valid'); + + // Verify with tampered message fails + final tamperedMessage = 'Hello, tampered message!'.codeUnits; + final invalidResult = await crypto.signing.verify( + keypair.publicKey, + tamperedMessage, + signature, + ); + print('Tampered message verification: $invalidResult'); + + print(''); +} + +Future falconExample(SynorCrypto crypto) async { + print('=== Falcon Post-Quantum Signatures ==='); + + // Generate Falcon-512 keypair (128-bit security) + final falcon512 = await crypto.falcon.generate(FalconVariant.falcon512); + print('Falcon-512 keypair:'); + print(' Public key: ${falcon512.publicKey.keyBytes.length} bytes'); + print(' Security level: 128-bit'); + + // Generate Falcon-1024 keypair (256-bit security) + final falcon1024 = await crypto.falcon.generate(FalconVariant.falcon1024); + print('\nFalcon-1024 keypair:'); + print(' Public key: ${falcon1024.publicKey.keyBytes.length} bytes'); + print(' Security level: 256-bit'); + + // Sign with Falcon-512 + final message = 'Post-quantum secure message'.codeUnits; + final signature = await crypto.falcon.sign(falcon512, message); + print('\nFalcon-512 signature: ${signature.signatureBytes.length} bytes'); + + // Verify + final valid = await crypto.falcon.verify( + falcon512.publicKey.keyBytes, + message, + signature, + ); + print('Verification: $valid'); + + print(''); +} + +Future sphincsExample(SynorCrypto crypto) async { + print('=== SPHINCS+ Hash-Based Signatures ==='); + + // SPHINCS+ variants with different security levels + final variants = [ + (SphincsVariant.shake128s, 128, 7856), + (SphincsVariant.shake192s, 192, 16224), + (SphincsVariant.shake256s, 256, 29792), + ]; + + // Generate and demonstrate each variant + for (final (variant, security, sigSize) in variants) { + final keypair = await crypto.sphincs.generate(variant); + print('SPHINCS+ $variant:'); + print(' Security level: $security-bit'); + print(' Expected signature size: $sigSize bytes'); + + // Sign a message + final message = 'Hash-based quantum security'.codeUnits; + final signature = await crypto.sphincs.sign(keypair, message); + print(' Actual signature size: ${signature.signatureBytes.length} bytes'); + + // Verify + final valid = await crypto.sphincs.verify( + keypair.publicKey.keyBytes, + message, + signature, + ); + print(' Verification: $valid\n'); + } +} + +Future kdfExample(SynorCrypto crypto) async { + print('=== Key Derivation Functions ==='); + + // HKDF (HMAC-based Key Derivation Function) + final seed = 'master-secret-key-material-here'.codeUnits; + final hkdfConfig = DerivationConfig( + salt: 'application-salt'.codeUnits, + info: 'encryption-key'.codeUnits, + outputLength: 32, + ); + + final derivedKey = await crypto.kdf.deriveKey(seed, hkdfConfig); + print('HKDF derived key: ${derivedKey.toHex()}'); + + // PBKDF2 (Password-Based Key Derivation Function) + final password = 'user-password'.codeUnits; + final pbkdf2Config = PasswordDerivationConfig( + salt: 'random-salt-value'.codeUnits, + iterations: 100000, + outputLength: 32, + ); + + final passwordKey = await crypto.kdf.deriveFromPassword(password, pbkdf2Config); + print('PBKDF2 derived key: ${passwordKey.toHex()}'); + + print(''); +} + +Future hashExample(SynorCrypto crypto) async { + print('=== Hash Functions ==='); + + final data = 'Data to hash'.codeUnits; + + // SHA3-256 (FIPS 202) + final sha3 = await crypto.hash.sha3_256(data); + print('SHA3-256: ${sha3.hex}'); + + // BLAKE3 (fast, parallel) + final blake3 = await crypto.hash.blake3(data); + print('BLAKE3: ${blake3.hex}'); + + // Keccak-256 (Ethereum compatible) + final keccak = await crypto.hash.keccak256(data); + print('Keccak: ${keccak.hex}'); + + print(''); +} + +extension on List { + String toHex() { + return map((b) => b.toRadixString(16).padLeft(2, '0')).join(); + } +} diff --git a/sdk/flutter/example/dex_example.dart b/sdk/flutter/example/dex_example.dart new file mode 100644 index 0000000..1ad6b97 --- /dev/null +++ b/sdk/flutter/example/dex_example.dart @@ -0,0 +1,349 @@ +/// Synor DEX SDK Examples for Flutter/Dart +/// +/// Demonstrates decentralized exchange operations: +/// - Spot trading (limit/market orders) +/// - Perpetual futures trading +/// - Liquidity provision (AMM pools) +/// - Order book management +/// - Portfolio tracking + +import 'dart:io'; +import 'dart:math'; +import 'package:synor_dex/synor_dex.dart'; + +Future main() async { + // Initialize client + final config = DexConfig( + apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key', + endpoint: 'https://dex.synor.io/v1', + timeout: const Duration(seconds: 30), + retries: 3, + debug: false, + defaultMarket: 'SYN-USDC', + ); + + final dex = SynorDex(config); + + try { + // Check service health + final healthy = await dex.healthCheck(); + print('Service healthy: $healthy\n'); + + // Run examples + await marketsExample(dex); + await spotTradingExample(dex); + await perpsTradingExample(dex); + await liquidityExample(dex); + await orderbookExample(dex); + await portfolioExample(dex); + } finally { + await dex.close(); + } +} + +Future marketsExample(SynorDex dex) async { + print('=== Markets ==='); + + // Get all markets + final markets = await dex.markets.list(); + print('Available markets: ${markets.length}'); + + for (final market in markets.take(5)) { + print('\n ${market.symbol}:'); + print(' Base: ${market.baseAsset}, Quote: ${market.quoteAsset}'); + print(' Price: ${market.lastPrice}'); + print(' 24h Volume: ${market.volume24h}'); + print(' 24h Change: ${market.change24h}%'); + print(' Status: ${market.status}'); + } + + // Get specific market + final market = await dex.markets.get('SYN-USDC'); + print('\nSYN-USDC details:'); + print(' Min order size: ${market.minOrderSize}'); + print(' Tick size: ${market.tickSize}'); + print(' Maker fee: ${market.makerFee}%'); + print(' Taker fee: ${market.takerFee}%'); + + // Get market statistics + final stats = await dex.markets.getStats('SYN-USDC'); + print('\nMarket statistics:'); + print(' High 24h: ${stats.high24h}'); + print(' Low 24h: ${stats.low24h}'); + print(' Open interest: ${stats.openInterest}'); + print(' Funding rate: ${stats.fundingRate}%'); + + print(''); +} + +Future spotTradingExample(SynorDex dex) async { + print('=== Spot Trading ==='); + + // Place a limit order + print('Placing limit buy order...'); + final limitOrder = await dex.spot.placeOrder(OrderRequest( + market: 'SYN-USDC', + side: OrderSide.buy, + orderType: OrderType.limit, + price: '1.50', + quantity: '100', + timeInForce: TimeInForce.gtc, + )); + + print('Limit order placed:'); + print(' Order ID: ${limitOrder.orderId}'); + print(' Status: ${limitOrder.status}'); + print(' Price: ${limitOrder.price}'); + print(' Quantity: ${limitOrder.quantity}'); + + // Place a market order + print('\nPlacing market sell order...'); + final marketOrder = await dex.spot.placeOrder(OrderRequest( + market: 'SYN-USDC', + side: OrderSide.sell, + orderType: OrderType.market, + quantity: '50', + )); + + print('Market order executed:'); + print(' Order ID: ${marketOrder.orderId}'); + print(' Status: ${marketOrder.status}'); + print(' Filled: ${marketOrder.filledQuantity}'); + print(' Avg price: ${marketOrder.averagePrice}'); + + // Get order status + final status = await dex.spot.getOrder(limitOrder.orderId); + print('\nOrder status:'); + print(' Status: ${status.status}'); + print(' Filled: ${status.filledQuantity} / ${status.quantity}'); + print(' Remaining: ${status.remainingQuantity}'); + + // Cancel order + print('\nCancelling order...'); + await dex.spot.cancelOrder(limitOrder.orderId); + print('Order cancelled successfully'); + + // Get open orders + final openOrders = await dex.spot.getOpenOrders('SYN-USDC'); + print('\nOpen orders: ${openOrders.length}'); + + // Get trade history + final trades = await dex.spot.getTradeHistory('SYN-USDC', limit: 10); + print('\nRecent trades: ${trades.length}'); + for (final trade in trades.take(3)) { + print(' ${trade.side} ${trade.quantity} @ ${trade.price} (${trade.timestamp})'); + } + + print(''); +} + +Future perpsTradingExample(SynorDex dex) async { + print('=== Perpetual Futures Trading ==='); + + // Get available perps markets + final perpsMarkets = await dex.perps.listMarkets(); + print('Available perps markets: ${perpsMarkets.length}'); + + for (final market in perpsMarkets.take(3)) { + print(' ${market.symbol}: ${market.markPrice} (funding: ${market.fundingRate}%)'); + } + + // Open a long position + print('\nOpening long position...'); + final position = await dex.perps.openPosition(PerpsOrderRequest( + market: 'SYN-USDC-PERP', + side: OrderSide.buy, + orderType: OrderType.limit, + price: '1.50', + size: '1000', + leverage: 10, + reduceOnly: false, + )); + + print('Position opened:'); + print(' Position ID: ${position.positionId}'); + print(' Size: ${position.size}'); + print(' Entry price: ${position.entryPrice}'); + print(' Leverage: ${position.leverage}x'); + print(' Liquidation price: ${position.liquidationPrice}'); + + // Get position details + final details = await dex.perps.getPosition(position.positionId); + print('\nPosition details:'); + print(' Unrealized PnL: ${details.unrealizedPnL}'); + print(' Margin: ${details.margin}'); + print(' Margin ratio: ${details.marginRatio}%'); + + // Set stop loss and take profit + print('\nSetting stop loss and take profit...'); + await dex.perps.setStopLoss(position.positionId, '1.40'); + print('Stop loss set at 1.40'); + + await dex.perps.setTakeProfit(position.positionId, '1.80'); + print('Take profit set at 1.80'); + + // Close position + print('\nClosing position...'); + final closeResult = await dex.perps.closePosition(position.positionId); + print('Position closed:'); + print(' Realized PnL: ${closeResult.realizedPnL}'); + print(' Close price: ${closeResult.closePrice}'); + + // Get all positions + final positions = await dex.perps.getPositions(); + print('\nOpen positions: ${positions.length}'); + + // Get funding history + final funding = await dex.perps.getFundingHistory('SYN-USDC-PERP', limit: 10); + print('Funding payments: ${funding.length}'); + + print(''); +} + +Future liquidityExample(SynorDex dex) async { + print('=== Liquidity Provision ==='); + + // Get available pools + final pools = await dex.liquidity.listPools(); + print('Available pools: ${pools.length}'); + + for (final pool in pools.take(3)) { + print('\n ${pool.name}:'); + print(' TVL: \$${pool.tvl}'); + print(' APR: ${pool.apr}%'); + print(' Volume 24h: \$${pool.volume24h}'); + print(' Fee tier: ${pool.feeTier}%'); + } + + // Get pool details + final pool = await dex.liquidity.getPool('SYN-USDC'); + print('\nSYN-USDC pool details:'); + print(' Token0: ${pool.token0.symbol} (${pool.token0Reserve})'); + print(' Token1: ${pool.token1.symbol} (${pool.token1Reserve})'); + print(' Price: ${pool.price}'); + print(' Total LP tokens: ${pool.totalLPTokens}'); + + // Add liquidity + print('\nAdding liquidity...'); + final addResult = await dex.liquidity.addLiquidity(AddLiquidityRequest( + pool: 'SYN-USDC', + amount0: '100', + amount1: '150', + slippageBps: 50, // 0.5% + )); + + print('Liquidity added:'); + print(' LP tokens received: ${addResult.lpTokens}'); + print(' Position ID: ${addResult.positionId}'); + print(' Share of pool: ${addResult.shareOfPool}%'); + + // Get LP positions + final lpPositions = await dex.liquidity.getPositions(); + print('\nLP positions: ${lpPositions.length}'); + for (final pos in lpPositions) { + print(' ${pos.pool}: ${pos.lpTokens} LP tokens (value: \$${pos.value})'); + } + + // Claim fees + print('\nClaiming fees...'); + final fees = await dex.liquidity.claimFees(addResult.positionId); + print('Fees claimed:'); + print(' Token0: ${fees.amount0}'); + print(' Token1: ${fees.amount1}'); + + // Remove liquidity + print('\nRemoving liquidity...'); + final removeResult = await dex.liquidity.removeLiquidity(RemoveLiquidityRequest( + positionId: addResult.positionId, + lpTokens: addResult.lpTokens, + slippageBps: 50, + )); + + print('Liquidity removed:'); + print(' Token0 received: ${removeResult.amount0}'); + print(' Token1 received: ${removeResult.amount1}'); + + print(''); +} + +Future orderbookExample(SynorDex dex) async { + print('=== Order Book ==='); + + // Get order book snapshot + final orderbook = await dex.orderbook.getSnapshot('SYN-USDC', depth: 10); + + print('Order book for SYN-USDC:'); + print('\nAsks (sells):'); + for (final ask in orderbook.asks.take(5)) { + print(' ${ask.quantity} @ ${ask.price}'); + } + + print('\nBids (buys):'); + for (final bid in orderbook.bids.take(5)) { + print(' ${bid.quantity} @ ${bid.price}'); + } + + print('\nSpread: ${orderbook.spread} (${orderbook.spreadPercent}%)'); + print('Mid price: ${orderbook.midPrice}'); + + // Get recent trades + final recentTrades = await dex.orderbook.getRecentTrades('SYN-USDC', limit: 10); + print('\nRecent trades:'); + for (final trade in recentTrades.take(5)) { + print(' ${trade.side} ${trade.quantity} @ ${trade.price}'); + } + + // Subscribe to orderbook updates (simulated) + print('\nSubscribing to orderbook updates...'); + final subscription = dex.orderbook.subscribe('SYN-USDC'); + + // Process a few updates + int count = 0; + await for (final update in subscription) { + print(' Update: ${update.side} ${update.quantity} @ ${update.price}'); + count++; + if (count >= 3) break; + } + + print(''); +} + +Future portfolioExample(SynorDex dex) async { + print('=== Portfolio ==='); + + // Get portfolio overview + final portfolio = await dex.portfolio.getOverview(); + + print('Portfolio overview:'); + print(' Total value: \$${portfolio.totalValue}'); + print(' Available balance: \$${portfolio.availableBalance}'); + print(' In orders: \$${portfolio.inOrders}'); + print(' In positions: \$${portfolio.inPositions}'); + print(' Unrealized PnL: \$${portfolio.unrealizedPnL}'); + + // Get balances + final balances = await dex.portfolio.getBalances(); + print('\nBalances:'); + for (final balance in balances) { + print(' ${balance.asset}: ${balance.total} (available: ${balance.available}, in orders: ${balance.inOrders})'); + } + + // Get PnL history + final pnlHistory = await dex.portfolio.getPnLHistory(days: 30); // Last 30 days + print('\nPnL history (last ${pnlHistory.length} days):'); + if (pnlHistory.isNotEmpty) { + print(' Total PnL: \$${pnlHistory.last.cumulativePnL}'); + } + + // Get trade statistics + final stats = await dex.portfolio.getStats(); + print('\nTrade statistics:'); + print(' Total trades: ${stats.totalTrades}'); + print(' Win rate: ${stats.winRate}%'); + print(' Avg profit: \$${stats.avgProfit}'); + print(' Avg loss: \$${stats.avgLoss}'); + print(' Best trade: \$${stats.bestTrade}'); + print(' Worst trade: \$${stats.worstTrade}'); + + print(''); +} diff --git a/sdk/flutter/example/ibc_example.dart b/sdk/flutter/example/ibc_example.dart new file mode 100644 index 0000000..4ddf0ae --- /dev/null +++ b/sdk/flutter/example/ibc_example.dart @@ -0,0 +1,355 @@ +/// Synor IBC SDK Examples for Flutter/Dart +/// +/// Demonstrates Inter-Blockchain Communication operations: +/// - Cross-chain token transfers +/// - Channel management +/// - Packet handling +/// - Relayer operations + +import 'dart:io'; +import 'package:synor_ibc/synor_ibc.dart'; + +Future main() async { + // Initialize client + final config = IbcConfig( + apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key', + endpoint: 'https://ibc.synor.io/v1', + timeout: const Duration(seconds: 30), + retries: 3, + debug: false, + defaultNetwork: Network.mainnet, + ); + + final ibc = SynorIbc(config); + + try { + // Check service health + final healthy = await ibc.healthCheck(); + print('Service healthy: $healthy\n'); + + // Run examples + await chainsExample(ibc); + await channelsExample(ibc); + await transferExample(ibc); + await packetExample(ibc); + await relayerExample(ibc); + await connectionExample(ibc); + } finally { + await ibc.close(); + } +} + +Future chainsExample(SynorIbc ibc) async { + print('=== Connected Chains ==='); + + // Get all connected chains + final chains = await ibc.chains.list(); + print('Connected chains: ${chains.length}'); + + for (final chain in chains) { + print(' ${chain.chainId}:'); + print(' Name: ${chain.name}'); + print(' Status: ${chain.status}'); + print(' Block height: ${chain.latestHeight}'); + print(' Channels: ${chain.channelCount}'); + } + + // Get specific chain info + final cosmos = await ibc.chains.get('cosmoshub-4'); + print('\nCosmos Hub details:'); + print(' RPC: ${cosmos.rpcEndpoint}'); + print(' Rest: ${cosmos.restEndpoint}'); + print(' Native denom: ${cosmos.nativeDenom}'); + print(' Prefix: ${cosmos.bech32Prefix}'); + + // Get supported assets on a chain + final assets = await ibc.chains.getAssets('cosmoshub-4'); + print('\nSupported assets on Cosmos Hub:'); + for (final asset in assets.take(5)) { + print(' ${asset.symbol}: ${asset.denom}'); + print(' Origin: ${asset.originChain}'); + print(' Decimals: ${asset.decimals}'); + } + + // Get chain paths (routes) + final paths = await ibc.chains.getPaths('synor-1', 'cosmoshub-4'); + print('\nPaths from Synor to Cosmos Hub:'); + for (final path in paths) { + print(' ${path.sourceChannel} -> ${path.destChannel}'); + print(' Hops: ${path.hops}'); + print(' Avg time: ${path.avgTransferTime}s'); + } + + print(''); +} + +Future channelsExample(SynorIbc ibc) async { + print('=== Channel Management ==='); + + // List all channels + final channels = await ibc.channels.list(); + print('Total channels: ${channels.length}'); + + // Filter by state + final openChannels = + channels.where((c) => c.state == ChannelState.open).toList(); + print('Open channels: ${openChannels.length}'); + + for (final channel in openChannels.take(3)) { + print('\n Channel ${channel.channelId}:'); + print(' Port: ${channel.portId}'); + print(' Counterparty: ${channel.counterpartyChannelId} on ${channel.counterpartyChainId}'); + print(' Ordering: ${channel.ordering}'); + print(' Version: ${channel.version}'); + print(' State: ${channel.state}'); + } + + // Get specific channel + final channel = await ibc.channels.get('channel-0'); + print('\nChannel-0 details:'); + print(' Connection: ${channel.connectionId}'); + print(' Counterparty port: ${channel.counterpartyPortId}'); + + // Get channel statistics + final stats = await ibc.channels.getStats('channel-0'); + print('\nChannel-0 statistics:'); + print(' Total packets sent: ${stats.packetsSent}'); + print(' Total packets received: ${stats.packetsReceived}'); + print(' Pending packets: ${stats.pendingPackets}'); + print(' Success rate: ${stats.successRate}%'); + print(' Avg relay time: ${stats.avgRelayTime}s'); + + // Get channel capacity + final capacity = await ibc.channels.getCapacity('channel-0'); + print('\nChannel-0 capacity:'); + print(' Max throughput: ${capacity.maxPacketsPerBlock} packets/block'); + print(' Current utilization: ${capacity.utilization}%'); + + print(''); +} + +Future transferExample(SynorIbc ibc) async { + print('=== Cross-Chain Transfers ==='); + + // Estimate transfer fee + final estimate = await ibc.transfers.estimateFee(FeeEstimateRequest( + sourceChain: 'synor-1', + destChain: 'cosmoshub-4', + denom: 'usyn', + amount: '1000000', // 1 SYN (6 decimals) + )); + + print('Transfer fee estimate:'); + print(' Gas: ${estimate.gas}'); + print(' Fee: ${estimate.fee} ${estimate.feeDenom}'); + print(' Timeout: ${estimate.timeout}s'); + + // Initiate a transfer + print('\nInitiating transfer...'); + final transfer = await ibc.transfers.send(TransferRequest( + sourceChain: 'synor-1', + destChain: 'cosmoshub-4', + channel: 'channel-0', + sender: 'synor1abc...', // Your address + receiver: 'cosmos1xyz...', // Recipient address + denom: 'usyn', + amount: '1000000', // 1 SYN + memo: 'Cross-chain transfer example', + timeoutHeight: 0, // Use timestamp instead + timeoutTimestamp: DateTime.now().add(const Duration(minutes: 10)).millisecondsSinceEpoch, + )); + + print('Transfer initiated:'); + print(' TX Hash: ${transfer.txHash}'); + print(' Sequence: ${transfer.sequence}'); + print(' Status: ${transfer.status}'); + + // Track transfer status + print('\nTracking transfer...'); + final status = await ibc.transfers.getStatus(transfer.txHash); + print('Current status: ${status.state}'); + print(' Source confirmed: ${status.sourceConfirmed}'); + print(' Relayed: ${status.relayed}'); + print(' Dest confirmed: ${status.destConfirmed}'); + + // Get transfer history + final history = await ibc.transfers.getHistory('synor1abc...', limit: 5); + print('\nTransfer history (last 5):'); + for (final tx in history) { + final direction = tx.sender == 'synor1abc...' ? 'OUT' : 'IN'; + print(' $direction ${tx.amount} ${tx.denom} (${tx.status})'); + } + + // Get pending transfers + final pending = await ibc.transfers.getPending('synor1abc...'); + print('\nPending transfers: ${pending.length}'); + + print(''); +} + +Future packetExample(SynorIbc ibc) async { + print('=== Packet Handling ==='); + + // Get pending packets + final packets = await ibc.packets.getPending('channel-0'); + print('Pending packets on channel-0: ${packets.length}'); + + for (final packet in packets.take(3)) { + print('\n Packet ${packet.sequence}:'); + print(' Source: ${packet.sourcePort}/${packet.sourceChannel}'); + print(' Dest: ${packet.destPort}/${packet.destChannel}'); + print(' State: ${packet.state}'); + print(' Data size: ${packet.data.length} bytes'); + print(' Timeout height: ${packet.timeoutHeight}'); + print(' Timeout timestamp: ${packet.timeoutTimestamp}'); + } + + // Get packet by sequence + final packet = await ibc.packets.get('channel-0', 1); + print('\nPacket details:'); + print(' Commitment: ${packet.commitment}'); + print(' Receipt: ${packet.receipt}'); + print(' Acknowledgement: ${packet.acknowledgement}'); + + // Get packet receipts + final receipts = await ibc.packets.getReceipts('channel-0', [1, 2, 3]); + print('\nPacket receipts:'); + for (final entry in receipts.entries) { + final status = entry.value ? 'received' : 'not received'; + print(' Sequence ${entry.key}: $status'); + } + + // Get timed out packets + final timedOut = await ibc.packets.getTimedOut('channel-0'); + print('\nTimed out packets: ${timedOut.length}'); + for (final p in timedOut) { + print(' Sequence ${p.sequence}: timeout at ${p.timeoutTimestamp}'); + } + + // Get unreceived packets + final unreceived = await ibc.packets.getUnreceived('channel-0'); + final unreceivedStr = unreceived.isEmpty ? 'none' : unreceived.join(', '); + print('\nUnreceived packet sequences: $unreceivedStr'); + + // Get unacknowledged packets + final unacked = await ibc.packets.getUnacknowledged('channel-0'); + final unackedStr = unacked.isEmpty ? 'none' : unacked.join(', '); + print('Unacknowledged packet sequences: $unackedStr'); + + print(''); +} + +Future relayerExample(SynorIbc ibc) async { + print('=== Relayer Operations ==='); + + // Get active relayers + final relayers = await ibc.relayers.list(); + print('Active relayers: ${relayers.length}'); + + for (final relayer in relayers.take(3)) { + print('\n ${relayer.address}:'); + print(' Chains: ${relayer.chains.join(", ")}'); + print(' Packets relayed: ${relayer.packetsRelayed}'); + print(' Success rate: ${relayer.successRate}%'); + print(' Avg latency: ${relayer.avgLatency}ms'); + print(' Fee rate: ${relayer.feeRate}%'); + } + + // Get relayer statistics + final stats = await ibc.relayers.getStats(); + print('\nGlobal relayer statistics:'); + print(' Total relayers: ${stats.totalRelayers}'); + print(' Active relayers: ${stats.activeRelayers}'); + print(' Packets relayed (24h): ${stats.packetsRelayed24h}'); + print(' Total fees earned: ${stats.totalFeesEarned}'); + + // Register as a relayer + print('\nRegistering as relayer...'); + final registration = await ibc.relayers.register(RelayerRegistration( + chains: ['synor-1', 'cosmoshub-4'], + feeRate: 0.1, // 0.1% fee + minPacketSize: 0, + maxPacketSize: 1000000, + )); + print('Registered with address: ${registration.relayerAddress}'); + + // Start relaying (in background) + print('\nStarting relay service...'); + final relaySession = await ibc.relayers.startRelay(RelayConfig( + channels: ['channel-0'], + autoAck: true, + batchSize: 10, + pollInterval: 5000, + )); + print('Relay session started: ${relaySession.sessionId}'); + + // Get relay queue + final queue = await ibc.relayers.getQueue('channel-0'); + print('\nRelay queue for channel-0: ${queue.length} packets'); + + // Manually relay a packet + if (queue.isNotEmpty) { + print('\nRelaying packet...'); + final relayResult = await ibc.relayers.relayPacket(queue.first.sequence, 'channel-0'); + print('Relay result: ${relayResult.status}'); + print(' TX Hash: ${relayResult.txHash}'); + print(' Fee earned: ${relayResult.feeEarned}'); + } + + // Stop relay session + await ibc.relayers.stopRelay(relaySession.sessionId); + print('\nRelay session stopped'); + + print(''); +} + +Future connectionExample(SynorIbc ibc) async { + print('=== Connection Information ==='); + + // List connections + final connections = await ibc.connections.list(); + print('Total connections: ${connections.length}'); + + for (final conn in connections.take(3)) { + print('\n ${conn.connectionId}:'); + print(' Client: ${conn.clientId}'); + print(' Counterparty: ${conn.counterpartyConnectionId}'); + print(' State: ${conn.state}'); + print(' Versions: ${conn.versions.join(", ")}'); + } + + // Get connection details + final connection = await ibc.connections.get('connection-0'); + print('\nConnection-0 details:'); + print(' Delay period: ${connection.delayPeriod}ns'); + print(' Counterparty client: ${connection.counterpartyClientId}'); + print(' Counterparty prefix: ${connection.counterpartyPrefix}'); + + // Get client state + final client = await ibc.clients.get(connection.clientId); + print('\nClient state:'); + print(' Chain ID: ${client.chainId}'); + print(' Trust level: ${client.trustLevel}'); + print(' Trusting period: ${client.trustingPeriod}'); + print(' Unbonding period: ${client.unbondingPeriod}'); + print(' Latest height: ${client.latestHeight}'); + print(' Frozen: ${client.frozen}'); + + // Get consensus state + final consensus = await ibc.clients.getConsensusState( + connection.clientId, + client.latestHeight, + ); + print('\nConsensus state at height ${client.latestHeight}:'); + print(' Timestamp: ${consensus.timestamp}'); + final rootPreview = consensus.root.length > 20 + ? consensus.root.substring(0, 20) + : consensus.root; + print(' Root: $rootPreview...'); + final validatorsPreview = consensus.nextValidatorsHash.length > 20 + ? consensus.nextValidatorsHash.substring(0, 20) + : consensus.nextValidatorsHash; + print(' Next validators hash: $validatorsPreview...'); + + print(''); +} diff --git a/sdk/flutter/example/zk_example.dart b/sdk/flutter/example/zk_example.dart new file mode 100644 index 0000000..f6653c6 --- /dev/null +++ b/sdk/flutter/example/zk_example.dart @@ -0,0 +1,504 @@ +/// Synor ZK SDK Examples for Flutter/Dart +/// +/// Demonstrates Zero-Knowledge proof operations: +/// - Circuit compilation +/// - Proof generation and verification +/// - Groth16, PLONK, and STARK proving systems +/// - Recursive proofs +/// - On-chain verification + +import 'dart:io'; +import 'package:synor_zk/synor_zk.dart'; + +Future main() async { + // Initialize client + final config = ZkConfig( + apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key', + endpoint: 'https://zk.synor.io/v1', + timeout: const Duration(seconds: 120), // ZK ops can be slow + retries: 3, + debug: false, + defaultProvingSystem: ProvingSystem.groth16, + ); + + final zk = SynorZk(config); + + try { + // Check service health + final healthy = await zk.healthCheck(); + print('Service healthy: $healthy\n'); + + // Run examples + await circuitExample(zk); + await proofExample(zk); + await provingSystemsExample(zk); + await recursiveProofExample(zk); + await onChainVerificationExample(zk); + await setupExample(zk); + } finally { + await zk.close(); + } +} + +Future circuitExample(SynorZk zk) async { + print('=== Circuit Compilation ==='); + + // Circom circuit example: prove knowledge of preimage + const circomCircuit = ''' + pragma circom 2.1.0; + + template HashPreimage() { + signal input preimage; + signal input hash; + + // Simplified hash computation (in reality, use proper hash) + signal preimageSquared; + preimageSquared <== preimage * preimage; + + // Constrain that hash matches + hash === preimageSquared; + } + + component main {public [hash]} = HashPreimage(); + '''; + + // Compile circuit + print('Compiling Circom circuit...'); + final compiled = await zk.circuits.compile(CompileRequest( + code: circomCircuit, + format: CircuitFormat.circom, + name: 'hash_preimage', + provingSystem: ProvingSystem.groth16, + )); + + print('Circuit compiled:'); + print(' Circuit ID: ${compiled.circuitId}'); + print(' Constraints: ${compiled.constraintCount}'); + print(' Public inputs: ${compiled.publicInputCount}'); + print(' Private inputs: ${compiled.privateInputCount}'); + print(' Proving key size: ${compiled.provingKeySize} bytes'); + print(' Verification key size: ${compiled.verificationKeySize} bytes'); + + // List circuits + final circuits = await zk.circuits.list(); + print('\nYour circuits: ${circuits.length}'); + for (final circuit in circuits) { + print(' ${circuit.name} (${circuit.circuitId})'); + } + + // Get circuit details + final details = await zk.circuits.get(compiled.circuitId); + print('\nCircuit details:'); + print(' Format: ${details.format}'); + print(' Proving system: ${details.provingSystem}'); + print(' Created: ${details.createdAt}'); + + // Download proving key + final provingKey = await zk.circuits.getProvingKey(compiled.circuitId); + print('\nProving key downloaded: ${provingKey.length} bytes'); + + // Download verification key + final verificationKey = await zk.circuits.getVerificationKey(compiled.circuitId); + print('Verification key downloaded: ${verificationKey.length} bytes'); + + print(''); +} + +Future proofExample(SynorZk zk) async { + print('=== Proof Generation ==='); + + // First, compile a simple circuit + const circuit = ''' + pragma circom 2.1.0; + + template Multiplier() { + signal input a; + signal input b; + signal output c; + + c <== a * b; + } + + component main {public [c]} = Multiplier(); + '''; + + final compiled = await zk.circuits.compile(CompileRequest( + code: circuit, + format: CircuitFormat.circom, + name: 'multiplier', + provingSystem: ProvingSystem.groth16, + )); + + // Generate proof + print('Generating proof...'); + final startTime = DateTime.now(); + + final proof = await zk.proofs.generate(GenerateProofRequest( + circuitId: compiled.circuitId, + inputs: {'a': '3', 'b': '7'}, + )); + + final proofTime = DateTime.now().difference(startTime); + print('Proof generated in ${proofTime.inMilliseconds}ms'); + print(' Proof ID: ${proof.proofId}'); + print(' Proof size: ${proof.proof.length} bytes'); + print(' Public signals: ${proof.publicSignals}'); + + // Verify proof + print('\nVerifying proof...'); + final verifyStart = DateTime.now(); + + final isValid = await zk.proofs.verify(VerifyRequest( + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: proof.publicSignals, + )); + + final verifyTime = DateTime.now().difference(verifyStart); + print('Verification completed in ${verifyTime.inMilliseconds}ms'); + print(' Valid: $isValid'); + + // Verify with wrong public signals (should fail) + print('\nVerifying with wrong signals...'); + final invalidResult = await zk.proofs.verify(VerifyRequest( + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: ['42'], // Wrong answer + )); + print(' Valid: $invalidResult (expected false)'); + + // Get proof status + final status = await zk.proofs.getStatus(proof.proofId); + print('\nProof status:'); + print(' State: ${status.state}'); + print(' Verified: ${status.verified}'); + print(' Created: ${status.createdAt}'); + + // List proofs + final proofs = await zk.proofs.list(compiled.circuitId); + print('\nProofs for circuit: ${proofs.length}'); + + print(''); +} + +Future provingSystemsExample(SynorZk zk) async { + print('=== Proving Systems Comparison ==='); + + // Simple circuit for comparison + const circuit = ''' + pragma circom 2.1.0; + + template Comparison() { + signal input x; + signal input y; + signal output sum; + + sum <== x + y; + } + + component main {public [sum]} = Comparison(); + '''; + + final systems = [ + (ProvingSystem.groth16, 'GROTH16'), + (ProvingSystem.plonk, 'PLONK'), + (ProvingSystem.stark, 'STARK'), + ]; + + print('Comparing proving systems:\n'); + + for (final (system, name) in systems) { + print('$name:'); + + // Compile for this system + final compiled = await zk.circuits.compile(CompileRequest( + code: circuit, + format: CircuitFormat.circom, + name: 'comparison_${name.toLowerCase()}', + provingSystem: system, + )); + + // Generate proof + final proofStart = DateTime.now(); + final proof = await zk.proofs.generate(GenerateProofRequest( + circuitId: compiled.circuitId, + inputs: {'x': '10', 'y': '20'}, + )); + final proofTime = DateTime.now().difference(proofStart); + + // Verify proof + final verifyStart = DateTime.now(); + await zk.proofs.verify(VerifyRequest( + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: proof.publicSignals, + )); + final verifyTime = DateTime.now().difference(verifyStart); + + print(' Setup: ${compiled.setupTime}ms'); + print(' Proof time: ${proofTime.inMilliseconds}ms'); + print(' Verify time: ${verifyTime.inMilliseconds}ms'); + print(' Proof size: ${proof.proof.length} bytes'); + print(' Verification key: ${compiled.verificationKeySize} bytes'); + print(''); + } + + print('Summary:'); + print(' Groth16: Smallest proofs, fast verification, trusted setup required'); + print(' PLONK: Universal setup, flexible, moderate proof size'); + print(' STARK: No trusted setup, largest proofs, quantum resistant'); + + print(''); +} + +Future recursiveProofExample(SynorZk zk) async { + print('=== Recursive Proofs ==='); + + // Inner circuit + const innerCircuit = ''' + pragma circom 2.1.0; + + template Inner() { + signal input x; + signal output y; + y <== x * x; + } + + component main {public [y]} = Inner(); + '''; + + // Compile inner circuit + final inner = await zk.circuits.compile(CompileRequest( + code: innerCircuit, + format: CircuitFormat.circom, + name: 'inner_circuit', + provingSystem: ProvingSystem.groth16, + )); + + // Generate multiple proofs to aggregate + print('Generating proofs to aggregate...'); + final proofsToAggregate = []; + for (var i = 1; i <= 4; i++) { + final proof = await zk.proofs.generate(GenerateProofRequest( + circuitId: inner.circuitId, + inputs: {'x': '$i'}, + )); + proofsToAggregate.add(ProofData( + proof: proof.proof, + publicSignals: proof.publicSignals, + )); + print(' Proof $i: y = ${proof.publicSignals[0]}'); + } + + // Aggregate proofs recursively + print('\nAggregating proofs...'); + final aggregated = await zk.proofs.aggregate(AggregateRequest( + circuitId: inner.circuitId, + proofs: proofsToAggregate, + aggregationType: 'recursive', + )); + + final originalSize = proofsToAggregate.fold( + 0, + (sum, p) => sum + p.proof.length, + ); + + print('Aggregated proof:'); + print(' Proof ID: ${aggregated.proofId}'); + print(' Aggregated count: ${aggregated.aggregatedCount}'); + print(' Proof size: ${aggregated.proof.length} bytes'); + print(' Size reduction: ${((1 - aggregated.proof.length / originalSize) * 100).toStringAsFixed(1)}%'); + + // Verify aggregated proof + final isValid = await zk.proofs.verifyAggregated(VerifyAggregatedRequest( + circuitId: inner.circuitId, + proof: aggregated.proof, + publicSignalsList: proofsToAggregate.map((p) => p.publicSignals).toList(), + )); + print('\nAggregated proof valid: $isValid'); + + // Batch verification (verify multiple proofs in one operation) + print('\nBatch verification...'); + final batchResult = await zk.proofs.batchVerify(BatchVerifyRequest( + circuitId: inner.circuitId, + proofs: proofsToAggregate, + )); + print(' All valid: ${batchResult.allValid}'); + print(' Results: ${batchResult.results.join(", ")}'); + + print(''); +} + +Future onChainVerificationExample(SynorZk zk) async { + print('=== On-Chain Verification ==='); + + // Compile circuit + const circuit = ''' + pragma circom 2.1.0; + + template VoteCommitment() { + signal input vote; // Private: actual vote + signal input nullifier; // Private: unique identifier + signal input commitment; // Public: commitment to verify + + // Simplified commitment (in practice, use Poseidon hash) + signal computed; + computed <== vote * nullifier; + commitment === computed; + } + + component main {public [commitment]} = VoteCommitment(); + '''; + + final compiled = await zk.circuits.compile(CompileRequest( + code: circuit, + format: CircuitFormat.circom, + name: 'vote_commitment', + provingSystem: ProvingSystem.groth16, + )); + + // Generate Solidity verifier + print('Generating Solidity verifier...'); + final solidityVerifier = await zk.contracts.generateVerifier(GenerateVerifierRequest( + circuitId: compiled.circuitId, + language: 'solidity', + optimized: true, + )); + print('Solidity verifier generated: ${solidityVerifier.code.length} bytes'); + print(' Contract name: ${solidityVerifier.contractName}'); + print(' Gas estimate: ${solidityVerifier.gasEstimate}'); + + // Generate proof + final proof = await zk.proofs.generate(GenerateProofRequest( + circuitId: compiled.circuitId, + inputs: { + 'vote': '1', // Vote YES (1) or NO (0) + 'nullifier': '12345', + 'commitment': '12345', // 1 * 12345 + }, + )); + + // Format proof for on-chain verification + print('\nFormatting proof for on-chain...'); + final onChainProof = await zk.contracts.formatProof(FormatProofRequest( + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: proof.publicSignals, + format: 'calldata', + )); + final calldataPreview = onChainProof.calldata.length > 100 + ? onChainProof.calldata.substring(0, 100) + : onChainProof.calldata; + print(' Calldata: $calldataPreview...'); + print(' Estimated gas: ${onChainProof.gasEstimate}'); + + // Deploy verifier contract (simulation) + print('\nDeploying verifier contract...'); + final deployment = await zk.contracts.deployVerifier(DeployRequest( + circuitId: compiled.circuitId, + network: 'synor-testnet', + )); + print(' Contract address: ${deployment.address}'); + print(' TX hash: ${deployment.txHash}'); + print(' Gas used: ${deployment.gasUsed}'); + + // Verify on-chain + print('\nVerifying on-chain...'); + final onChainResult = await zk.contracts.verifyOnChain(OnChainVerifyRequest( + contractAddress: deployment.address, + proof: proof.proof, + publicSignals: proof.publicSignals, + network: 'synor-testnet', + )); + print(' TX hash: ${onChainResult.txHash}'); + print(' Verified: ${onChainResult.verified}'); + print(' Gas used: ${onChainResult.gasUsed}'); + + // Generate verifier for other targets + print('\nGenerating verifiers for other targets:'); + final targets = ['cairo', 'noir', 'ink']; + for (final target in targets) { + final verifier = await zk.contracts.generateVerifier(GenerateVerifierRequest( + circuitId: compiled.circuitId, + language: target, + )); + print(' $target: ${verifier.code.length} bytes'); + } + + print(''); +} + +Future setupExample(SynorZk zk) async { + print('=== Trusted Setup ==='); + + // Get available ceremonies + final ceremonies = await zk.setup.listCeremonies(); + print('Active ceremonies: ${ceremonies.length}'); + for (final ceremony in ceremonies) { + print(' ${ceremony.name}:'); + print(' Status: ${ceremony.status}'); + print(' Participants: ${ceremony.participantCount}'); + print(' Current round: ${ceremony.currentRound}'); + } + + // Create a new circuit setup + const circuit = ''' + pragma circom 2.1.0; + + template NewCircuit() { + signal input a; + signal output b; + b <== a + 1; + } + + component main {public [b]} = NewCircuit(); + '''; + + print('\nInitializing setup for new circuit...'); + final setup = await zk.setup.initialize(SetupInitRequest( + circuit: circuit, + format: CircuitFormat.circom, + name: 'new_circuit_setup', + provingSystem: ProvingSystem.groth16, + ceremonyType: 'powers_of_tau', // or 'phase2' + )); + print('Setup initialized:'); + print(' Ceremony ID: ${setup.ceremonyId}'); + print(' Powers of Tau required: ${setup.powersRequired}'); + print(' Current phase: ${setup.phase}'); + + // Contribute to ceremony (in practice, generates random entropy) + print('\nContributing to ceremony...'); + final contribution = await zk.setup.contribute(ContributeRequest( + ceremonyId: setup.ceremonyId, + entropy: 'random-entropy-from-user'.codeUnits.map((b) => b.toRadixString(16).padLeft(2, '0')).join(), + )); + print('Contribution submitted:'); + print(' Participant: ${contribution.participantId}'); + print(' Contribution hash: ${contribution.hash}'); + print(' Verification status: ${contribution.verified}'); + + // Get ceremony status + final status = await zk.setup.getStatus(setup.ceremonyId); + print('\nCeremony status:'); + print(' Phase: ${status.phase}'); + print(' Total contributions: ${status.totalContributions}'); + print(' Verified contributions: ${status.verifiedContributions}'); + print(' Ready for finalization: ${status.readyForFinalization}'); + + // Finalize setup (when enough contributions) + if (status.readyForFinalization) { + print('\nFinalizing setup...'); + final finalized = await zk.setup.finalize(setup.ceremonyId); + print('Setup finalized:'); + print(' Proving key hash: ${finalized.provingKeyHash}'); + print(' Verification key hash: ${finalized.verificationKeyHash}'); + print(' Contribution transcript: ${finalized.transcriptCid}'); + } + + // Download ceremony transcript + final transcript = await zk.setup.getTranscript(setup.ceremonyId); + print('\nCeremony transcript: ${transcript.length} bytes'); + + print(''); +} diff --git a/sdk/go/examples/compiler_example.go b/sdk/go/examples/compiler_example.go new file mode 100644 index 0000000..1f308de --- /dev/null +++ b/sdk/go/examples/compiler_example.go @@ -0,0 +1,465 @@ +// Package main demonstrates the Synor Compiler SDK for Go +// +// This example covers smart contract compilation and analysis: +// - WASM contract compilation and optimization +// - ABI extraction and encoding +// - Contract analysis and security scanning +// - Validation and verification +package main + +import ( + "context" + "fmt" + "log" + "os" + "time" + + "github.com/synor/sdk-go/compiler" +) + +func main() { + // Initialize client + config := compiler.Config{ + APIKey: getEnv("SYNOR_API_KEY", "your-api-key"), + Endpoint: "https://compiler.synor.io/v1", + Timeout: 60 * time.Second, + Retries: 3, + Debug: false, + DefaultOptimizationLevel: compiler.OptimizationSize, + MaxContractSize: 256 * 1024, + UseWasmOpt: true, + Validate: true, + ExtractMetadata: true, + GenerateABI: true, + } + + client, err := compiler.NewClient(config) + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + defer client.Close() + + ctx := context.Background() + + // Check service health + healthy, err := client.HealthCheck(ctx) + if err != nil { + log.Printf("Health check failed: %v", err) + } else { + fmt.Printf("Service healthy: %v\n\n", healthy) + } + + // Run examples + compileContractExample(ctx, client) + compilationModesExample(ctx, client) + abiExample(ctx, client) + analysisExample(ctx, client) + validationExample(ctx, client) + securityExample(ctx, client) +} + +// createMinimalWasm creates a minimal valid WASM module for testing. +func createMinimalWasm() []byte { + return []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, 0x61, 0x64, 0x64, 0x00, 0x00, + // Code section + 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b, + } +} + +func compileContractExample(ctx context.Context, client *compiler.Client) { + fmt.Println("=== Contract Compilation ===") + + wasm := createMinimalWasm() + + result, err := client.Compile(ctx, wasm, &compiler.CompileOptions{ + OptimizationLevel: compiler.OptimizationSize, + UseWasmOpt: true, + Validate: true, + ExtractMetadata: true, + GenerateABI: true, + StripOptions: &compiler.StripOptions{ + StripDebug: true, + StripProducers: true, + StripNames: true, + StripCustom: true, + StripUnused: true, + PreserveSections: []string{}, + }, + }) + if err != nil { + log.Printf("Failed to compile contract: %v", err) + return + } + + fmt.Println("Compilation result:") + fmt.Printf(" Contract ID: %s\n", result.ContractID) + fmt.Printf(" Code hash: %s\n", result.CodeHash) + fmt.Printf(" Original size: %d bytes\n", result.OriginalSize) + fmt.Printf(" Optimized size: %d bytes\n", result.OptimizedSize) + fmt.Printf(" Size reduction: %.1f%%\n", result.SizeReduction) + fmt.Printf(" Estimated deploy gas: %d\n", result.EstimatedDeployGas) + + if result.Metadata != nil { + fmt.Println("\nMetadata:") + fmt.Printf(" Name: %s\n", result.Metadata.Name) + fmt.Printf(" Version: %s\n", result.Metadata.Version) + fmt.Printf(" SDK Version: %s\n", result.Metadata.SDKVersion) + } + + if result.ABI != nil { + fmt.Println("\nABI:") + fmt.Printf(" Functions: %d\n", len(result.ABI.Functions)) + fmt.Printf(" Events: %d\n", len(result.ABI.Events)) + fmt.Printf(" Errors: %d\n", len(result.ABI.Errors)) + } + + fmt.Println() +} + +func compilationModesExample(ctx context.Context, client *compiler.Client) { + fmt.Println("=== Compilation Modes ===") + + wasm := createMinimalWasm() + + // Development mode: fast compilation, debugging support + fmt.Println("Development mode:") + devResult, err := client.Contracts.CompileDev(ctx, wasm) + if err != nil { + log.Printf("Failed to compile in dev mode: %v", err) + return + } + fmt.Printf(" Size: %d bytes\n", devResult.OptimizedSize) + fmt.Println(" Optimization: none") + + // Production mode: maximum optimization + fmt.Println("\nProduction mode:") + prodResult, err := client.Contracts.CompileProduction(ctx, wasm) + if err != nil { + log.Printf("Failed to compile in production mode: %v", err) + return + } + fmt.Printf(" Size: %d bytes\n", prodResult.OptimizedSize) + fmt.Println(" Optimization: aggressive") + fmt.Printf(" Size savings: %d bytes\n", devResult.OptimizedSize-prodResult.OptimizedSize) + + // Custom optimization levels + fmt.Println("\nOptimization levels:") + levels := []compiler.OptimizationLevel{ + compiler.OptimizationNone, + compiler.OptimizationBasic, + compiler.OptimizationSize, + compiler.OptimizationAggressive, + } + + for _, level := range levels { + result, err := client.Compile(ctx, wasm, &compiler.CompileOptions{ + OptimizationLevel: level, + }) + if err != nil { + log.Printf("Failed to compile with %s: %v", level, err) + continue + } + fmt.Printf(" %s: %d bytes\n", level, result.OptimizedSize) + } + + fmt.Println() +} + +func abiExample(ctx context.Context, client *compiler.Client) { + fmt.Println("=== ABI Operations ===") + + wasm := createMinimalWasm() + + // Extract ABI from WASM + abi, err := client.ABI.Extract(ctx, wasm) + if err != nil { + log.Printf("Failed to extract ABI: %v", err) + return + } + fmt.Printf("Contract: %s\n", abi.Name) + fmt.Printf("Version: %s\n", abi.Version) + + // List functions + if len(abi.Functions) > 0 { + fmt.Println("\nFunctions:") + for _, fn := range abi.Functions { + inputs := "" + for i, input := range fn.Inputs { + if i > 0 { + inputs += ", " + } + inputs += fmt.Sprintf("%s: %s", input.Name, input.Type.TypeName) + } + + outputs := "void" + if len(fn.Outputs) > 0 { + outputTypes := make([]string, len(fn.Outputs)) + for i, output := range fn.Outputs { + outputTypes[i] = output.Type.TypeName + } + outputs = fmt.Sprintf("%v", outputTypes) + } + + modifiers := "" + if fn.View { + modifiers += "view " + } + if fn.Payable { + modifiers += "payable" + } + + fmt.Printf(" %s(%s) -> %s %s\n", fn.Name, inputs, outputs, modifiers) + fmt.Printf(" Selector: %s\n", fn.Selector) + } + } + + // List events + if len(abi.Events) > 0 { + fmt.Println("\nEvents:") + for _, event := range abi.Events { + params := "" + for i, param := range event.Params { + if i > 0 { + params += ", " + } + indexed := "" + if param.Indexed { + indexed = "indexed " + } + params += fmt.Sprintf("%s%s: %s", indexed, param.Name, param.Type.TypeName) + } + fmt.Printf(" %s(%s)\n", event.Name, params) + fmt.Printf(" Topic: %s\n", event.Topic) + } + } + + // Encode a function call + if len(abi.Functions) > 0 { + fn := abi.Functions[0] + encoded, err := client.ABI.EncodeCall(ctx, fn, []interface{}{"arg1", "arg2"}) + if err != nil { + log.Printf("Failed to encode call: %v", err) + } else { + fmt.Printf("\nEncoded call to %s: %s\n", fn.Name, encoded) + } + + // Decode a result + decoded, err := client.ABI.DecodeResult(ctx, fn, encoded) + if err != nil { + log.Printf("Failed to decode result: %v", err) + } else { + fmt.Printf("Decoded result: %v\n", decoded) + } + } + + fmt.Println() +} + +func analysisExample(ctx context.Context, client *compiler.Client) { + fmt.Println("=== Contract Analysis ===") + + wasm := createMinimalWasm() + + // Full analysis + analysis, err := client.Analysis.Analyze(ctx, wasm) + if err != nil { + log.Printf("Failed to analyze contract: %v", err) + return + } + + // Size breakdown + if analysis.SizeBreakdown != nil { + fmt.Println("Size breakdown:") + fmt.Printf(" Code: %d bytes\n", analysis.SizeBreakdown.Code) + fmt.Printf(" Data: %d bytes\n", analysis.SizeBreakdown.Data) + fmt.Printf(" Functions: %d bytes\n", analysis.SizeBreakdown.Functions) + fmt.Printf(" Memory: %d bytes\n", analysis.SizeBreakdown.Memory) + fmt.Printf(" Exports: %d bytes\n", analysis.SizeBreakdown.Exports) + fmt.Printf(" Imports: %d bytes\n", analysis.SizeBreakdown.Imports) + fmt.Printf(" Total: %d bytes\n", analysis.SizeBreakdown.Total) + } + + // Function analysis + if len(analysis.Functions) > 0 { + fmt.Println("\nFunction analysis:") + limit := 5 + if len(analysis.Functions) < limit { + limit = len(analysis.Functions) + } + for _, fn := range analysis.Functions[:limit] { + fmt.Printf(" %s:\n", fn.Name) + fmt.Printf(" Size: %d bytes\n", fn.Size) + fmt.Printf(" Instructions: %d\n", fn.InstructionCount) + fmt.Printf(" Locals: %d\n", fn.LocalCount) + fmt.Printf(" Exported: %v\n", fn.Exported) + fmt.Printf(" Estimated gas: %d\n", fn.EstimatedGas) + } + } + + // Import analysis + if len(analysis.Imports) > 0 { + fmt.Println("\nImports:") + for _, imp := range analysis.Imports { + fmt.Printf(" %s.%s (%s)\n", imp.Module, imp.Name, imp.Kind) + } + } + + // Gas analysis + if analysis.GasAnalysis != nil { + fmt.Println("\nGas analysis:") + fmt.Printf(" Deployment: %d\n", analysis.GasAnalysis.DeploymentGas) + fmt.Printf(" Memory init: %d\n", analysis.GasAnalysis.MemoryInitGas) + fmt.Printf(" Data section: %d\n", analysis.GasAnalysis.DataSectionGas) + } + + // Extract metadata + metadata, err := client.Analysis.ExtractMetadata(ctx, wasm) + if err != nil { + log.Printf("Failed to extract metadata: %v", err) + } else { + fmt.Println("\nContract metadata:") + fmt.Printf(" Name: %s\n", metadata.Name) + fmt.Printf(" Version: %s\n", metadata.Version) + fmt.Printf(" Build timestamp: %s\n", metadata.BuildTimestamp) + } + + // Estimate deployment gas + gas, err := client.Analysis.EstimateDeployGas(ctx, wasm) + if err != nil { + log.Printf("Failed to estimate deploy gas: %v", err) + } else { + fmt.Printf("\nEstimated deployment gas: %d\n", gas) + } + + fmt.Println() +} + +func validationExample(ctx context.Context, client *compiler.Client) { + fmt.Println("=== Contract Validation ===") + + wasm := createMinimalWasm() + + // Full validation + result, err := client.Validation.Validate(ctx, wasm) + if err != nil { + log.Printf("Failed to validate contract: %v", err) + return + } + fmt.Printf("Valid: %v\n", result.Valid) + fmt.Printf("Exports: %d\n", result.ExportCount) + fmt.Printf("Imports: %d\n", result.ImportCount) + fmt.Printf("Functions: %d\n", result.FunctionCount) + fmt.Printf("Memory pages: %d\n", result.MemoryPages) + + if len(result.Errors) > 0 { + fmt.Println("\nValidation errors:") + for _, e := range result.Errors { + fmt.Printf(" [%s] %s\n", e.Code, e.Message) + if e.Location != "" { + fmt.Printf(" at %s\n", e.Location) + } + } + } + + if len(result.Warnings) > 0 { + fmt.Println("\nWarnings:") + for _, warning := range result.Warnings { + fmt.Printf(" %s\n", warning) + } + } + + // Quick validation + isValid, err := client.Validation.IsValid(ctx, wasm) + if err != nil { + log.Printf("Failed quick validation: %v", err) + } else { + fmt.Printf("\nQuick validation: %v\n", isValid) + } + + // Get validation errors only + errors, err := client.Validation.GetErrors(ctx, wasm) + if err != nil { + log.Printf("Failed to get validation errors: %v", err) + } else { + fmt.Printf("Error count: %d\n", len(errors)) + } + + // Validate required exports + hasRequired, err := client.Validation.ValidateExports(ctx, wasm, []string{"init", "execute", "query"}) + if err != nil { + log.Printf("Failed to validate exports: %v", err) + } else { + fmt.Printf("Has required exports: %v\n", hasRequired) + } + + // Validate memory constraints + memoryValid, err := client.Validation.ValidateMemory(ctx, wasm, 16) + if err != nil { + log.Printf("Failed to validate memory: %v", err) + } else { + fmt.Printf("Memory within 16 pages: %v\n", memoryValid) + } + + fmt.Println() +} + +func securityExample(ctx context.Context, client *compiler.Client) { + fmt.Println("=== Security Scanning ===") + + wasm := createMinimalWasm() + + security, err := client.Analysis.SecurityScan(ctx, wasm) + if err != nil { + log.Printf("Failed to perform security scan: %v", err) + return + } + + fmt.Printf("Security score: %d/100\n", security.Score) + + if len(security.Issues) > 0 { + fmt.Println("\nSecurity issues:") + severityIcons := map[string]string{ + "critical": "[CRIT]", + "high": "[HIGH]", + "medium": "[MED]", + "low": "[LOW]", + } + for _, issue := range security.Issues { + icon := severityIcons[issue.Severity] + if icon == "" { + icon = "[???]" + } + fmt.Printf("%s [%s] %s\n", icon, issue.Severity, issue.Type) + fmt.Printf(" %s\n", issue.Description) + if issue.Location != "" { + fmt.Printf(" at %s\n", issue.Location) + } + } + } else { + fmt.Println("No security issues found!") + } + + if len(security.Recommendations) > 0 { + fmt.Println("\nRecommendations:") + for _, rec := range security.Recommendations { + fmt.Printf(" * %s\n", rec) + } + } + + fmt.Println() +} + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/sdk/go/examples/crypto_example.go b/sdk/go/examples/crypto_example.go new file mode 100644 index 0000000..a86fb3c --- /dev/null +++ b/sdk/go/examples/crypto_example.go @@ -0,0 +1,344 @@ +// Package main demonstrates the Synor Crypto SDK for Go +// +// This example covers quantum-resistant cryptographic operations: +// - Hybrid Ed25519 + Dilithium3 signatures +// - BIP-39 mnemonic generation and validation +// - Post-quantum algorithms (Falcon, SPHINCS+) +// - Key derivation functions +package main + +import ( + "context" + "fmt" + "log" + "os" + "time" + + "github.com/synor/sdk-go/crypto" +) + +func main() { + // Initialize client + config := crypto.Config{ + APIKey: getEnv("SYNOR_API_KEY", "your-api-key"), + Endpoint: "https://crypto.synor.io/v1", + Timeout: 30 * time.Second, + Retries: 3, + Debug: false, + DefaultNetwork: crypto.NetworkMainnet, + } + + client, err := crypto.NewClient(config) + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + defer client.Close() + + ctx := context.Background() + + // Check service health + healthy, err := client.HealthCheck(ctx) + if err != nil { + log.Printf("Health check failed: %v", err) + } else { + fmt.Printf("Service healthy: %v\n\n", healthy) + } + + // Run examples + mnemonicExample(ctx, client) + keypairExample(ctx, client) + signingExample(ctx, client) + falconExample(ctx, client) + sphincsExample(ctx, client) + kdfExample(ctx, client) + hashExample(ctx, client) +} + +func mnemonicExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== Mnemonic Operations ===") + + // Generate a 24-word mnemonic (256-bit entropy) + mnemonic, err := client.Mnemonic.Generate(ctx, 24) + if err != nil { + log.Printf("Failed to generate mnemonic: %v", err) + return + } + fmt.Printf("Generated mnemonic: %s\n", mnemonic.Phrase) + fmt.Printf("Word count: %d\n", mnemonic.WordCount) + + // Validate a mnemonic + validation, err := client.Mnemonic.Validate(ctx, mnemonic.Phrase) + if err != nil { + log.Printf("Failed to validate mnemonic: %v", err) + return + } + fmt.Printf("Valid: %v\n", validation.Valid) + if !validation.Valid { + fmt.Printf("Error: %s\n", validation.Error) + } + + // Convert mnemonic to seed + seed, err := client.Mnemonic.ToSeed(ctx, mnemonic.Phrase, "optional-passphrase") + if err != nil { + log.Printf("Failed to convert to seed: %v", err) + return + } + fmt.Printf("Seed (hex): %s...\n", fmt.Sprintf("%x", seed)[:32]) + + // Word suggestions for autocomplete + suggestions, err := client.Mnemonic.SuggestWords(ctx, "aban", 5) + if err != nil { + log.Printf("Failed to get suggestions: %v", err) + return + } + fmt.Printf("Suggestions for 'aban': %v\n", suggestions) + + fmt.Println() +} + +func keypairExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== Keypair Operations ===") + + // Generate a random keypair + keypair, err := client.Keypairs.Generate(ctx) + if err != nil { + log.Printf("Failed to generate keypair: %v", err) + return + } + fmt.Println("Generated hybrid keypair:") + fmt.Printf(" Ed25519 public key size: %d bytes\n", len(keypair.PublicKey.Ed25519Bytes)) + fmt.Printf(" Dilithium public key size: %d bytes\n", len(keypair.PublicKey.DilithiumBytes)) + fmt.Printf(" Total public key size: %d bytes\n", keypair.PublicKey.Size) + + // Get addresses for different networks + fmt.Println("\nAddresses:") + fmt.Printf(" Mainnet: %s\n", keypair.GetAddress(crypto.NetworkMainnet)) + fmt.Printf(" Testnet: %s\n", keypair.GetAddress(crypto.NetworkTestnet)) + fmt.Printf(" Devnet: %s\n", keypair.GetAddress(crypto.NetworkDevnet)) + + // Create keypair from mnemonic (deterministic) + mnemonic, err := client.Mnemonic.Generate(ctx, 24) + if err != nil { + log.Printf("Failed to generate mnemonic: %v", err) + return + } + + keypair2, err := client.Keypairs.FromMnemonic(ctx, mnemonic.Phrase, "") + if err != nil { + log.Printf("Failed to create keypair from mnemonic: %v", err) + return + } + addr := keypair2.GetAddress(crypto.NetworkMainnet) + fmt.Printf("\nKeypair from mnemonic: %s...\n", addr[:20]) + + // Derive child keypair using BIP-44 path + path := crypto.DerivationPathExternal(0, 0) // m/44'/21337'/0'/0/0 + fmt.Printf("Derivation path: %s\n", path) + + fmt.Println() +} + +func signingExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== Hybrid Signing ===") + + // Generate keypair + keypair, err := client.Keypairs.Generate(ctx) + if err != nil { + log.Printf("Failed to generate keypair: %v", err) + return + } + + // Sign a message + message := []byte("Hello, quantum-resistant world!") + signature, err := client.Signing.Sign(ctx, keypair, message) + if err != nil { + log.Printf("Failed to sign message: %v", err) + return + } + + fmt.Println("Signature created:") + fmt.Printf(" Ed25519 component: %d bytes\n", len(signature.Ed25519Bytes)) + fmt.Printf(" Dilithium component: %d bytes\n", len(signature.DilithiumBytes)) + fmt.Printf(" Total signature size: %d bytes\n", signature.Size) + + // Verify the signature + valid, err := client.Signing.Verify(ctx, keypair.PublicKey, message, signature) + if err != nil { + log.Printf("Failed to verify signature: %v", err) + return + } + fmt.Printf("\nVerification result: %v\n", valid) + + // Verify with tampered message fails + tamperedMessage := []byte("Hello, tampered message!") + invalidResult, err := client.Signing.Verify(ctx, keypair.PublicKey, tamperedMessage, signature) + if err != nil { + log.Printf("Failed to verify tampered signature: %v", err) + return + } + fmt.Printf("Tampered message verification: %v\n", invalidResult) + + fmt.Println() +} + +func falconExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== Falcon Post-Quantum Signatures ===") + + // Generate Falcon-512 keypair (128-bit security) + falcon512, err := client.Falcon.Generate(ctx, crypto.Falcon512) + if err != nil { + log.Printf("Failed to generate Falcon-512 keypair: %v", err) + return + } + fmt.Println("Falcon-512 keypair:") + fmt.Printf(" Public key: %d bytes\n", len(falcon512.PublicKey.KeyBytes)) + fmt.Println(" Security level: 128-bit") + + // Generate Falcon-1024 keypair (256-bit security) + falcon1024, err := client.Falcon.Generate(ctx, crypto.Falcon1024) + if err != nil { + log.Printf("Failed to generate Falcon-1024 keypair: %v", err) + return + } + fmt.Println("\nFalcon-1024 keypair:") + fmt.Printf(" Public key: %d bytes\n", len(falcon1024.PublicKey.KeyBytes)) + fmt.Println(" Security level: 256-bit") + + // Sign with Falcon-512 + message := []byte("Post-quantum secure message") + signature, err := client.Falcon.Sign(ctx, falcon512, message) + if err != nil { + log.Printf("Failed to sign with Falcon-512: %v", err) + return + } + fmt.Printf("\nFalcon-512 signature: %d bytes\n", len(signature.SignatureBytes)) + + // Verify + valid, err := client.Falcon.Verify(ctx, falcon512.PublicKey.KeyBytes, message, signature) + if err != nil { + log.Printf("Failed to verify Falcon signature: %v", err) + return + } + fmt.Printf("Verification: %v\n", valid) + + fmt.Println() +} + +func sphincsExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== SPHINCS+ Hash-Based Signatures ===") + + // SPHINCS+ variants with different security levels + variants := []struct { + variant crypto.SphincsVariant + security int + sigSize int + }{ + {crypto.Shake128s, 128, 7856}, + {crypto.Shake192s, 192, 16224}, + {crypto.Shake256s, 256, 29792}, + } + + // Generate and demonstrate each variant + for _, v := range variants { + keypair, err := client.Sphincs.Generate(ctx, v.variant) + if err != nil { + log.Printf("Failed to generate SPHINCS+ keypair: %v", err) + continue + } + fmt.Printf("SPHINCS+ %s:\n", v.variant) + fmt.Printf(" Security level: %d-bit\n", v.security) + fmt.Printf(" Expected signature size: %d bytes\n", v.sigSize) + + // Sign a message + message := []byte("Hash-based quantum security") + signature, err := client.Sphincs.Sign(ctx, keypair, message) + if err != nil { + log.Printf("Failed to sign with SPHINCS+: %v", err) + continue + } + fmt.Printf(" Actual signature size: %d bytes\n", len(signature.SignatureBytes)) + + // Verify + valid, err := client.Sphincs.Verify(ctx, keypair.PublicKey.KeyBytes, message, signature) + if err != nil { + log.Printf("Failed to verify SPHINCS+ signature: %v", err) + continue + } + fmt.Printf(" Verification: %v\n\n", valid) + } +} + +func kdfExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== Key Derivation Functions ===") + + // HKDF (HMAC-based Key Derivation Function) + seed := []byte("master-secret-key-material-here") + hkdfConfig := crypto.DerivationConfig{ + Salt: []byte("application-salt"), + Info: []byte("encryption-key"), + OutputLength: 32, + } + + derivedKey, err := client.KDF.DeriveKey(ctx, seed, hkdfConfig) + if err != nil { + log.Printf("Failed to derive key with HKDF: %v", err) + return + } + fmt.Printf("HKDF derived key: %x\n", derivedKey) + + // PBKDF2 (Password-Based Key Derivation Function) + password := []byte("user-password") + pbkdf2Config := crypto.PasswordDerivationConfig{ + Salt: []byte("random-salt-value"), + Iterations: 100000, + OutputLength: 32, + } + + passwordKey, err := client.KDF.DeriveFromPassword(ctx, password, pbkdf2Config) + if err != nil { + log.Printf("Failed to derive key with PBKDF2: %v", err) + return + } + fmt.Printf("PBKDF2 derived key: %x\n", passwordKey) + + fmt.Println() +} + +func hashExample(ctx context.Context, client *crypto.Client) { + fmt.Println("=== Hash Functions ===") + + data := []byte("Data to hash") + + // SHA3-256 (FIPS 202) + sha3, err := client.Hash.SHA3_256(ctx, data) + if err != nil { + log.Printf("Failed to compute SHA3-256: %v", err) + return + } + fmt.Printf("SHA3-256: %s\n", sha3.Hex) + + // BLAKE3 (fast, parallel) + blake3, err := client.Hash.Blake3(ctx, data) + if err != nil { + log.Printf("Failed to compute BLAKE3: %v", err) + return + } + fmt.Printf("BLAKE3: %s\n", blake3.Hex) + + // Keccak-256 (Ethereum compatible) + keccak, err := client.Hash.Keccak256(ctx, data) + if err != nil { + log.Printf("Failed to compute Keccak-256: %v", err) + return + } + fmt.Printf("Keccak: %s\n", keccak.Hex) + + fmt.Println() +} + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/sdk/go/examples/dex_example.go b/sdk/go/examples/dex_example.go new file mode 100644 index 0000000..a363f46 --- /dev/null +++ b/sdk/go/examples/dex_example.go @@ -0,0 +1,506 @@ +// Package main demonstrates the Synor DEX SDK for Go +// +// This example covers decentralized exchange operations: +// - Spot trading (limit/market orders) +// - Perpetual futures trading +// - Liquidity provision (AMM pools) +// - Order book management +// - Portfolio tracking +package main + +import ( + "context" + "fmt" + "log" + "os" + "time" + + "github.com/synor/sdk-go/dex" +) + +func main() { + // Initialize client + config := dex.Config{ + APIKey: getEnv("SYNOR_API_KEY", "your-api-key"), + Endpoint: "https://dex.synor.io/v1", + Timeout: 30 * time.Second, + Retries: 3, + Debug: false, + DefaultMarket: "SYN-USDC", + } + + client, err := dex.NewClient(config) + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + defer client.Close() + + ctx := context.Background() + + // Check service health + healthy, err := client.HealthCheck(ctx) + if err != nil { + log.Printf("Health check failed: %v", err) + } else { + fmt.Printf("Service healthy: %v\n\n", healthy) + } + + // Run examples + marketsExample(ctx, client) + spotTradingExample(ctx, client) + perpsTradingExample(ctx, client) + liquidityExample(ctx, client) + orderbookExample(ctx, client) + portfolioExample(ctx, client) +} + +func marketsExample(ctx context.Context, client *dex.Client) { + fmt.Println("=== Markets ===") + + // Get all markets + markets, err := client.Markets.List(ctx) + if err != nil { + log.Printf("Failed to list markets: %v", err) + return + } + fmt.Printf("Available markets: %d\n", len(markets)) + + for _, market := range markets[:min(5, len(markets))] { + fmt.Printf("\n %s:\n", market.Symbol) + fmt.Printf(" Base: %s, Quote: %s\n", market.BaseAsset, market.QuoteAsset) + fmt.Printf(" Price: %s\n", market.LastPrice) + fmt.Printf(" 24h Volume: %s\n", market.Volume24h) + fmt.Printf(" 24h Change: %s%%\n", market.Change24h) + fmt.Printf(" Status: %s\n", market.Status) + } + + // Get specific market + market, err := client.Markets.Get(ctx, "SYN-USDC") + if err != nil { + log.Printf("Failed to get market: %v", err) + return + } + fmt.Printf("\nSYN-USDC details:\n") + fmt.Printf(" Min order size: %s\n", market.MinOrderSize) + fmt.Printf(" Tick size: %s\n", market.TickSize) + fmt.Printf(" Maker fee: %s%%\n", market.MakerFee) + fmt.Printf(" Taker fee: %s%%\n", market.TakerFee) + + // Get market statistics + stats, err := client.Markets.GetStats(ctx, "SYN-USDC") + if err != nil { + log.Printf("Failed to get market stats: %v", err) + return + } + fmt.Printf("\nMarket statistics:\n") + fmt.Printf(" High 24h: %s\n", stats.High24h) + fmt.Printf(" Low 24h: %s\n", stats.Low24h) + fmt.Printf(" Open interest: %s\n", stats.OpenInterest) + fmt.Printf(" Funding rate: %s%%\n", stats.FundingRate) + + fmt.Println() +} + +func spotTradingExample(ctx context.Context, client *dex.Client) { + fmt.Println("=== Spot Trading ===") + + // Place a limit order + fmt.Println("Placing limit buy order...") + limitOrder, err := client.Spot.PlaceOrder(ctx, &dex.OrderRequest{ + Market: "SYN-USDC", + Side: dex.SideBuy, + OrderType: dex.OrderTypeLimit, + Price: "1.50", + Quantity: "100", + TimeInForce: dex.TimeInForceGTC, + }) + if err != nil { + log.Printf("Failed to place limit order: %v", err) + } else { + fmt.Printf("Limit order placed:\n") + fmt.Printf(" Order ID: %s\n", limitOrder.OrderID) + fmt.Printf(" Status: %s\n", limitOrder.Status) + fmt.Printf(" Price: %s\n", limitOrder.Price) + fmt.Printf(" Quantity: %s\n", limitOrder.Quantity) + } + + // Place a market order + fmt.Println("\nPlacing market sell order...") + marketOrder, err := client.Spot.PlaceOrder(ctx, &dex.OrderRequest{ + Market: "SYN-USDC", + Side: dex.SideSell, + OrderType: dex.OrderTypeMarket, + Quantity: "50", + }) + if err != nil { + log.Printf("Failed to place market order: %v", err) + } else { + fmt.Printf("Market order executed:\n") + fmt.Printf(" Order ID: %s\n", marketOrder.OrderID) + fmt.Printf(" Status: %s\n", marketOrder.Status) + fmt.Printf(" Filled: %s\n", marketOrder.FilledQuantity) + fmt.Printf(" Avg price: %s\n", marketOrder.AveragePrice) + } + + // Get order status + if limitOrder != nil { + status, err := client.Spot.GetOrder(ctx, limitOrder.OrderID) + if err != nil { + log.Printf("Failed to get order status: %v", err) + } else { + fmt.Printf("\nOrder status:\n") + fmt.Printf(" Status: %s\n", status.Status) + fmt.Printf(" Filled: %s / %s\n", status.FilledQuantity, status.Quantity) + fmt.Printf(" Remaining: %s\n", status.RemainingQuantity) + } + + // Cancel order + fmt.Println("\nCancelling order...") + err = client.Spot.CancelOrder(ctx, limitOrder.OrderID) + if err != nil { + log.Printf("Failed to cancel order: %v", err) + } else { + fmt.Println("Order cancelled successfully") + } + } + + // Get open orders + openOrders, err := client.Spot.GetOpenOrders(ctx, "SYN-USDC") + if err != nil { + log.Printf("Failed to get open orders: %v", err) + } else { + fmt.Printf("\nOpen orders: %d\n", len(openOrders)) + } + + // Get trade history + trades, err := client.Spot.GetTradeHistory(ctx, "SYN-USDC", 10) + if err != nil { + log.Printf("Failed to get trade history: %v", err) + } else { + fmt.Printf("\nRecent trades: %d\n", len(trades)) + for _, trade := range trades[:min(3, len(trades))] { + fmt.Printf(" %s %s @ %s (%s)\n", trade.Side, trade.Quantity, trade.Price, trade.Timestamp.Format(time.RFC3339)) + } + } + + fmt.Println() +} + +func perpsTradingExample(ctx context.Context, client *dex.Client) { + fmt.Println("=== Perpetual Futures Trading ===") + + // Get available perps markets + perpsMarkets, err := client.Perps.ListMarkets(ctx) + if err != nil { + log.Printf("Failed to list perps markets: %v", err) + return + } + fmt.Printf("Available perps markets: %d\n", len(perpsMarkets)) + + for _, market := range perpsMarkets[:min(3, len(perpsMarkets))] { + fmt.Printf(" %s: %s (funding: %s%%)\n", market.Symbol, market.MarkPrice, market.FundingRate) + } + + // Open a long position + fmt.Println("\nOpening long position...") + position, err := client.Perps.OpenPosition(ctx, &dex.PerpsOrderRequest{ + Market: "SYN-USDC-PERP", + Side: dex.SideBuy, + OrderType: dex.OrderTypeLimit, + Price: "1.50", + Size: "1000", + Leverage: 10, + ReduceOnly: false, + }) + if err != nil { + log.Printf("Failed to open position: %v", err) + } else { + fmt.Printf("Position opened:\n") + fmt.Printf(" Position ID: %s\n", position.PositionID) + fmt.Printf(" Size: %s\n", position.Size) + fmt.Printf(" Entry price: %s\n", position.EntryPrice) + fmt.Printf(" Leverage: %dx\n", position.Leverage) + fmt.Printf(" Liquidation price: %s\n", position.LiquidationPrice) + } + + // Get position details + if position != nil { + details, err := client.Perps.GetPosition(ctx, position.PositionID) + if err != nil { + log.Printf("Failed to get position: %v", err) + } else { + fmt.Printf("\nPosition details:\n") + fmt.Printf(" Unrealized PnL: %s\n", details.UnrealizedPnL) + fmt.Printf(" Margin: %s\n", details.Margin) + fmt.Printf(" Margin ratio: %s%%\n", details.MarginRatio) + } + } + + // Set stop loss and take profit + if position != nil { + fmt.Println("\nSetting stop loss and take profit...") + err = client.Perps.SetStopLoss(ctx, position.PositionID, "1.40") + if err != nil { + log.Printf("Failed to set stop loss: %v", err) + } else { + fmt.Println("Stop loss set at 1.40") + } + + err = client.Perps.SetTakeProfit(ctx, position.PositionID, "1.80") + if err != nil { + log.Printf("Failed to set take profit: %v", err) + } else { + fmt.Println("Take profit set at 1.80") + } + + // Close position + fmt.Println("\nClosing position...") + closeResult, err := client.Perps.ClosePosition(ctx, position.PositionID) + if err != nil { + log.Printf("Failed to close position: %v", err) + } else { + fmt.Printf("Position closed:\n") + fmt.Printf(" Realized PnL: %s\n", closeResult.RealizedPnL) + fmt.Printf(" Close price: %s\n", closeResult.ClosePrice) + } + } + + // Get all positions + positions, err := client.Perps.GetPositions(ctx) + if err != nil { + log.Printf("Failed to get positions: %v", err) + } else { + fmt.Printf("\nOpen positions: %d\n", len(positions)) + } + + // Get funding history + funding, err := client.Perps.GetFundingHistory(ctx, "SYN-USDC-PERP", 10) + if err != nil { + log.Printf("Failed to get funding history: %v", err) + } else { + fmt.Printf("Funding payments: %d\n", len(funding)) + } + + fmt.Println() +} + +func liquidityExample(ctx context.Context, client *dex.Client) { + fmt.Println("=== Liquidity Provision ===") + + // Get available pools + pools, err := client.Liquidity.ListPools(ctx) + if err != nil { + log.Printf("Failed to list pools: %v", err) + return + } + fmt.Printf("Available pools: %d\n", len(pools)) + + for _, pool := range pools[:min(3, len(pools))] { + fmt.Printf("\n %s:\n", pool.Name) + fmt.Printf(" TVL: $%s\n", pool.TVL) + fmt.Printf(" APR: %s%%\n", pool.APR) + fmt.Printf(" Volume 24h: $%s\n", pool.Volume24h) + fmt.Printf(" Fee tier: %s%%\n", pool.FeeTier) + } + + // Get pool details + pool, err := client.Liquidity.GetPool(ctx, "SYN-USDC") + if err != nil { + log.Printf("Failed to get pool: %v", err) + return + } + fmt.Printf("\nSYN-USDC pool details:\n") + fmt.Printf(" Token0: %s (%s)\n", pool.Token0.Symbol, pool.Token0Reserve) + fmt.Printf(" Token1: %s (%s)\n", pool.Token1.Symbol, pool.Token1Reserve) + fmt.Printf(" Price: %s\n", pool.Price) + fmt.Printf(" Total LP tokens: %s\n", pool.TotalLPTokens) + + // Add liquidity + fmt.Println("\nAdding liquidity...") + addResult, err := client.Liquidity.AddLiquidity(ctx, &dex.AddLiquidityRequest{ + Pool: "SYN-USDC", + Amount0: "100", + Amount1: "150", + SlippageBps: 50, // 0.5% + }) + if err != nil { + log.Printf("Failed to add liquidity: %v", err) + } else { + fmt.Printf("Liquidity added:\n") + fmt.Printf(" LP tokens received: %s\n", addResult.LPTokens) + fmt.Printf(" Position ID: %s\n", addResult.PositionID) + fmt.Printf(" Share of pool: %s%%\n", addResult.ShareOfPool) + } + + // Get LP positions + lpPositions, err := client.Liquidity.GetPositions(ctx) + if err != nil { + log.Printf("Failed to get LP positions: %v", err) + } else { + fmt.Printf("\nLP positions: %d\n", len(lpPositions)) + for _, pos := range lpPositions { + fmt.Printf(" %s: %s LP tokens (value: $%s)\n", pos.Pool, pos.LPTokens, pos.Value) + } + } + + // Claim fees + if addResult != nil { + fmt.Println("\nClaiming fees...") + fees, err := client.Liquidity.ClaimFees(ctx, addResult.PositionID) + if err != nil { + log.Printf("Failed to claim fees: %v", err) + } else { + fmt.Printf("Fees claimed:\n") + fmt.Printf(" Token0: %s\n", fees.Amount0) + fmt.Printf(" Token1: %s\n", fees.Amount1) + } + + // Remove liquidity + fmt.Println("\nRemoving liquidity...") + removeResult, err := client.Liquidity.RemoveLiquidity(ctx, &dex.RemoveLiquidityRequest{ + PositionID: addResult.PositionID, + LPTokens: addResult.LPTokens, + SlippageBps: 50, + }) + if err != nil { + log.Printf("Failed to remove liquidity: %v", err) + } else { + fmt.Printf("Liquidity removed:\n") + fmt.Printf(" Token0 received: %s\n", removeResult.Amount0) + fmt.Printf(" Token1 received: %s\n", removeResult.Amount1) + } + } + + fmt.Println() +} + +func orderbookExample(ctx context.Context, client *dex.Client) { + fmt.Println("=== Order Book ===") + + // Get order book snapshot + orderbook, err := client.Orderbook.GetSnapshot(ctx, "SYN-USDC", 10) + if err != nil { + log.Printf("Failed to get orderbook: %v", err) + return + } + + fmt.Println("Order book for SYN-USDC:") + fmt.Println("\nAsks (sells):") + for _, ask := range orderbook.Asks[:min(5, len(orderbook.Asks))] { + fmt.Printf(" %s @ %s\n", ask.Quantity, ask.Price) + } + + fmt.Println("\nBids (buys):") + for _, bid := range orderbook.Bids[:min(5, len(orderbook.Bids))] { + fmt.Printf(" %s @ %s\n", bid.Quantity, bid.Price) + } + + fmt.Printf("\nSpread: %s (%s%%)\n", orderbook.Spread, orderbook.SpreadPercent) + fmt.Printf("Mid price: %s\n", orderbook.MidPrice) + + // Get recent trades + recentTrades, err := client.Orderbook.GetRecentTrades(ctx, "SYN-USDC", 10) + if err != nil { + log.Printf("Failed to get recent trades: %v", err) + } else { + fmt.Println("\nRecent trades:") + for _, trade := range recentTrades[:min(5, len(recentTrades))] { + fmt.Printf(" %s %s @ %s\n", trade.Side, trade.Quantity, trade.Price) + } + } + + // Subscribe to orderbook updates (simulated) + fmt.Println("\nSubscribing to orderbook updates...") + updates := client.Orderbook.Subscribe(ctx, "SYN-USDC") + + // Process a few updates (in real usage, this would be a goroutine) + go func() { + for i := 0; i < 3; i++ { + select { + case update := <-updates: + fmt.Printf(" Update: %s %s @ %s\n", update.Side, update.Quantity, update.Price) + case <-time.After(5 * time.Second): + return + } + } + }() + + time.Sleep(2 * time.Second) // Wait for some updates + + fmt.Println() +} + +func portfolioExample(ctx context.Context, client *dex.Client) { + fmt.Println("=== Portfolio ===") + + // Get portfolio overview + portfolio, err := client.Portfolio.GetOverview(ctx) + if err != nil { + log.Printf("Failed to get portfolio: %v", err) + return + } + + fmt.Println("Portfolio overview:") + fmt.Printf(" Total value: $%s\n", portfolio.TotalValue) + fmt.Printf(" Available balance: $%s\n", portfolio.AvailableBalance) + fmt.Printf(" In orders: $%s\n", portfolio.InOrders) + fmt.Printf(" In positions: $%s\n", portfolio.InPositions) + fmt.Printf(" Unrealized PnL: $%s\n", portfolio.UnrealizedPnL) + + // Get balances + balances, err := client.Portfolio.GetBalances(ctx) + if err != nil { + log.Printf("Failed to get balances: %v", err) + } else { + fmt.Println("\nBalances:") + for _, balance := range balances { + fmt.Printf(" %s: %s (available: %s, in orders: %s)\n", + balance.Asset, balance.Total, balance.Available, balance.InOrders) + } + } + + // Get PnL history + pnlHistory, err := client.Portfolio.GetPnLHistory(ctx, 30) // Last 30 days + if err != nil { + log.Printf("Failed to get PnL history: %v", err) + } else { + fmt.Printf("\nPnL history (last %d days):\n", len(pnlHistory)) + if len(pnlHistory) > 0 { + totalPnL := "0" + for _, day := range pnlHistory { + totalPnL = day.CumulativePnL + } + fmt.Printf(" Total PnL: $%s\n", totalPnL) + } + } + + // Get trade statistics + stats, err := client.Portfolio.GetStats(ctx) + if err != nil { + log.Printf("Failed to get trade stats: %v", err) + } else { + fmt.Println("\nTrade statistics:") + fmt.Printf(" Total trades: %d\n", stats.TotalTrades) + fmt.Printf(" Win rate: %s%%\n", stats.WinRate) + fmt.Printf(" Avg profit: $%s\n", stats.AvgProfit) + fmt.Printf(" Avg loss: $%s\n", stats.AvgLoss) + fmt.Printf(" Best trade: $%s\n", stats.BestTrade) + fmt.Printf(" Worst trade: $%s\n", stats.WorstTrade) + } + + fmt.Println() +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/sdk/go/examples/ibc_example.go b/sdk/go/examples/ibc_example.go new file mode 100644 index 0000000..5eff639 --- /dev/null +++ b/sdk/go/examples/ibc_example.go @@ -0,0 +1,509 @@ +// Package main demonstrates the Synor IBC SDK for Go +// +// This example covers Inter-Blockchain Communication operations: +// - Cross-chain token transfers +// - Channel management +// - Packet handling +// - Relayer operations +package main + +import ( + "context" + "fmt" + "log" + "os" + "time" + + "github.com/synor/sdk-go/ibc" +) + +func main() { + // Initialize client + config := ibc.Config{ + APIKey: getEnv("SYNOR_API_KEY", "your-api-key"), + Endpoint: "https://ibc.synor.io/v1", + Timeout: 30 * time.Second, + Retries: 3, + Debug: false, + DefaultNetwork: ibc.NetworkMainnet, + } + + client, err := ibc.NewClient(config) + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + defer client.Close() + + ctx := context.Background() + + // Check service health + healthy, err := client.HealthCheck(ctx) + if err != nil { + log.Printf("Health check failed: %v", err) + } else { + fmt.Printf("Service healthy: %v\n\n", healthy) + } + + // Run examples + chainsExample(ctx, client) + channelsExample(ctx, client) + transferExample(ctx, client) + packetExample(ctx, client) + relayerExample(ctx, client) + connectionExample(ctx, client) +} + +func chainsExample(ctx context.Context, client *ibc.Client) { + fmt.Println("=== Connected Chains ===") + + // Get all connected chains + chains, err := client.Chains.List(ctx) + if err != nil { + log.Printf("Failed to list chains: %v", err) + return + } + fmt.Printf("Connected chains: %d\n", len(chains)) + + for _, chain := range chains { + fmt.Printf(" %s:\n", chain.ChainID) + fmt.Printf(" Name: %s\n", chain.Name) + fmt.Printf(" Status: %s\n", chain.Status) + fmt.Printf(" Block height: %d\n", chain.LatestHeight) + fmt.Printf(" Channels: %d\n", chain.ChannelCount) + } + + // Get specific chain info + cosmos, err := client.Chains.Get(ctx, "cosmoshub-4") + if err != nil { + log.Printf("Failed to get Cosmos Hub: %v", err) + return + } + fmt.Println("\nCosmos Hub details:") + fmt.Printf(" RPC: %s\n", cosmos.RPCEndpoint) + fmt.Printf(" Rest: %s\n", cosmos.RestEndpoint) + fmt.Printf(" Native denom: %s\n", cosmos.NativeDenom) + fmt.Printf(" Prefix: %s\n", cosmos.Bech32Prefix) + + // Get supported assets on a chain + assets, err := client.Chains.GetAssets(ctx, "cosmoshub-4") + if err != nil { + log.Printf("Failed to get assets: %v", err) + return + } + fmt.Println("\nSupported assets on Cosmos Hub:") + for _, asset := range assets[:min(5, len(assets))] { + fmt.Printf(" %s: %s\n", asset.Symbol, asset.Denom) + fmt.Printf(" Origin: %s\n", asset.OriginChain) + fmt.Printf(" Decimals: %d\n", asset.Decimals) + } + + // Get chain paths (routes) + paths, err := client.Chains.GetPaths(ctx, "synor-1", "cosmoshub-4") + if err != nil { + log.Printf("Failed to get paths: %v", err) + return + } + fmt.Println("\nPaths from Synor to Cosmos Hub:") + for _, path := range paths { + fmt.Printf(" %s -> %s\n", path.SourceChannel, path.DestChannel) + fmt.Printf(" Hops: %d\n", path.Hops) + fmt.Printf(" Avg time: %ds\n", path.AvgTransferTime) + } + + fmt.Println() +} + +func channelsExample(ctx context.Context, client *ibc.Client) { + fmt.Println("=== Channel Management ===") + + // List all channels + channels, err := client.Channels.List(ctx) + if err != nil { + log.Printf("Failed to list channels: %v", err) + return + } + fmt.Printf("Total channels: %d\n", len(channels)) + + // Filter by state + var openChannels []ibc.Channel + for _, c := range channels { + if c.State == ibc.ChannelStateOpen { + openChannels = append(openChannels, c) + } + } + fmt.Printf("Open channels: %d\n", len(openChannels)) + + for _, channel := range openChannels[:min(3, len(openChannels))] { + fmt.Printf("\n Channel %s:\n", channel.ChannelID) + fmt.Printf(" Port: %s\n", channel.PortID) + fmt.Printf(" Counterparty: %s on %s\n", channel.CounterpartyChannelID, channel.CounterpartyChainID) + fmt.Printf(" Ordering: %s\n", channel.Ordering) + fmt.Printf(" Version: %s\n", channel.Version) + fmt.Printf(" State: %s\n", channel.State) + } + + // Get specific channel + channel, err := client.Channels.Get(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get channel: %v", err) + return + } + fmt.Println("\nChannel-0 details:") + fmt.Printf(" Connection: %s\n", channel.ConnectionID) + fmt.Printf(" Counterparty port: %s\n", channel.CounterpartyPortID) + + // Get channel statistics + stats, err := client.Channels.GetStats(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get channel stats: %v", err) + return + } + fmt.Println("\nChannel-0 statistics:") + fmt.Printf(" Total packets sent: %d\n", stats.PacketsSent) + fmt.Printf(" Total packets received: %d\n", stats.PacketsReceived) + fmt.Printf(" Pending packets: %d\n", stats.PendingPackets) + fmt.Printf(" Success rate: %.1f%%\n", stats.SuccessRate) + fmt.Printf(" Avg relay time: %ds\n", stats.AvgRelayTime) + + // Get channel capacity + capacity, err := client.Channels.GetCapacity(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get channel capacity: %v", err) + return + } + fmt.Println("\nChannel-0 capacity:") + fmt.Printf(" Max throughput: %d packets/block\n", capacity.MaxPacketsPerBlock) + fmt.Printf(" Current utilization: %.1f%%\n", capacity.Utilization) + + fmt.Println() +} + +func transferExample(ctx context.Context, client *ibc.Client) { + fmt.Println("=== Cross-Chain Transfers ===") + + // Estimate transfer fee + estimate, err := client.Transfers.EstimateFee(ctx, &ibc.FeeEstimateRequest{ + SourceChain: "synor-1", + DestChain: "cosmoshub-4", + Denom: "usyn", + Amount: "1000000", // 1 SYN (6 decimals) + }) + if err != nil { + log.Printf("Failed to estimate fee: %v", err) + return + } + fmt.Println("Transfer fee estimate:") + fmt.Printf(" Gas: %d\n", estimate.Gas) + fmt.Printf(" Fee: %s %s\n", estimate.Fee, estimate.FeeDenom) + fmt.Printf(" Timeout: %ds\n", estimate.Timeout) + + // Initiate a transfer + fmt.Println("\nInitiating transfer...") + transfer, err := client.Transfers.Send(ctx, &ibc.TransferRequest{ + SourceChain: "synor-1", + DestChain: "cosmoshub-4", + Channel: "channel-0", + Sender: "synor1abc...", // Your address + Receiver: "cosmos1xyz...", // Recipient address + Denom: "usyn", + Amount: "1000000", // 1 SYN + Memo: "Cross-chain transfer example", + TimeoutHeight: 0, // Use timestamp instead + TimeoutTimestamp: time.Now().Add(10 * time.Minute).UnixMilli(), + }) + if err != nil { + log.Printf("Failed to initiate transfer: %v", err) + return + } + + fmt.Println("Transfer initiated:") + fmt.Printf(" TX Hash: %s\n", transfer.TxHash) + fmt.Printf(" Sequence: %d\n", transfer.Sequence) + fmt.Printf(" Status: %s\n", transfer.Status) + + // Track transfer status + fmt.Println("\nTracking transfer...") + status, err := client.Transfers.GetStatus(ctx, transfer.TxHash) + if err != nil { + log.Printf("Failed to get transfer status: %v", err) + return + } + fmt.Printf("Current status: %s\n", status.State) + fmt.Printf(" Source confirmed: %v\n", status.SourceConfirmed) + fmt.Printf(" Relayed: %v\n", status.Relayed) + fmt.Printf(" Dest confirmed: %v\n", status.DestConfirmed) + + // Get transfer history + history, err := client.Transfers.GetHistory(ctx, "synor1abc...", 5) + if err != nil { + log.Printf("Failed to get transfer history: %v", err) + return + } + fmt.Println("\nTransfer history (last 5):") + for _, tx := range history { + direction := "OUT" + if tx.Sender != "synor1abc..." { + direction = "IN" + } + fmt.Printf(" %s %s %s (%s)\n", direction, tx.Amount, tx.Denom, tx.Status) + } + + // Get pending transfers + pending, err := client.Transfers.GetPending(ctx, "synor1abc...") + if err != nil { + log.Printf("Failed to get pending transfers: %v", err) + return + } + fmt.Printf("\nPending transfers: %d\n", len(pending)) + + fmt.Println() +} + +func packetExample(ctx context.Context, client *ibc.Client) { + fmt.Println("=== Packet Handling ===") + + // Get pending packets + packets, err := client.Packets.GetPending(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get pending packets: %v", err) + return + } + fmt.Printf("Pending packets on channel-0: %d\n", len(packets)) + + for _, packet := range packets[:min(3, len(packets))] { + fmt.Printf("\n Packet %d:\n", packet.Sequence) + fmt.Printf(" Source: %s/%s\n", packet.SourcePort, packet.SourceChannel) + fmt.Printf(" Dest: %s/%s\n", packet.DestPort, packet.DestChannel) + fmt.Printf(" State: %s\n", packet.State) + fmt.Printf(" Data size: %d bytes\n", len(packet.Data)) + fmt.Printf(" Timeout height: %d\n", packet.TimeoutHeight) + fmt.Printf(" Timeout timestamp: %d\n", packet.TimeoutTimestamp) + } + + // Get packet by sequence + packet, err := client.Packets.Get(ctx, "channel-0", 1) + if err != nil { + log.Printf("Failed to get packet: %v", err) + return + } + fmt.Println("\nPacket details:") + fmt.Printf(" Commitment: %s\n", packet.Commitment) + fmt.Printf(" Receipt: %s\n", packet.Receipt) + fmt.Printf(" Acknowledgement: %s\n", packet.Acknowledgement) + + // Get packet receipts + receipts, err := client.Packets.GetReceipts(ctx, "channel-0", []uint64{1, 2, 3}) + if err != nil { + log.Printf("Failed to get receipts: %v", err) + return + } + fmt.Println("\nPacket receipts:") + for seq, receipt := range receipts { + status := "not received" + if receipt { + status = "received" + } + fmt.Printf(" Sequence %d: %s\n", seq, status) + } + + // Get timed out packets + timedOut, err := client.Packets.GetTimedOut(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get timed out packets: %v", err) + return + } + fmt.Printf("\nTimed out packets: %d\n", len(timedOut)) + for _, p := range timedOut { + fmt.Printf(" Sequence %d: timeout at %d\n", p.Sequence, p.TimeoutTimestamp) + } + + // Get unreceived packets + unreceived, err := client.Packets.GetUnreceived(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get unreceived packets: %v", err) + return + } + unreceivedStr := "none" + if len(unreceived) > 0 { + unreceivedStr = fmt.Sprintf("%v", unreceived) + } + fmt.Printf("\nUnreceived packet sequences: %s\n", unreceivedStr) + + // Get unacknowledged packets + unacked, err := client.Packets.GetUnacknowledged(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get unacknowledged packets: %v", err) + return + } + unackedStr := "none" + if len(unacked) > 0 { + unackedStr = fmt.Sprintf("%v", unacked) + } + fmt.Printf("Unacknowledged packet sequences: %s\n", unackedStr) + + fmt.Println() +} + +func relayerExample(ctx context.Context, client *ibc.Client) { + fmt.Println("=== Relayer Operations ===") + + // Get active relayers + relayers, err := client.Relayers.List(ctx) + if err != nil { + log.Printf("Failed to list relayers: %v", err) + return + } + fmt.Printf("Active relayers: %d\n", len(relayers)) + + for _, relayer := range relayers[:min(3, len(relayers))] { + fmt.Printf("\n %s:\n", relayer.Address) + fmt.Printf(" Chains: %v\n", relayer.Chains) + fmt.Printf(" Packets relayed: %d\n", relayer.PacketsRelayed) + fmt.Printf(" Success rate: %.1f%%\n", relayer.SuccessRate) + fmt.Printf(" Avg latency: %dms\n", relayer.AvgLatency) + fmt.Printf(" Fee rate: %.2f%%\n", relayer.FeeRate) + } + + // Get relayer statistics + stats, err := client.Relayers.GetStats(ctx) + if err != nil { + log.Printf("Failed to get relayer stats: %v", err) + return + } + fmt.Println("\nGlobal relayer statistics:") + fmt.Printf(" Total relayers: %d\n", stats.TotalRelayers) + fmt.Printf(" Active relayers: %d\n", stats.ActiveRelayers) + fmt.Printf(" Packets relayed (24h): %d\n", stats.PacketsRelayed24h) + fmt.Printf(" Total fees earned: %s\n", stats.TotalFeesEarned) + + // Register as a relayer + fmt.Println("\nRegistering as relayer...") + registration, err := client.Relayers.Register(ctx, &ibc.RelayerRegistration{ + Chains: []string{"synor-1", "cosmoshub-4"}, + FeeRate: 0.1, // 0.1% fee + MinPacketSize: 0, + MaxPacketSize: 1000000, + }) + if err != nil { + log.Printf("Failed to register as relayer: %v", err) + return + } + fmt.Printf("Registered with address: %s\n", registration.RelayerAddress) + + // Start relaying (in background) + fmt.Println("\nStarting relay service...") + relaySession, err := client.Relayers.StartRelay(ctx, &ibc.RelayConfig{ + Channels: []string{"channel-0"}, + AutoAck: true, + BatchSize: 10, + PollInterval: 5000, + }) + if err != nil { + log.Printf("Failed to start relay: %v", err) + return + } + fmt.Printf("Relay session started: %s\n", relaySession.SessionID) + + // Get relay queue + queue, err := client.Relayers.GetQueue(ctx, "channel-0") + if err != nil { + log.Printf("Failed to get relay queue: %v", err) + return + } + fmt.Printf("\nRelay queue for channel-0: %d packets\n", len(queue)) + + // Manually relay a packet + if len(queue) > 0 { + fmt.Println("\nRelaying packet...") + relayResult, err := client.Relayers.RelayPacket(ctx, queue[0].Sequence, "channel-0") + if err != nil { + log.Printf("Failed to relay packet: %v", err) + } else { + fmt.Printf("Relay result: %s\n", relayResult.Status) + fmt.Printf(" TX Hash: %s\n", relayResult.TxHash) + fmt.Printf(" Fee earned: %s\n", relayResult.FeeEarned) + } + } + + // Stop relay session + err = client.Relayers.StopRelay(ctx, relaySession.SessionID) + if err != nil { + log.Printf("Failed to stop relay: %v", err) + } else { + fmt.Println("\nRelay session stopped") + } + + fmt.Println() +} + +func connectionExample(ctx context.Context, client *ibc.Client) { + fmt.Println("=== Connection Information ===") + + // List connections + connections, err := client.Connections.List(ctx) + if err != nil { + log.Printf("Failed to list connections: %v", err) + return + } + fmt.Printf("Total connections: %d\n", len(connections)) + + for _, conn := range connections[:min(3, len(connections))] { + fmt.Printf("\n %s:\n", conn.ConnectionID) + fmt.Printf(" Client: %s\n", conn.ClientID) + fmt.Printf(" Counterparty: %s\n", conn.CounterpartyConnectionID) + fmt.Printf(" State: %s\n", conn.State) + fmt.Printf(" Versions: %v\n", conn.Versions) + } + + // Get connection details + connection, err := client.Connections.Get(ctx, "connection-0") + if err != nil { + log.Printf("Failed to get connection: %v", err) + return + } + fmt.Println("\nConnection-0 details:") + fmt.Printf(" Delay period: %dns\n", connection.DelayPeriod) + fmt.Printf(" Counterparty client: %s\n", connection.CounterpartyClientID) + fmt.Printf(" Counterparty prefix: %s\n", connection.CounterpartyPrefix) + + // Get client state + clientState, err := client.Clients.Get(ctx, connection.ClientID) + if err != nil { + log.Printf("Failed to get client state: %v", err) + return + } + fmt.Println("\nClient state:") + fmt.Printf(" Chain ID: %s\n", clientState.ChainID) + fmt.Printf(" Trust level: %s\n", clientState.TrustLevel) + fmt.Printf(" Trusting period: %s\n", clientState.TrustingPeriod) + fmt.Printf(" Unbonding period: %s\n", clientState.UnbondingPeriod) + fmt.Printf(" Latest height: %d\n", clientState.LatestHeight) + fmt.Printf(" Frozen: %v\n", clientState.Frozen) + + // Get consensus state + consensus, err := client.Clients.GetConsensusState(ctx, connection.ClientID, clientState.LatestHeight) + if err != nil { + log.Printf("Failed to get consensus state: %v", err) + return + } + fmt.Printf("\nConsensus state at height %d:\n", clientState.LatestHeight) + fmt.Printf(" Timestamp: %s\n", consensus.Timestamp) + fmt.Printf(" Root: %s...\n", consensus.Root[:min(20, len(consensus.Root))]) + fmt.Printf(" Next validators hash: %s...\n", consensus.NextValidatorsHash[:min(20, len(consensus.NextValidatorsHash))]) + + fmt.Println() +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/sdk/go/examples/zk_example.go b/sdk/go/examples/zk_example.go new file mode 100644 index 0000000..b06ec78 --- /dev/null +++ b/sdk/go/examples/zk_example.go @@ -0,0 +1,662 @@ +// Package main demonstrates the Synor ZK SDK for Go +// +// This example covers Zero-Knowledge proof operations: +// - Circuit compilation +// - Proof generation and verification +// - Groth16, PLONK, and STARK proving systems +// - Recursive proofs +// - On-chain verification +package main + +import ( + "context" + "fmt" + "log" + "os" + "time" + + "github.com/synor/sdk-go/zk" +) + +func main() { + // Initialize client + config := zk.Config{ + APIKey: getEnv("SYNOR_API_KEY", "your-api-key"), + Endpoint: "https://zk.synor.io/v1", + Timeout: 120 * time.Second, // ZK ops can be slow + Retries: 3, + Debug: false, + DefaultProvingSystem: zk.ProvingSystemGroth16, + } + + client, err := zk.NewClient(config) + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + defer client.Close() + + ctx := context.Background() + + // Check service health + healthy, err := client.HealthCheck(ctx) + if err != nil { + log.Printf("Health check failed: %v", err) + } else { + fmt.Printf("Service healthy: %v\n\n", healthy) + } + + // Run examples + circuitExample(ctx, client) + proofExample(ctx, client) + provingSystemsExample(ctx, client) + recursiveProofExample(ctx, client) + onChainVerificationExample(ctx, client) + setupExample(ctx, client) +} + +func circuitExample(ctx context.Context, client *zk.Client) { + fmt.Println("=== Circuit Compilation ===") + + // Circom circuit example: prove knowledge of preimage + circomCircuit := ` + pragma circom 2.1.0; + + template HashPreimage() { + signal input preimage; + signal input hash; + + // Simplified hash computation (in reality, use proper hash) + signal preimageSquared; + preimageSquared <== preimage * preimage; + + // Constrain that hash matches + hash === preimageSquared; + } + + component main {public [hash]} = HashPreimage(); + ` + + // Compile circuit + fmt.Println("Compiling Circom circuit...") + compiled, err := client.Circuits.Compile(ctx, &zk.CompileRequest{ + Code: circomCircuit, + Format: zk.CircuitFormatCircom, + Name: "hash_preimage", + ProvingSystem: zk.ProvingSystemGroth16, + }) + if err != nil { + log.Printf("Failed to compile circuit: %v", err) + return + } + + fmt.Println("Circuit compiled:") + fmt.Printf(" Circuit ID: %s\n", compiled.CircuitID) + fmt.Printf(" Constraints: %d\n", compiled.ConstraintCount) + fmt.Printf(" Public inputs: %d\n", compiled.PublicInputCount) + fmt.Printf(" Private inputs: %d\n", compiled.PrivateInputCount) + fmt.Printf(" Proving key size: %d bytes\n", compiled.ProvingKeySize) + fmt.Printf(" Verification key size: %d bytes\n", compiled.VerificationKeySize) + + // List circuits + circuits, err := client.Circuits.List(ctx) + if err != nil { + log.Printf("Failed to list circuits: %v", err) + return + } + fmt.Printf("\nYour circuits: %d\n", len(circuits)) + for _, circuit := range circuits { + fmt.Printf(" %s (%s)\n", circuit.Name, circuit.CircuitID) + } + + // Get circuit details + details, err := client.Circuits.Get(ctx, compiled.CircuitID) + if err != nil { + log.Printf("Failed to get circuit details: %v", err) + return + } + fmt.Println("\nCircuit details:") + fmt.Printf(" Format: %s\n", details.Format) + fmt.Printf(" Proving system: %s\n", details.ProvingSystem) + fmt.Printf(" Created: %s\n", details.CreatedAt) + + // Download proving key + provingKey, err := client.Circuits.GetProvingKey(ctx, compiled.CircuitID) + if err != nil { + log.Printf("Failed to get proving key: %v", err) + return + } + fmt.Printf("\nProving key downloaded: %d bytes\n", len(provingKey)) + + // Download verification key + verificationKey, err := client.Circuits.GetVerificationKey(ctx, compiled.CircuitID) + if err != nil { + log.Printf("Failed to get verification key: %v", err) + return + } + fmt.Printf("Verification key downloaded: %d bytes\n", len(verificationKey)) + + fmt.Println() +} + +func proofExample(ctx context.Context, client *zk.Client) { + fmt.Println("=== Proof Generation ===") + + // First, compile a simple circuit + circuit := ` + pragma circom 2.1.0; + + template Multiplier() { + signal input a; + signal input b; + signal output c; + + c <== a * b; + } + + component main {public [c]} = Multiplier(); + ` + + compiled, err := client.Circuits.Compile(ctx, &zk.CompileRequest{ + Code: circuit, + Format: zk.CircuitFormatCircom, + Name: "multiplier", + ProvingSystem: zk.ProvingSystemGroth16, + }) + if err != nil { + log.Printf("Failed to compile circuit: %v", err) + return + } + + // Generate proof + fmt.Println("Generating proof...") + startTime := time.Now() + + proof, err := client.Proofs.Generate(ctx, &zk.GenerateProofRequest{ + CircuitID: compiled.CircuitID, + Inputs: map[string]string{"a": "3", "b": "7"}, + }) + if err != nil { + log.Printf("Failed to generate proof: %v", err) + return + } + + proofTime := time.Since(startTime) + fmt.Printf("Proof generated in %v\n", proofTime) + fmt.Printf(" Proof ID: %s\n", proof.ProofID) + fmt.Printf(" Proof size: %d bytes\n", len(proof.Proof)) + fmt.Printf(" Public signals: %v\n", proof.PublicSignals) + + // Verify proof + fmt.Println("\nVerifying proof...") + verifyStart := time.Now() + + isValid, err := client.Proofs.Verify(ctx, &zk.VerifyRequest{ + CircuitID: compiled.CircuitID, + Proof: proof.Proof, + PublicSignals: proof.PublicSignals, + }) + if err != nil { + log.Printf("Failed to verify proof: %v", err) + return + } + + verifyTime := time.Since(verifyStart) + fmt.Printf("Verification completed in %v\n", verifyTime) + fmt.Printf(" Valid: %v\n", isValid) + + // Verify with wrong public signals (should fail) + fmt.Println("\nVerifying with wrong signals...") + invalidResult, err := client.Proofs.Verify(ctx, &zk.VerifyRequest{ + CircuitID: compiled.CircuitID, + Proof: proof.Proof, + PublicSignals: []string{"42"}, // Wrong answer + }) + if err != nil { + log.Printf("Failed to verify with wrong signals: %v", err) + return + } + fmt.Printf(" Valid: %v (expected false)\n", invalidResult) + + // Get proof status + status, err := client.Proofs.GetStatus(ctx, proof.ProofID) + if err != nil { + log.Printf("Failed to get proof status: %v", err) + return + } + fmt.Println("\nProof status:") + fmt.Printf(" State: %s\n", status.State) + fmt.Printf(" Verified: %v\n", status.Verified) + fmt.Printf(" Created: %s\n", status.CreatedAt) + + // List proofs + proofs, err := client.Proofs.List(ctx, compiled.CircuitID) + if err != nil { + log.Printf("Failed to list proofs: %v", err) + return + } + fmt.Printf("\nProofs for circuit: %d\n", len(proofs)) + + fmt.Println() +} + +func provingSystemsExample(ctx context.Context, client *zk.Client) { + fmt.Println("=== Proving Systems Comparison ===") + + // Simple circuit for comparison + circuit := ` + pragma circom 2.1.0; + + template Comparison() { + signal input x; + signal input y; + signal output sum; + + sum <== x + y; + } + + component main {public [sum]} = Comparison(); + ` + + systems := []struct { + system zk.ProvingSystem + name string + }{ + {zk.ProvingSystemGroth16, "GROTH16"}, + {zk.ProvingSystemPLONK, "PLONK"}, + {zk.ProvingSystemSTARK, "STARK"}, + } + + fmt.Println("Comparing proving systems:\n") + + for _, s := range systems { + fmt.Printf("%s:\n", s.name) + + // Compile for this system + compiled, err := client.Circuits.Compile(ctx, &zk.CompileRequest{ + Code: circuit, + Format: zk.CircuitFormatCircom, + Name: fmt.Sprintf("comparison_%s", s.name), + ProvingSystem: s.system, + }) + if err != nil { + log.Printf("Failed to compile for %s: %v", s.name, err) + continue + } + + // Generate proof + proofStart := time.Now() + proof, err := client.Proofs.Generate(ctx, &zk.GenerateProofRequest{ + CircuitID: compiled.CircuitID, + Inputs: map[string]string{"x": "10", "y": "20"}, + }) + if err != nil { + log.Printf("Failed to generate proof for %s: %v", s.name, err) + continue + } + proofTime := time.Since(proofStart) + + // Verify proof + verifyStart := time.Now() + _, err = client.Proofs.Verify(ctx, &zk.VerifyRequest{ + CircuitID: compiled.CircuitID, + Proof: proof.Proof, + PublicSignals: proof.PublicSignals, + }) + if err != nil { + log.Printf("Failed to verify proof for %s: %v", s.name, err) + continue + } + verifyTime := time.Since(verifyStart) + + fmt.Printf(" Setup: %dms\n", compiled.SetupTime) + fmt.Printf(" Proof time: %v\n", proofTime) + fmt.Printf(" Verify time: %v\n", verifyTime) + fmt.Printf(" Proof size: %d bytes\n", len(proof.Proof)) + fmt.Printf(" Verification key: %d bytes\n", compiled.VerificationKeySize) + fmt.Println() + } + + fmt.Println("Summary:") + fmt.Println(" Groth16: Smallest proofs, fast verification, trusted setup required") + fmt.Println(" PLONK: Universal setup, flexible, moderate proof size") + fmt.Println(" STARK: No trusted setup, largest proofs, quantum resistant") + + fmt.Println() +} + +func recursiveProofExample(ctx context.Context, client *zk.Client) { + fmt.Println("=== Recursive Proofs ===") + + // Inner circuit + innerCircuit := ` + pragma circom 2.1.0; + + template Inner() { + signal input x; + signal output y; + y <== x * x; + } + + component main {public [y]} = Inner(); + ` + + // Compile inner circuit + inner, err := client.Circuits.Compile(ctx, &zk.CompileRequest{ + Code: innerCircuit, + Format: zk.CircuitFormatCircom, + Name: "inner_circuit", + ProvingSystem: zk.ProvingSystemGroth16, + }) + if err != nil { + log.Printf("Failed to compile inner circuit: %v", err) + return + } + + // Generate multiple proofs to aggregate + fmt.Println("Generating proofs to aggregate...") + var proofsToAggregate []zk.ProofData + for i := 1; i <= 4; i++ { + proof, err := client.Proofs.Generate(ctx, &zk.GenerateProofRequest{ + CircuitID: inner.CircuitID, + Inputs: map[string]string{"x": fmt.Sprintf("%d", i)}, + }) + if err != nil { + log.Printf("Failed to generate proof %d: %v", i, err) + continue + } + proofsToAggregate = append(proofsToAggregate, zk.ProofData{ + Proof: proof.Proof, + PublicSignals: proof.PublicSignals, + }) + fmt.Printf(" Proof %d: y = %s\n", i, proof.PublicSignals[0]) + } + + // Aggregate proofs recursively + fmt.Println("\nAggregating proofs...") + aggregated, err := client.Proofs.Aggregate(ctx, &zk.AggregateRequest{ + CircuitID: inner.CircuitID, + Proofs: proofsToAggregate, + AggregationType: "recursive", + }) + if err != nil { + log.Printf("Failed to aggregate proofs: %v", err) + return + } + + originalSize := 0 + for _, p := range proofsToAggregate { + originalSize += len(p.Proof) + } + + fmt.Println("Aggregated proof:") + fmt.Printf(" Proof ID: %s\n", aggregated.ProofID) + fmt.Printf(" Aggregated count: %d\n", aggregated.AggregatedCount) + fmt.Printf(" Proof size: %d bytes\n", len(aggregated.Proof)) + fmt.Printf(" Size reduction: %.1f%%\n", (1-float64(len(aggregated.Proof))/float64(originalSize))*100) + + // Verify aggregated proof + publicSignalsList := make([][]string, len(proofsToAggregate)) + for i, p := range proofsToAggregate { + publicSignalsList[i] = p.PublicSignals + } + + isValid, err := client.Proofs.VerifyAggregated(ctx, &zk.VerifyAggregatedRequest{ + CircuitID: inner.CircuitID, + Proof: aggregated.Proof, + PublicSignalsList: publicSignalsList, + }) + if err != nil { + log.Printf("Failed to verify aggregated proof: %v", err) + return + } + fmt.Printf("\nAggregated proof valid: %v\n", isValid) + + // Batch verification (verify multiple proofs in one operation) + fmt.Println("\nBatch verification...") + batchResult, err := client.Proofs.BatchVerify(ctx, &zk.BatchVerifyRequest{ + CircuitID: inner.CircuitID, + Proofs: proofsToAggregate, + }) + if err != nil { + log.Printf("Failed to batch verify: %v", err) + return + } + fmt.Printf(" All valid: %v\n", batchResult.AllValid) + fmt.Printf(" Results: %v\n", batchResult.Results) + + fmt.Println() +} + +func onChainVerificationExample(ctx context.Context, client *zk.Client) { + fmt.Println("=== On-Chain Verification ===") + + // Compile circuit + circuit := ` + pragma circom 2.1.0; + + template VoteCommitment() { + signal input vote; // Private: actual vote + signal input nullifier; // Private: unique identifier + signal input commitment; // Public: commitment to verify + + // Simplified commitment (in practice, use Poseidon hash) + signal computed; + computed <== vote * nullifier; + commitment === computed; + } + + component main {public [commitment]} = VoteCommitment(); + ` + + compiled, err := client.Circuits.Compile(ctx, &zk.CompileRequest{ + Code: circuit, + Format: zk.CircuitFormatCircom, + Name: "vote_commitment", + ProvingSystem: zk.ProvingSystemGroth16, + }) + if err != nil { + log.Printf("Failed to compile circuit: %v", err) + return + } + + // Generate Solidity verifier + fmt.Println("Generating Solidity verifier...") + solidityVerifier, err := client.Contracts.GenerateVerifier(ctx, &zk.GenerateVerifierRequest{ + CircuitID: compiled.CircuitID, + Language: "solidity", + Optimized: true, + }) + if err != nil { + log.Printf("Failed to generate verifier: %v", err) + return + } + fmt.Printf("Solidity verifier generated: %d bytes\n", len(solidityVerifier.Code)) + fmt.Printf(" Contract name: %s\n", solidityVerifier.ContractName) + fmt.Printf(" Gas estimate: %d\n", solidityVerifier.GasEstimate) + + // Generate proof + proof, err := client.Proofs.Generate(ctx, &zk.GenerateProofRequest{ + CircuitID: compiled.CircuitID, + Inputs: map[string]string{ + "vote": "1", // Vote YES (1) or NO (0) + "nullifier": "12345", + "commitment": "12345", // 1 * 12345 + }, + }) + if err != nil { + log.Printf("Failed to generate proof: %v", err) + return + } + + // Format proof for on-chain verification + fmt.Println("\nFormatting proof for on-chain...") + onChainProof, err := client.Contracts.FormatProof(ctx, &zk.FormatProofRequest{ + CircuitID: compiled.CircuitID, + Proof: proof.Proof, + PublicSignals: proof.PublicSignals, + Format: "calldata", + }) + if err != nil { + log.Printf("Failed to format proof: %v", err) + return + } + calldataPreview := onChainProof.Calldata + if len(calldataPreview) > 100 { + calldataPreview = calldataPreview[:100] + } + fmt.Printf(" Calldata: %s...\n", calldataPreview) + fmt.Printf(" Estimated gas: %d\n", onChainProof.GasEstimate) + + // Deploy verifier contract (simulation) + fmt.Println("\nDeploying verifier contract...") + deployment, err := client.Contracts.DeployVerifier(ctx, &zk.DeployRequest{ + CircuitID: compiled.CircuitID, + Network: "synor-testnet", + }) + if err != nil { + log.Printf("Failed to deploy verifier: %v", err) + return + } + fmt.Printf(" Contract address: %s\n", deployment.Address) + fmt.Printf(" TX hash: %s\n", deployment.TxHash) + fmt.Printf(" Gas used: %d\n", deployment.GasUsed) + + // Verify on-chain + fmt.Println("\nVerifying on-chain...") + onChainResult, err := client.Contracts.VerifyOnChain(ctx, &zk.OnChainVerifyRequest{ + ContractAddress: deployment.Address, + Proof: proof.Proof, + PublicSignals: proof.PublicSignals, + Network: "synor-testnet", + }) + if err != nil { + log.Printf("Failed to verify on-chain: %v", err) + return + } + fmt.Printf(" TX hash: %s\n", onChainResult.TxHash) + fmt.Printf(" Verified: %v\n", onChainResult.Verified) + fmt.Printf(" Gas used: %d\n", onChainResult.GasUsed) + + // Generate verifier for other targets + fmt.Println("\nGenerating verifiers for other targets:") + targets := []string{"cairo", "noir", "ink"} + for _, target := range targets { + verifier, err := client.Contracts.GenerateVerifier(ctx, &zk.GenerateVerifierRequest{ + CircuitID: compiled.CircuitID, + Language: target, + }) + if err != nil { + log.Printf("Failed to generate %s verifier: %v", target, err) + continue + } + fmt.Printf(" %s: %d bytes\n", target, len(verifier.Code)) + } + + fmt.Println() +} + +func setupExample(ctx context.Context, client *zk.Client) { + fmt.Println("=== Trusted Setup ===") + + // Get available ceremonies + ceremonies, err := client.Setup.ListCeremonies(ctx) + if err != nil { + log.Printf("Failed to list ceremonies: %v", err) + return + } + fmt.Printf("Active ceremonies: %d\n", len(ceremonies)) + for _, ceremony := range ceremonies { + fmt.Printf(" %s:\n", ceremony.Name) + fmt.Printf(" Status: %s\n", ceremony.Status) + fmt.Printf(" Participants: %d\n", ceremony.ParticipantCount) + fmt.Printf(" Current round: %d\n", ceremony.CurrentRound) + } + + // Create a new circuit setup + circuit := ` + pragma circom 2.1.0; + + template NewCircuit() { + signal input a; + signal output b; + b <== a + 1; + } + + component main {public [b]} = NewCircuit(); + ` + + fmt.Println("\nInitializing setup for new circuit...") + setup, err := client.Setup.Initialize(ctx, &zk.SetupInitRequest{ + Circuit: circuit, + Format: zk.CircuitFormatCircom, + Name: "new_circuit_setup", + ProvingSystem: zk.ProvingSystemGroth16, + CeremonyType: "powers_of_tau", // or 'phase2' + }) + if err != nil { + log.Printf("Failed to initialize setup: %v", err) + return + } + fmt.Println("Setup initialized:") + fmt.Printf(" Ceremony ID: %s\n", setup.CeremonyID) + fmt.Printf(" Powers of Tau required: %d\n", setup.PowersRequired) + fmt.Printf(" Current phase: %s\n", setup.Phase) + + // Contribute to ceremony (in practice, generates random entropy) + fmt.Println("\nContributing to ceremony...") + contribution, err := client.Setup.Contribute(ctx, &zk.ContributeRequest{ + CeremonyID: setup.CeremonyID, + Entropy: fmt.Sprintf("%x", []byte("random-entropy-from-user")), + }) + if err != nil { + log.Printf("Failed to contribute: %v", err) + return + } + fmt.Println("Contribution submitted:") + fmt.Printf(" Participant: %s\n", contribution.ParticipantID) + fmt.Printf(" Contribution hash: %s\n", contribution.Hash) + fmt.Printf(" Verification status: %v\n", contribution.Verified) + + // Get ceremony status + status, err := client.Setup.GetStatus(ctx, setup.CeremonyID) + if err != nil { + log.Printf("Failed to get ceremony status: %v", err) + return + } + fmt.Println("\nCeremony status:") + fmt.Printf(" Phase: %s\n", status.Phase) + fmt.Printf(" Total contributions: %d\n", status.TotalContributions) + fmt.Printf(" Verified contributions: %d\n", status.VerifiedContributions) + fmt.Printf(" Ready for finalization: %v\n", status.ReadyForFinalization) + + // Finalize setup (when enough contributions) + if status.ReadyForFinalization { + fmt.Println("\nFinalizing setup...") + finalized, err := client.Setup.Finalize(ctx, setup.CeremonyID) + if err != nil { + log.Printf("Failed to finalize setup: %v", err) + return + } + fmt.Println("Setup finalized:") + fmt.Printf(" Proving key hash: %s\n", finalized.ProvingKeyHash) + fmt.Printf(" Verification key hash: %s\n", finalized.VerificationKeyHash) + fmt.Printf(" Contribution transcript: %s\n", finalized.TranscriptCID) + } + + // Download ceremony transcript + transcript, err := client.Setup.GetTranscript(ctx, setup.CeremonyID) + if err != nil { + log.Printf("Failed to get transcript: %v", err) + return + } + fmt.Printf("\nCeremony transcript: %d bytes\n", len(transcript)) + + fmt.Println() +} + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +} diff --git a/sdk/java/examples/CryptoExample.java b/sdk/java/examples/CryptoExample.java new file mode 100644 index 0000000..81825ca --- /dev/null +++ b/sdk/java/examples/CryptoExample.java @@ -0,0 +1,249 @@ +package io.synor.examples; + +import io.synor.crypto.*; +import io.synor.crypto.types.*; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * Synor Crypto SDK Examples for Java + * + * Demonstrates quantum-resistant cryptographic operations: + * - Hybrid Ed25519 + Dilithium3 signatures + * - BIP-39 mnemonic generation and validation + * - Post-quantum algorithms (Falcon, SPHINCS+) + * - Key derivation functions + */ +public class CryptoExample { + + public static void main(String[] args) throws Exception { + // Initialize client + CryptoConfig config = CryptoConfig.builder() + .apiKey(System.getenv("SYNOR_API_KEY") != null ? + System.getenv("SYNOR_API_KEY") : "your-api-key") + .endpoint("https://crypto.synor.io/v1") + .timeout(30000) + .retries(3) + .debug(false) + .defaultNetwork(Network.MAINNET) + .build(); + + SynorCrypto crypto = new SynorCrypto(config); + + try { + // Check service health + boolean healthy = crypto.healthCheck().get(); + System.out.println("Service healthy: " + healthy + "\n"); + + // Run examples + mnemonicExample(crypto); + keypairExample(crypto); + signingExample(crypto); + falconExample(crypto); + sphincsExample(crypto); + kdfExample(crypto); + hashExample(crypto); + } finally { + crypto.close(); + } + } + + static void mnemonicExample(SynorCrypto crypto) throws Exception { + System.out.println("=== Mnemonic Operations ==="); + + // Generate a 24-word mnemonic (256-bit entropy) + Mnemonic mnemonic = crypto.mnemonic().generate(24).get(); + System.out.println("Generated mnemonic: " + mnemonic.getPhrase()); + System.out.println("Word count: " + mnemonic.getWordCount()); + + // Validate a mnemonic + ValidationResult validation = crypto.mnemonic().validate(mnemonic.getPhrase()).get(); + System.out.println("Valid: " + validation.isValid()); + if (!validation.isValid()) { + System.out.println("Error: " + validation.getError()); + } + + // Convert mnemonic to seed + byte[] seed = crypto.mnemonic().toSeed(mnemonic.getPhrase(), "optional-passphrase").get(); + System.out.println("Seed (hex): " + bytesToHex(seed).substring(0, 32) + "..."); + + // Word suggestions for autocomplete + List suggestions = crypto.mnemonic().suggestWords("aban", 5).get(); + System.out.println("Suggestions for 'aban': " + String.join(", ", suggestions)); + + System.out.println(); + } + + static void keypairExample(SynorCrypto crypto) throws Exception { + System.out.println("=== Keypair Operations ==="); + + // Generate a random keypair + HybridKeypair keypair = crypto.keypairs().generate().get(); + System.out.println("Generated hybrid keypair:"); + System.out.println(" Ed25519 public key size: " + keypair.getPublicKey().getEd25519Bytes().length + " bytes"); + System.out.println(" Dilithium public key size: " + keypair.getPublicKey().getDilithiumBytes().length + " bytes"); + System.out.println(" Total public key size: " + keypair.getPublicKey().getSize() + " bytes"); + + // Get addresses for different networks + System.out.println("\nAddresses:"); + System.out.println(" Mainnet: " + keypair.getAddress(Network.MAINNET)); + System.out.println(" Testnet: " + keypair.getAddress(Network.TESTNET)); + System.out.println(" Devnet: " + keypair.getAddress(Network.DEVNET)); + + // Create keypair from mnemonic (deterministic) + Mnemonic mnemonic = crypto.mnemonic().generate(24).get(); + HybridKeypair keypair2 = crypto.keypairs().fromMnemonic(mnemonic.getPhrase(), "").get(); + String addr = keypair2.getAddress(Network.MAINNET); + System.out.println("\nKeypair from mnemonic: " + addr.substring(0, 20) + "..."); + + // Derive child keypair using BIP-44 path + DerivationPath path = DerivationPath.external(0, 0); // m/44'/21337'/0'/0/0 + System.out.println("Derivation path: " + path); + + System.out.println(); + } + + static void signingExample(SynorCrypto crypto) throws Exception { + System.out.println("=== Hybrid Signing ==="); + + // Generate keypair + HybridKeypair keypair = crypto.keypairs().generate().get(); + + // Sign a message + byte[] message = "Hello, quantum-resistant world!".getBytes(); + HybridSignature signature = crypto.signing().sign(keypair, message).get(); + + System.out.println("Signature created:"); + System.out.println(" Ed25519 component: " + signature.getEd25519Bytes().length + " bytes"); + System.out.println(" Dilithium component: " + signature.getDilithiumBytes().length + " bytes"); + System.out.println(" Total signature size: " + signature.getSize() + " bytes"); + + // Verify the signature + boolean valid = crypto.signing().verify(keypair.getPublicKey(), message, signature).get(); + System.out.println("\nVerification result: " + valid); + + // Verify with tampered message fails + byte[] tamperedMessage = "Hello, tampered message!".getBytes(); + boolean invalidResult = crypto.signing().verify(keypair.getPublicKey(), tamperedMessage, signature).get(); + System.out.println("Tampered message verification: " + invalidResult); + + System.out.println(); + } + + static void falconExample(SynorCrypto crypto) throws Exception { + System.out.println("=== Falcon Post-Quantum Signatures ==="); + + // Generate Falcon-512 keypair (128-bit security) + FalconKeypair falcon512 = crypto.falcon().generate(FalconVariant.FALCON512).get(); + System.out.println("Falcon-512 keypair:"); + System.out.println(" Public key: " + falcon512.getPublicKey().getKeyBytes().length + " bytes"); + System.out.println(" Security level: 128-bit"); + + // Generate Falcon-1024 keypair (256-bit security) + FalconKeypair falcon1024 = crypto.falcon().generate(FalconVariant.FALCON1024).get(); + System.out.println("\nFalcon-1024 keypair:"); + System.out.println(" Public key: " + falcon1024.getPublicKey().getKeyBytes().length + " bytes"); + System.out.println(" Security level: 256-bit"); + + // Sign with Falcon-512 + byte[] message = "Post-quantum secure message".getBytes(); + FalconSignature signature = crypto.falcon().sign(falcon512, message).get(); + System.out.println("\nFalcon-512 signature: " + signature.getSignatureBytes().length + " bytes"); + + // Verify + boolean valid = crypto.falcon().verify(falcon512.getPublicKey().getKeyBytes(), message, signature).get(); + System.out.println("Verification: " + valid); + + System.out.println(); + } + + static void sphincsExample(SynorCrypto crypto) throws Exception { + System.out.println("=== SPHINCS+ Hash-Based Signatures ==="); + + // SPHINCS+ variants with different security levels + Object[][] variants = { + {SphincsVariant.SHAKE128S, 128, 7856}, + {SphincsVariant.SHAKE192S, 192, 16224}, + {SphincsVariant.SHAKE256S, 256, 29792}, + }; + + // Generate and demonstrate each variant + for (Object[] v : variants) { + SphincsVariant variant = (SphincsVariant) v[0]; + int security = (int) v[1]; + int sigSize = (int) v[2]; + + SphincsKeypair keypair = crypto.sphincs().generate(variant).get(); + System.out.println("SPHINCS+ " + variant + ":"); + System.out.println(" Security level: " + security + "-bit"); + System.out.println(" Expected signature size: " + sigSize + " bytes"); + + // Sign a message + byte[] message = "Hash-based quantum security".getBytes(); + SphincsSignature signature = crypto.sphincs().sign(keypair, message).get(); + System.out.println(" Actual signature size: " + signature.getSignatureBytes().length + " bytes"); + + // Verify + boolean valid = crypto.sphincs().verify(keypair.getPublicKey().getKeyBytes(), message, signature).get(); + System.out.println(" Verification: " + valid + "\n"); + } + } + + static void kdfExample(SynorCrypto crypto) throws Exception { + System.out.println("=== Key Derivation Functions ==="); + + // HKDF (HMAC-based Key Derivation Function) + byte[] seed = "master-secret-key-material-here".getBytes(); + DerivationConfig hkdfConfig = DerivationConfig.builder() + .salt("application-salt".getBytes()) + .info("encryption-key".getBytes()) + .outputLength(32) + .build(); + + byte[] derivedKey = crypto.kdf().deriveKey(seed, hkdfConfig).get(); + System.out.println("HKDF derived key: " + bytesToHex(derivedKey)); + + // PBKDF2 (Password-Based Key Derivation Function) + byte[] password = "user-password".getBytes(); + PasswordDerivationConfig pbkdf2Config = PasswordDerivationConfig.builder() + .salt("random-salt-value".getBytes()) + .iterations(100000) + .outputLength(32) + .build(); + + byte[] passwordKey = crypto.kdf().deriveFromPassword(password, pbkdf2Config).get(); + System.out.println("PBKDF2 derived key: " + bytesToHex(passwordKey)); + + System.out.println(); + } + + static void hashExample(SynorCrypto crypto) throws Exception { + System.out.println("=== Hash Functions ==="); + + byte[] data = "Data to hash".getBytes(); + + // SHA3-256 (FIPS 202) + HashResult sha3 = crypto.hash().sha3_256(data).get(); + System.out.println("SHA3-256: " + sha3.getHex()); + + // BLAKE3 (fast, parallel) + HashResult blake3 = crypto.hash().blake3(data).get(); + System.out.println("BLAKE3: " + blake3.getHex()); + + // Keccak-256 (Ethereum compatible) + HashResult keccak = crypto.hash().keccak256(data).get(); + System.out.println("Keccak: " + keccak.getHex()); + + System.out.println(); + } + + private static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +} diff --git a/sdk/js/examples/compiler_example.ts b/sdk/js/examples/compiler_example.ts new file mode 100644 index 0000000..1fd892e --- /dev/null +++ b/sdk/js/examples/compiler_example.ts @@ -0,0 +1,393 @@ +/** + * Synor Compiler SDK Examples for JavaScript/TypeScript + * + * Demonstrates smart contract compilation and analysis: + * - WASM contract compilation and optimization + * - ABI extraction and encoding + * - Contract analysis and security scanning + * - Validation and verification + */ + +import * as fs from 'fs'; +import { + SynorCompiler, + CompilerConfig, + OptimizationLevel, + StripOptions, +} from '../src/compiler'; + +async function main() { + // Initialize client + const config: CompilerConfig = { + apiKey: process.env.SYNOR_API_KEY || 'your-api-key', + endpoint: 'https://compiler.synor.io/v1', + timeout: 60000, + retries: 3, + debug: false, + defaultOptimizationLevel: OptimizationLevel.Size, + maxContractSize: 256 * 1024, + useWasmOpt: true, + validate: true, + extractMetadata: true, + generateAbi: true, + }; + + const compiler = new SynorCompiler(config); + + try { + // Check service health + const healthy = await compiler.healthCheck(); + console.log(`Service healthy: ${healthy}\n`); + + // Example 1: Compile a contract + await compileContractExample(compiler); + + // Example 2: Development vs Production compilation + await compilationModesExample(compiler); + + // Example 3: ABI operations + await abiExample(compiler); + + // Example 4: Contract analysis + await analysisExample(compiler); + + // Example 5: Validation + await validationExample(compiler); + + // Example 6: Security scanning + await securityExample(compiler); + } finally { + compiler.close(); + } +} + +/** + * Basic contract compilation + */ +async function compileContractExample(compiler: SynorCompiler): Promise { + console.log('=== Contract Compilation ==='); + + // In production, load from file: + // const wasm = fs.readFileSync('my_contract.wasm'); + + // For demonstration, create a minimal WASM module + const wasm = createMinimalWasm(); + + const result = await compiler.compile(wasm, { + optimizationLevel: OptimizationLevel.Size, + useWasmOpt: true, + validate: true, + extractMetadata: true, + generateAbi: true, + stripOptions: { + stripDebug: true, + stripProducers: true, + stripNames: true, + stripCustom: true, + stripUnused: true, + preserveSections: [], + }, + }); + + console.log('Compilation result:'); + console.log(` Contract ID: ${result.contractId}`); + console.log(` Code hash: ${result.codeHash}`); + console.log(` Original size: ${result.originalSize} bytes`); + console.log(` Optimized size: ${result.optimizedSize} bytes`); + console.log(` Size reduction: ${result.sizeReduction.toFixed(1)}%`); + console.log(` Estimated deploy gas: ${result.estimatedDeployGas}`); + + if (result.metadata) { + console.log('\nMetadata:'); + console.log(` Name: ${result.metadata.name}`); + console.log(` Version: ${result.metadata.version}`); + console.log(` SDK Version: ${result.metadata.sdkVersion}`); + } + + if (result.abi) { + console.log('\nABI:'); + console.log(` Functions: ${result.abi.functions?.length || 0}`); + console.log(` Events: ${result.abi.events?.length || 0}`); + console.log(` Errors: ${result.abi.errors?.length || 0}`); + } + + console.log(''); +} + +/** + * Development vs Production compilation modes + */ +async function compilationModesExample(compiler: SynorCompiler): Promise { + console.log('=== Compilation Modes ==='); + + const wasm = createMinimalWasm(); + + // Development mode: fast compilation, debugging support + console.log('Development mode:'); + const devResult = await compiler.contracts.compileDev(wasm); + console.log(` Size: ${devResult.optimizedSize} bytes`); + console.log(` Optimization: none`); + + // Production mode: maximum optimization + console.log('\nProduction mode:'); + const prodResult = await compiler.contracts.compileProduction(wasm); + console.log(` Size: ${prodResult.optimizedSize} bytes`); + console.log(` Optimization: aggressive`); + console.log(` Size savings: ${(devResult.optimizedSize - prodResult.optimizedSize)} bytes`); + + // Custom optimization levels + console.log('\nOptimization levels:'); + const levels = [ + OptimizationLevel.None, + OptimizationLevel.Basic, + OptimizationLevel.Size, + OptimizationLevel.Aggressive, + ]; + + for (const level of levels) { + const result = await compiler.compile(wasm, { optimizationLevel: level }); + console.log(` ${level}: ${result.optimizedSize} bytes`); + } + + console.log(''); +} + +/** + * ABI extraction and encoding + */ +async function abiExample(compiler: SynorCompiler): Promise { + console.log('=== ABI Operations ==='); + + const wasm = createMinimalWasm(); + + // Extract ABI from WASM + const abi = await compiler.abi.extract(wasm); + console.log(`Contract: ${abi.name}`); + console.log(`Version: ${abi.version}`); + + // List functions + if (abi.functions && abi.functions.length > 0) { + console.log('\nFunctions:'); + for (const func of abi.functions) { + const inputs = func.inputs?.map(i => `${i.name}: ${i.type.typeName}`).join(', ') || ''; + const outputs = func.outputs?.map(o => o.type.typeName).join(', ') || 'void'; + const modifiers = [ + func.view ? 'view' : '', + func.payable ? 'payable' : '', + ].filter(Boolean).join(' '); + console.log(` ${func.name}(${inputs}) -> ${outputs} ${modifiers}`); + console.log(` Selector: ${func.selector}`); + } + } + + // List events + if (abi.events && abi.events.length > 0) { + console.log('\nEvents:'); + for (const event of abi.events) { + const params = event.params?.map(p => { + const indexed = p.indexed ? 'indexed ' : ''; + return `${indexed}${p.name}: ${p.type.typeName}`; + }).join(', ') || ''; + console.log(` ${event.name}(${params})`); + console.log(` Topic: ${event.topic}`); + } + } + + // Encode a function call + if (abi.functions && abi.functions.length > 0) { + const func = abi.functions[0]; + const encoded = await compiler.abi.encodeCall(func, ['arg1', 'arg2']); + console.log(`\nEncoded call to ${func.name}: ${encoded}`); + + // Decode a result + const decoded = await compiler.abi.decodeResult(func, encoded); + console.log(`Decoded result: ${JSON.stringify(decoded)}`); + } + + console.log(''); +} + +/** + * Contract analysis + */ +async function analysisExample(compiler: SynorCompiler): Promise { + console.log('=== Contract Analysis ==='); + + const wasm = createMinimalWasm(); + + // Full analysis + const analysis = await compiler.analysis.analyze(wasm); + + // Size breakdown + if (analysis.sizeBreakdown) { + console.log('Size breakdown:'); + console.log(` Code: ${analysis.sizeBreakdown.code} bytes`); + console.log(` Data: ${analysis.sizeBreakdown.data} bytes`); + console.log(` Functions: ${analysis.sizeBreakdown.functions} bytes`); + console.log(` Memory: ${analysis.sizeBreakdown.memory} bytes`); + console.log(` Exports: ${analysis.sizeBreakdown.exports} bytes`); + console.log(` Imports: ${analysis.sizeBreakdown.imports} bytes`); + console.log(` Total: ${analysis.sizeBreakdown.total} bytes`); + } + + // Function analysis + if (analysis.functions && analysis.functions.length > 0) { + console.log('\nFunction analysis:'); + for (const func of analysis.functions.slice(0, 5)) { + console.log(` ${func.name}:`); + console.log(` Size: ${func.size} bytes`); + console.log(` Instructions: ${func.instructionCount}`); + console.log(` Locals: ${func.localCount}`); + console.log(` Exported: ${func.exported}`); + console.log(` Estimated gas: ${func.estimatedGas}`); + } + } + + // Import analysis + if (analysis.imports && analysis.imports.length > 0) { + console.log('\nImports:'); + for (const imp of analysis.imports) { + console.log(` ${imp.module}.${imp.name} (${imp.kind})`); + } + } + + // Gas analysis + if (analysis.gasAnalysis) { + console.log('\nGas analysis:'); + console.log(` Deployment: ${analysis.gasAnalysis.deploymentGas}`); + console.log(` Memory init: ${analysis.gasAnalysis.memoryInitGas}`); + console.log(` Data section: ${analysis.gasAnalysis.dataSectionGas}`); + } + + // Extract metadata + const metadata = await compiler.analysis.extractMetadata(wasm); + console.log('\nContract metadata:'); + console.log(` Name: ${metadata.name}`); + console.log(` Version: ${metadata.version}`); + console.log(` Build timestamp: ${metadata.buildTimestamp}`); + + // Estimate deployment gas + const gas = await compiler.analysis.estimateDeployGas(wasm); + console.log(`\nEstimated deployment gas: ${gas}`); + + console.log(''); +} + +/** + * Contract validation + */ +async function validationExample(compiler: SynorCompiler): Promise { + console.log('=== Contract Validation ==='); + + const wasm = createMinimalWasm(); + + // Full validation + const result = await compiler.validation.validate(wasm); + console.log(`Valid: ${result.valid}`); + console.log(`Exports: ${result.exportCount}`); + console.log(`Imports: ${result.importCount}`); + console.log(`Functions: ${result.functionCount}`); + console.log(`Memory pages: ${result.memoryPages}`); + + if (result.errors && result.errors.length > 0) { + console.log('\nValidation errors:'); + for (const error of result.errors) { + console.log(` [${error.code}] ${error.message}`); + if (error.location) { + console.log(` at ${error.location}`); + } + } + } + + if (result.warnings && result.warnings.length > 0) { + console.log('\nWarnings:'); + for (const warning of result.warnings) { + console.log(` ${warning}`); + } + } + + // Quick validation + const isValid = await compiler.validation.isValid(wasm); + console.log(`\nQuick validation: ${isValid}`); + + // Get validation errors only + const errors = await compiler.validation.getErrors(wasm); + console.log(`Error count: ${errors.length}`); + + // Validate required exports + const hasRequiredExports = await compiler.validation.validateExports( + wasm, + ['init', 'execute', 'query'] + ); + console.log(`Has required exports: ${hasRequiredExports}`); + + // Validate memory constraints + const memoryValid = await compiler.validation.validateMemory(wasm, 16); + console.log(`Memory within 16 pages: ${memoryValid}`); + + console.log(''); +} + +/** + * Security scanning + */ +async function securityExample(compiler: SynorCompiler): Promise { + console.log('=== Security Scanning ==='); + + const wasm = createMinimalWasm(); + + const security = await compiler.analysis.securityScan(wasm); + + console.log(`Security score: ${security.score}/100`); + + if (security.issues && security.issues.length > 0) { + console.log('\nSecurity issues:'); + for (const issue of security.issues) { + const severityIcon = { + 'critical': '🔴', + 'high': '🟠', + 'medium': '🟡', + 'low': '🟢', + }[issue.severity] || '⚪'; + + console.log(`${severityIcon} [${issue.severity.toUpperCase()}] ${issue.type}`); + console.log(` ${issue.description}`); + if (issue.location) { + console.log(` at ${issue.location}`); + } + } + } else { + console.log('No security issues found!'); + } + + if (security.recommendations && security.recommendations.length > 0) { + console.log('\nRecommendations:'); + for (const rec of security.recommendations) { + console.log(` • ${rec}`); + } + } + + console.log(''); +} + +/** + * Create a minimal valid WASM module for testing + */ +function createMinimalWasm(): Buffer { + // Minimal WASM module with magic number and version + return Buffer.from([ + 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, + ]); +} + +// Run examples +main().catch(console.error); diff --git a/sdk/js/examples/crypto_example.ts b/sdk/js/examples/crypto_example.ts new file mode 100644 index 0000000..12c8d00 --- /dev/null +++ b/sdk/js/examples/crypto_example.ts @@ -0,0 +1,279 @@ +/** + * Synor Crypto SDK Examples for JavaScript/TypeScript + * + * Demonstrates quantum-resistant cryptographic operations including: + * - Hybrid Ed25519 + Dilithium3 signatures + * - BIP-39 mnemonic generation and validation + * - Post-quantum algorithms (Falcon, SPHINCS+) + * - Key derivation functions + */ + +import { + SynorCrypto, + CryptoConfig, + Network, + FalconVariant, + SphincsVariant, + DerivationConfig, + PasswordDerivationConfig, + DerivationPath, +} from '../src/crypto'; + +async function main() { + // Initialize client + const config: CryptoConfig = { + apiKey: process.env.SYNOR_API_KEY || 'your-api-key', + endpoint: 'https://crypto.synor.io/v1', + timeout: 30000, + retries: 3, + debug: false, + defaultNetwork: Network.Mainnet, + }; + + const crypto = new SynorCrypto(config); + + try { + // Check service health + const healthy = await crypto.healthCheck(); + console.log(`Service healthy: ${healthy}\n`); + + // Example 1: Mnemonic operations + await mnemonicExample(crypto); + + // Example 2: Keypair generation + await keypairExample(crypto); + + // Example 3: Hybrid signing + await signingExample(crypto); + + // Example 4: Falcon post-quantum signatures + await falconExample(crypto); + + // Example 5: SPHINCS+ post-quantum signatures + await sphincsExample(crypto); + + // Example 6: Key derivation + await kdfExample(crypto); + + // Example 7: Hashing + await hashExample(crypto); + } finally { + crypto.close(); + } +} + +/** + * Mnemonic generation and validation + */ +async function mnemonicExample(crypto: SynorCrypto): Promise { + console.log('=== Mnemonic Operations ==='); + + // Generate a 24-word mnemonic (256-bit entropy) + const mnemonic = await crypto.mnemonic.generate(24); + console.log(`Generated mnemonic: ${mnemonic.phrase}`); + console.log(`Word count: ${mnemonic.wordCount}`); + + // Validate a mnemonic + const validation = await crypto.mnemonic.validate(mnemonic.phrase); + console.log(`Valid: ${validation.valid}`); + if (!validation.valid) { + console.log(`Error: ${validation.error}`); + } + + // Convert mnemonic to seed + const seed = await crypto.mnemonic.toSeed(mnemonic.phrase, 'optional-passphrase'); + console.log(`Seed (hex): ${Buffer.from(seed).toString('hex').slice(0, 32)}...`); + + // Word suggestions for autocomplete + const suggestions = await crypto.mnemonic.suggestWords('aban', 5); + console.log(`Suggestions for "aban": ${suggestions.join(', ')}`); + + console.log(''); +} + +/** + * Keypair generation and address derivation + */ +async function keypairExample(crypto: SynorCrypto): Promise { + console.log('=== Keypair Operations ==='); + + // Generate a random keypair + const keypair = await crypto.keypairs.generate(); + console.log('Generated hybrid keypair:'); + console.log(` Ed25519 public key size: ${keypair.publicKey.ed25519Bytes.length} bytes`); + console.log(` Dilithium public key size: ${keypair.publicKey.dilithiumBytes.length} bytes`); + console.log(` Total public key size: ${keypair.publicKey.size} bytes`); + + // Get addresses for different networks + console.log('\nAddresses:'); + console.log(` Mainnet: ${keypair.getAddress(Network.Mainnet)}`); + console.log(` Testnet: ${keypair.getAddress(Network.Testnet)}`); + console.log(` Devnet: ${keypair.getAddress(Network.Devnet)}`); + + // Create keypair from mnemonic (deterministic) + const mnemonic = await crypto.mnemonic.generate(24); + const keypair2 = await crypto.keypairs.fromMnemonic(mnemonic.phrase, ''); + console.log(`\nKeypair from mnemonic: ${keypair2.getAddress(Network.Mainnet).slice(0, 20)}...`); + + // Derive child keypair using BIP-44 path + const path = DerivationPath.external(0, 0); // m/44'/21337'/0'/0/0 + console.log(`Derivation path: ${path.toString()}`); + + console.log(''); +} + +/** + * Hybrid signature operations (Ed25519 + Dilithium3) + */ +async function signingExample(crypto: SynorCrypto): Promise { + console.log('=== Hybrid Signing ==='); + + // Generate keypair + const keypair = await crypto.keypairs.generate(); + + // Sign a message + const message = Buffer.from('Hello, quantum-resistant world!'); + const signature = await crypto.signing.sign(keypair, message); + + console.log('Signature created:'); + console.log(` Ed25519 component: ${signature.ed25519Bytes.length} bytes`); + console.log(` Dilithium component: ${signature.dilithiumBytes.length} bytes`); + console.log(` Total signature size: ${signature.size} bytes`); + + // Verify the signature + const valid = await crypto.signing.verify(keypair.publicKey, message, signature); + console.log(`\nVerification result: ${valid}`); + + // Verify with tampered message fails + const tamperedMessage = Buffer.from('Hello, tampered message!'); + const invalidResult = await crypto.signing.verify(keypair.publicKey, tamperedMessage, signature); + console.log(`Tampered message verification: ${invalidResult}`); + + console.log(''); +} + +/** + * Falcon post-quantum signature example + */ +async function falconExample(crypto: SynorCrypto): Promise { + console.log('=== Falcon Post-Quantum Signatures ==='); + + // Generate Falcon-512 keypair (128-bit security) + const falcon512 = await crypto.falcon.generate(FalconVariant.Falcon512); + console.log('Falcon-512 keypair:'); + console.log(` Public key: ${falcon512.publicKey.bytes.length} bytes`); + console.log(` Security level: 128-bit`); + + // Generate Falcon-1024 keypair (256-bit security) + const falcon1024 = await crypto.falcon.generate(FalconVariant.Falcon1024); + console.log('\nFalcon-1024 keypair:'); + console.log(` Public key: ${falcon1024.publicKey.bytes.length} bytes`); + console.log(` Security level: 256-bit`); + + // Sign with Falcon-512 + const message = Buffer.from('Post-quantum secure message'); + const signature = await crypto.falcon.sign(falcon512, message); + console.log(`\nFalcon-512 signature: ${signature.signatureBytes.length} bytes`); + + // Verify + const valid = await crypto.falcon.verify( + falcon512.publicKey.bytes, + message, + signature + ); + console.log(`Verification: ${valid}`); + + console.log(''); +} + +/** + * SPHINCS+ post-quantum signature example (hash-based) + */ +async function sphincsExample(crypto: SynorCrypto): Promise { + console.log('=== SPHINCS+ Hash-Based Signatures ==='); + + // SPHINCS+ variants with different security levels + const variants = [ + { variant: SphincsVariant.Shake128s, security: 128, sigSize: 7856 }, + { variant: SphincsVariant.Shake192s, security: 192, sigSize: 16224 }, + { variant: SphincsVariant.Shake256s, security: 256, sigSize: 29792 }, + ]; + + // Generate and demonstrate each variant + for (const { variant, security, sigSize } of variants) { + const keypair = await crypto.sphincs.generate(variant); + console.log(`SPHINCS+ ${variant}:`); + console.log(` Security level: ${security}-bit`); + console.log(` Expected signature size: ${sigSize} bytes`); + + // Sign a message + const message = Buffer.from('Hash-based quantum security'); + const signature = await crypto.sphincs.sign(keypair, message); + console.log(` Actual signature size: ${signature.signatureBytes.length} bytes`); + + // Verify + const valid = await crypto.sphincs.verify( + keypair.publicKey.bytes, + message, + signature + ); + console.log(` Verification: ${valid}\n`); + } +} + +/** + * Key derivation functions + */ +async function kdfExample(crypto: SynorCrypto): Promise { + console.log('=== Key Derivation Functions ==='); + + // HKDF (HMAC-based Key Derivation Function) + const seed = Buffer.from('master-secret-key-material-here'); + const hkdfConfig: DerivationConfig = { + salt: Buffer.from('application-salt'), + info: Buffer.from('encryption-key'), + outputLength: 32, + }; + + const derivedKey = await crypto.kdf.deriveKey(seed, hkdfConfig); + console.log(`HKDF derived key: ${Buffer.from(derivedKey).toString('hex')}`); + + // PBKDF2 (Password-Based Key Derivation Function) + const password = Buffer.from('user-password'); + const pbkdf2Config: PasswordDerivationConfig = { + salt: Buffer.from('random-salt-value'), + iterations: 100000, + outputLength: 32, + }; + + const passwordKey = await crypto.kdf.deriveFromPassword(password, pbkdf2Config); + console.log(`PBKDF2 derived key: ${Buffer.from(passwordKey).toString('hex')}`); + + console.log(''); +} + +/** + * Cryptographic hash functions + */ +async function hashExample(crypto: SynorCrypto): Promise { + console.log('=== Hash Functions ==='); + + const data = Buffer.from('Data to hash'); + + // SHA3-256 (FIPS 202) + const sha3 = await crypto.hash.sha3_256(data); + console.log(`SHA3-256: ${sha3.hex}`); + + // BLAKE3 (fast, parallel) + const blake3 = await crypto.hash.blake3(data); + console.log(`BLAKE3: ${blake3.hex}`); + + // Keccak-256 (Ethereum compatible) + const keccak = await crypto.hash.keccak256(data); + console.log(`Keccak: ${keccak.hex}`); + + console.log(''); +} + +// Run examples +main().catch(console.error); diff --git a/sdk/js/examples/dex_example.ts b/sdk/js/examples/dex_example.ts new file mode 100644 index 0000000..81db714 --- /dev/null +++ b/sdk/js/examples/dex_example.ts @@ -0,0 +1,488 @@ +/** + * Synor DEX SDK Examples for JavaScript/TypeScript + * + * Demonstrates decentralized exchange operations: + * - Spot trading (market/limit orders) + * - Perpetual futures trading + * - Liquidity provision + * - Order management + * - Real-time market data + */ + +import { + SynorDex, + DexConfig, + Network, + OrderSide, + OrderType, + TimeInForce, + PositionSide, + MarginType, +} from '../src/dex'; + +async function main() { + // Initialize client + const config: DexConfig = { + apiKey: process.env.SYNOR_API_KEY || 'your-api-key', + endpoint: 'https://dex.synor.io/v1', + wsEndpoint: 'wss://dex.synor.io/v1/ws', + timeout: 30000, + retries: 3, + debug: false, + defaultNetwork: Network.Mainnet, + }; + + const dex = new SynorDex(config); + + try { + // Check service health + const healthy = await dex.healthCheck(); + console.log(`Service healthy: ${healthy}\n`); + + // Example 1: Market data + await marketDataExample(dex); + + // Example 2: Spot trading + await spotTradingExample(dex); + + // Example 3: Perpetual futures + await perpetualFuturesExample(dex); + + // Example 4: Liquidity provision + await liquidityExample(dex); + + // Example 5: Order management + await orderManagementExample(dex); + + // Example 6: Account information + await accountExample(dex); + + // Example 7: Real-time streaming + await streamingExample(dex); + } finally { + dex.close(); + } +} + +/** + * Market data and orderbook + */ +async function marketDataExample(dex: SynorDex): Promise { + console.log('=== Market Data ==='); + + // Get all trading pairs + const pairs = await dex.markets.getPairs(); + console.log(`Available trading pairs: ${pairs.length}`); + for (const pair of pairs.slice(0, 5)) { + console.log(` ${pair.symbol}: ${pair.baseAsset}/${pair.quoteAsset}`); + } + + // Get ticker for a specific pair + const ticker = await dex.markets.getTicker('SYN-USDT'); + console.log(`\nSYN-USDT Ticker:`); + console.log(` Last price: $${ticker.lastPrice}`); + console.log(` 24h change: ${ticker.priceChangePercent}%`); + console.log(` 24h high: $${ticker.highPrice}`); + console.log(` 24h low: $${ticker.lowPrice}`); + console.log(` 24h volume: ${ticker.volume} SYN`); + console.log(` 24h quote volume: $${ticker.quoteVolume}`); + + // Get orderbook + const orderbook = await dex.markets.getOrderbook('SYN-USDT', 10); + console.log(`\nOrderbook (top 5):`); + console.log(' Bids:'); + for (const bid of orderbook.bids.slice(0, 5)) { + console.log(` $${bid.price} - ${bid.quantity} SYN`); + } + console.log(' Asks:'); + for (const ask of orderbook.asks.slice(0, 5)) { + console.log(` $${ask.price} - ${ask.quantity} SYN`); + } + + // Get recent trades + const trades = await dex.markets.getTrades('SYN-USDT', 5); + console.log(`\nRecent trades:`); + for (const trade of trades) { + const side = trade.isBuyerMaker ? 'SELL' : 'BUY'; + console.log(` ${side} ${trade.quantity} @ $${trade.price}`); + } + + // Get OHLCV candles + const candles = await dex.markets.getCandles('SYN-USDT', '1h', 5); + console.log(`\nHourly candles:`); + for (const candle of candles) { + console.log(` ${new Date(candle.openTime).toISOString()}: O=${candle.open} H=${candle.high} L=${candle.low} C=${candle.close}`); + } + + console.log(''); +} + +/** + * Spot trading operations + */ +async function spotTradingExample(dex: SynorDex): Promise { + console.log('=== Spot Trading ==='); + + // Place a market buy order + console.log('Placing market buy order...'); + const marketBuy = await dex.spot.createOrder({ + symbol: 'SYN-USDT', + side: OrderSide.Buy, + type: OrderType.Market, + quantity: 10, // Buy 10 SYN + }); + console.log(`Market buy order: ${marketBuy.orderId}`); + console.log(` Status: ${marketBuy.status}`); + console.log(` Filled: ${marketBuy.executedQty} SYN`); + console.log(` Avg price: $${marketBuy.avgPrice}`); + + // Place a limit sell order + console.log('\nPlacing limit sell order...'); + const limitSell = await dex.spot.createOrder({ + symbol: 'SYN-USDT', + side: OrderSide.Sell, + type: OrderType.Limit, + quantity: 5, + price: 15.50, // Sell at $15.50 + timeInForce: TimeInForce.GTC, // Good till cancelled + }); + console.log(`Limit sell order: ${limitSell.orderId}`); + console.log(` Price: $${limitSell.price}`); + console.log(` Status: ${limitSell.status}`); + + // Place a stop-loss order + console.log('\nPlacing stop-loss order...'); + const stopLoss = await dex.spot.createOrder({ + symbol: 'SYN-USDT', + side: OrderSide.Sell, + type: OrderType.StopLoss, + quantity: 10, + stopPrice: 12.00, // Trigger at $12.00 + }); + console.log(`Stop-loss order: ${stopLoss.orderId}`); + console.log(` Stop price: $${stopLoss.stopPrice}`); + + // Place a take-profit limit order + console.log('\nPlacing take-profit order...'); + const takeProfit = await dex.spot.createOrder({ + symbol: 'SYN-USDT', + side: OrderSide.Sell, + type: OrderType.TakeProfitLimit, + quantity: 10, + price: 20.00, // Sell at $20.00 + stopPrice: 19.50, // Trigger at $19.50 + timeInForce: TimeInForce.GTC, + }); + console.log(`Take-profit order: ${takeProfit.orderId}`); + + console.log(''); +} + +/** + * Perpetual futures trading + */ +async function perpetualFuturesExample(dex: SynorDex): Promise { + console.log('=== Perpetual Futures ==='); + + // Get perpetual markets + const markets = await dex.perpetuals.getMarkets(); + console.log(`Available perpetual markets: ${markets.length}`); + for (const market of markets.slice(0, 3)) { + console.log(` ${market.symbol}: ${market.maxLeverage}x max leverage, ${market.maintenanceMarginRate}% MMR`); + } + + // Get funding rate + const funding = await dex.perpetuals.getFundingRate('SYN-USDT-PERP'); + console.log(`\nFunding rate for SYN-USDT-PERP:`); + console.log(` Current rate: ${(funding.fundingRate * 100).toFixed(4)}%`); + console.log(` Predicted rate: ${(funding.predictedRate * 100).toFixed(4)}%`); + console.log(` Next funding: ${new Date(funding.nextFundingTime).toISOString()}`); + + // Set leverage + await dex.perpetuals.setLeverage('SYN-USDT-PERP', 10); + console.log('\nLeverage set to 10x'); + + // Set margin type (isolated/cross) + await dex.perpetuals.setMarginType('SYN-USDT-PERP', MarginType.Isolated); + console.log('Margin type set to Isolated'); + + // Open a long position + console.log('\nOpening long position...'); + const longOrder = await dex.perpetuals.createOrder({ + symbol: 'SYN-USDT-PERP', + side: OrderSide.Buy, + positionSide: PositionSide.Long, + type: OrderType.Market, + quantity: 100, // 100 contracts + }); + console.log(`Long position opened: ${longOrder.orderId}`); + console.log(` Entry price: $${longOrder.avgPrice}`); + console.log(` Position size: ${longOrder.executedQty} contracts`); + + // Set stop-loss and take-profit + console.log('\nSetting SL/TP...'); + await dex.perpetuals.createOrder({ + symbol: 'SYN-USDT-PERP', + side: OrderSide.Sell, + positionSide: PositionSide.Long, + type: OrderType.StopMarket, + quantity: 100, + stopPrice: 12.00, // Stop-loss at $12 + reduceOnly: true, + }); + console.log(' Stop-loss set at $12.00'); + + await dex.perpetuals.createOrder({ + symbol: 'SYN-USDT-PERP', + side: OrderSide.Sell, + positionSide: PositionSide.Long, + type: OrderType.TakeProfitMarket, + quantity: 100, + stopPrice: 18.00, // Take-profit at $18 + reduceOnly: true, + }); + console.log(' Take-profit set at $18.00'); + + // Get position info + const positions = await dex.perpetuals.getPositions('SYN-USDT-PERP'); + for (const pos of positions) { + console.log(`\nPosition info:`); + console.log(` Symbol: ${pos.symbol}`); + console.log(` Side: ${pos.positionSide}`); + console.log(` Size: ${pos.positionAmount} contracts`); + console.log(` Entry: $${pos.entryPrice}`); + console.log(` Mark: $${pos.markPrice}`); + console.log(` PnL: $${pos.unrealizedPnl} (${pos.unrealizedPnlPercent}%)`); + console.log(` Leverage: ${pos.leverage}x`); + console.log(` Liq. price: $${pos.liquidationPrice}`); + } + + // Close position + console.log('\nClosing position...'); + await dex.perpetuals.closePosition('SYN-USDT-PERP', PositionSide.Long); + console.log('Position closed'); + + console.log(''); +} + +/** + * Liquidity provision + */ +async function liquidityExample(dex: SynorDex): Promise { + console.log('=== Liquidity Provision ==='); + + // Get available pools + const pools = await dex.liquidity.getPools(); + console.log(`Available liquidity pools: ${pools.length}`); + for (const pool of pools.slice(0, 3)) { + console.log(` ${pool.name}:`); + console.log(` TVL: $${pool.tvl.toLocaleString()}`); + console.log(` APY: ${pool.apy.toFixed(2)}%`); + console.log(` Fee tier: ${pool.feeTier}%`); + } + + // Get pool details + const pool = await dex.liquidity.getPool('SYN-USDT'); + console.log(`\nSYN-USDT Pool details:`); + console.log(` Reserve A: ${pool.reserveA} SYN`); + console.log(` Reserve B: ${pool.reserveB} USDT`); + console.log(` Total shares: ${pool.totalShares}`); + console.log(` Your shares: ${pool.userShares}`); + + // Add liquidity + console.log('\nAdding liquidity...'); + const addResult = await dex.liquidity.addLiquidity({ + poolId: 'SYN-USDT', + amountA: 100, // 100 SYN + amountB: 1400, // 1400 USDT + slippageTolerance: 0.5, // 0.5% slippage + }); + console.log(`Liquidity added:`); + console.log(` Shares received: ${addResult.sharesReceived}`); + console.log(` Amount A deposited: ${addResult.amountADeposited}`); + console.log(` Amount B deposited: ${addResult.amountBDeposited}`); + + // Get LP positions + const lpPositions = await dex.liquidity.getPositions(); + console.log(`\nYour LP positions:`); + for (const lp of lpPositions) { + console.log(` ${lp.poolId}: ${lp.shares} shares ($${lp.valueUsd})`); + console.log(` Fees earned: $${lp.feesEarned}`); + } + + // Remove liquidity + console.log('\nRemoving liquidity...'); + const removeResult = await dex.liquidity.removeLiquidity({ + poolId: 'SYN-USDT', + shares: addResult.sharesReceived * 0.5, // Remove 50% + slippageTolerance: 0.5, + }); + console.log(`Liquidity removed:`); + console.log(` Amount A received: ${removeResult.amountAReceived}`); + console.log(` Amount B received: ${removeResult.amountBReceived}`); + + console.log(''); +} + +/** + * Order management + */ +async function orderManagementExample(dex: SynorDex): Promise { + console.log('=== Order Management ==='); + + // Get open orders + const openOrders = await dex.orders.getOpenOrders('SYN-USDT'); + console.log(`Open orders: ${openOrders.length}`); + for (const order of openOrders) { + console.log(` ${order.orderId}: ${order.side} ${order.quantity} @ $${order.price}`); + } + + // Get order history + const history = await dex.orders.getOrderHistory({ + symbol: 'SYN-USDT', + limit: 5, + }); + console.log(`\nOrder history (last 5):`); + for (const order of history) { + console.log(` ${order.orderId}: ${order.side} ${order.quantity} ${order.status}`); + } + + // Get specific order + if (openOrders.length > 0) { + const order = await dex.orders.getOrder(openOrders[0].orderId); + console.log(`\nOrder details:`); + console.log(` Symbol: ${order.symbol}`); + console.log(` Type: ${order.type}`); + console.log(` Side: ${order.side}`); + console.log(` Quantity: ${order.quantity}`); + console.log(` Filled: ${order.executedQty}`); + console.log(` Status: ${order.status}`); + } + + // Cancel a specific order + if (openOrders.length > 0) { + console.log('\nCancelling order...'); + const cancelled = await dex.orders.cancelOrder(openOrders[0].orderId); + console.log(`Order ${cancelled.orderId} cancelled`); + } + + // Cancel all orders for a symbol + console.log('\nCancelling all SYN-USDT orders...'); + const cancelledOrders = await dex.orders.cancelAllOrders('SYN-USDT'); + console.log(`Cancelled ${cancelledOrders.length} orders`); + + // Get trade history + const trades = await dex.orders.getTradeHistory({ + symbol: 'SYN-USDT', + limit: 5, + }); + console.log(`\nTrade history (last 5):`); + for (const trade of trades) { + console.log(` ${trade.side} ${trade.quantity} @ $${trade.price} (fee: $${trade.fee})`); + } + + console.log(''); +} + +/** + * Account information + */ +async function accountExample(dex: SynorDex): Promise { + console.log('=== Account Information ==='); + + // Get account balances + const balances = await dex.account.getBalances(); + console.log('Balances:'); + for (const balance of balances.filter(b => parseFloat(b.total) > 0)) { + console.log(` ${balance.asset}: ${balance.free} free, ${balance.locked} locked`); + } + + // Get account summary + const summary = await dex.account.getSummary(); + console.log(`\nAccount summary:`); + console.log(` Total equity: $${summary.totalEquity}`); + console.log(` Available margin: $${summary.availableMargin}`); + console.log(` Used margin: $${summary.usedMargin}`); + console.log(` Margin level: ${summary.marginLevel}%`); + console.log(` Unrealized PnL: $${summary.unrealizedPnl}`); + + // Get deposit address + const depositAddr = await dex.account.getDepositAddress('SYN'); + console.log(`\nDeposit address for SYN: ${depositAddr.address}`); + + // Get deposit/withdrawal history + const deposits = await dex.account.getDepositHistory({ limit: 3 }); + console.log(`\nRecent deposits:`); + for (const dep of deposits) { + console.log(` ${dep.asset}: ${dep.amount} (${dep.status})`); + } + + const withdrawals = await dex.account.getWithdrawalHistory({ limit: 3 }); + console.log(`\nRecent withdrawals:`); + for (const wd of withdrawals) { + console.log(` ${wd.asset}: ${wd.amount} (${wd.status})`); + } + + // Get fee rates + const fees = await dex.account.getFeeRates('SYN-USDT'); + console.log(`\nFee rates for SYN-USDT:`); + console.log(` Maker: ${fees.makerRate}%`); + console.log(` Taker: ${fees.takerRate}%`); + + console.log(''); +} + +/** + * Real-time WebSocket streaming + */ +async function streamingExample(dex: SynorDex): Promise { + console.log('=== Real-time Streaming ==='); + + // Subscribe to ticker updates + console.log('Subscribing to SYN-USDT ticker...'); + const tickerUnsub = dex.streams.subscribeTicker('SYN-USDT', (ticker) => { + console.log(` Ticker: $${ticker.lastPrice} (${ticker.priceChangePercent}%)`); + }); + + // Subscribe to orderbook updates + console.log('Subscribing to orderbook...'); + const orderbookUnsub = dex.streams.subscribeOrderbook('SYN-USDT', (orderbook) => { + console.log(` Best bid: $${orderbook.bids[0]?.price}, Best ask: $${orderbook.asks[0]?.price}`); + }); + + // Subscribe to trades + console.log('Subscribing to trades...'); + const tradesUnsub = dex.streams.subscribeTrades('SYN-USDT', (trade) => { + const side = trade.isBuyerMaker ? 'SELL' : 'BUY'; + console.log(` Trade: ${side} ${trade.quantity} @ $${trade.price}`); + }); + + // Subscribe to user order updates + console.log('Subscribing to order updates...'); + const orderUnsub = dex.streams.subscribeOrders((order) => { + console.log(` Order update: ${order.orderId} ${order.status}`); + }); + + // Subscribe to position updates + console.log('Subscribing to position updates...'); + const positionUnsub = dex.streams.subscribePositions((position) => { + console.log(` Position update: ${position.symbol} PnL: $${position.unrealizedPnl}`); + }); + + // Wait for some updates + console.log('\nListening for 5 seconds...'); + await new Promise(resolve => setTimeout(resolve, 5000)); + + // Unsubscribe + tickerUnsub(); + orderbookUnsub(); + tradesUnsub(); + orderUnsub(); + positionUnsub(); + console.log('Unsubscribed from all streams'); + + console.log(''); +} + +// Run examples +main().catch(console.error); diff --git a/sdk/js/examples/ibc_example.ts b/sdk/js/examples/ibc_example.ts new file mode 100644 index 0000000..ab03210 --- /dev/null +++ b/sdk/js/examples/ibc_example.ts @@ -0,0 +1,380 @@ +/** + * Synor IBC SDK Examples for JavaScript/TypeScript + * + * Demonstrates Inter-Blockchain Communication operations: + * - Cross-chain token transfers + * - Channel management + * - Packet handling + * - Relayer operations + */ + +import { + SynorIbc, + IbcConfig, + Network, + ChannelState, + PacketState, +} from '../src/ibc'; + +async function main() { + // Initialize client + const config: IbcConfig = { + apiKey: process.env.SYNOR_API_KEY || 'your-api-key', + endpoint: 'https://ibc.synor.io/v1', + timeout: 30000, + retries: 3, + debug: false, + defaultNetwork: Network.Mainnet, + }; + + const ibc = new SynorIbc(config); + + try { + // Check service health + const healthy = await ibc.healthCheck(); + console.log(`Service healthy: ${healthy}\n`); + + // Example 1: Connected chains + await chainsExample(ibc); + + // Example 2: Channel management + await channelsExample(ibc); + + // Example 3: Token transfers + await transferExample(ibc); + + // Example 4: Packet tracking + await packetExample(ibc); + + // Example 5: Relayer operations + await relayerExample(ibc); + + // Example 6: Connection info + await connectionExample(ibc); + } finally { + ibc.close(); + } +} + +/** + * Connected chains information + */ +async function chainsExample(ibc: SynorIbc): Promise { + console.log('=== Connected Chains ==='); + + // Get all connected chains + const chains = await ibc.chains.list(); + console.log(`Connected chains: ${chains.length}`); + for (const chain of chains) { + console.log(` ${chain.chainId}:`); + console.log(` Name: ${chain.name}`); + console.log(` Status: ${chain.status}`); + console.log(` Block height: ${chain.latestHeight}`); + console.log(` Channels: ${chain.channelCount}`); + } + + // Get specific chain info + const cosmos = await ibc.chains.get('cosmoshub-4'); + console.log(`\nCosmos Hub details:`); + console.log(` RPC: ${cosmos.rpcEndpoint}`); + console.log(` Rest: ${cosmos.restEndpoint}`); + console.log(` Native denom: ${cosmos.nativeDenom}`); + console.log(` Prefix: ${cosmos.bech32Prefix}`); + + // Get supported assets on a chain + const assets = await ibc.chains.getAssets('cosmoshub-4'); + console.log(`\nSupported assets on Cosmos Hub:`); + for (const asset of assets.slice(0, 5)) { + console.log(` ${asset.symbol}: ${asset.denom}`); + console.log(` Origin: ${asset.originChain}`); + console.log(` Decimals: ${asset.decimals}`); + } + + // Get chain paths (routes) + const paths = await ibc.chains.getPaths('synor-1', 'cosmoshub-4'); + console.log(`\nPaths from Synor to Cosmos Hub:`); + for (const path of paths) { + console.log(` ${path.sourceChannel} -> ${path.destChannel}`); + console.log(` Hops: ${path.hops}`); + console.log(` Avg time: ${path.avgTransferTime}s`); + } + + console.log(''); +} + +/** + * Channel management + */ +async function channelsExample(ibc: SynorIbc): Promise { + console.log('=== Channel Management ==='); + + // List all channels + const channels = await ibc.channels.list(); + console.log(`Total channels: ${channels.length}`); + + // Filter by state + const openChannels = channels.filter(c => c.state === ChannelState.Open); + console.log(`Open channels: ${openChannels.length}`); + + for (const channel of openChannels.slice(0, 3)) { + console.log(`\n Channel ${channel.channelId}:`); + console.log(` Port: ${channel.portId}`); + console.log(` Counterparty: ${channel.counterpartyChannelId} on ${channel.counterpartyChainId}`); + console.log(` Ordering: ${channel.ordering}`); + console.log(` Version: ${channel.version}`); + console.log(` State: ${channel.state}`); + } + + // Get specific channel + const channel = await ibc.channels.get('channel-0'); + console.log(`\nChannel-0 details:`); + console.log(` Connection: ${channel.connectionId}`); + console.log(` Counterparty port: ${channel.counterpartyPortId}`); + + // Get channel statistics + const stats = await ibc.channels.getStats('channel-0'); + console.log(`\nChannel-0 statistics:`); + console.log(` Total packets sent: ${stats.packetsSent}`); + console.log(` Total packets received: ${stats.packetsReceived}`); + console.log(` Pending packets: ${stats.pendingPackets}`); + console.log(` Success rate: ${stats.successRate}%`); + console.log(` Avg relay time: ${stats.avgRelayTime}s`); + + // Get channel capacity + const capacity = await ibc.channels.getCapacity('channel-0'); + console.log(`\nChannel-0 capacity:`); + console.log(` Max throughput: ${capacity.maxPacketsPerBlock} packets/block`); + console.log(` Current utilization: ${capacity.utilization}%`); + + console.log(''); +} + +/** + * Cross-chain token transfers + */ +async function transferExample(ibc: SynorIbc): Promise { + console.log('=== Cross-Chain Transfers ==='); + + // Estimate transfer fee + const estimate = await ibc.transfers.estimateFee({ + sourceChain: 'synor-1', + destChain: 'cosmoshub-4', + denom: 'usyn', + amount: '1000000', // 1 SYN (6 decimals) + }); + console.log('Transfer fee estimate:'); + console.log(` Gas: ${estimate.gas}`); + console.log(` Fee: ${estimate.fee} ${estimate.feeDenom}`); + console.log(` Timeout: ${estimate.timeout}s`); + + // Initiate a transfer + console.log('\nInitiating transfer...'); + const transfer = await ibc.transfers.send({ + sourceChain: 'synor-1', + destChain: 'cosmoshub-4', + channel: 'channel-0', + sender: 'synor1abc...', // Your address + receiver: 'cosmos1xyz...', // Recipient address + denom: 'usyn', + amount: '1000000', // 1 SYN + memo: 'Cross-chain transfer example', + timeoutHeight: 0, // Use timestamp instead + timeoutTimestamp: Date.now() + 600000, // 10 minutes + }); + + console.log(`Transfer initiated:`); + console.log(` TX Hash: ${transfer.txHash}`); + console.log(` Sequence: ${transfer.sequence}`); + console.log(` Status: ${transfer.status}`); + + // Track transfer status + console.log('\nTracking transfer...'); + const status = await ibc.transfers.getStatus(transfer.txHash); + console.log(`Current status: ${status.state}`); + console.log(` Source confirmed: ${status.sourceConfirmed}`); + console.log(` Relayed: ${status.relayed}`); + console.log(` Dest confirmed: ${status.destConfirmed}`); + + // Get transfer history + const history = await ibc.transfers.getHistory({ + address: 'synor1abc...', + limit: 5, + }); + console.log(`\nTransfer history (last 5):`); + for (const tx of history) { + const direction = tx.sender === 'synor1abc...' ? 'OUT' : 'IN'; + console.log(` ${direction} ${tx.amount} ${tx.denom} (${tx.status})`); + } + + // Get pending transfers + const pending = await ibc.transfers.getPending('synor1abc...'); + console.log(`\nPending transfers: ${pending.length}`); + + console.log(''); +} + +/** + * Packet handling + */ +async function packetExample(ibc: SynorIbc): Promise { + console.log('=== Packet Handling ==='); + + // Get pending packets + const packets = await ibc.packets.getPending('channel-0'); + console.log(`Pending packets on channel-0: ${packets.length}`); + + for (const packet of packets.slice(0, 3)) { + console.log(`\n Packet ${packet.sequence}:`); + console.log(` Source: ${packet.sourcePort}/${packet.sourceChannel}`); + console.log(` Dest: ${packet.destPort}/${packet.destChannel}`); + console.log(` State: ${packet.state}`); + console.log(` Data size: ${packet.data.length} bytes`); + console.log(` Timeout height: ${packet.timeoutHeight}`); + console.log(` Timeout timestamp: ${new Date(packet.timeoutTimestamp).toISOString()}`); + } + + // Get packet by sequence + const packet = await ibc.packets.get('channel-0', 1); + console.log(`\nPacket details:`); + console.log(` Commitment: ${packet.commitment}`); + console.log(` Receipt: ${packet.receipt}`); + console.log(` Acknowledgement: ${packet.acknowledgement}`); + + // Get packet receipts + const receipts = await ibc.packets.getReceipts('channel-0', [1, 2, 3]); + console.log(`\nPacket receipts:`); + for (const [seq, receipt] of Object.entries(receipts)) { + console.log(` Sequence ${seq}: ${receipt ? 'received' : 'not received'}`); + } + + // Get timed out packets + const timedOut = await ibc.packets.getTimedOut('channel-0'); + console.log(`\nTimed out packets: ${timedOut.length}`); + for (const p of timedOut) { + console.log(` Sequence ${p.sequence}: timeout at ${new Date(p.timeoutTimestamp).toISOString()}`); + } + + // Get unreceived packets + const unreceived = await ibc.packets.getUnreceived('channel-0'); + console.log(`\nUnreceived packet sequences: ${unreceived.join(', ') || 'none'}`); + + // Get unacknowledged packets + const unacked = await ibc.packets.getUnacknowledged('channel-0'); + console.log(`Unacknowledged packet sequences: ${unacked.join(', ') || 'none'}`); + + console.log(''); +} + +/** + * Relayer operations + */ +async function relayerExample(ibc: SynorIbc): Promise { + console.log('=== Relayer Operations ==='); + + // Get active relayers + const relayers = await ibc.relayers.list(); + console.log(`Active relayers: ${relayers.length}`); + for (const relayer of relayers.slice(0, 3)) { + console.log(`\n ${relayer.address}:`); + console.log(` Chains: ${relayer.chains.join(', ')}`); + console.log(` Packets relayed: ${relayer.packetsRelayed}`); + console.log(` Success rate: ${relayer.successRate}%`); + console.log(` Avg latency: ${relayer.avgLatency}ms`); + console.log(` Fee rate: ${relayer.feeRate}%`); + } + + // Get relayer statistics + const stats = await ibc.relayers.getStats(); + console.log('\nGlobal relayer statistics:'); + console.log(` Total relayers: ${stats.totalRelayers}`); + console.log(` Active relayers: ${stats.activeRelayers}`); + console.log(` Packets relayed (24h): ${stats.packetsRelayed24h}`); + console.log(` Total fees earned: ${stats.totalFeesEarned}`); + + // Register as a relayer + console.log('\nRegistering as relayer...'); + const registration = await ibc.relayers.register({ + chains: ['synor-1', 'cosmoshub-4'], + feeRate: 0.1, // 0.1% fee + minPacketSize: 0, + maxPacketSize: 1000000, + }); + console.log(`Registered with address: ${registration.relayerAddress}`); + + // Start relaying (in background) + console.log('\nStarting relay service...'); + const relaySession = await ibc.relayers.startRelay({ + channels: ['channel-0'], + autoAck: true, + batchSize: 10, + pollInterval: 5000, + }); + console.log(`Relay session started: ${relaySession.sessionId}`); + + // Get relay queue + const queue = await ibc.relayers.getQueue('channel-0'); + console.log(`\nRelay queue for channel-0: ${queue.length} packets`); + + // Manually relay a packet + if (queue.length > 0) { + console.log('\nRelaying packet...'); + const relayResult = await ibc.relayers.relayPacket(queue[0].sequence, 'channel-0'); + console.log(`Relay result: ${relayResult.status}`); + console.log(` TX Hash: ${relayResult.txHash}`); + console.log(` Fee earned: ${relayResult.feeEarned}`); + } + + // Stop relay session + await ibc.relayers.stopRelay(relaySession.sessionId); + console.log('\nRelay session stopped'); + + console.log(''); +} + +/** + * Connection information + */ +async function connectionExample(ibc: SynorIbc): Promise { + console.log('=== Connection Information ==='); + + // List connections + const connections = await ibc.connections.list(); + console.log(`Total connections: ${connections.length}`); + + for (const conn of connections.slice(0, 3)) { + console.log(`\n ${conn.connectionId}:`); + console.log(` Client: ${conn.clientId}`); + console.log(` Counterparty: ${conn.counterpartyConnectionId}`); + console.log(` State: ${conn.state}`); + console.log(` Versions: ${conn.versions.join(', ')}`); + } + + // Get connection details + const connection = await ibc.connections.get('connection-0'); + console.log(`\nConnection-0 details:`); + console.log(` Delay period: ${connection.delayPeriod}ns`); + console.log(` Counterparty client: ${connection.counterpartyClientId}`); + console.log(` Counterparty prefix: ${connection.counterpartyPrefix}`); + + // Get client state + const client = await ibc.clients.get(connection.clientId); + console.log(`\nClient state:`); + console.log(` Chain ID: ${client.chainId}`); + console.log(` Trust level: ${client.trustLevel}`); + console.log(` Trusting period: ${client.trustingPeriod}`); + console.log(` Unbonding period: ${client.unbondingPeriod}`); + console.log(` Latest height: ${client.latestHeight}`); + console.log(` Frozen: ${client.frozen}`); + + // Get consensus state + const consensus = await ibc.clients.getConsensusState(connection.clientId, client.latestHeight); + console.log(`\nConsensus state at height ${client.latestHeight}:`); + console.log(` Timestamp: ${new Date(consensus.timestamp).toISOString()}`); + console.log(` Root: ${consensus.root.slice(0, 20)}...`); + console.log(` Next validators hash: ${consensus.nextValidatorsHash.slice(0, 20)}...`); + + console.log(''); +} + +// Run examples +main().catch(console.error); diff --git a/sdk/js/examples/zk_example.ts b/sdk/js/examples/zk_example.ts new file mode 100644 index 0000000..4eb12b6 --- /dev/null +++ b/sdk/js/examples/zk_example.ts @@ -0,0 +1,537 @@ +/** + * Synor ZK SDK Examples for JavaScript/TypeScript + * + * Demonstrates Zero-Knowledge proof operations: + * - Circuit compilation + * - Proof generation and verification + * - Groth16, PLONK, and STARK proving systems + * - Recursive proofs + * - On-chain verification + */ + +import { + SynorZk, + ZkConfig, + ProvingSystem, + CircuitFormat, + ProofStatus, +} from '../src/zk'; + +async function main() { + // Initialize client + const config: ZkConfig = { + apiKey: process.env.SYNOR_API_KEY || 'your-api-key', + endpoint: 'https://zk.synor.io/v1', + timeout: 120000, // ZK ops can be slow + retries: 3, + debug: false, + defaultProvingSystem: ProvingSystem.Groth16, + }; + + const zk = new SynorZk(config); + + try { + // Check service health + const healthy = await zk.healthCheck(); + console.log(`Service healthy: ${healthy}\n`); + + // Example 1: Circuit compilation + await circuitExample(zk); + + // Example 2: Proof generation + await proofExample(zk); + + // Example 3: Different proving systems + await provingSystemsExample(zk); + + // Example 4: Recursive proofs + await recursiveProofExample(zk); + + // Example 5: On-chain verification + await onChainVerificationExample(zk); + + // Example 6: Trusted setup + await setupExample(zk); + } finally { + zk.close(); + } +} + +/** + * Circuit compilation + */ +async function circuitExample(zk: SynorZk): Promise { + console.log('=== Circuit Compilation ==='); + + // Circom circuit example: prove knowledge of preimage + const circomCircuit = ` + pragma circom 2.1.0; + + template HashPreimage() { + signal input preimage; + signal input hash; + + // Simplified hash computation (in reality, use proper hash) + signal preimageSquared; + preimageSquared <== preimage * preimage; + + // Constrain that hash matches + hash === preimageSquared; + } + + component main {public [hash]} = HashPreimage(); + `; + + // Compile circuit + console.log('Compiling Circom circuit...'); + const compiled = await zk.circuits.compile({ + code: circomCircuit, + format: CircuitFormat.Circom, + name: 'hash_preimage', + provingSystem: ProvingSystem.Groth16, + }); + + console.log(`Circuit compiled:`); + console.log(` Circuit ID: ${compiled.circuitId}`); + console.log(` Constraints: ${compiled.constraintCount}`); + console.log(` Public inputs: ${compiled.publicInputCount}`); + console.log(` Private inputs: ${compiled.privateInputCount}`); + console.log(` Proving key size: ${compiled.provingKeySize} bytes`); + console.log(` Verification key size: ${compiled.verificationKeySize} bytes`); + + // List circuits + const circuits = await zk.circuits.list(); + console.log(`\nYour circuits: ${circuits.length}`); + for (const circuit of circuits) { + console.log(` ${circuit.name} (${circuit.circuitId})`); + } + + // Get circuit details + const details = await zk.circuits.get(compiled.circuitId); + console.log(`\nCircuit details:`); + console.log(` Format: ${details.format}`); + console.log(` Proving system: ${details.provingSystem}`); + console.log(` Created: ${new Date(details.createdAt).toISOString()}`); + + // Download proving key + const provingKey = await zk.circuits.getProvingKey(compiled.circuitId); + console.log(`\nProving key downloaded: ${provingKey.length} bytes`); + + // Download verification key + const verificationKey = await zk.circuits.getVerificationKey(compiled.circuitId); + console.log(`Verification key downloaded: ${verificationKey.length} bytes`); + + console.log(''); +} + +/** + * Proof generation and verification + */ +async function proofExample(zk: SynorZk): Promise { + console.log('=== Proof Generation ==='); + + // First, compile a simple circuit + const circuit = ` + pragma circom 2.1.0; + + template Multiplier() { + signal input a; + signal input b; + signal output c; + + c <== a * b; + } + + component main {public [c]} = Multiplier(); + `; + + const compiled = await zk.circuits.compile({ + code: circuit, + format: CircuitFormat.Circom, + name: 'multiplier', + provingSystem: ProvingSystem.Groth16, + }); + + // Generate proof + console.log('Generating proof...'); + const startTime = Date.now(); + + const proof = await zk.proofs.generate({ + circuitId: compiled.circuitId, + inputs: { + a: '3', + b: '7', + }, + }); + + const proofTime = Date.now() - startTime; + console.log(`Proof generated in ${proofTime}ms`); + console.log(` Proof ID: ${proof.proofId}`); + console.log(` Proof size: ${proof.proof.length} bytes`); + console.log(` Public signals: ${proof.publicSignals}`); + + // Verify proof + console.log('\nVerifying proof...'); + const verifyStart = Date.now(); + + const isValid = await zk.proofs.verify({ + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: proof.publicSignals, + }); + + const verifyTime = Date.now() - verifyStart; + console.log(`Verification completed in ${verifyTime}ms`); + console.log(` Valid: ${isValid}`); + + // Verify with wrong public signals (should fail) + console.log('\nVerifying with wrong signals...'); + const invalidResult = await zk.proofs.verify({ + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: ['42'], // Wrong answer + }); + console.log(` Valid: ${invalidResult} (expected false)`); + + // Get proof status + const status = await zk.proofs.getStatus(proof.proofId); + console.log(`\nProof status:`); + console.log(` State: ${status.state}`); + console.log(` Verified: ${status.verified}`); + console.log(` Created: ${new Date(status.createdAt).toISOString()}`); + + // List proofs + const proofs = await zk.proofs.list({ circuitId: compiled.circuitId }); + console.log(`\nProofs for circuit: ${proofs.length}`); + + console.log(''); +} + +/** + * Different proving systems comparison + */ +async function provingSystemsExample(zk: SynorZk): Promise { + console.log('=== Proving Systems Comparison ==='); + + // Simple circuit for comparison + const circuit = ` + pragma circom 2.1.0; + + template Comparison() { + signal input x; + signal input y; + signal output sum; + + sum <== x + y; + } + + component main {public [sum]} = Comparison(); + `; + + const systems = [ + ProvingSystem.Groth16, + ProvingSystem.Plonk, + ProvingSystem.Stark, + ]; + + console.log('Comparing proving systems:\n'); + + for (const system of systems) { + console.log(`${system}:`); + + // Compile for this system + const compiled = await zk.circuits.compile({ + code: circuit, + format: CircuitFormat.Circom, + name: `comparison_${system.toLowerCase()}`, + provingSystem: system, + }); + + // Generate proof + const proofStart = Date.now(); + const proof = await zk.proofs.generate({ + circuitId: compiled.circuitId, + inputs: { x: '10', y: '20' }, + }); + const proofTime = Date.now() - proofStart; + + // Verify proof + const verifyStart = Date.now(); + await zk.proofs.verify({ + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: proof.publicSignals, + }); + const verifyTime = Date.now() - verifyStart; + + console.log(` Setup: ${compiled.setupTime}ms`); + console.log(` Proof time: ${proofTime}ms`); + console.log(` Verify time: ${verifyTime}ms`); + console.log(` Proof size: ${proof.proof.length} bytes`); + console.log(` Verification key: ${compiled.verificationKeySize} bytes`); + console.log(''); + } + + console.log('Summary:'); + console.log(' Groth16: Smallest proofs, fast verification, trusted setup required'); + console.log(' PLONK: Universal setup, flexible, moderate proof size'); + console.log(' STARK: No trusted setup, largest proofs, quantum resistant'); + + console.log(''); +} + +/** + * Recursive proof aggregation + */ +async function recursiveProofExample(zk: SynorZk): Promise { + console.log('=== Recursive Proofs ==='); + + // Inner circuit + const innerCircuit = ` + pragma circom 2.1.0; + + template Inner() { + signal input x; + signal output y; + y <== x * x; + } + + component main {public [y]} = Inner(); + `; + + // Compile inner circuit + const inner = await zk.circuits.compile({ + code: innerCircuit, + format: CircuitFormat.Circom, + name: 'inner_circuit', + provingSystem: ProvingSystem.Groth16, + }); + + // Generate multiple proofs to aggregate + console.log('Generating proofs to aggregate...'); + const proofsToAggregate = []; + for (let i = 1; i <= 4; i++) { + const proof = await zk.proofs.generate({ + circuitId: inner.circuitId, + inputs: { x: i.toString() }, + }); + proofsToAggregate.push({ + proof: proof.proof, + publicSignals: proof.publicSignals, + }); + console.log(` Proof ${i}: y = ${proof.publicSignals[0]}`); + } + + // Aggregate proofs recursively + console.log('\nAggregating proofs...'); + const aggregated = await zk.proofs.aggregate({ + circuitId: inner.circuitId, + proofs: proofsToAggregate, + aggregationType: 'recursive', + }); + + console.log(`Aggregated proof:`); + console.log(` Proof ID: ${aggregated.proofId}`); + console.log(` Aggregated count: ${aggregated.aggregatedCount}`); + console.log(` Proof size: ${aggregated.proof.length} bytes`); + console.log(` Size reduction: ${(1 - aggregated.proof.length / (proofsToAggregate.length * proofsToAggregate[0].proof.length)) * 100}%`); + + // Verify aggregated proof + const isValid = await zk.proofs.verifyAggregated({ + circuitId: inner.circuitId, + proof: aggregated.proof, + publicSignalsList: proofsToAggregate.map(p => p.publicSignals), + }); + console.log(`\nAggregated proof valid: ${isValid}`); + + // Batch verification (verify multiple proofs in one operation) + console.log('\nBatch verification...'); + const batchResult = await zk.proofs.batchVerify({ + circuitId: inner.circuitId, + proofs: proofsToAggregate, + }); + console.log(` All valid: ${batchResult.allValid}`); + console.log(` Results: ${batchResult.results.join(', ')}`); + + console.log(''); +} + +/** + * On-chain verification + */ +async function onChainVerificationExample(zk: SynorZk): Promise { + console.log('=== On-Chain Verification ==='); + + // Compile circuit + const circuit = ` + pragma circom 2.1.0; + + template VoteCommitment() { + signal input vote; // Private: actual vote + signal input nullifier; // Private: unique identifier + signal input commitment; // Public: commitment to verify + + // Simplified commitment (in practice, use Poseidon hash) + signal computed; + computed <== vote * nullifier; + commitment === computed; + } + + component main {public [commitment]} = VoteCommitment(); + `; + + const compiled = await zk.circuits.compile({ + code: circuit, + format: CircuitFormat.Circom, + name: 'vote_commitment', + provingSystem: ProvingSystem.Groth16, + }); + + // Generate Solidity verifier + console.log('Generating Solidity verifier...'); + const solidityVerifier = await zk.contracts.generateVerifier({ + circuitId: compiled.circuitId, + language: 'solidity', + optimized: true, + }); + console.log(`Solidity verifier generated: ${solidityVerifier.code.length} bytes`); + console.log(` Contract name: ${solidityVerifier.contractName}`); + console.log(` Gas estimate: ${solidityVerifier.gasEstimate}`); + + // Generate proof + const proof = await zk.proofs.generate({ + circuitId: compiled.circuitId, + inputs: { + vote: '1', // Vote YES (1) or NO (0) + nullifier: '12345', + commitment: '12345', // 1 * 12345 + }, + }); + + // Format proof for on-chain verification + console.log('\nFormatting proof for on-chain...'); + const onChainProof = await zk.contracts.formatProof({ + circuitId: compiled.circuitId, + proof: proof.proof, + publicSignals: proof.publicSignals, + format: 'calldata', + }); + console.log(` Calldata: ${onChainProof.calldata.slice(0, 100)}...`); + console.log(` Estimated gas: ${onChainProof.gasEstimate}`); + + // Deploy verifier contract (simulation) + console.log('\nDeploying verifier contract...'); + const deployment = await zk.contracts.deployVerifier({ + circuitId: compiled.circuitId, + network: 'synor-testnet', + }); + console.log(` Contract address: ${deployment.address}`); + console.log(` TX hash: ${deployment.txHash}`); + console.log(` Gas used: ${deployment.gasUsed}`); + + // Verify on-chain + console.log('\nVerifying on-chain...'); + const onChainResult = await zk.contracts.verifyOnChain({ + contractAddress: deployment.address, + proof: proof.proof, + publicSignals: proof.publicSignals, + network: 'synor-testnet', + }); + console.log(` TX hash: ${onChainResult.txHash}`); + console.log(` Verified: ${onChainResult.verified}`); + console.log(` Gas used: ${onChainResult.gasUsed}`); + + // Generate verifier for other targets + console.log('\nGenerating verifiers for other targets:'); + const targets = ['cairo', 'noir', 'ink']; + for (const target of targets) { + const verifier = await zk.contracts.generateVerifier({ + circuitId: compiled.circuitId, + language: target, + }); + console.log(` ${target}: ${verifier.code.length} bytes`); + } + + console.log(''); +} + +/** + * Trusted setup ceremonies + */ +async function setupExample(zk: SynorZk): Promise { + console.log('=== Trusted Setup ==='); + + // Get available ceremonies + const ceremonies = await zk.setup.listCeremonies(); + console.log(`Active ceremonies: ${ceremonies.length}`); + for (const ceremony of ceremonies) { + console.log(` ${ceremony.name}:`); + console.log(` Status: ${ceremony.status}`); + console.log(` Participants: ${ceremony.participantCount}`); + console.log(` Current round: ${ceremony.currentRound}`); + } + + // Create a new circuit setup + const circuit = ` + pragma circom 2.1.0; + + template NewCircuit() { + signal input a; + signal output b; + b <== a + 1; + } + + component main {public [b]} = NewCircuit(); + `; + + console.log('\nInitializing setup for new circuit...'); + const setup = await zk.setup.initialize({ + circuit, + format: CircuitFormat.Circom, + name: 'new_circuit_setup', + provingSystem: ProvingSystem.Groth16, + ceremonyType: 'powers_of_tau', // or 'phase2' + }); + console.log(`Setup initialized:`); + console.log(` Ceremony ID: ${setup.ceremonyId}`); + console.log(` Powers of Tau required: ${setup.powersRequired}`); + console.log(` Current phase: ${setup.phase}`); + + // Contribute to ceremony (in practice, generates random entropy) + console.log('\nContributing to ceremony...'); + const contribution = await zk.setup.contribute({ + ceremonyId: setup.ceremonyId, + entropy: Buffer.from('random-entropy-from-user').toString('hex'), + }); + console.log(`Contribution submitted:`); + console.log(` Participant: ${contribution.participantId}`); + console.log(` Contribution hash: ${contribution.hash}`); + console.log(` Verification status: ${contribution.verified}`); + + // Get ceremony status + const status = await zk.setup.getStatus(setup.ceremonyId); + console.log(`\nCeremony status:`); + console.log(` Phase: ${status.phase}`); + console.log(` Total contributions: ${status.totalContributions}`); + console.log(` Verified contributions: ${status.verifiedContributions}`); + console.log(` Ready for finalization: ${status.readyForFinalization}`); + + // Finalize setup (when enough contributions) + if (status.readyForFinalization) { + console.log('\nFinalizing setup...'); + const finalized = await zk.setup.finalize(setup.ceremonyId); + console.log(`Setup finalized:`); + console.log(` Proving key hash: ${finalized.provingKeyHash}`); + console.log(` Verification key hash: ${finalized.verificationKeyHash}`); + console.log(` Contribution transcript: ${finalized.transcriptCid}`); + } + + // Download ceremony transcript + const transcript = await zk.setup.getTranscript(setup.ceremonyId); + console.log(`\nCeremony transcript: ${transcript.length} bytes`); + + console.log(''); +} + +// Run examples +main().catch(console.error); diff --git a/sdk/python/examples/compiler_example.py b/sdk/python/examples/compiler_example.py new file mode 100644 index 0000000..6140711 --- /dev/null +++ b/sdk/python/examples/compiler_example.py @@ -0,0 +1,354 @@ +#!/usr/bin/env python3 +""" +Synor Compiler SDK Examples for Python + +Demonstrates smart contract compilation and analysis: +- WASM contract compilation and optimization +- ABI extraction and encoding +- Contract analysis and security scanning +- Validation and verification +""" + +import asyncio +import os +from synor_compiler import ( + SynorCompiler, + CompilerConfig, + OptimizationLevel, + StripOptions, +) + + +async def main(): + """Main entry point.""" + # Initialize client + config = CompilerConfig( + api_key=os.environ.get("SYNOR_API_KEY", "your-api-key"), + endpoint="https://compiler.synor.io/v1", + timeout=60000, + 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, + ) + + compiler = SynorCompiler(config) + + try: + # Check service health + healthy = await compiler.health_check() + print(f"Service healthy: {healthy}\n") + + # Example 1: Compile a contract + await compile_contract_example(compiler) + + # Example 2: Development vs Production + await compilation_modes_example(compiler) + + # Example 3: ABI operations + await abi_example(compiler) + + # Example 4: Contract analysis + await analysis_example(compiler) + + # Example 5: Validation + await validation_example(compiler) + + # Example 6: Security scanning + await security_example(compiler) + finally: + await compiler.close() + + +def create_minimal_wasm() -> bytes: + """Create a minimal valid WASM module for testing.""" + return bytes([ + 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, + ]) + + +async def compile_contract_example(compiler: SynorCompiler): + """Basic contract compilation.""" + print("=== Contract Compilation ===") + + wasm = create_minimal_wasm() + + result = await compiler.compile( + wasm, + optimization_level=OptimizationLevel.SIZE, + use_wasm_opt=True, + validate=True, + extract_metadata=True, + generate_abi=True, + strip_options=StripOptions( + strip_debug=True, + strip_producers=True, + strip_names=True, + strip_custom=True, + strip_unused=True, + preserve_sections=[], + ), + ) + + print("Compilation result:") + print(f" Contract ID: {result.contract_id}") + print(f" Code hash: {result.code_hash}") + print(f" Original size: {result.original_size} bytes") + print(f" Optimized size: {result.optimized_size} bytes") + print(f" Size reduction: {result.size_reduction:.1f}%") + print(f" Estimated deploy gas: {result.estimated_deploy_gas}") + + if result.metadata: + print("\nMetadata:") + print(f" Name: {result.metadata.name}") + print(f" Version: {result.metadata.version}") + print(f" SDK Version: {result.metadata.sdk_version}") + + if result.abi: + print("\nABI:") + print(f" Functions: {len(result.abi.functions or [])}") + print(f" Events: {len(result.abi.events or [])}") + print(f" Errors: {len(result.abi.errors or [])}") + + print() + + +async def compilation_modes_example(compiler: SynorCompiler): + """Development vs Production compilation modes.""" + print("=== Compilation Modes ===") + + wasm = create_minimal_wasm() + + # Development mode: fast compilation, debugging support + print("Development mode:") + dev_result = await compiler.contracts.compile_dev(wasm) + print(f" Size: {dev_result.optimized_size} bytes") + print(f" Optimization: none") + + # Production mode: maximum optimization + print("\nProduction mode:") + prod_result = await compiler.contracts.compile_production(wasm) + print(f" Size: {prod_result.optimized_size} bytes") + print(f" Optimization: aggressive") + print(f" Size savings: {dev_result.optimized_size - prod_result.optimized_size} bytes") + + # Custom optimization levels + print("\nOptimization levels:") + levels = [ + OptimizationLevel.NONE, + OptimizationLevel.BASIC, + OptimizationLevel.SIZE, + OptimizationLevel.AGGRESSIVE, + ] + + for level in levels: + result = await compiler.compile(wasm, optimization_level=level) + print(f" {level.value}: {result.optimized_size} bytes") + + print() + + +async def abi_example(compiler: SynorCompiler): + """ABI extraction and encoding.""" + print("=== ABI Operations ===") + + wasm = create_minimal_wasm() + + # Extract ABI from WASM + abi = await compiler.abi.extract(wasm) + print(f"Contract: {abi.name}") + print(f"Version: {abi.version}") + + # List functions + if abi.functions: + print("\nFunctions:") + for func in abi.functions: + inputs = ", ".join( + f"{i.name}: {i.type.type_name}" for i in (func.inputs or []) + ) + outputs = ", ".join(o.type.type_name for o in (func.outputs or [])) or "void" + modifiers = " ".join( + filter(None, ["view" if func.view else "", "payable" if func.payable else ""]) + ) + print(f" {func.name}({inputs}) -> {outputs} {modifiers}") + print(f" Selector: {func.selector}") + + # List events + if abi.events: + print("\nEvents:") + for event in abi.events: + params = ", ".join( + f"{'indexed ' if p.indexed else ''}{p.name}: {p.type.type_name}" + for p in (event.params or []) + ) + print(f" {event.name}({params})") + print(f" Topic: {event.topic}") + + # Encode a function call + if abi.functions: + func = abi.functions[0] + encoded = await compiler.abi.encode_call(func, ["arg1", "arg2"]) + print(f"\nEncoded call to {func.name}: {encoded}") + + # Decode a result + decoded = await compiler.abi.decode_result(func, encoded) + print(f"Decoded result: {decoded}") + + print() + + +async def analysis_example(compiler: SynorCompiler): + """Contract analysis.""" + print("=== Contract Analysis ===") + + wasm = create_minimal_wasm() + + # Full analysis + analysis = await compiler.analysis.analyze(wasm) + + # Size breakdown + if analysis.size_breakdown: + print("Size breakdown:") + print(f" Code: {analysis.size_breakdown.code} bytes") + print(f" Data: {analysis.size_breakdown.data} bytes") + print(f" Functions: {analysis.size_breakdown.functions} bytes") + print(f" Memory: {analysis.size_breakdown.memory} bytes") + print(f" Exports: {analysis.size_breakdown.exports} bytes") + print(f" Imports: {analysis.size_breakdown.imports} bytes") + print(f" Total: {analysis.size_breakdown.total} bytes") + + # Function analysis + if analysis.functions: + print("\nFunction analysis:") + for func in analysis.functions[:5]: + print(f" {func.name}:") + print(f" Size: {func.size} bytes") + print(f" Instructions: {func.instruction_count}") + print(f" Locals: {func.local_count}") + print(f" Exported: {func.exported}") + print(f" Estimated gas: {func.estimated_gas}") + + # Import analysis + if analysis.imports: + print("\nImports:") + for imp in analysis.imports: + print(f" {imp.module}.{imp.name} ({imp.kind})") + + # Gas analysis + if analysis.gas_analysis: + print("\nGas analysis:") + print(f" Deployment: {analysis.gas_analysis.deployment_gas}") + print(f" Memory init: {analysis.gas_analysis.memory_init_gas}") + print(f" Data section: {analysis.gas_analysis.data_section_gas}") + + # Extract metadata + metadata = await compiler.analysis.extract_metadata(wasm) + print("\nContract metadata:") + print(f" Name: {metadata.name}") + print(f" Version: {metadata.version}") + print(f" Build timestamp: {metadata.build_timestamp}") + + # Estimate deployment gas + gas = await compiler.analysis.estimate_deploy_gas(wasm) + print(f"\nEstimated deployment gas: {gas}") + + print() + + +async def validation_example(compiler: SynorCompiler): + """Contract validation.""" + print("=== Contract Validation ===") + + wasm = create_minimal_wasm() + + # Full validation + result = await compiler.validation.validate(wasm) + print(f"Valid: {result.valid}") + print(f"Exports: {result.export_count}") + print(f"Imports: {result.import_count}") + print(f"Functions: {result.function_count}") + print(f"Memory pages: {result.memory_pages}") + + if result.errors: + print("\nValidation errors:") + for error in result.errors: + print(f" [{error.code}] {error.message}") + if error.location: + print(f" at {error.location}") + + if result.warnings: + print("\nWarnings:") + for warning in result.warnings: + print(f" {warning}") + + # Quick validation + is_valid = await compiler.validation.is_valid(wasm) + print(f"\nQuick validation: {is_valid}") + + # Get validation errors only + errors = await compiler.validation.get_errors(wasm) + print(f"Error count: {len(errors)}") + + # Validate required exports + has_required = await compiler.validation.validate_exports( + wasm, ["init", "execute", "query"] + ) + print(f"Has required exports: {has_required}") + + # Validate memory constraints + memory_valid = await compiler.validation.validate_memory(wasm, 16) + print(f"Memory within 16 pages: {memory_valid}") + + print() + + +async def security_example(compiler: SynorCompiler): + """Security scanning.""" + print("=== Security Scanning ===") + + wasm = create_minimal_wasm() + + security = await compiler.analysis.security_scan(wasm) + + print(f"Security score: {security.score}/100") + + if security.issues: + print("\nSecurity issues:") + severity_icons = { + "critical": "🔴", + "high": "🟠", + "medium": "🟡", + "low": "🟢", + } + for issue in security.issues: + icon = severity_icons.get(issue.severity, "⚪") + print(f"{icon} [{issue.severity.upper()}] {issue.type}") + print(f" {issue.description}") + if issue.location: + print(f" at {issue.location}") + else: + print("No security issues found!") + + if security.recommendations: + print("\nRecommendations:") + for rec in security.recommendations: + print(f" • {rec}") + + print() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/python/examples/crypto_example.py b/sdk/python/examples/crypto_example.py new file mode 100644 index 0000000..50a6827 --- /dev/null +++ b/sdk/python/examples/crypto_example.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python3 +""" +Synor Crypto SDK Examples for Python + +Demonstrates quantum-resistant cryptographic operations including: +- Hybrid Ed25519 + Dilithium3 signatures +- BIP-39 mnemonic generation and validation +- Post-quantum algorithms (Falcon, SPHINCS+) +- Key derivation functions +""" + +import asyncio +import os +from synor_crypto import ( + SynorCrypto, + CryptoConfig, + Network, + FalconVariant, + SphincsVariant, + DerivationConfig, + PasswordDerivationConfig, + DerivationPath, +) + + +async def main(): + """Main entry point.""" + # Initialize client + config = CryptoConfig( + api_key=os.environ.get("SYNOR_API_KEY", "your-api-key"), + endpoint="https://crypto.synor.io/v1", + timeout=30000, + retries=3, + debug=False, + default_network=Network.MAINNET, + ) + + crypto = SynorCrypto(config) + + try: + # Check service health + healthy = await crypto.health_check() + print(f"Service healthy: {healthy}\n") + + # Example 1: Mnemonic operations + await mnemonic_example(crypto) + + # Example 2: Keypair generation + await keypair_example(crypto) + + # Example 3: Hybrid signing + await signing_example(crypto) + + # Example 4: Falcon post-quantum signatures + await falcon_example(crypto) + + # Example 5: SPHINCS+ post-quantum signatures + await sphincs_example(crypto) + + # Example 6: Key derivation + await kdf_example(crypto) + + # Example 7: Hashing + await hash_example(crypto) + finally: + await crypto.close() + + +async def mnemonic_example(crypto: SynorCrypto): + """Mnemonic generation and validation.""" + print("=== Mnemonic Operations ===") + + # Generate a 24-word mnemonic (256-bit entropy) + mnemonic = await crypto.mnemonic.generate(24) + print(f"Generated mnemonic: {mnemonic.phrase}") + print(f"Word count: {mnemonic.word_count}") + + # Validate a mnemonic + validation = await crypto.mnemonic.validate(mnemonic.phrase) + print(f"Valid: {validation.valid}") + if not validation.valid: + print(f"Error: {validation.error}") + + # Convert mnemonic to seed + seed = await crypto.mnemonic.to_seed(mnemonic.phrase, "optional-passphrase") + print(f"Seed (hex): {seed.hex()[:32]}...") + + # Word suggestions for autocomplete + suggestions = await crypto.mnemonic.suggest_words("aban", 5) + print(f"Suggestions for 'aban': {', '.join(suggestions)}") + + print() + + +async def keypair_example(crypto: SynorCrypto): + """Keypair generation and address derivation.""" + print("=== Keypair Operations ===") + + # Generate a random keypair + keypair = await crypto.keypairs.generate() + print("Generated hybrid keypair:") + print(f" Ed25519 public key size: {len(keypair.public_key.ed25519_bytes)} bytes") + print(f" Dilithium public key size: {len(keypair.public_key.dilithium_bytes)} bytes") + print(f" Total public key size: {keypair.public_key.size} bytes") + + # Get addresses for different networks + print("\nAddresses:") + print(f" Mainnet: {keypair.get_address(Network.MAINNET)}") + print(f" Testnet: {keypair.get_address(Network.TESTNET)}") + print(f" Devnet: {keypair.get_address(Network.DEVNET)}") + + # Create keypair from mnemonic (deterministic) + mnemonic = await crypto.mnemonic.generate(24) + keypair2 = await crypto.keypairs.from_mnemonic(mnemonic.phrase, "") + print(f"\nKeypair from mnemonic: {keypair2.get_address(Network.MAINNET)[:20]}...") + + # Derive child keypair using BIP-44 path + path = DerivationPath.external(0, 0) # m/44'/21337'/0'/0/0 + print(f"Derivation path: {path}") + + print() + + +async def signing_example(crypto: SynorCrypto): + """Hybrid signature operations (Ed25519 + Dilithium3).""" + print("=== Hybrid Signing ===") + + # Generate keypair + keypair = await crypto.keypairs.generate() + + # Sign a message + message = b"Hello, quantum-resistant world!" + signature = await crypto.signing.sign(keypair, message) + + print("Signature created:") + print(f" Ed25519 component: {len(signature.ed25519_bytes)} bytes") + print(f" Dilithium component: {len(signature.dilithium_bytes)} bytes") + print(f" Total signature size: {signature.size} bytes") + + # Verify the signature + valid = await crypto.signing.verify(keypair.public_key, message, signature) + print(f"\nVerification result: {valid}") + + # Verify with tampered message fails + tampered_message = b"Hello, tampered message!" + invalid_result = await crypto.signing.verify( + keypair.public_key, tampered_message, signature + ) + print(f"Tampered message verification: {invalid_result}") + + print() + + +async def falcon_example(crypto: SynorCrypto): + """Falcon post-quantum signature example.""" + print("=== Falcon Post-Quantum Signatures ===") + + # Generate Falcon-512 keypair (128-bit security) + falcon512 = await crypto.falcon.generate(FalconVariant.FALCON512) + print("Falcon-512 keypair:") + print(f" Public key: {len(falcon512.public_key.key_bytes)} bytes") + print(f" Security level: 128-bit") + + # Generate Falcon-1024 keypair (256-bit security) + falcon1024 = await crypto.falcon.generate(FalconVariant.FALCON1024) + print("\nFalcon-1024 keypair:") + print(f" Public key: {len(falcon1024.public_key.key_bytes)} bytes") + print(f" Security level: 256-bit") + + # Sign with Falcon-512 + message = b"Post-quantum secure message" + signature = await crypto.falcon.sign(falcon512, message) + print(f"\nFalcon-512 signature: {len(signature.signature_bytes)} bytes") + + # Verify + valid = await crypto.falcon.verify( + falcon512.public_key.key_bytes, message, signature + ) + print(f"Verification: {valid}") + + print() + + +async def sphincs_example(crypto: SynorCrypto): + """SPHINCS+ post-quantum signature example (hash-based).""" + print("=== SPHINCS+ Hash-Based Signatures ===") + + # SPHINCS+ variants with different security levels + variants = [ + (SphincsVariant.SHAKE128S, 128, 7856), + (SphincsVariant.SHAKE192S, 192, 16224), + (SphincsVariant.SHAKE256S, 256, 29792), + ] + + # Generate and demonstrate each variant + for variant, security, sig_size in variants: + keypair = await crypto.sphincs.generate(variant) + print(f"SPHINCS+ {variant.value}:") + print(f" Security level: {security}-bit") + print(f" Expected signature size: {sig_size} bytes") + + # Sign a message + message = b"Hash-based quantum security" + signature = await crypto.sphincs.sign(keypair, message) + print(f" Actual signature size: {len(signature.signature_bytes)} bytes") + + # Verify + valid = await crypto.sphincs.verify( + keypair.public_key.key_bytes, message, signature + ) + print(f" Verification: {valid}\n") + + +async def kdf_example(crypto: SynorCrypto): + """Key derivation functions.""" + print("=== Key Derivation Functions ===") + + # HKDF (HMAC-based Key Derivation Function) + seed = b"master-secret-key-material-here" + hkdf_config = DerivationConfig( + salt=b"application-salt", + info=b"encryption-key", + output_length=32, + ) + + derived_key = await crypto.kdf.derive_key(seed, hkdf_config) + print(f"HKDF derived key: {derived_key.hex()}") + + # PBKDF2 (Password-Based Key Derivation Function) + password = b"user-password" + pbkdf2_config = PasswordDerivationConfig( + salt=b"random-salt-value", + iterations=100000, + output_length=32, + ) + + password_key = await crypto.kdf.derive_from_password(password, pbkdf2_config) + print(f"PBKDF2 derived key: {password_key.hex()}") + + print() + + +async def hash_example(crypto: SynorCrypto): + """Cryptographic hash functions.""" + print("=== Hash Functions ===") + + data = b"Data to hash" + + # SHA3-256 (FIPS 202) + sha3 = await crypto.hash.sha3_256(data) + print(f"SHA3-256: {sha3.hex}") + + # BLAKE3 (fast, parallel) + blake3 = await crypto.hash.blake3(data) + print(f"BLAKE3: {blake3.hex}") + + # Keccak-256 (Ethereum compatible) + keccak = await crypto.hash.keccak256(data) + print(f"Keccak: {keccak.hex}") + + print() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/python/examples/dex_example.py b/sdk/python/examples/dex_example.py new file mode 100644 index 0000000..4e86a32 --- /dev/null +++ b/sdk/python/examples/dex_example.py @@ -0,0 +1,450 @@ +#!/usr/bin/env python3 +""" +Synor DEX SDK Examples for Python + +Demonstrates decentralized exchange operations: +- Spot trading (market/limit orders) +- Perpetual futures trading +- Liquidity provision +- Order management +- Real-time market data +""" + +import asyncio +import os +from synor_dex import ( + SynorDex, + DexConfig, + Network, + OrderSide, + OrderType, + TimeInForce, + PositionSide, + MarginType, +) + + +async def main(): + """Main entry point.""" + # Initialize client + config = DexConfig( + api_key=os.environ.get("SYNOR_API_KEY", "your-api-key"), + endpoint="https://dex.synor.io/v1", + ws_endpoint="wss://dex.synor.io/v1/ws", + timeout=30000, + retries=3, + debug=False, + default_network=Network.MAINNET, + ) + + dex = SynorDex(config) + + try: + # Check service health + healthy = await dex.health_check() + print(f"Service healthy: {healthy}\n") + + # Example 1: Market data + await market_data_example(dex) + + # Example 2: Spot trading + await spot_trading_example(dex) + + # Example 3: Perpetual futures + await perpetual_futures_example(dex) + + # Example 4: Liquidity provision + await liquidity_example(dex) + + # Example 5: Order management + await order_management_example(dex) + + # Example 6: Account information + await account_example(dex) + + # Example 7: Real-time streaming + await streaming_example(dex) + finally: + await dex.close() + + +async def market_data_example(dex: SynorDex): + """Market data and orderbook.""" + print("=== Market Data ===") + + # Get all trading pairs + pairs = await dex.markets.get_pairs() + print(f"Available trading pairs: {len(pairs)}") + for pair in pairs[:5]: + print(f" {pair.symbol}: {pair.base_asset}/{pair.quote_asset}") + + # Get ticker for a specific pair + ticker = await dex.markets.get_ticker("SYN-USDT") + print(f"\nSYN-USDT Ticker:") + print(f" Last price: ${ticker.last_price}") + print(f" 24h change: {ticker.price_change_percent}%") + print(f" 24h high: ${ticker.high_price}") + print(f" 24h low: ${ticker.low_price}") + print(f" 24h volume: {ticker.volume} SYN") + print(f" 24h quote volume: ${ticker.quote_volume}") + + # Get orderbook + orderbook = await dex.markets.get_orderbook("SYN-USDT", depth=10) + print(f"\nOrderbook (top 5):") + print(" Bids:") + for bid in orderbook.bids[:5]: + print(f" ${bid.price} - {bid.quantity} SYN") + print(" Asks:") + for ask in orderbook.asks[:5]: + print(f" ${ask.price} - {ask.quantity} SYN") + + # Get recent trades + trades = await dex.markets.get_trades("SYN-USDT", limit=5) + print(f"\nRecent trades:") + for trade in trades: + side = "SELL" if trade.is_buyer_maker else "BUY" + print(f" {side} {trade.quantity} @ ${trade.price}") + + # Get OHLCV candles + candles = await dex.markets.get_candles("SYN-USDT", interval="1h", limit=5) + print(f"\nHourly candles:") + for candle in candles: + print(f" {candle.open_time}: O={candle.open} H={candle.high} L={candle.low} C={candle.close}") + + print() + + +async def spot_trading_example(dex: SynorDex): + """Spot trading operations.""" + print("=== Spot Trading ===") + + # Place a market buy order + print("Placing market buy order...") + market_buy = await dex.spot.create_order( + symbol="SYN-USDT", + side=OrderSide.BUY, + order_type=OrderType.MARKET, + quantity=10, # Buy 10 SYN + ) + print(f"Market buy order: {market_buy.order_id}") + print(f" Status: {market_buy.status}") + print(f" Filled: {market_buy.executed_qty} SYN") + print(f" Avg price: ${market_buy.avg_price}") + + # Place a limit sell order + print("\nPlacing limit sell order...") + limit_sell = await dex.spot.create_order( + symbol="SYN-USDT", + side=OrderSide.SELL, + order_type=OrderType.LIMIT, + quantity=5, + price=15.50, # Sell at $15.50 + time_in_force=TimeInForce.GTC, # Good till cancelled + ) + print(f"Limit sell order: {limit_sell.order_id}") + print(f" Price: ${limit_sell.price}") + print(f" Status: {limit_sell.status}") + + # Place a stop-loss order + print("\nPlacing stop-loss order...") + stop_loss = await dex.spot.create_order( + symbol="SYN-USDT", + side=OrderSide.SELL, + order_type=OrderType.STOP_LOSS, + quantity=10, + stop_price=12.00, # Trigger at $12.00 + ) + print(f"Stop-loss order: {stop_loss.order_id}") + print(f" Stop price: ${stop_loss.stop_price}") + + # Place a take-profit limit order + print("\nPlacing take-profit order...") + take_profit = await dex.spot.create_order( + symbol="SYN-USDT", + side=OrderSide.SELL, + order_type=OrderType.TAKE_PROFIT_LIMIT, + quantity=10, + price=20.00, # Sell at $20.00 + stop_price=19.50, # Trigger at $19.50 + time_in_force=TimeInForce.GTC, + ) + print(f"Take-profit order: {take_profit.order_id}") + + print() + + +async def perpetual_futures_example(dex: SynorDex): + """Perpetual futures trading.""" + print("=== Perpetual Futures ===") + + # Get perpetual markets + markets = await dex.perpetuals.get_markets() + print(f"Available perpetual markets: {len(markets)}") + for market in markets[:3]: + print(f" {market.symbol}: {market.max_leverage}x max leverage, {market.maintenance_margin_rate}% MMR") + + # Get funding rate + funding = await dex.perpetuals.get_funding_rate("SYN-USDT-PERP") + print(f"\nFunding rate for SYN-USDT-PERP:") + print(f" Current rate: {funding.funding_rate * 100:.4f}%") + print(f" Predicted rate: {funding.predicted_rate * 100:.4f}%") + print(f" Next funding: {funding.next_funding_time}") + + # Set leverage + await dex.perpetuals.set_leverage("SYN-USDT-PERP", 10) + print("\nLeverage set to 10x") + + # Set margin type (isolated/cross) + await dex.perpetuals.set_margin_type("SYN-USDT-PERP", MarginType.ISOLATED) + print("Margin type set to Isolated") + + # Open a long position + print("\nOpening long position...") + long_order = await dex.perpetuals.create_order( + symbol="SYN-USDT-PERP", + side=OrderSide.BUY, + position_side=PositionSide.LONG, + order_type=OrderType.MARKET, + quantity=100, # 100 contracts + ) + print(f"Long position opened: {long_order.order_id}") + print(f" Entry price: ${long_order.avg_price}") + print(f" Position size: {long_order.executed_qty} contracts") + + # Set stop-loss and take-profit + print("\nSetting SL/TP...") + await dex.perpetuals.create_order( + symbol="SYN-USDT-PERP", + side=OrderSide.SELL, + position_side=PositionSide.LONG, + order_type=OrderType.STOP_MARKET, + quantity=100, + stop_price=12.00, # Stop-loss at $12 + reduce_only=True, + ) + print(" Stop-loss set at $12.00") + + await dex.perpetuals.create_order( + symbol="SYN-USDT-PERP", + side=OrderSide.SELL, + position_side=PositionSide.LONG, + order_type=OrderType.TAKE_PROFIT_MARKET, + quantity=100, + stop_price=18.00, # Take-profit at $18 + reduce_only=True, + ) + print(" Take-profit set at $18.00") + + # Get position info + positions = await dex.perpetuals.get_positions("SYN-USDT-PERP") + for pos in positions: + print(f"\nPosition info:") + print(f" Symbol: {pos.symbol}") + print(f" Side: {pos.position_side}") + print(f" Size: {pos.position_amount} contracts") + print(f" Entry: ${pos.entry_price}") + print(f" Mark: ${pos.mark_price}") + print(f" PnL: ${pos.unrealized_pnl} ({pos.unrealized_pnl_percent}%)") + print(f" Leverage: {pos.leverage}x") + print(f" Liq. price: ${pos.liquidation_price}") + + # Close position + print("\nClosing position...") + await dex.perpetuals.close_position("SYN-USDT-PERP", PositionSide.LONG) + print("Position closed") + + print() + + +async def liquidity_example(dex: SynorDex): + """Liquidity provision.""" + print("=== Liquidity Provision ===") + + # Get available pools + pools = await dex.liquidity.get_pools() + print(f"Available liquidity pools: {len(pools)}") + for pool in pools[:3]: + print(f" {pool.name}:") + print(f" TVL: ${pool.tvl:,.0f}") + print(f" APY: {pool.apy:.2f}%") + print(f" Fee tier: {pool.fee_tier}%") + + # Get pool details + pool = await dex.liquidity.get_pool("SYN-USDT") + print(f"\nSYN-USDT Pool details:") + print(f" Reserve A: {pool.reserve_a} SYN") + print(f" Reserve B: {pool.reserve_b} USDT") + print(f" Total shares: {pool.total_shares}") + print(f" Your shares: {pool.user_shares}") + + # Add liquidity + print("\nAdding liquidity...") + add_result = await dex.liquidity.add_liquidity( + pool_id="SYN-USDT", + amount_a=100, # 100 SYN + amount_b=1400, # 1400 USDT + slippage_tolerance=0.5, # 0.5% slippage + ) + print(f"Liquidity added:") + print(f" Shares received: {add_result.shares_received}") + print(f" Amount A deposited: {add_result.amount_a_deposited}") + print(f" Amount B deposited: {add_result.amount_b_deposited}") + + # Get LP positions + lp_positions = await dex.liquidity.get_positions() + print(f"\nYour LP positions:") + for lp in lp_positions: + print(f" {lp.pool_id}: {lp.shares} shares (${lp.value_usd})") + print(f" Fees earned: ${lp.fees_earned}") + + # Remove liquidity + print("\nRemoving liquidity...") + remove_result = await dex.liquidity.remove_liquidity( + pool_id="SYN-USDT", + shares=add_result.shares_received * 0.5, # Remove 50% + slippage_tolerance=0.5, + ) + print(f"Liquidity removed:") + print(f" Amount A received: {remove_result.amount_a_received}") + print(f" Amount B received: {remove_result.amount_b_received}") + + print() + + +async def order_management_example(dex: SynorDex): + """Order management.""" + print("=== Order Management ===") + + # Get open orders + open_orders = await dex.orders.get_open_orders("SYN-USDT") + print(f"Open orders: {len(open_orders)}") + for order in open_orders: + print(f" {order.order_id}: {order.side} {order.quantity} @ ${order.price}") + + # Get order history + history = await dex.orders.get_order_history(symbol="SYN-USDT", limit=5) + print(f"\nOrder history (last 5):") + for order in history: + print(f" {order.order_id}: {order.side} {order.quantity} {order.status}") + + # Get specific order + if open_orders: + order = await dex.orders.get_order(open_orders[0].order_id) + print(f"\nOrder details:") + print(f" Symbol: {order.symbol}") + print(f" Type: {order.order_type}") + print(f" Side: {order.side}") + print(f" Quantity: {order.quantity}") + print(f" Filled: {order.executed_qty}") + print(f" Status: {order.status}") + + # Cancel a specific order + if open_orders: + print("\nCancelling order...") + cancelled = await dex.orders.cancel_order(open_orders[0].order_id) + print(f"Order {cancelled.order_id} cancelled") + + # Cancel all orders for a symbol + print("\nCancelling all SYN-USDT orders...") + cancelled_orders = await dex.orders.cancel_all_orders("SYN-USDT") + print(f"Cancelled {len(cancelled_orders)} orders") + + # Get trade history + trades = await dex.orders.get_trade_history(symbol="SYN-USDT", limit=5) + print(f"\nTrade history (last 5):") + for trade in trades: + print(f" {trade.side} {trade.quantity} @ ${trade.price} (fee: ${trade.fee})") + + print() + + +async def account_example(dex: SynorDex): + """Account information.""" + print("=== Account Information ===") + + # Get account balances + balances = await dex.account.get_balances() + print("Balances:") + for balance in balances: + if float(balance.total) > 0: + print(f" {balance.asset}: {balance.free} free, {balance.locked} locked") + + # Get account summary + summary = await dex.account.get_summary() + print(f"\nAccount summary:") + print(f" Total equity: ${summary.total_equity}") + print(f" Available margin: ${summary.available_margin}") + print(f" Used margin: ${summary.used_margin}") + print(f" Margin level: {summary.margin_level}%") + print(f" Unrealized PnL: ${summary.unrealized_pnl}") + + # Get deposit address + deposit_addr = await dex.account.get_deposit_address("SYN") + print(f"\nDeposit address for SYN: {deposit_addr.address}") + + # Get deposit/withdrawal history + deposits = await dex.account.get_deposit_history(limit=3) + print(f"\nRecent deposits:") + for dep in deposits: + print(f" {dep.asset}: {dep.amount} ({dep.status})") + + withdrawals = await dex.account.get_withdrawal_history(limit=3) + print(f"\nRecent withdrawals:") + for wd in withdrawals: + print(f" {wd.asset}: {wd.amount} ({wd.status})") + + # Get fee rates + fees = await dex.account.get_fee_rates("SYN-USDT") + print(f"\nFee rates for SYN-USDT:") + print(f" Maker: {fees.maker_rate}%") + print(f" Taker: {fees.taker_rate}%") + + print() + + +async def streaming_example(dex: SynorDex): + """Real-time WebSocket streaming.""" + print("=== Real-time Streaming ===") + + received_count = 0 + + def on_ticker(ticker): + nonlocal received_count + received_count += 1 + print(f" Ticker: ${ticker.last_price} ({ticker.price_change_percent}%)") + + def on_orderbook(orderbook): + print(f" Best bid: ${orderbook.bids[0].price if orderbook.bids else 'N/A'}, " + f"Best ask: ${orderbook.asks[0].price if orderbook.asks else 'N/A'}") + + def on_trade(trade): + side = "SELL" if trade.is_buyer_maker else "BUY" + print(f" Trade: {side} {trade.quantity} @ ${trade.price}") + + # Subscribe to ticker updates + print("Subscribing to SYN-USDT ticker...") + ticker_unsub = await dex.streams.subscribe_ticker("SYN-USDT", on_ticker) + + # Subscribe to orderbook updates + print("Subscribing to orderbook...") + orderbook_unsub = await dex.streams.subscribe_orderbook("SYN-USDT", on_orderbook) + + # Subscribe to trades + print("Subscribing to trades...") + trades_unsub = await dex.streams.subscribe_trades("SYN-USDT", on_trade) + + # Wait for some updates + print("\nListening for 5 seconds...") + await asyncio.sleep(5) + + # Unsubscribe + await ticker_unsub() + await orderbook_unsub() + await trades_unsub() + print(f"Unsubscribed from all streams. Received {received_count} ticker updates.") + + print() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/python/examples/ibc_example.py b/sdk/python/examples/ibc_example.py new file mode 100644 index 0000000..b40b45a --- /dev/null +++ b/sdk/python/examples/ibc_example.py @@ -0,0 +1,358 @@ +#!/usr/bin/env python3 +""" +Synor IBC SDK Examples for Python + +Demonstrates Inter-Blockchain Communication operations: +- Cross-chain token transfers +- Channel management +- Packet handling +- Relayer operations +""" + +import asyncio +import os +from datetime import datetime +from synor_ibc import ( + SynorIbc, + IbcConfig, + Network, + ChannelState, +) + + +async def main(): + """Main entry point.""" + # Initialize client + config = IbcConfig( + api_key=os.environ.get("SYNOR_API_KEY", "your-api-key"), + endpoint="https://ibc.synor.io/v1", + timeout=30000, + retries=3, + debug=False, + default_network=Network.MAINNET, + ) + + ibc = SynorIbc(config) + + try: + # Check service health + healthy = await ibc.health_check() + print(f"Service healthy: {healthy}\n") + + # Example 1: Connected chains + await chains_example(ibc) + + # Example 2: Channel management + await channels_example(ibc) + + # Example 3: Token transfers + await transfer_example(ibc) + + # Example 4: Packet tracking + await packet_example(ibc) + + # Example 5: Relayer operations + await relayer_example(ibc) + + # Example 6: Connection info + await connection_example(ibc) + finally: + await ibc.close() + + +async def chains_example(ibc: SynorIbc): + """Connected chains information.""" + print("=== Connected Chains ===") + + # Get all connected chains + chains = await ibc.chains.list() + print(f"Connected chains: {len(chains)}") + for chain in chains: + print(f" {chain.chain_id}:") + print(f" Name: {chain.name}") + print(f" Status: {chain.status}") + print(f" Block height: {chain.latest_height}") + print(f" Channels: {chain.channel_count}") + + # Get specific chain info + cosmos = await ibc.chains.get("cosmoshub-4") + print(f"\nCosmos Hub details:") + print(f" RPC: {cosmos.rpc_endpoint}") + print(f" Rest: {cosmos.rest_endpoint}") + print(f" Native denom: {cosmos.native_denom}") + print(f" Prefix: {cosmos.bech32_prefix}") + + # Get supported assets on a chain + assets = await ibc.chains.get_assets("cosmoshub-4") + print(f"\nSupported assets on Cosmos Hub:") + for asset in assets[:5]: + print(f" {asset.symbol}: {asset.denom}") + print(f" Origin: {asset.origin_chain}") + print(f" Decimals: {asset.decimals}") + + # Get chain paths (routes) + paths = await ibc.chains.get_paths("synor-1", "cosmoshub-4") + print(f"\nPaths from Synor to Cosmos Hub:") + for path in paths: + print(f" {path.source_channel} -> {path.dest_channel}") + print(f" Hops: {path.hops}") + print(f" Avg time: {path.avg_transfer_time}s") + + print() + + +async def channels_example(ibc: SynorIbc): + """Channel management.""" + print("=== Channel Management ===") + + # List all channels + channels = await ibc.channels.list() + print(f"Total channels: {len(channels)}") + + # Filter by state + open_channels = [c for c in channels if c.state == ChannelState.OPEN] + print(f"Open channels: {len(open_channels)}") + + for channel in open_channels[:3]: + print(f"\n Channel {channel.channel_id}:") + print(f" Port: {channel.port_id}") + print(f" Counterparty: {channel.counterparty_channel_id} on {channel.counterparty_chain_id}") + print(f" Ordering: {channel.ordering}") + print(f" Version: {channel.version}") + print(f" State: {channel.state}") + + # Get specific channel + channel = await ibc.channels.get("channel-0") + print(f"\nChannel-0 details:") + print(f" Connection: {channel.connection_id}") + print(f" Counterparty port: {channel.counterparty_port_id}") + + # Get channel statistics + stats = await ibc.channels.get_stats("channel-0") + print(f"\nChannel-0 statistics:") + print(f" Total packets sent: {stats.packets_sent}") + print(f" Total packets received: {stats.packets_received}") + print(f" Pending packets: {stats.pending_packets}") + print(f" Success rate: {stats.success_rate}%") + print(f" Avg relay time: {stats.avg_relay_time}s") + + # Get channel capacity + capacity = await ibc.channels.get_capacity("channel-0") + print(f"\nChannel-0 capacity:") + print(f" Max throughput: {capacity.max_packets_per_block} packets/block") + print(f" Current utilization: {capacity.utilization}%") + + print() + + +async def transfer_example(ibc: SynorIbc): + """Cross-chain token transfers.""" + print("=== Cross-Chain Transfers ===") + + # Estimate transfer fee + estimate = await ibc.transfers.estimate_fee( + source_chain="synor-1", + dest_chain="cosmoshub-4", + denom="usyn", + amount="1000000", # 1 SYN (6 decimals) + ) + print("Transfer fee estimate:") + print(f" Gas: {estimate.gas}") + print(f" Fee: {estimate.fee} {estimate.fee_denom}") + print(f" Timeout: {estimate.timeout}s") + + # Initiate a transfer + print("\nInitiating transfer...") + transfer = await ibc.transfers.send( + source_chain="synor-1", + dest_chain="cosmoshub-4", + channel="channel-0", + sender="synor1abc...", # Your address + receiver="cosmos1xyz...", # Recipient address + denom="usyn", + amount="1000000", # 1 SYN + memo="Cross-chain transfer example", + timeout_height=0, # Use timestamp instead + timeout_timestamp=int(datetime.now().timestamp() * 1000) + 600000, # 10 minutes + ) + + print(f"Transfer initiated:") + print(f" TX Hash: {transfer.tx_hash}") + print(f" Sequence: {transfer.sequence}") + print(f" Status: {transfer.status}") + + # Track transfer status + print("\nTracking transfer...") + status = await ibc.transfers.get_status(transfer.tx_hash) + print(f"Current status: {status.state}") + print(f" Source confirmed: {status.source_confirmed}") + print(f" Relayed: {status.relayed}") + print(f" Dest confirmed: {status.dest_confirmed}") + + # Get transfer history + history = await ibc.transfers.get_history(address="synor1abc...", limit=5) + print(f"\nTransfer history (last 5):") + for tx in history: + direction = "OUT" if tx.sender == "synor1abc..." else "IN" + print(f" {direction} {tx.amount} {tx.denom} ({tx.status})") + + # Get pending transfers + pending = await ibc.transfers.get_pending("synor1abc...") + print(f"\nPending transfers: {len(pending)}") + + print() + + +async def packet_example(ibc: SynorIbc): + """Packet handling.""" + print("=== Packet Handling ===") + + # Get pending packets + packets = await ibc.packets.get_pending("channel-0") + print(f"Pending packets on channel-0: {len(packets)}") + + for packet in packets[:3]: + print(f"\n Packet {packet.sequence}:") + print(f" Source: {packet.source_port}/{packet.source_channel}") + print(f" Dest: {packet.dest_port}/{packet.dest_channel}") + print(f" State: {packet.state}") + print(f" Data size: {len(packet.data)} bytes") + print(f" Timeout height: {packet.timeout_height}") + print(f" Timeout timestamp: {packet.timeout_timestamp}") + + # Get packet by sequence + packet = await ibc.packets.get("channel-0", 1) + print(f"\nPacket details:") + print(f" Commitment: {packet.commitment}") + print(f" Receipt: {packet.receipt}") + print(f" Acknowledgement: {packet.acknowledgement}") + + # Get packet receipts + receipts = await ibc.packets.get_receipts("channel-0", [1, 2, 3]) + print(f"\nPacket receipts:") + for seq, receipt in receipts.items(): + print(f" Sequence {seq}: {'received' if receipt else 'not received'}") + + # Get timed out packets + timed_out = await ibc.packets.get_timed_out("channel-0") + print(f"\nTimed out packets: {len(timed_out)}") + for p in timed_out: + print(f" Sequence {p.sequence}: timeout at {p.timeout_timestamp}") + + # Get unreceived packets + unreceived = await ibc.packets.get_unreceived("channel-0") + print(f"\nUnreceived packet sequences: {', '.join(map(str, unreceived)) or 'none'}") + + # Get unacknowledged packets + unacked = await ibc.packets.get_unacknowledged("channel-0") + print(f"Unacknowledged packet sequences: {', '.join(map(str, unacked)) or 'none'}") + + print() + + +async def relayer_example(ibc: SynorIbc): + """Relayer operations.""" + print("=== Relayer Operations ===") + + # Get active relayers + relayers = await ibc.relayers.list() + print(f"Active relayers: {len(relayers)}") + for relayer in relayers[:3]: + print(f"\n {relayer.address}:") + print(f" Chains: {', '.join(relayer.chains)}") + print(f" Packets relayed: {relayer.packets_relayed}") + print(f" Success rate: {relayer.success_rate}%") + print(f" Avg latency: {relayer.avg_latency}ms") + print(f" Fee rate: {relayer.fee_rate}%") + + # Get relayer statistics + stats = await ibc.relayers.get_stats() + print("\nGlobal relayer statistics:") + print(f" Total relayers: {stats.total_relayers}") + print(f" Active relayers: {stats.active_relayers}") + print(f" Packets relayed (24h): {stats.packets_relayed_24h}") + print(f" Total fees earned: {stats.total_fees_earned}") + + # Register as a relayer + print("\nRegistering as relayer...") + registration = await ibc.relayers.register( + chains=["synor-1", "cosmoshub-4"], + fee_rate=0.1, # 0.1% fee + min_packet_size=0, + max_packet_size=1000000, + ) + print(f"Registered with address: {registration.relayer_address}") + + # Start relaying (in background) + print("\nStarting relay service...") + relay_session = await ibc.relayers.start_relay( + channels=["channel-0"], + auto_ack=True, + batch_size=10, + poll_interval=5000, + ) + print(f"Relay session started: {relay_session.session_id}") + + # Get relay queue + queue = await ibc.relayers.get_queue("channel-0") + print(f"\nRelay queue for channel-0: {len(queue)} packets") + + # Manually relay a packet + if queue: + print("\nRelaying packet...") + relay_result = await ibc.relayers.relay_packet(queue[0].sequence, "channel-0") + print(f"Relay result: {relay_result.status}") + print(f" TX Hash: {relay_result.tx_hash}") + print(f" Fee earned: {relay_result.fee_earned}") + + # Stop relay session + await ibc.relayers.stop_relay(relay_session.session_id) + print("\nRelay session stopped") + + print() + + +async def connection_example(ibc: SynorIbc): + """Connection information.""" + print("=== Connection Information ===") + + # List connections + connections = await ibc.connections.list() + print(f"Total connections: {len(connections)}") + + for conn in connections[:3]: + print(f"\n {conn.connection_id}:") + print(f" Client: {conn.client_id}") + print(f" Counterparty: {conn.counterparty_connection_id}") + print(f" State: {conn.state}") + print(f" Versions: {', '.join(conn.versions)}") + + # Get connection details + connection = await ibc.connections.get("connection-0") + print(f"\nConnection-0 details:") + print(f" Delay period: {connection.delay_period}ns") + print(f" Counterparty client: {connection.counterparty_client_id}") + print(f" Counterparty prefix: {connection.counterparty_prefix}") + + # Get client state + client = await ibc.clients.get(connection.client_id) + print(f"\nClient state:") + print(f" Chain ID: {client.chain_id}") + print(f" Trust level: {client.trust_level}") + print(f" Trusting period: {client.trusting_period}") + print(f" Unbonding period: {client.unbonding_period}") + print(f" Latest height: {client.latest_height}") + print(f" Frozen: {client.frozen}") + + # Get consensus state + consensus = await ibc.clients.get_consensus_state(connection.client_id, client.latest_height) + print(f"\nConsensus state at height {client.latest_height}:") + print(f" Timestamp: {consensus.timestamp}") + print(f" Root: {consensus.root[:20]}...") + print(f" Next validators hash: {consensus.next_validators_hash[:20]}...") + + print() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/python/examples/zk_example.py b/sdk/python/examples/zk_example.py new file mode 100644 index 0000000..1ee0d88 --- /dev/null +++ b/sdk/python/examples/zk_example.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python3 +""" +Synor ZK SDK Examples for Python + +Demonstrates Zero-Knowledge proof operations: +- Circuit compilation +- Proof generation and verification +- Groth16, PLONK, and STARK proving systems +- Recursive proofs +- On-chain verification +""" + +import asyncio +import os +import time +from synor_zk import ( + SynorZk, + ZkConfig, + ProvingSystem, + CircuitFormat, +) + + +async def main(): + """Main entry point.""" + # Initialize client + config = ZkConfig( + api_key=os.environ.get("SYNOR_API_KEY", "your-api-key"), + endpoint="https://zk.synor.io/v1", + timeout=120000, # ZK ops can be slow + retries=3, + debug=False, + default_proving_system=ProvingSystem.GROTH16, + ) + + zk = SynorZk(config) + + try: + # Check service health + healthy = await zk.health_check() + print(f"Service healthy: {healthy}\n") + + # Example 1: Circuit compilation + await circuit_example(zk) + + # Example 2: Proof generation + await proof_example(zk) + + # Example 3: Different proving systems + await proving_systems_example(zk) + + # Example 4: Recursive proofs + await recursive_proof_example(zk) + + # Example 5: On-chain verification + await on_chain_verification_example(zk) + + # Example 6: Trusted setup + await setup_example(zk) + finally: + await zk.close() + + +async def circuit_example(zk: SynorZk): + """Circuit compilation.""" + print("=== Circuit Compilation ===") + + # Circom circuit example: prove knowledge of preimage + circom_circuit = """ + pragma circom 2.1.0; + + template HashPreimage() { + signal input preimage; + signal input hash; + + // Simplified hash computation (in reality, use proper hash) + signal preimageSquared; + preimageSquared <== preimage * preimage; + + // Constrain that hash matches + hash === preimageSquared; + } + + component main {public [hash]} = HashPreimage(); + """ + + # Compile circuit + print("Compiling Circom circuit...") + compiled = await zk.circuits.compile( + code=circom_circuit, + format=CircuitFormat.CIRCOM, + name="hash_preimage", + proving_system=ProvingSystem.GROTH16, + ) + + print(f"Circuit compiled:") + print(f" Circuit ID: {compiled.circuit_id}") + print(f" Constraints: {compiled.constraint_count}") + print(f" Public inputs: {compiled.public_input_count}") + print(f" Private inputs: {compiled.private_input_count}") + print(f" Proving key size: {compiled.proving_key_size} bytes") + print(f" Verification key size: {compiled.verification_key_size} bytes") + + # List circuits + circuits = await zk.circuits.list() + print(f"\nYour circuits: {len(circuits)}") + for circuit in circuits: + print(f" {circuit.name} ({circuit.circuit_id})") + + # Get circuit details + details = await zk.circuits.get(compiled.circuit_id) + print(f"\nCircuit details:") + print(f" Format: {details.format}") + print(f" Proving system: {details.proving_system}") + print(f" Created: {details.created_at}") + + # Download proving key + proving_key = await zk.circuits.get_proving_key(compiled.circuit_id) + print(f"\nProving key downloaded: {len(proving_key)} bytes") + + # Download verification key + verification_key = await zk.circuits.get_verification_key(compiled.circuit_id) + print(f"Verification key downloaded: {len(verification_key)} bytes") + + print() + + +async def proof_example(zk: SynorZk): + """Proof generation and verification.""" + print("=== Proof Generation ===") + + # First, compile a simple circuit + circuit = """ + pragma circom 2.1.0; + + template Multiplier() { + signal input a; + signal input b; + signal output c; + + c <== a * b; + } + + component main {public [c]} = Multiplier(); + """ + + compiled = await zk.circuits.compile( + code=circuit, + format=CircuitFormat.CIRCOM, + name="multiplier", + proving_system=ProvingSystem.GROTH16, + ) + + # Generate proof + print("Generating proof...") + start_time = time.time() + + proof = await zk.proofs.generate( + circuit_id=compiled.circuit_id, + inputs={"a": "3", "b": "7"}, + ) + + proof_time = (time.time() - start_time) * 1000 + print(f"Proof generated in {proof_time:.0f}ms") + print(f" Proof ID: {proof.proof_id}") + print(f" Proof size: {len(proof.proof)} bytes") + print(f" Public signals: {proof.public_signals}") + + # Verify proof + print("\nVerifying proof...") + verify_start = time.time() + + is_valid = await zk.proofs.verify( + circuit_id=compiled.circuit_id, + proof=proof.proof, + public_signals=proof.public_signals, + ) + + verify_time = (time.time() - verify_start) * 1000 + print(f"Verification completed in {verify_time:.0f}ms") + print(f" Valid: {is_valid}") + + # Verify with wrong public signals (should fail) + print("\nVerifying with wrong signals...") + invalid_result = await zk.proofs.verify( + circuit_id=compiled.circuit_id, + proof=proof.proof, + public_signals=["42"], # Wrong answer + ) + print(f" Valid: {invalid_result} (expected False)") + + # Get proof status + status = await zk.proofs.get_status(proof.proof_id) + print(f"\nProof status:") + print(f" State: {status.state}") + print(f" Verified: {status.verified}") + print(f" Created: {status.created_at}") + + # List proofs + proofs = await zk.proofs.list(circuit_id=compiled.circuit_id) + print(f"\nProofs for circuit: {len(proofs)}") + + print() + + +async def proving_systems_example(zk: SynorZk): + """Different proving systems comparison.""" + print("=== Proving Systems Comparison ===") + + # Simple circuit for comparison + circuit = """ + pragma circom 2.1.0; + + template Comparison() { + signal input x; + signal input y; + signal output sum; + + sum <== x + y; + } + + component main {public [sum]} = Comparison(); + """ + + systems = [ + ProvingSystem.GROTH16, + ProvingSystem.PLONK, + ProvingSystem.STARK, + ] + + print("Comparing proving systems:\n") + + for system in systems: + print(f"{system.value}:") + + # Compile for this system + compiled = await zk.circuits.compile( + code=circuit, + format=CircuitFormat.CIRCOM, + name=f"comparison_{system.value.lower()}", + proving_system=system, + ) + + # Generate proof + proof_start = time.time() + proof = await zk.proofs.generate( + circuit_id=compiled.circuit_id, + inputs={"x": "10", "y": "20"}, + ) + proof_time = (time.time() - proof_start) * 1000 + + # Verify proof + verify_start = time.time() + await zk.proofs.verify( + circuit_id=compiled.circuit_id, + proof=proof.proof, + public_signals=proof.public_signals, + ) + verify_time = (time.time() - verify_start) * 1000 + + print(f" Setup: {compiled.setup_time}ms") + print(f" Proof time: {proof_time:.0f}ms") + print(f" Verify time: {verify_time:.0f}ms") + print(f" Proof size: {len(proof.proof)} bytes") + print(f" Verification key: {compiled.verification_key_size} bytes") + print() + + print("Summary:") + print(" Groth16: Smallest proofs, fast verification, trusted setup required") + print(" PLONK: Universal setup, flexible, moderate proof size") + print(" STARK: No trusted setup, largest proofs, quantum resistant") + + print() + + +async def recursive_proof_example(zk: SynorZk): + """Recursive proof aggregation.""" + print("=== Recursive Proofs ===") + + # Inner circuit + inner_circuit = """ + pragma circom 2.1.0; + + template Inner() { + signal input x; + signal output y; + y <== x * x; + } + + component main {public [y]} = Inner(); + """ + + # Compile inner circuit + inner = await zk.circuits.compile( + code=inner_circuit, + format=CircuitFormat.CIRCOM, + name="inner_circuit", + proving_system=ProvingSystem.GROTH16, + ) + + # Generate multiple proofs to aggregate + print("Generating proofs to aggregate...") + proofs_to_aggregate = [] + for i in range(1, 5): + proof = await zk.proofs.generate( + circuit_id=inner.circuit_id, + inputs={"x": str(i)}, + ) + proofs_to_aggregate.append({ + "proof": proof.proof, + "public_signals": proof.public_signals, + }) + print(f" Proof {i}: y = {proof.public_signals[0]}") + + # Aggregate proofs recursively + print("\nAggregating proofs...") + aggregated = await zk.proofs.aggregate( + circuit_id=inner.circuit_id, + proofs=proofs_to_aggregate, + aggregation_type="recursive", + ) + + original_size = sum(len(p["proof"]) for p in proofs_to_aggregate) + print(f"Aggregated proof:") + print(f" Proof ID: {aggregated.proof_id}") + print(f" Aggregated count: {aggregated.aggregated_count}") + print(f" Proof size: {len(aggregated.proof)} bytes") + print(f" Size reduction: {(1 - len(aggregated.proof) / original_size) * 100:.1f}%") + + # Verify aggregated proof + is_valid = await zk.proofs.verify_aggregated( + circuit_id=inner.circuit_id, + proof=aggregated.proof, + public_signals_list=[p["public_signals"] for p in proofs_to_aggregate], + ) + print(f"\nAggregated proof valid: {is_valid}") + + # Batch verification (verify multiple proofs in one operation) + print("\nBatch verification...") + batch_result = await zk.proofs.batch_verify( + circuit_id=inner.circuit_id, + proofs=proofs_to_aggregate, + ) + print(f" All valid: {batch_result.all_valid}") + print(f" Results: {', '.join(str(r) for r in batch_result.results)}") + + print() + + +async def on_chain_verification_example(zk: SynorZk): + """On-chain verification.""" + print("=== On-Chain Verification ===") + + # Compile circuit + circuit = """ + pragma circom 2.1.0; + + template VoteCommitment() { + signal input vote; // Private: actual vote + signal input nullifier; // Private: unique identifier + signal input commitment; // Public: commitment to verify + + // Simplified commitment (in practice, use Poseidon hash) + signal computed; + computed <== vote * nullifier; + commitment === computed; + } + + component main {public [commitment]} = VoteCommitment(); + """ + + compiled = await zk.circuits.compile( + code=circuit, + format=CircuitFormat.CIRCOM, + name="vote_commitment", + proving_system=ProvingSystem.GROTH16, + ) + + # Generate Solidity verifier + print("Generating Solidity verifier...") + solidity_verifier = await zk.contracts.generate_verifier( + circuit_id=compiled.circuit_id, + language="solidity", + optimized=True, + ) + print(f"Solidity verifier generated: {len(solidity_verifier.code)} bytes") + print(f" Contract name: {solidity_verifier.contract_name}") + print(f" Gas estimate: {solidity_verifier.gas_estimate}") + + # Generate proof + proof = await zk.proofs.generate( + circuit_id=compiled.circuit_id, + inputs={ + "vote": "1", # Vote YES (1) or NO (0) + "nullifier": "12345", + "commitment": "12345", # 1 * 12345 + }, + ) + + # Format proof for on-chain verification + print("\nFormatting proof for on-chain...") + on_chain_proof = await zk.contracts.format_proof( + circuit_id=compiled.circuit_id, + proof=proof.proof, + public_signals=proof.public_signals, + format="calldata", + ) + print(f" Calldata: {on_chain_proof.calldata[:100]}...") + print(f" Estimated gas: {on_chain_proof.gas_estimate}") + + # Deploy verifier contract (simulation) + print("\nDeploying verifier contract...") + deployment = await zk.contracts.deploy_verifier( + circuit_id=compiled.circuit_id, + network="synor-testnet", + ) + print(f" Contract address: {deployment.address}") + print(f" TX hash: {deployment.tx_hash}") + print(f" Gas used: {deployment.gas_used}") + + # Verify on-chain + print("\nVerifying on-chain...") + on_chain_result = await zk.contracts.verify_on_chain( + contract_address=deployment.address, + proof=proof.proof, + public_signals=proof.public_signals, + network="synor-testnet", + ) + print(f" TX hash: {on_chain_result.tx_hash}") + print(f" Verified: {on_chain_result.verified}") + print(f" Gas used: {on_chain_result.gas_used}") + + # Generate verifier for other targets + print("\nGenerating verifiers for other targets:") + targets = ["cairo", "noir", "ink"] + for target in targets: + verifier = await zk.contracts.generate_verifier( + circuit_id=compiled.circuit_id, + language=target, + ) + print(f" {target}: {len(verifier.code)} bytes") + + print() + + +async def setup_example(zk: SynorZk): + """Trusted setup ceremonies.""" + print("=== Trusted Setup ===") + + # Get available ceremonies + ceremonies = await zk.setup.list_ceremonies() + print(f"Active ceremonies: {len(ceremonies)}") + for ceremony in ceremonies: + print(f" {ceremony.name}:") + print(f" Status: {ceremony.status}") + print(f" Participants: {ceremony.participant_count}") + print(f" Current round: {ceremony.current_round}") + + # Create a new circuit setup + circuit = """ + pragma circom 2.1.0; + + template NewCircuit() { + signal input a; + signal output b; + b <== a + 1; + } + + component main {public [b]} = NewCircuit(); + """ + + print("\nInitializing setup for new circuit...") + setup = await zk.setup.initialize( + circuit=circuit, + format=CircuitFormat.CIRCOM, + name="new_circuit_setup", + proving_system=ProvingSystem.GROTH16, + ceremony_type="powers_of_tau", # or 'phase2' + ) + print(f"Setup initialized:") + print(f" Ceremony ID: {setup.ceremony_id}") + print(f" Powers of Tau required: {setup.powers_required}") + print(f" Current phase: {setup.phase}") + + # Contribute to ceremony (in practice, generates random entropy) + print("\nContributing to ceremony...") + contribution = await zk.setup.contribute( + ceremony_id=setup.ceremony_id, + entropy=b"random-entropy-from-user".hex(), + ) + print(f"Contribution submitted:") + print(f" Participant: {contribution.participant_id}") + print(f" Contribution hash: {contribution.hash}") + print(f" Verification status: {contribution.verified}") + + # Get ceremony status + status = await zk.setup.get_status(setup.ceremony_id) + print(f"\nCeremony status:") + print(f" Phase: {status.phase}") + print(f" Total contributions: {status.total_contributions}") + print(f" Verified contributions: {status.verified_contributions}") + print(f" Ready for finalization: {status.ready_for_finalization}") + + # Finalize setup (when enough contributions) + if status.ready_for_finalization: + print("\nFinalizing setup...") + finalized = await zk.setup.finalize(setup.ceremony_id) + print(f"Setup finalized:") + print(f" Proving key hash: {finalized.proving_key_hash}") + print(f" Verification key hash: {finalized.verification_key_hash}") + print(f" Contribution transcript: {finalized.transcript_cid}") + + # Download ceremony transcript + transcript = await zk.setup.get_transcript(setup.ceremony_id) + print(f"\nCeremony transcript: {len(transcript)} bytes") + + print() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/rust/examples/compiler_example.rs b/sdk/rust/examples/compiler_example.rs new file mode 100644 index 0000000..b35496d --- /dev/null +++ b/sdk/rust/examples/compiler_example.rs @@ -0,0 +1,435 @@ +//! Synor Compiler SDK Examples for Rust +//! +//! Demonstrates smart contract compilation and analysis: +//! - WASM contract compilation and optimization +//! - ABI extraction and encoding +//! - Contract analysis and security scanning +//! - Validation and verification + +use std::env; +use synor_compiler::{ + CompilerConfig, CompileOptions, OptimizationLevel, StripOptions, SynorCompiler, +}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initialize client + let config = CompilerConfig { + api_key: env::var("SYNOR_API_KEY").unwrap_or_else(|_| "your-api-key".to_string()), + endpoint: "https://compiler.synor.io/v1".to_string(), + timeout: 60000, + 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, + }; + + let compiler = SynorCompiler::new(config)?; + + // Check service health + let healthy = compiler.health_check().await?; + println!("Service healthy: {}\n", healthy); + + // Run examples + compile_contract_example(&compiler).await?; + compilation_modes_example(&compiler).await?; + abi_example(&compiler).await?; + analysis_example(&compiler).await?; + validation_example(&compiler).await?; + security_example(&compiler).await?; + + compiler.close().await?; + Ok(()) +} + +/// Create a minimal valid WASM module for testing. +fn create_minimal_wasm() -> Vec { + vec![ + 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, + ] +} + +async fn compile_contract_example(compiler: &SynorCompiler) -> Result<(), Box> { + println!("=== Contract Compilation ==="); + + let wasm = create_minimal_wasm(); + + let result = compiler + .compile( + &wasm, + Some(CompileOptions { + optimization_level: OptimizationLevel::Size, + use_wasm_opt: true, + validate: true, + extract_metadata: true, + generate_abi: true, + strip_options: Some(StripOptions { + strip_debug: true, + strip_producers: true, + strip_names: true, + strip_custom: true, + strip_unused: true, + preserve_sections: vec![], + }), + }), + ) + .await?; + + println!("Compilation result:"); + println!(" Contract ID: {}", result.contract_id); + println!(" Code hash: {}", result.code_hash); + println!(" Original size: {} bytes", result.original_size); + println!(" Optimized size: {} bytes", result.optimized_size); + println!(" Size reduction: {:.1}%", result.size_reduction); + println!(" Estimated deploy gas: {}", result.estimated_deploy_gas); + + if let Some(metadata) = &result.metadata { + println!("\nMetadata:"); + println!(" Name: {}", metadata.name); + println!(" Version: {}", metadata.version); + println!(" SDK Version: {}", metadata.sdk_version); + } + + if let Some(abi) = &result.abi { + println!("\nABI:"); + println!(" Functions: {}", abi.functions.as_ref().map_or(0, |f| f.len())); + println!(" Events: {}", abi.events.as_ref().map_or(0, |e| e.len())); + println!(" Errors: {}", abi.errors.as_ref().map_or(0, |e| e.len())); + } + + println!(); + Ok(()) +} + +async fn compilation_modes_example(compiler: &SynorCompiler) -> Result<(), Box> { + println!("=== Compilation Modes ==="); + + let wasm = create_minimal_wasm(); + + // Development mode: fast compilation, debugging support + println!("Development mode:"); + let dev_result = compiler.contracts.compile_dev(&wasm).await?; + println!(" Size: {} bytes", dev_result.optimized_size); + println!(" Optimization: none"); + + // Production mode: maximum optimization + println!("\nProduction mode:"); + let prod_result = compiler.contracts.compile_production(&wasm).await?; + println!(" Size: {} bytes", prod_result.optimized_size); + println!(" Optimization: aggressive"); + println!( + " Size savings: {} bytes", + dev_result.optimized_size - prod_result.optimized_size + ); + + // Custom optimization levels + println!("\nOptimization levels:"); + let levels = [ + OptimizationLevel::None, + OptimizationLevel::Basic, + OptimizationLevel::Size, + OptimizationLevel::Aggressive, + ]; + + for level in levels { + let result = compiler + .compile( + &wasm, + Some(CompileOptions { + optimization_level: level, + ..Default::default() + }), + ) + .await?; + println!(" {:?}: {} bytes", level, result.optimized_size); + } + + println!(); + Ok(()) +} + +async fn abi_example(compiler: &SynorCompiler) -> Result<(), Box> { + println!("=== ABI Operations ==="); + + let wasm = create_minimal_wasm(); + + // Extract ABI from WASM + let abi = compiler.abi.extract(&wasm).await?; + println!("Contract: {}", abi.name); + println!("Version: {}", abi.version); + + // List functions + if let Some(functions) = &abi.functions { + if !functions.is_empty() { + println!("\nFunctions:"); + for func in functions { + let inputs = func + .inputs + .as_ref() + .map(|inputs| { + inputs + .iter() + .map(|i| format!("{}: {}", i.name, i.type_info.type_name)) + .collect::>() + .join(", ") + }) + .unwrap_or_default(); + + let outputs = func + .outputs + .as_ref() + .map(|outputs| { + outputs + .iter() + .map(|o| o.type_info.type_name.clone()) + .collect::>() + .join(", ") + }) + .unwrap_or_else(|| "void".to_string()); + + let mut modifiers = vec![]; + if func.view { + modifiers.push("view"); + } + if func.payable { + modifiers.push("payable"); + } + + println!( + " {}({}) -> {} {}", + func.name, + inputs, + outputs, + modifiers.join(" ") + ); + println!(" Selector: {}", func.selector); + } + } + } + + // List events + if let Some(events) = &abi.events { + if !events.is_empty() { + println!("\nEvents:"); + for event in events { + let params = event + .params + .as_ref() + .map(|params| { + params + .iter() + .map(|p| { + let indexed = if p.indexed { "indexed " } else { "" }; + format!("{}{}: {}", indexed, p.name, p.type_info.type_name) + }) + .collect::>() + .join(", ") + }) + .unwrap_or_default(); + + println!(" {}({})", event.name, params); + println!(" Topic: {}", event.topic); + } + } + } + + // Encode a function call + if let Some(functions) = &abi.functions { + if let Some(func) = functions.first() { + let encoded = compiler + .abi + .encode_call(func, &["arg1".to_string(), "arg2".to_string()]) + .await?; + println!("\nEncoded call to {}: {}", func.name, encoded); + + // Decode a result + let decoded = compiler.abi.decode_result(func, &encoded).await?; + println!("Decoded result: {:?}", decoded); + } + } + + println!(); + Ok(()) +} + +async fn analysis_example(compiler: &SynorCompiler) -> Result<(), Box> { + println!("=== Contract Analysis ==="); + + let wasm = create_minimal_wasm(); + + // Full analysis + let analysis = compiler.analysis.analyze(&wasm).await?; + + // Size breakdown + if let Some(breakdown) = &analysis.size_breakdown { + println!("Size breakdown:"); + println!(" Code: {} bytes", breakdown.code); + println!(" Data: {} bytes", breakdown.data); + println!(" Functions: {} bytes", breakdown.functions); + println!(" Memory: {} bytes", breakdown.memory); + println!(" Exports: {} bytes", breakdown.exports); + println!(" Imports: {} bytes", breakdown.imports); + println!(" Total: {} bytes", breakdown.total); + } + + // Function analysis + if let Some(functions) = &analysis.functions { + if !functions.is_empty() { + println!("\nFunction analysis:"); + for func in functions.iter().take(5) { + println!(" {}:", func.name); + println!(" Size: {} bytes", func.size); + println!(" Instructions: {}", func.instruction_count); + println!(" Locals: {}", func.local_count); + println!(" Exported: {}", func.exported); + println!(" Estimated gas: {}", func.estimated_gas); + } + } + } + + // Import analysis + if let Some(imports) = &analysis.imports { + if !imports.is_empty() { + println!("\nImports:"); + for imp in imports { + println!(" {}.{} ({})", imp.module, imp.name, imp.kind); + } + } + } + + // Gas analysis + if let Some(gas) = &analysis.gas_analysis { + println!("\nGas analysis:"); + println!(" Deployment: {}", gas.deployment_gas); + println!(" Memory init: {}", gas.memory_init_gas); + println!(" Data section: {}", gas.data_section_gas); + } + + // Extract metadata + let metadata = compiler.analysis.extract_metadata(&wasm).await?; + println!("\nContract metadata:"); + println!(" Name: {}", metadata.name); + println!(" Version: {}", metadata.version); + println!(" Build timestamp: {}", metadata.build_timestamp); + + // Estimate deployment gas + let gas = compiler.analysis.estimate_deploy_gas(&wasm).await?; + println!("\nEstimated deployment gas: {}", gas); + + println!(); + Ok(()) +} + +async fn validation_example(compiler: &SynorCompiler) -> Result<(), Box> { + println!("=== Contract Validation ==="); + + let wasm = create_minimal_wasm(); + + // Full validation + let result = compiler.validation.validate(&wasm).await?; + println!("Valid: {}", result.valid); + println!("Exports: {}", result.export_count); + println!("Imports: {}", result.import_count); + println!("Functions: {}", result.function_count); + println!("Memory pages: {}", result.memory_pages); + + if let Some(errors) = &result.errors { + if !errors.is_empty() { + println!("\nValidation errors:"); + for error in errors { + println!(" [{}] {}", error.code, error.message); + if let Some(location) = &error.location { + println!(" at {}", location); + } + } + } + } + + if let Some(warnings) = &result.warnings { + if !warnings.is_empty() { + println!("\nWarnings:"); + for warning in warnings { + println!(" {}", warning); + } + } + } + + // Quick validation + let is_valid = compiler.validation.is_valid(&wasm).await?; + println!("\nQuick validation: {}", is_valid); + + // Get validation errors only + let errors = compiler.validation.get_errors(&wasm).await?; + println!("Error count: {}", errors.len()); + + // Validate required exports + let has_required = compiler + .validation + .validate_exports(&wasm, &["init", "execute", "query"]) + .await?; + println!("Has required exports: {}", has_required); + + // Validate memory constraints + let memory_valid = compiler.validation.validate_memory(&wasm, 16).await?; + println!("Memory within 16 pages: {}", memory_valid); + + println!(); + Ok(()) +} + +async fn security_example(compiler: &SynorCompiler) -> Result<(), Box> { + println!("=== Security Scanning ==="); + + let wasm = create_minimal_wasm(); + + let security = compiler.analysis.security_scan(&wasm).await?; + + println!("Security score: {}/100", security.score); + + if let Some(issues) = &security.issues { + if !issues.is_empty() { + println!("\nSecurity issues:"); + for issue in issues { + let icon = match issue.severity.as_str() { + "critical" => "[CRIT]", + "high" => "[HIGH]", + "medium" => "[MED]", + "low" => "[LOW]", + _ => "[???]", + }; + println!("{} [{}] {}", icon, issue.severity.to_uppercase(), issue.issue_type); + println!(" {}", issue.description); + if let Some(location) = &issue.location { + println!(" at {}", location); + } + } + } else { + println!("No security issues found!"); + } + } + + if let Some(recommendations) = &security.recommendations { + if !recommendations.is_empty() { + println!("\nRecommendations:"); + for rec in recommendations { + println!(" * {}", rec); + } + } + } + + println!(); + Ok(()) +} diff --git a/sdk/rust/examples/crypto_example.rs b/sdk/rust/examples/crypto_example.rs new file mode 100644 index 0000000..8fa6102 --- /dev/null +++ b/sdk/rust/examples/crypto_example.rs @@ -0,0 +1,279 @@ +//! Synor Crypto SDK Examples for Rust +//! +//! Demonstrates quantum-resistant cryptographic operations: +//! - Hybrid Ed25519 + Dilithium3 signatures +//! - BIP-39 mnemonic generation and validation +//! - Post-quantum algorithms (Falcon, SPHINCS+) +//! - Key derivation functions + +use std::env; +use synor_crypto::{ + CryptoConfig, DerivationConfig, DerivationPath, FalconVariant, Network, + PasswordDerivationConfig, SphincsVariant, SynorCrypto, +}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initialize client + let config = CryptoConfig { + api_key: env::var("SYNOR_API_KEY").unwrap_or_else(|_| "your-api-key".to_string()), + endpoint: "https://crypto.synor.io/v1".to_string(), + timeout: 30000, + retries: 3, + debug: false, + default_network: Network::Mainnet, + }; + + let crypto = SynorCrypto::new(config)?; + + // Check service health + let healthy = crypto.health_check().await?; + println!("Service healthy: {}\n", healthy); + + // Run examples + mnemonic_example(&crypto).await?; + keypair_example(&crypto).await?; + signing_example(&crypto).await?; + falcon_example(&crypto).await?; + sphincs_example(&crypto).await?; + kdf_example(&crypto).await?; + hash_example(&crypto).await?; + + crypto.close().await?; + Ok(()) +} + +async fn mnemonic_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== Mnemonic Operations ==="); + + // Generate a 24-word mnemonic (256-bit entropy) + let mnemonic = crypto.mnemonic.generate(24).await?; + println!("Generated mnemonic: {}", mnemonic.phrase); + println!("Word count: {}", mnemonic.word_count); + + // Validate a mnemonic + let validation = crypto.mnemonic.validate(&mnemonic.phrase).await?; + println!("Valid: {}", validation.valid); + if !validation.valid { + println!("Error: {}", validation.error.unwrap_or_default()); + } + + // Convert mnemonic to seed + let seed = crypto + .mnemonic + .to_seed(&mnemonic.phrase, Some("optional-passphrase")) + .await?; + println!("Seed (hex): {}...", &hex::encode(&seed)[..32]); + + // Word suggestions for autocomplete + let suggestions = crypto.mnemonic.suggest_words("aban", 5).await?; + println!("Suggestions for 'aban': {}", suggestions.join(", ")); + + println!(); + Ok(()) +} + +async fn keypair_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== Keypair Operations ==="); + + // Generate a random keypair + let keypair = crypto.keypairs.generate().await?; + println!("Generated hybrid keypair:"); + println!( + " Ed25519 public key size: {} bytes", + keypair.public_key.ed25519_bytes.len() + ); + println!( + " Dilithium public key size: {} bytes", + keypair.public_key.dilithium_bytes.len() + ); + println!(" Total public key size: {} bytes", keypair.public_key.size); + + // Get addresses for different networks + println!("\nAddresses:"); + println!(" Mainnet: {}", keypair.get_address(Network::Mainnet)); + println!(" Testnet: {}", keypair.get_address(Network::Testnet)); + println!(" Devnet: {}", keypair.get_address(Network::Devnet)); + + // Create keypair from mnemonic (deterministic) + let mnemonic = crypto.mnemonic.generate(24).await?; + let keypair2 = crypto + .keypairs + .from_mnemonic(&mnemonic.phrase, "") + .await?; + let addr = keypair2.get_address(Network::Mainnet); + println!("\nKeypair from mnemonic: {}...", &addr[..20]); + + // Derive child keypair using BIP-44 path + let path = DerivationPath::external(0, 0); // m/44'/21337'/0'/0/0 + println!("Derivation path: {}", path); + + println!(); + Ok(()) +} + +async fn signing_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== Hybrid Signing ==="); + + // Generate keypair + let keypair = crypto.keypairs.generate().await?; + + // Sign a message + let message = b"Hello, quantum-resistant world!"; + let signature = crypto.signing.sign(&keypair, message).await?; + + println!("Signature created:"); + println!( + " Ed25519 component: {} bytes", + signature.ed25519_bytes.len() + ); + println!( + " Dilithium component: {} bytes", + signature.dilithium_bytes.len() + ); + println!(" Total signature size: {} bytes", signature.size); + + // Verify the signature + let valid = crypto + .signing + .verify(&keypair.public_key, message, &signature) + .await?; + println!("\nVerification result: {}", valid); + + // Verify with tampered message fails + let tampered_message = b"Hello, tampered message!"; + let invalid_result = crypto + .signing + .verify(&keypair.public_key, tampered_message, &signature) + .await?; + println!("Tampered message verification: {}", invalid_result); + + println!(); + Ok(()) +} + +async fn falcon_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== Falcon Post-Quantum Signatures ==="); + + // Generate Falcon-512 keypair (128-bit security) + let falcon512 = crypto.falcon.generate(FalconVariant::Falcon512).await?; + println!("Falcon-512 keypair:"); + println!(" Public key: {} bytes", falcon512.public_key.key_bytes.len()); + println!(" Security level: 128-bit"); + + // Generate Falcon-1024 keypair (256-bit security) + let falcon1024 = crypto.falcon.generate(FalconVariant::Falcon1024).await?; + println!("\nFalcon-1024 keypair:"); + println!( + " Public key: {} bytes", + falcon1024.public_key.key_bytes.len() + ); + println!(" Security level: 256-bit"); + + // Sign with Falcon-512 + let message = b"Post-quantum secure message"; + let signature = crypto.falcon.sign(&falcon512, message).await?; + println!( + "\nFalcon-512 signature: {} bytes", + signature.signature_bytes.len() + ); + + // Verify + let valid = crypto + .falcon + .verify(&falcon512.public_key.key_bytes, message, &signature) + .await?; + println!("Verification: {}", valid); + + println!(); + Ok(()) +} + +async fn sphincs_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== SPHINCS+ Hash-Based Signatures ==="); + + // SPHINCS+ variants with different security levels + let variants = [ + (SphincsVariant::Shake128s, 128, 7856), + (SphincsVariant::Shake192s, 192, 16224), + (SphincsVariant::Shake256s, 256, 29792), + ]; + + // Generate and demonstrate each variant + for (variant, security, sig_size) in variants { + let keypair = crypto.sphincs.generate(variant).await?; + println!("SPHINCS+ {:?}:", variant); + println!(" Security level: {}-bit", security); + println!(" Expected signature size: {} bytes", sig_size); + + // Sign a message + let message = b"Hash-based quantum security"; + let signature = crypto.sphincs.sign(&keypair, message).await?; + println!( + " Actual signature size: {} bytes", + signature.signature_bytes.len() + ); + + // Verify + let valid = crypto + .sphincs + .verify(&keypair.public_key.key_bytes, message, &signature) + .await?; + println!(" Verification: {}\n", valid); + } + + Ok(()) +} + +async fn kdf_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== Key Derivation Functions ==="); + + // HKDF (HMAC-based Key Derivation Function) + let seed = b"master-secret-key-material-here"; + let hkdf_config = DerivationConfig { + salt: b"application-salt".to_vec(), + info: b"encryption-key".to_vec(), + output_length: 32, + }; + + let derived_key = crypto.kdf.derive_key(seed, &hkdf_config).await?; + println!("HKDF derived key: {}", hex::encode(&derived_key)); + + // PBKDF2 (Password-Based Key Derivation Function) + let password = b"user-password"; + let pbkdf2_config = PasswordDerivationConfig { + salt: b"random-salt-value".to_vec(), + iterations: 100000, + output_length: 32, + }; + + let password_key = crypto + .kdf + .derive_from_password(password, &pbkdf2_config) + .await?; + println!("PBKDF2 derived key: {}", hex::encode(&password_key)); + + println!(); + Ok(()) +} + +async fn hash_example(crypto: &SynorCrypto) -> Result<(), Box> { + println!("=== Hash Functions ==="); + + let data = b"Data to hash"; + + // SHA3-256 (FIPS 202) + let sha3 = crypto.hash.sha3_256(data).await?; + println!("SHA3-256: {}", sha3.hex); + + // BLAKE3 (fast, parallel) + let blake3 = crypto.hash.blake3(data).await?; + println!("BLAKE3: {}", blake3.hex); + + // Keccak-256 (Ethereum compatible) + let keccak = crypto.hash.keccak256(data).await?; + println!("Keccak: {}", keccak.hex); + + println!(); + Ok(()) +} diff --git a/sdk/rust/examples/dex_example.rs b/sdk/rust/examples/dex_example.rs new file mode 100644 index 0000000..2c2bb72 --- /dev/null +++ b/sdk/rust/examples/dex_example.rs @@ -0,0 +1,387 @@ +//! Synor DEX SDK Examples for Rust +//! +//! Demonstrates decentralized exchange operations: +//! - Spot trading (limit/market orders) +//! - Perpetual futures trading +//! - Liquidity provision (AMM pools) +//! - Order book management +//! - Portfolio tracking + +use std::env; +use synor_dex::{ + AddLiquidityRequest, DexConfig, OrderRequest, OrderSide, OrderType, PerpsOrderRequest, + RemoveLiquidityRequest, SynorDex, TimeInForce, +}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initialize client + let config = DexConfig { + api_key: env::var("SYNOR_API_KEY").unwrap_or_else(|_| "your-api-key".to_string()), + endpoint: "https://dex.synor.io/v1".to_string(), + timeout: 30000, + retries: 3, + debug: false, + default_market: "SYN-USDC".to_string(), + }; + + let dex = SynorDex::new(config)?; + + // Check service health + let healthy = dex.health_check().await?; + println!("Service healthy: {}\n", healthy); + + // Run examples + markets_example(&dex).await?; + spot_trading_example(&dex).await?; + perps_trading_example(&dex).await?; + liquidity_example(&dex).await?; + orderbook_example(&dex).await?; + portfolio_example(&dex).await?; + + dex.close().await?; + Ok(()) +} + +async fn markets_example(dex: &SynorDex) -> Result<(), Box> { + println!("=== Markets ==="); + + // Get all markets + let markets = dex.markets.list().await?; + println!("Available markets: {}", markets.len()); + + for market in markets.iter().take(5) { + println!("\n {}:", market.symbol); + println!(" Base: {}, Quote: {}", market.base_asset, market.quote_asset); + println!(" Price: {}", market.last_price); + println!(" 24h Volume: {}", market.volume_24h); + println!(" 24h Change: {}%", market.change_24h); + println!(" Status: {}", market.status); + } + + // Get specific market + let market = dex.markets.get("SYN-USDC").await?; + println!("\nSYN-USDC details:"); + println!(" Min order size: {}", market.min_order_size); + println!(" Tick size: {}", market.tick_size); + println!(" Maker fee: {}%", market.maker_fee); + println!(" Taker fee: {}%", market.taker_fee); + + // Get market statistics + let stats = dex.markets.get_stats("SYN-USDC").await?; + println!("\nMarket statistics:"); + println!(" High 24h: {}", stats.high_24h); + println!(" Low 24h: {}", stats.low_24h); + println!(" Open interest: {}", stats.open_interest); + println!(" Funding rate: {}%", stats.funding_rate); + + println!(); + Ok(()) +} + +async fn spot_trading_example(dex: &SynorDex) -> Result<(), Box> { + println!("=== Spot Trading ==="); + + // Place a limit order + println!("Placing limit buy order..."); + let limit_order = dex + .spot + .place_order(OrderRequest { + market: "SYN-USDC".to_string(), + side: OrderSide::Buy, + order_type: OrderType::Limit, + price: Some("1.50".to_string()), + quantity: "100".to_string(), + time_in_force: Some(TimeInForce::GTC), + }) + .await?; + + println!("Limit order placed:"); + println!(" Order ID: {}", limit_order.order_id); + println!(" Status: {}", limit_order.status); + println!(" Price: {}", limit_order.price.unwrap_or_default()); + println!(" Quantity: {}", limit_order.quantity); + + // Place a market order + println!("\nPlacing market sell order..."); + let market_order = dex + .spot + .place_order(OrderRequest { + market: "SYN-USDC".to_string(), + side: OrderSide::Sell, + order_type: OrderType::Market, + price: None, + quantity: "50".to_string(), + time_in_force: None, + }) + .await?; + + println!("Market order executed:"); + println!(" Order ID: {}", market_order.order_id); + println!(" Status: {}", market_order.status); + println!(" Filled: {}", market_order.filled_quantity); + println!(" Avg price: {}", market_order.average_price.unwrap_or_default()); + + // Get order status + let status = dex.spot.get_order(&limit_order.order_id).await?; + println!("\nOrder status:"); + println!(" Status: {}", status.status); + println!(" Filled: {} / {}", status.filled_quantity, status.quantity); + println!(" Remaining: {}", status.remaining_quantity); + + // Cancel order + println!("\nCancelling order..."); + dex.spot.cancel_order(&limit_order.order_id).await?; + println!("Order cancelled successfully"); + + // Get open orders + let open_orders = dex.spot.get_open_orders("SYN-USDC").await?; + println!("\nOpen orders: {}", open_orders.len()); + + // Get trade history + let trades = dex.spot.get_trade_history("SYN-USDC", 10).await?; + println!("\nRecent trades: {}", trades.len()); + for trade in trades.iter().take(3) { + println!(" {:?} {} @ {} ({})", trade.side, trade.quantity, trade.price, trade.timestamp); + } + + println!(); + Ok(()) +} + +async fn perps_trading_example(dex: &SynorDex) -> Result<(), Box> { + println!("=== Perpetual Futures Trading ==="); + + // Get available perps markets + let perps_markets = dex.perps.list_markets().await?; + println!("Available perps markets: {}", perps_markets.len()); + + for market in perps_markets.iter().take(3) { + println!( + " {}: {} (funding: {}%)", + market.symbol, market.mark_price, market.funding_rate + ); + } + + // Open a long position + println!("\nOpening long position..."); + let position = dex + .perps + .open_position(PerpsOrderRequest { + market: "SYN-USDC-PERP".to_string(), + side: OrderSide::Buy, + order_type: OrderType::Limit, + price: Some("1.50".to_string()), + size: "1000".to_string(), + leverage: 10, + reduce_only: false, + }) + .await?; + + println!("Position opened:"); + println!(" Position ID: {}", position.position_id); + println!(" Size: {}", position.size); + println!(" Entry price: {}", position.entry_price); + println!(" Leverage: {}x", position.leverage); + println!(" Liquidation price: {}", position.liquidation_price); + + // Get position details + let details = dex.perps.get_position(&position.position_id).await?; + println!("\nPosition details:"); + println!(" Unrealized PnL: {}", details.unrealized_pnl); + println!(" Margin: {}", details.margin); + println!(" Margin ratio: {}%", details.margin_ratio); + + // Set stop loss and take profit + println!("\nSetting stop loss and take profit..."); + dex.perps + .set_stop_loss(&position.position_id, "1.40") + .await?; + println!("Stop loss set at 1.40"); + + dex.perps + .set_take_profit(&position.position_id, "1.80") + .await?; + println!("Take profit set at 1.80"); + + // Close position + println!("\nClosing position..."); + let close_result = dex.perps.close_position(&position.position_id).await?; + println!("Position closed:"); + println!(" Realized PnL: {}", close_result.realized_pnl); + println!(" Close price: {}", close_result.close_price); + + // Get all positions + let positions = dex.perps.get_positions().await?; + println!("\nOpen positions: {}", positions.len()); + + // Get funding history + let funding = dex.perps.get_funding_history("SYN-USDC-PERP", 10).await?; + println!("Funding payments: {}", funding.len()); + + println!(); + Ok(()) +} + +async fn liquidity_example(dex: &SynorDex) -> Result<(), Box> { + println!("=== Liquidity Provision ==="); + + // Get available pools + let pools = dex.liquidity.list_pools().await?; + println!("Available pools: {}", pools.len()); + + for pool in pools.iter().take(3) { + println!("\n {}:", pool.name); + println!(" TVL: ${}", pool.tvl); + println!(" APR: {}%", pool.apr); + println!(" Volume 24h: ${}", pool.volume_24h); + println!(" Fee tier: {}%", pool.fee_tier); + } + + // Get pool details + let pool = dex.liquidity.get_pool("SYN-USDC").await?; + println!("\nSYN-USDC pool details:"); + println!(" Token0: {} ({})", pool.token0.symbol, pool.token0_reserve); + println!(" Token1: {} ({})", pool.token1.symbol, pool.token1_reserve); + println!(" Price: {}", pool.price); + println!(" Total LP tokens: {}", pool.total_lp_tokens); + + // Add liquidity + println!("\nAdding liquidity..."); + let add_result = dex + .liquidity + .add_liquidity(AddLiquidityRequest { + pool: "SYN-USDC".to_string(), + amount0: "100".to_string(), + amount1: "150".to_string(), + slippage_bps: 50, // 0.5% + }) + .await?; + + println!("Liquidity added:"); + println!(" LP tokens received: {}", add_result.lp_tokens); + println!(" Position ID: {}", add_result.position_id); + println!(" Share of pool: {}%", add_result.share_of_pool); + + // Get LP positions + let lp_positions = dex.liquidity.get_positions().await?; + println!("\nLP positions: {}", lp_positions.len()); + for pos in &lp_positions { + println!(" {}: {} LP tokens (value: ${})", pos.pool, pos.lp_tokens, pos.value); + } + + // Claim fees + println!("\nClaiming fees..."); + let fees = dex.liquidity.claim_fees(&add_result.position_id).await?; + println!("Fees claimed:"); + println!(" Token0: {}", fees.amount0); + println!(" Token1: {}", fees.amount1); + + // Remove liquidity + println!("\nRemoving liquidity..."); + let remove_result = dex + .liquidity + .remove_liquidity(RemoveLiquidityRequest { + position_id: add_result.position_id.clone(), + lp_tokens: add_result.lp_tokens.clone(), + slippage_bps: 50, + }) + .await?; + + println!("Liquidity removed:"); + println!(" Token0 received: {}", remove_result.amount0); + println!(" Token1 received: {}", remove_result.amount1); + + println!(); + Ok(()) +} + +async fn orderbook_example(dex: &SynorDex) -> Result<(), Box> { + println!("=== Order Book ==="); + + // Get order book snapshot + let orderbook = dex.orderbook.get_snapshot("SYN-USDC", 10).await?; + + println!("Order book for SYN-USDC:"); + println!("\nAsks (sells):"); + for ask in orderbook.asks.iter().take(5) { + println!(" {} @ {}", ask.quantity, ask.price); + } + + println!("\nBids (buys):"); + for bid in orderbook.bids.iter().take(5) { + println!(" {} @ {}", bid.quantity, bid.price); + } + + println!("\nSpread: {} ({}%)", orderbook.spread, orderbook.spread_percent); + println!("Mid price: {}", orderbook.mid_price); + + // Get recent trades + let recent_trades = dex.orderbook.get_recent_trades("SYN-USDC", 10).await?; + println!("\nRecent trades:"); + for trade in recent_trades.iter().take(5) { + println!(" {:?} {} @ {}", trade.side, trade.quantity, trade.price); + } + + // Subscribe to orderbook updates (simulated) + println!("\nSubscribing to orderbook updates..."); + let mut updates = dex.orderbook.subscribe("SYN-USDC").await?; + + // Process a few updates + tokio::spawn(async move { + for _ in 0..3 { + if let Some(update) = updates.recv().await { + println!(" Update: {:?} {} @ {}", update.side, update.quantity, update.price); + } + } + }); + + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + + println!(); + Ok(()) +} + +async fn portfolio_example(dex: &SynorDex) -> Result<(), Box> { + println!("=== Portfolio ==="); + + // Get portfolio overview + let portfolio = dex.portfolio.get_overview().await?; + + println!("Portfolio overview:"); + println!(" Total value: ${}", portfolio.total_value); + println!(" Available balance: ${}", portfolio.available_balance); + println!(" In orders: ${}", portfolio.in_orders); + println!(" In positions: ${}", portfolio.in_positions); + println!(" Unrealized PnL: ${}", portfolio.unrealized_pnl); + + // Get balances + let balances = dex.portfolio.get_balances().await?; + println!("\nBalances:"); + for balance in &balances { + println!( + " {}: {} (available: {}, in orders: {})", + balance.asset, balance.total, balance.available, balance.in_orders + ); + } + + // Get PnL history + let pnl_history = dex.portfolio.get_pnl_history(30).await?; // Last 30 days + println!("\nPnL history (last {} days):", pnl_history.len()); + if let Some(last) = pnl_history.last() { + println!(" Total PnL: ${}", last.cumulative_pnl); + } + + // Get trade statistics + let stats = dex.portfolio.get_stats().await?; + println!("\nTrade statistics:"); + println!(" Total trades: {}", stats.total_trades); + println!(" Win rate: {}%", stats.win_rate); + println!(" Avg profit: ${}", stats.avg_profit); + println!(" Avg loss: ${}", stats.avg_loss); + println!(" Best trade: ${}", stats.best_trade); + println!(" Worst trade: ${}", stats.worst_trade); + + println!(); + Ok(()) +} diff --git a/sdk/rust/examples/ibc_example.rs b/sdk/rust/examples/ibc_example.rs new file mode 100644 index 0000000..69928bc --- /dev/null +++ b/sdk/rust/examples/ibc_example.rs @@ -0,0 +1,407 @@ +//! Synor IBC SDK Examples for Rust +//! +//! Demonstrates Inter-Blockchain Communication operations: +//! - Cross-chain token transfers +//! - Channel management +//! - Packet handling +//! - Relayer operations + +use std::env; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use synor_ibc::{ + ChannelState, FeeEstimateRequest, IbcConfig, Network, RelayConfig, RelayerRegistration, + SynorIbc, TransferRequest, +}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initialize client + let config = IbcConfig { + api_key: env::var("SYNOR_API_KEY").unwrap_or_else(|_| "your-api-key".to_string()), + endpoint: "https://ibc.synor.io/v1".to_string(), + timeout: 30000, + retries: 3, + debug: false, + default_network: Network::Mainnet, + }; + + let ibc = SynorIbc::new(config)?; + + // Check service health + let healthy = ibc.health_check().await?; + println!("Service healthy: {}\n", healthy); + + // Run examples + chains_example(&ibc).await?; + channels_example(&ibc).await?; + transfer_example(&ibc).await?; + packet_example(&ibc).await?; + relayer_example(&ibc).await?; + connection_example(&ibc).await?; + + ibc.close().await?; + Ok(()) +} + +async fn chains_example(ibc: &SynorIbc) -> Result<(), Box> { + println!("=== Connected Chains ==="); + + // Get all connected chains + let chains = ibc.chains.list().await?; + println!("Connected chains: {}", chains.len()); + + for chain in &chains { + println!(" {}:", chain.chain_id); + println!(" Name: {}", chain.name); + println!(" Status: {}", chain.status); + println!(" Block height: {}", chain.latest_height); + println!(" Channels: {}", chain.channel_count); + } + + // Get specific chain info + let cosmos = ibc.chains.get("cosmoshub-4").await?; + println!("\nCosmos Hub details:"); + println!(" RPC: {}", cosmos.rpc_endpoint); + println!(" Rest: {}", cosmos.rest_endpoint); + println!(" Native denom: {}", cosmos.native_denom); + println!(" Prefix: {}", cosmos.bech32_prefix); + + // Get supported assets on a chain + let assets = ibc.chains.get_assets("cosmoshub-4").await?; + println!("\nSupported assets on Cosmos Hub:"); + for asset in assets.iter().take(5) { + println!(" {}: {}", asset.symbol, asset.denom); + println!(" Origin: {}", asset.origin_chain); + println!(" Decimals: {}", asset.decimals); + } + + // Get chain paths (routes) + let paths = ibc.chains.get_paths("synor-1", "cosmoshub-4").await?; + println!("\nPaths from Synor to Cosmos Hub:"); + for path in &paths { + println!(" {} -> {}", path.source_channel, path.dest_channel); + println!(" Hops: {}", path.hops); + println!(" Avg time: {}s", path.avg_transfer_time); + } + + println!(); + Ok(()) +} + +async fn channels_example(ibc: &SynorIbc) -> Result<(), Box> { + println!("=== Channel Management ==="); + + // List all channels + let channels = ibc.channels.list().await?; + println!("Total channels: {}", channels.len()); + + // Filter by state + let open_channels: Vec<_> = channels + .iter() + .filter(|c| c.state == ChannelState::Open) + .collect(); + println!("Open channels: {}", open_channels.len()); + + for channel in open_channels.iter().take(3) { + println!("\n Channel {}:", channel.channel_id); + println!(" Port: {}", channel.port_id); + println!( + " Counterparty: {} on {}", + channel.counterparty_channel_id, channel.counterparty_chain_id + ); + println!(" Ordering: {}", channel.ordering); + println!(" Version: {}", channel.version); + println!(" State: {:?}", channel.state); + } + + // Get specific channel + let channel = ibc.channels.get("channel-0").await?; + println!("\nChannel-0 details:"); + println!(" Connection: {}", channel.connection_id); + println!(" Counterparty port: {}", channel.counterparty_port_id); + + // Get channel statistics + let stats = ibc.channels.get_stats("channel-0").await?; + println!("\nChannel-0 statistics:"); + println!(" Total packets sent: {}", stats.packets_sent); + println!(" Total packets received: {}", stats.packets_received); + println!(" Pending packets: {}", stats.pending_packets); + println!(" Success rate: {:.1}%", stats.success_rate); + println!(" Avg relay time: {}s", stats.avg_relay_time); + + // Get channel capacity + let capacity = ibc.channels.get_capacity("channel-0").await?; + println!("\nChannel-0 capacity:"); + println!(" Max throughput: {} packets/block", capacity.max_packets_per_block); + println!(" Current utilization: {:.1}%", capacity.utilization); + + println!(); + Ok(()) +} + +async fn transfer_example(ibc: &SynorIbc) -> Result<(), Box> { + println!("=== Cross-Chain Transfers ==="); + + // Estimate transfer fee + let estimate = ibc + .transfers + .estimate_fee(FeeEstimateRequest { + source_chain: "synor-1".to_string(), + dest_chain: "cosmoshub-4".to_string(), + denom: "usyn".to_string(), + amount: "1000000".to_string(), // 1 SYN (6 decimals) + }) + .await?; + + println!("Transfer fee estimate:"); + println!(" Gas: {}", estimate.gas); + println!(" Fee: {} {}", estimate.fee, estimate.fee_denom); + println!(" Timeout: {}s", estimate.timeout); + + // Calculate timeout timestamp (10 minutes from now) + let timeout_timestamp = SystemTime::now() + .duration_since(UNIX_EPOCH)? + .as_millis() as u64 + + 600000; + + // Initiate a transfer + println!("\nInitiating transfer..."); + let transfer = ibc + .transfers + .send(TransferRequest { + source_chain: "synor-1".to_string(), + dest_chain: "cosmoshub-4".to_string(), + channel: "channel-0".to_string(), + sender: "synor1abc...".to_string(), // Your address + receiver: "cosmos1xyz...".to_string(), // Recipient address + denom: "usyn".to_string(), + amount: "1000000".to_string(), // 1 SYN + memo: Some("Cross-chain transfer example".to_string()), + timeout_height: 0, // Use timestamp instead + timeout_timestamp, + }) + .await?; + + println!("Transfer initiated:"); + println!(" TX Hash: {}", transfer.tx_hash); + println!(" Sequence: {}", transfer.sequence); + println!(" Status: {}", transfer.status); + + // Track transfer status + println!("\nTracking transfer..."); + let status = ibc.transfers.get_status(&transfer.tx_hash).await?; + println!("Current status: {}", status.state); + println!(" Source confirmed: {}", status.source_confirmed); + println!(" Relayed: {}", status.relayed); + println!(" Dest confirmed: {}", status.dest_confirmed); + + // Get transfer history + let history = ibc.transfers.get_history("synor1abc...", 5).await?; + println!("\nTransfer history (last 5):"); + for tx in &history { + let direction = if tx.sender == "synor1abc..." { + "OUT" + } else { + "IN" + }; + println!(" {} {} {} ({})", direction, tx.amount, tx.denom, tx.status); + } + + // Get pending transfers + let pending = ibc.transfers.get_pending("synor1abc...").await?; + println!("\nPending transfers: {}", pending.len()); + + println!(); + Ok(()) +} + +async fn packet_example(ibc: &SynorIbc) -> Result<(), Box> { + println!("=== Packet Handling ==="); + + // Get pending packets + let packets = ibc.packets.get_pending("channel-0").await?; + println!("Pending packets on channel-0: {}", packets.len()); + + for packet in packets.iter().take(3) { + println!("\n Packet {}:", packet.sequence); + println!(" Source: {}/{}", packet.source_port, packet.source_channel); + println!(" Dest: {}/{}", packet.dest_port, packet.dest_channel); + println!(" State: {}", packet.state); + println!(" Data size: {} bytes", packet.data.len()); + println!(" Timeout height: {}", packet.timeout_height); + println!(" Timeout timestamp: {}", packet.timeout_timestamp); + } + + // Get packet by sequence + let packet = ibc.packets.get("channel-0", 1).await?; + println!("\nPacket details:"); + println!(" Commitment: {}", packet.commitment); + println!(" Receipt: {}", packet.receipt.unwrap_or_default()); + println!(" Acknowledgement: {}", packet.acknowledgement.unwrap_or_default()); + + // Get packet receipts + let receipts = ibc.packets.get_receipts("channel-0", &[1, 2, 3]).await?; + println!("\nPacket receipts:"); + for (seq, receipt) in &receipts { + let status = if *receipt { "received" } else { "not received" }; + println!(" Sequence {}: {}", seq, status); + } + + // Get timed out packets + let timed_out = ibc.packets.get_timed_out("channel-0").await?; + println!("\nTimed out packets: {}", timed_out.len()); + for p in &timed_out { + println!(" Sequence {}: timeout at {}", p.sequence, p.timeout_timestamp); + } + + // Get unreceived packets + let unreceived = ibc.packets.get_unreceived("channel-0").await?; + let unreceived_str = if unreceived.is_empty() { + "none".to_string() + } else { + format!("{:?}", unreceived) + }; + println!("\nUnreceived packet sequences: {}", unreceived_str); + + // Get unacknowledged packets + let unacked = ibc.packets.get_unacknowledged("channel-0").await?; + let unacked_str = if unacked.is_empty() { + "none".to_string() + } else { + format!("{:?}", unacked) + }; + println!("Unacknowledged packet sequences: {}", unacked_str); + + println!(); + Ok(()) +} + +async fn relayer_example(ibc: &SynorIbc) -> Result<(), Box> { + println!("=== Relayer Operations ==="); + + // Get active relayers + let relayers = ibc.relayers.list().await?; + println!("Active relayers: {}", relayers.len()); + + for relayer in relayers.iter().take(3) { + println!("\n {}:", relayer.address); + println!(" Chains: {:?}", relayer.chains); + println!(" Packets relayed: {}", relayer.packets_relayed); + println!(" Success rate: {:.1}%", relayer.success_rate); + println!(" Avg latency: {}ms", relayer.avg_latency); + println!(" Fee rate: {:.2}%", relayer.fee_rate); + } + + // Get relayer statistics + let stats = ibc.relayers.get_stats().await?; + println!("\nGlobal relayer statistics:"); + println!(" Total relayers: {}", stats.total_relayers); + println!(" Active relayers: {}", stats.active_relayers); + println!(" Packets relayed (24h): {}", stats.packets_relayed_24h); + println!(" Total fees earned: {}", stats.total_fees_earned); + + // Register as a relayer + println!("\nRegistering as relayer..."); + let registration = ibc + .relayers + .register(RelayerRegistration { + chains: vec!["synor-1".to_string(), "cosmoshub-4".to_string()], + fee_rate: 0.1, // 0.1% fee + min_packet_size: 0, + max_packet_size: 1000000, + }) + .await?; + println!("Registered with address: {}", registration.relayer_address); + + // Start relaying (in background) + println!("\nStarting relay service..."); + let relay_session = ibc + .relayers + .start_relay(RelayConfig { + channels: vec!["channel-0".to_string()], + auto_ack: true, + batch_size: 10, + poll_interval: 5000, + }) + .await?; + println!("Relay session started: {}", relay_session.session_id); + + // Get relay queue + let queue = ibc.relayers.get_queue("channel-0").await?; + println!("\nRelay queue for channel-0: {} packets", queue.len()); + + // Manually relay a packet + if let Some(first_packet) = queue.first() { + println!("\nRelaying packet..."); + let relay_result = ibc + .relayers + .relay_packet(first_packet.sequence, "channel-0") + .await?; + println!("Relay result: {}", relay_result.status); + println!(" TX Hash: {}", relay_result.tx_hash); + println!(" Fee earned: {}", relay_result.fee_earned); + } + + // Stop relay session + ibc.relayers.stop_relay(&relay_session.session_id).await?; + println!("\nRelay session stopped"); + + println!(); + Ok(()) +} + +async fn connection_example(ibc: &SynorIbc) -> Result<(), Box> { + println!("=== Connection Information ==="); + + // List connections + let connections = ibc.connections.list().await?; + println!("Total connections: {}", connections.len()); + + for conn in connections.iter().take(3) { + println!("\n {}:", conn.connection_id); + println!(" Client: {}", conn.client_id); + println!(" Counterparty: {}", conn.counterparty_connection_id); + println!(" State: {}", conn.state); + println!(" Versions: {:?}", conn.versions); + } + + // Get connection details + let connection = ibc.connections.get("connection-0").await?; + println!("\nConnection-0 details:"); + println!(" Delay period: {}ns", connection.delay_period); + println!(" Counterparty client: {}", connection.counterparty_client_id); + println!(" Counterparty prefix: {}", connection.counterparty_prefix); + + // Get client state + let client = ibc.clients.get(&connection.client_id).await?; + println!("\nClient state:"); + println!(" Chain ID: {}", client.chain_id); + println!(" Trust level: {}", client.trust_level); + println!(" Trusting period: {}", client.trusting_period); + println!(" Unbonding period: {}", client.unbonding_period); + println!(" Latest height: {}", client.latest_height); + println!(" Frozen: {}", client.frozen); + + // Get consensus state + let consensus = ibc + .clients + .get_consensus_state(&connection.client_id, client.latest_height) + .await?; + println!("\nConsensus state at height {}:", client.latest_height); + println!(" Timestamp: {}", consensus.timestamp); + let root_preview = if consensus.root.len() > 20 { + &consensus.root[..20] + } else { + &consensus.root + }; + println!(" Root: {}...", root_preview); + let validators_preview = if consensus.next_validators_hash.len() > 20 { + &consensus.next_validators_hash[..20] + } else { + &consensus.next_validators_hash + }; + println!(" Next validators hash: {}...", validators_preview); + + println!(); + Ok(()) +} diff --git a/sdk/rust/examples/zk_example.rs b/sdk/rust/examples/zk_example.rs new file mode 100644 index 0000000..d61a8b3 --- /dev/null +++ b/sdk/rust/examples/zk_example.rs @@ -0,0 +1,607 @@ +//! Synor ZK SDK Examples for Rust +//! +//! Demonstrates Zero-Knowledge proof operations: +//! - Circuit compilation +//! - Proof generation and verification +//! - Groth16, PLONK, and STARK proving systems +//! - Recursive proofs +//! - On-chain verification + +use std::collections::HashMap; +use std::env; +use std::time::Instant; +use synor_zk::{ + AggregateRequest, BatchVerifyRequest, CircuitFormat, CompileRequest, ContributeRequest, + DeployRequest, FormatProofRequest, GenerateProofRequest, GenerateVerifierRequest, + OnChainVerifyRequest, ProofData, ProvingSystem, SetupInitRequest, SynorZk, VerifyAggregatedRequest, + VerifyRequest, ZkConfig, +}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initialize client + let config = ZkConfig { + api_key: env::var("SYNOR_API_KEY").unwrap_or_else(|_| "your-api-key".to_string()), + endpoint: "https://zk.synor.io/v1".to_string(), + timeout: 120000, // ZK ops can be slow + retries: 3, + debug: false, + default_proving_system: ProvingSystem::Groth16, + }; + + let zk = SynorZk::new(config)?; + + // Check service health + let healthy = zk.health_check().await?; + println!("Service healthy: {}\n", healthy); + + // Run examples + circuit_example(&zk).await?; + proof_example(&zk).await?; + proving_systems_example(&zk).await?; + recursive_proof_example(&zk).await?; + on_chain_verification_example(&zk).await?; + setup_example(&zk).await?; + + zk.close().await?; + Ok(()) +} + +async fn circuit_example(zk: &SynorZk) -> Result<(), Box> { + println!("=== Circuit Compilation ==="); + + // Circom circuit example: prove knowledge of preimage + let circom_circuit = r#" + pragma circom 2.1.0; + + template HashPreimage() { + signal input preimage; + signal input hash; + + // Simplified hash computation (in reality, use proper hash) + signal preimageSquared; + preimageSquared <== preimage * preimage; + + // Constrain that hash matches + hash === preimageSquared; + } + + component main {public [hash]} = HashPreimage(); + "#; + + // Compile circuit + println!("Compiling Circom circuit..."); + let compiled = zk + .circuits + .compile(CompileRequest { + code: circom_circuit.to_string(), + format: CircuitFormat::Circom, + name: "hash_preimage".to_string(), + proving_system: ProvingSystem::Groth16, + }) + .await?; + + println!("Circuit compiled:"); + println!(" Circuit ID: {}", compiled.circuit_id); + println!(" Constraints: {}", compiled.constraint_count); + println!(" Public inputs: {}", compiled.public_input_count); + println!(" Private inputs: {}", compiled.private_input_count); + println!(" Proving key size: {} bytes", compiled.proving_key_size); + println!(" Verification key size: {} bytes", compiled.verification_key_size); + + // List circuits + let circuits = zk.circuits.list().await?; + println!("\nYour circuits: {}", circuits.len()); + for circuit in &circuits { + println!(" {} ({})", circuit.name, circuit.circuit_id); + } + + // Get circuit details + let details = zk.circuits.get(&compiled.circuit_id).await?; + println!("\nCircuit details:"); + println!(" Format: {:?}", details.format); + println!(" Proving system: {:?}", details.proving_system); + println!(" Created: {}", details.created_at); + + // Download proving key + let proving_key = zk.circuits.get_proving_key(&compiled.circuit_id).await?; + println!("\nProving key downloaded: {} bytes", proving_key.len()); + + // Download verification key + let verification_key = zk.circuits.get_verification_key(&compiled.circuit_id).await?; + println!("Verification key downloaded: {} bytes", verification_key.len()); + + println!(); + Ok(()) +} + +async fn proof_example(zk: &SynorZk) -> Result<(), Box> { + println!("=== Proof Generation ==="); + + // First, compile a simple circuit + let circuit = r#" + pragma circom 2.1.0; + + template Multiplier() { + signal input a; + signal input b; + signal output c; + + c <== a * b; + } + + component main {public [c]} = Multiplier(); + "#; + + let compiled = zk + .circuits + .compile(CompileRequest { + code: circuit.to_string(), + format: CircuitFormat::Circom, + name: "multiplier".to_string(), + proving_system: ProvingSystem::Groth16, + }) + .await?; + + // Generate proof + println!("Generating proof..."); + let start_time = Instant::now(); + + let mut inputs = HashMap::new(); + inputs.insert("a".to_string(), "3".to_string()); + inputs.insert("b".to_string(), "7".to_string()); + + let proof = zk + .proofs + .generate(GenerateProofRequest { + circuit_id: compiled.circuit_id.clone(), + inputs, + }) + .await?; + + let proof_time = start_time.elapsed(); + println!("Proof generated in {:?}", proof_time); + println!(" Proof ID: {}", proof.proof_id); + println!(" Proof size: {} bytes", proof.proof.len()); + println!(" Public signals: {:?}", proof.public_signals); + + // Verify proof + println!("\nVerifying proof..."); + let verify_start = Instant::now(); + + let is_valid = zk + .proofs + .verify(VerifyRequest { + circuit_id: compiled.circuit_id.clone(), + proof: proof.proof.clone(), + public_signals: proof.public_signals.clone(), + }) + .await?; + + let verify_time = verify_start.elapsed(); + println!("Verification completed in {:?}", verify_time); + println!(" Valid: {}", is_valid); + + // Verify with wrong public signals (should fail) + println!("\nVerifying with wrong signals..."); + let invalid_result = zk + .proofs + .verify(VerifyRequest { + circuit_id: compiled.circuit_id.clone(), + proof: proof.proof.clone(), + public_signals: vec!["42".to_string()], // Wrong answer + }) + .await?; + println!(" Valid: {} (expected false)", invalid_result); + + // Get proof status + let status = zk.proofs.get_status(&proof.proof_id).await?; + println!("\nProof status:"); + println!(" State: {}", status.state); + println!(" Verified: {}", status.verified); + println!(" Created: {}", status.created_at); + + // List proofs + let proofs = zk.proofs.list(&compiled.circuit_id).await?; + println!("\nProofs for circuit: {}", proofs.len()); + + println!(); + Ok(()) +} + +async fn proving_systems_example(zk: &SynorZk) -> Result<(), Box> { + println!("=== Proving Systems Comparison ==="); + + // Simple circuit for comparison + let circuit = r#" + pragma circom 2.1.0; + + template Comparison() { + signal input x; + signal input y; + signal output sum; + + sum <== x + y; + } + + component main {public [sum]} = Comparison(); + "#; + + let systems = [ + (ProvingSystem::Groth16, "GROTH16"), + (ProvingSystem::PLONK, "PLONK"), + (ProvingSystem::STARK, "STARK"), + ]; + + println!("Comparing proving systems:\n"); + + for (system, name) in systems { + println!("{}:", name); + + // Compile for this system + let compiled = zk + .circuits + .compile(CompileRequest { + code: circuit.to_string(), + format: CircuitFormat::Circom, + name: format!("comparison_{}", name.to_lowercase()), + proving_system: system, + }) + .await?; + + // Generate proof + let proof_start = Instant::now(); + let mut inputs = HashMap::new(); + inputs.insert("x".to_string(), "10".to_string()); + inputs.insert("y".to_string(), "20".to_string()); + + let proof = zk + .proofs + .generate(GenerateProofRequest { + circuit_id: compiled.circuit_id.clone(), + inputs, + }) + .await?; + let proof_time = proof_start.elapsed(); + + // Verify proof + let verify_start = Instant::now(); + zk.proofs + .verify(VerifyRequest { + circuit_id: compiled.circuit_id.clone(), + proof: proof.proof.clone(), + public_signals: proof.public_signals.clone(), + }) + .await?; + let verify_time = verify_start.elapsed(); + + println!(" Setup: {}ms", compiled.setup_time); + println!(" Proof time: {:?}", proof_time); + println!(" Verify time: {:?}", verify_time); + println!(" Proof size: {} bytes", proof.proof.len()); + println!(" Verification key: {} bytes", compiled.verification_key_size); + println!(); + } + + println!("Summary:"); + println!(" Groth16: Smallest proofs, fast verification, trusted setup required"); + println!(" PLONK: Universal setup, flexible, moderate proof size"); + println!(" STARK: No trusted setup, largest proofs, quantum resistant"); + + println!(); + Ok(()) +} + +async fn recursive_proof_example(zk: &SynorZk) -> Result<(), Box> { + println!("=== Recursive Proofs ==="); + + // Inner circuit + let inner_circuit = r#" + pragma circom 2.1.0; + + template Inner() { + signal input x; + signal output y; + y <== x * x; + } + + component main {public [y]} = Inner(); + "#; + + // Compile inner circuit + let inner = zk + .circuits + .compile(CompileRequest { + code: inner_circuit.to_string(), + format: CircuitFormat::Circom, + name: "inner_circuit".to_string(), + proving_system: ProvingSystem::Groth16, + }) + .await?; + + // Generate multiple proofs to aggregate + println!("Generating proofs to aggregate..."); + let mut proofs_to_aggregate = Vec::new(); + for i in 1..=4 { + let mut inputs = HashMap::new(); + inputs.insert("x".to_string(), i.to_string()); + + let proof = zk + .proofs + .generate(GenerateProofRequest { + circuit_id: inner.circuit_id.clone(), + inputs, + }) + .await?; + + proofs_to_aggregate.push(ProofData { + proof: proof.proof, + public_signals: proof.public_signals.clone(), + }); + println!(" Proof {}: y = {}", i, proof.public_signals[0]); + } + + // Aggregate proofs recursively + println!("\nAggregating proofs..."); + let aggregated = zk + .proofs + .aggregate(AggregateRequest { + circuit_id: inner.circuit_id.clone(), + proofs: proofs_to_aggregate.clone(), + aggregation_type: "recursive".to_string(), + }) + .await?; + + let original_size: usize = proofs_to_aggregate.iter().map(|p| p.proof.len()).sum(); + + println!("Aggregated proof:"); + println!(" Proof ID: {}", aggregated.proof_id); + println!(" Aggregated count: {}", aggregated.aggregated_count); + println!(" Proof size: {} bytes", aggregated.proof.len()); + println!( + " Size reduction: {:.1}%", + (1.0 - aggregated.proof.len() as f64 / original_size as f64) * 100.0 + ); + + // Verify aggregated proof + let public_signals_list: Vec> = proofs_to_aggregate + .iter() + .map(|p| p.public_signals.clone()) + .collect(); + + let is_valid = zk + .proofs + .verify_aggregated(VerifyAggregatedRequest { + circuit_id: inner.circuit_id.clone(), + proof: aggregated.proof, + public_signals_list, + }) + .await?; + println!("\nAggregated proof valid: {}", is_valid); + + // Batch verification (verify multiple proofs in one operation) + println!("\nBatch verification..."); + let batch_result = zk + .proofs + .batch_verify(BatchVerifyRequest { + circuit_id: inner.circuit_id.clone(), + proofs: proofs_to_aggregate, + }) + .await?; + println!(" All valid: {}", batch_result.all_valid); + println!(" Results: {:?}", batch_result.results); + + println!(); + Ok(()) +} + +async fn on_chain_verification_example(zk: &SynorZk) -> Result<(), Box> { + println!("=== On-Chain Verification ==="); + + // Compile circuit + let circuit = r#" + pragma circom 2.1.0; + + template VoteCommitment() { + signal input vote; // Private: actual vote + signal input nullifier; // Private: unique identifier + signal input commitment; // Public: commitment to verify + + // Simplified commitment (in practice, use Poseidon hash) + signal computed; + computed <== vote * nullifier; + commitment === computed; + } + + component main {public [commitment]} = VoteCommitment(); + "#; + + let compiled = zk + .circuits + .compile(CompileRequest { + code: circuit.to_string(), + format: CircuitFormat::Circom, + name: "vote_commitment".to_string(), + proving_system: ProvingSystem::Groth16, + }) + .await?; + + // Generate Solidity verifier + println!("Generating Solidity verifier..."); + let solidity_verifier = zk + .contracts + .generate_verifier(GenerateVerifierRequest { + circuit_id: compiled.circuit_id.clone(), + language: "solidity".to_string(), + optimized: true, + }) + .await?; + println!( + "Solidity verifier generated: {} bytes", + solidity_verifier.code.len() + ); + println!(" Contract name: {}", solidity_verifier.contract_name); + println!(" Gas estimate: {}", solidity_verifier.gas_estimate); + + // Generate proof + let mut inputs = HashMap::new(); + inputs.insert("vote".to_string(), "1".to_string()); // Vote YES (1) or NO (0) + inputs.insert("nullifier".to_string(), "12345".to_string()); + inputs.insert("commitment".to_string(), "12345".to_string()); // 1 * 12345 + + let proof = zk + .proofs + .generate(GenerateProofRequest { + circuit_id: compiled.circuit_id.clone(), + inputs, + }) + .await?; + + // Format proof for on-chain verification + println!("\nFormatting proof for on-chain..."); + let on_chain_proof = zk + .contracts + .format_proof(FormatProofRequest { + circuit_id: compiled.circuit_id.clone(), + proof: proof.proof.clone(), + public_signals: proof.public_signals.clone(), + format: "calldata".to_string(), + }) + .await?; + + let calldata_preview = if on_chain_proof.calldata.len() > 100 { + &on_chain_proof.calldata[..100] + } else { + &on_chain_proof.calldata + }; + println!(" Calldata: {}...", calldata_preview); + println!(" Estimated gas: {}", on_chain_proof.gas_estimate); + + // Deploy verifier contract (simulation) + println!("\nDeploying verifier contract..."); + let deployment = zk + .contracts + .deploy_verifier(DeployRequest { + circuit_id: compiled.circuit_id.clone(), + network: "synor-testnet".to_string(), + }) + .await?; + println!(" Contract address: {}", deployment.address); + println!(" TX hash: {}", deployment.tx_hash); + println!(" Gas used: {}", deployment.gas_used); + + // Verify on-chain + println!("\nVerifying on-chain..."); + let on_chain_result = zk + .contracts + .verify_on_chain(OnChainVerifyRequest { + contract_address: deployment.address, + proof: proof.proof, + public_signals: proof.public_signals, + network: "synor-testnet".to_string(), + }) + .await?; + println!(" TX hash: {}", on_chain_result.tx_hash); + println!(" Verified: {}", on_chain_result.verified); + println!(" Gas used: {}", on_chain_result.gas_used); + + // Generate verifier for other targets + println!("\nGenerating verifiers for other targets:"); + let targets = ["cairo", "noir", "ink"]; + for target in targets { + let verifier = zk + .contracts + .generate_verifier(GenerateVerifierRequest { + circuit_id: compiled.circuit_id.clone(), + language: target.to_string(), + optimized: false, + }) + .await?; + println!(" {}: {} bytes", target, verifier.code.len()); + } + + println!(); + Ok(()) +} + +async fn setup_example(zk: &SynorZk) -> Result<(), Box> { + println!("=== Trusted Setup ==="); + + // Get available ceremonies + let ceremonies = zk.setup.list_ceremonies().await?; + println!("Active ceremonies: {}", ceremonies.len()); + for ceremony in &ceremonies { + println!(" {}:", ceremony.name); + println!(" Status: {}", ceremony.status); + println!(" Participants: {}", ceremony.participant_count); + println!(" Current round: {}", ceremony.current_round); + } + + // Create a new circuit setup + let circuit = r#" + pragma circom 2.1.0; + + template NewCircuit() { + signal input a; + signal output b; + b <== a + 1; + } + + component main {public [b]} = NewCircuit(); + "#; + + println!("\nInitializing setup for new circuit..."); + let setup = zk + .setup + .initialize(SetupInitRequest { + circuit: circuit.to_string(), + format: CircuitFormat::Circom, + name: "new_circuit_setup".to_string(), + proving_system: ProvingSystem::Groth16, + ceremony_type: "powers_of_tau".to_string(), // or 'phase2' + }) + .await?; + println!("Setup initialized:"); + println!(" Ceremony ID: {}", setup.ceremony_id); + println!(" Powers of Tau required: {}", setup.powers_required); + println!(" Current phase: {}", setup.phase); + + // Contribute to ceremony (in practice, generates random entropy) + println!("\nContributing to ceremony..."); + let contribution = zk + .setup + .contribute(ContributeRequest { + ceremony_id: setup.ceremony_id.clone(), + entropy: hex::encode(b"random-entropy-from-user"), + }) + .await?; + println!("Contribution submitted:"); + println!(" Participant: {}", contribution.participant_id); + println!(" Contribution hash: {}", contribution.hash); + println!(" Verification status: {}", contribution.verified); + + // Get ceremony status + let status = zk.setup.get_status(&setup.ceremony_id).await?; + println!("\nCeremony status:"); + println!(" Phase: {}", status.phase); + println!(" Total contributions: {}", status.total_contributions); + println!(" Verified contributions: {}", status.verified_contributions); + println!(" Ready for finalization: {}", status.ready_for_finalization); + + // Finalize setup (when enough contributions) + if status.ready_for_finalization { + println!("\nFinalizing setup..."); + let finalized = zk.setup.finalize(&setup.ceremony_id).await?; + println!("Setup finalized:"); + println!(" Proving key hash: {}", finalized.proving_key_hash); + println!(" Verification key hash: {}", finalized.verification_key_hash); + println!(" Contribution transcript: {}", finalized.transcript_cid); + } + + // Download ceremony transcript + let transcript = zk.setup.get_transcript(&setup.ceremony_id).await?; + println!("\nCeremony transcript: {} bytes", transcript.len()); + + println!(); + Ok(()) +}