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