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