smoldot 0.1.1 copy "smoldot: ^0.1.1" to clipboard
smoldot: ^0.1.1 copied to clipboard

A Dart wrapper for smoldot-light, providing a lightweight Polkadot/Substrate client implementation via Rust FFI bindings

example/smoldot_example.dart

import 'dart:io';

import 'package:smoldot/smoldot.dart';

/// Example demonstrating the smoldot package
///
/// This example showcases all implemented features including:
/// - Client initialization and multi-chain management
/// - JSON-RPC requests (including concurrent requests)
/// - Chain subscriptions
/// - Chain information queries
void main() async {
  await basicExample();
  await jsonRpcExample();
  await chainInfoExample();
  await subscriptionExample();
  await multiChainExample();
  await concurrentRequestsExample();
}

/// Basic example showing client initialization and chain creation
Future<void> basicExample() async {
  print('\n=== Basic Example: Client Initialization & Chain Creation ===\n');

  // Create and initialize the client
  final client = SmoldotClient(
    config: SmoldotConfig(
      maxLogLevel: 3,
      maxChains: 8,
    ),
  );

  try {
    print('Initializing client...');
    await client.initialize();
    print('✓ Client initialized');

    // Load real Westend chain spec
    final chainSpecFile = File('test/fixtures/westend.json');
    if (!chainSpecFile.existsSync()) {
      print('⚠ Westend chain spec not found at test/fixtures/westend.json');
      print(
          '  Download it with: curl -o test/fixtures/westend.json https://raw.githubusercontent.com/smol-dot/smoldot/main/demo-chain-specs/westend.json');
      return;
    }

    print('Loading Westend chain spec...');
    final chainSpec = await chainSpecFile.readAsString();

    print('Adding Westend chain...');
    final chain = await client.addChain(
      AddChainConfig(chainSpec: chainSpec),
    );
    print('✓ Chain added with ID: ${chain.chainId}');
    print('✓ Westend chain successfully initialized');

    print('\nChain object created successfully!');
    print('Chain ID: ${chain.chainId}');
    print('Is disposed: ${chain.isDisposed}');

    // Test basic JSON-RPC request
    print('\nMaking system_chain request...');
    final chainName = await chain.request('system_chain', []);
    print('✓ Chain name: ${chainName.result}');
  } catch (e, stackTrace) {
    print('Error: $e');
    print('Stack trace: $stackTrace');
  } finally {
    print('\nDisposing client...');
    await client.dispose();
    print('✓ Client disposed');
  }
}

/// Example showing multi-chain support (relay + parachain)
Future<void> multiChainExample() async {
  print('\n=== Multi-Chain Example: Relay Chain + Parachain ===\n');

  final client = SmoldotClient();

  try {
    await client.initialize();
    print('✓ Client initialized');

    // Load Polkadot relay chain spec
    final polkadotSpecFile = File('test/fixtures/polkadot.json');
    if (!polkadotSpecFile.existsSync()) {
      print('⚠ Polkadot chain spec not found');
      print('  This example requires both Polkadot and Statemint chain specs');
      print(
          '  Download them from: https://github.com/smol-dot/smoldot/tree/main/demo-chain-specs');
      return;
    }

    print('Adding Polkadot relay chain...');
    final polkadotSpec = await polkadotSpecFile.readAsString();
    final polkadot = await client.addChain(
      AddChainConfig(chainSpec: polkadotSpec),
    );
    print('✓ Polkadot relay chain added (ID: ${polkadot.chainId})');

    // Note: Parachain support requires the parachain chain spec
    // and proper relay chain reference
    print('\nTo add a parachain, use:');
    print('  AddChainConfig(');
    print('    chainSpec: parachainSpec,');
    print('    potentialRelayChains: [polkadot.chainId],');
    print('  )');

    print('\nActive chains in client: ${client.chains.length}');
    for (final chain in client.chains) {
      print('  - Chain ID: ${chain.chainId}');
    }
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.dispose();
    print('✓ Client disposed');
  }
}

/// Example showing subscriptions to blockchain events
Future<void> subscriptionExample() async {
  print('\n=== Subscription Example ===\n');

  final client = SmoldotClient();

  try {
    await client.initialize();
    print('✓ Client initialized');

    final chainSpecFile = File('test/fixtures/westend.json');
    if (!chainSpecFile.existsSync()) {
      print('⚠ Westend chain spec not found');
      return;
    }

    final chainSpec = await chainSpecFile.readAsString();
    final chain = await client.addChain(
      AddChainConfig(chainSpec: chainSpec),
    );
    print('✓ Chain added');

    print('\nSubscribing to new block headers...');
    print('(Will receive 3 blocks then unsubscribe)');

    final subscription = chain.subscribe('chain_subscribeNewHeads', []);

    int blockCount = 0;
    await for (final response in subscription) {
      final header = response.result as Map<String, dynamic>;
      final blockNumber = header['number'] as String;
      final blockHash = header['parentHash'] as String;

      print('✓ New block #$blockNumber');
      print('  Hash: ${blockHash.substring(0, 20)}...');

      blockCount++;
      if (blockCount >= 3) {
        print('\nReceived 3 blocks, stopping subscription...');
        break;
      }
    }

    print('✓ Subscription completed');
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.dispose();
  }
}

