synor/sdk/flutter/example/ibc_example.dart
Gulshan Yadav 9416d76108 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.
2026-01-28 14:15:51 +05:30

355 lines
12 KiB
Dart

/// 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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<void> 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('');
}