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