/// Example showing JSON-RPC requests
Future<void> jsonRpcExample() async {
  print('\n=== JSON-RPC Example ===\n');

  final client = SmoldotClient();

  try {
    await client.initialize();
    print('✓ Client initialized');

    final chainSpecFile = File('test/fixtures/westend.json');
    if (!chainSpecFile.existsSync()) {
      print('⚠ Westend chain spec not found');
      return;
    }

    final chainSpec = await chainSpecFile.readAsString();
    final chain = await client.addChain(
      AddChainConfig(chainSpec: chainSpec),
    );
    print('✓ Chain added');

    print('\nMaking JSON-RPC requests...');

    final chainName = await chain.request('system_chain', []);
    print('✓ Chain: ${chainName.result}');

    final version = await chain.request('system_version', []);
    print('✓ Version: ${version.result}');

    final properties = await chain.request('system_properties', []);
    print('✓ Properties: $properties');

    final health = await chain.request('system_health', []);
    print('✓ Health: $health');
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.dispose();
  }
}

/// Example showing chain information queries
Future<void> chainInfoExample() async {
  print('\n=== Chain Information Example ===\n');

  final client = SmoldotClient();

  try {
    await client.initialize();
    print('✓ Client initialized');

    final chainSpecFile = File('test/fixtures/westend.json');
    if (!chainSpecFile.existsSync()) {
      print('⚠ Westend chain spec not found');
      return;
    }

    final chainSpec = await chainSpecFile.readAsString();
    final chain = await client.addChain(
      AddChainConfig(chainSpec: chainSpec),
    );
    print('✓ Chain added');

    print('\nGetting chain information...');

    // Get comprehensive chain info
    final info = await chain.getInfo();
    print('✓ Chain Info:');
    print('  Name: ${info.name}');
    print('  Status: ${info.status}');
    print('  Peers: ${info.peerCount}');
    print('  Best Block: #${info.bestBlockNumber}');
    print('  Best Hash: ${info.bestBlockHash?.substring(0, 20)}...');

    // Get individual pieces of information
    final blockNumber = await chain.getBestBlockNumber();
    print('\n✓ Best block number: $blockNumber');

    final blockHash = await chain.getBestBlockHash();
    print('✓ Best block hash: ${blockHash?.substring(0, 20)}...');

    final peerCount = await chain.getPeerCount();
    print('✓ Peer count: $peerCount');

    final status = await chain.getStatus();
    print('✓ Chain status: $status');

    // Get info for all chains
    final allInfo = await client.getAllChainInfo();
    print('\n✓ Total chains: ${allInfo.length}');
    for (final chainInfo in allInfo) {
      print('  - ${chainInfo.name} (${chainInfo.status})');
    }
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.dispose();
  }
}

/// Example showing concurrent JSON-RPC requests
Future<void> concurrentRequestsExample() async {
  print('\n=== Concurrent Requests Example ===\n');

  final client = SmoldotClient();

  try {
    await client.initialize();
    print('✓ Client initialized');

    final chainSpecFile = File('test/fixtures/westend.json');
    if (!chainSpecFile.existsSync()) {
      print('⚠ Westend chain spec not found');
      return;
    }

    final chainSpec = await chainSpecFile.readAsString();
    final chain = await client.addChain(
      AddChainConfig(chainSpec: chainSpec),
    );
    print('✓ Chain added');

    print('\nMaking 4 concurrent JSON-RPC requests...');

    final stopwatch = Stopwatch()..start();

    final futures = [
      chain.request('system_chain', []),
      chain.request('system_version', []),
      chain.request('system_name', []),
      chain.request('system_properties', []),
    ];

    final responses = await Future.wait(futures);
    stopwatch.stop();

    print('✓ All requests completed in ${stopwatch.elapsedMilliseconds}ms');
    print('\nResults:');
    print('  Chain: ${responses[0].result}');
    print('  Version: ${responses[1].result}');
    print('  Name: ${responses[2].result}');
    print('  Properties: ${responses[3].result}');
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.dispose();
  }
}
0
likes
150
points
60
downloads

Publisher

unverified uploader

Weekly Downloads

A Dart wrapper for smoldot-light, providing a lightweight Polkadot/Substrate client implementation via Rust FFI bindings

Homepage
Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

convert, ffi, meta, path

More

Packages that depend on smoldot