/// Synor IBC SDK Examples for Flutter/Dart /// /// Demonstrates Inter-Blockchain Communication operations: /// - Cross-chain token transfers /// - Channel management /// - Packet handling /// - Relayer operations library; 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(''); }