Durt2 Library

Overview

Durt2 is a Dart library designed for Duniter v2s blockchain and cryptocurrency management. It provides a comprehensive SDK for building Duniter applications with built-in wallet management, transaction processing, identity services, and GraphQL indexer integration.

Features

  • Polkadart Integration: Direct access to Duniter blockchain via WebSocket connections
  • Wallet Services: Comprehensive wallet and safe management with encrypted storage
  • Transaction Processing: Support for payments, certifications, identity operations, and Universal Dividends
  • GraphQL Services: Integration with Squid indexer for transaction history and Datapod for profiles
  • Multi-network Support: Seamless switching between networks (gdev, gtest, g1, local)
  • Auto-discovery: Automatic endpoint discovery and connection management
  • State Management Agnostic: Works with any state management solution (Riverpod, Provider, Bloc, etc.)
  • Multilingual BIP39: Support for multiple languages in mnemonic generation

Getting Started

Installation

Add Durt2 to your pubspec.yaml file:

dependencies:
  durt2: <version>

Run the following command to get the package:

flutter pub get

Basic Initialization

import 'package:durt2/durt2.dart';

void main() async {  
  // Choose your network
  final selectedNetwork = Networks.gtest; // or Networks.gdev, Networks.g1
  
  // Initialize Durt2 with network and key pair type
  final durt = Durt();
  await durt.init(
    network: selectedNetwork, 
    keyPairType: KeyPairType.ed25519
  );
  
  // Connect to the network
  await durt.connect();
  
  runApp(MyApp());
}

Accessing Services

Once initialized, you can access all services through the global Durt instance:

import 'package:durt2/durt2.dart';

// Access the global Durt instance
final durt = Durt.i;

// Access individual services
final walletService = durt.wallets;
final duniterService = durt.duniter;
final squidService = durt.squid;
final storageService = durt.storage;
final datapodService = durt.datapod;

// Get current network and connection status
final currentNetwork = durt.network;
final isConnected = durt.isConnected;
final connectionStatus = durt.duniterConnectionStatus;

// Listen to connection status changes
duniterServiceConnectionStatusStream.listen((status) {
  print('Connection status: $status');
});

Basic Usage Examples

Making a Payment

Future<void> sendPayment() async {
  final durt = Durt.i;
  
  // Get sender wallet
  final wallet = walletService.getWallet(derivationPath: '//0');
  final keypair = await walletService.getKeypair(wallet);
  
  // Send payment
  final transactionStream = duniterService.pay(
    keypair: keypair,
    destAddress: 'destination_address',
    amount: 10.0, // in G1 units
    comment: 'Payment comment',
  );
  
  // Listen to transaction status
  await for (final status in transactionStream) {
    print('Transaction status: ${status.state}');
    if (status.state == TransactionState.included) {
      print('Transaction included in block!');
      break;
    }
  }
}

Getting Wallet Balance

Future<void> getWalletBalance(String address) async {
  final durt = Durt.i;
  
  try {
    final balance = await storageService.getBalance(address);
    print('Balance: ${balance.transferable / 100} G1');
    print('Transferable: ${balance.transferable / 100} G1');
    print('Reserved: ${balance.reserved / 100} G1');
    print('Unclaimed UDs: ${balance.unclaimedUds}');
  } catch (e) {
    print('Error getting balance: $e');
  }
}

Transaction History

Future<void> getTransactionHistory(String address) async {
  final durt = Durt.i;
  
  try {
    final result = await squidService.client.getAccountHistory(
      address,
      number: 20,
    );
    
    if (result != null) {
      final transactions = result.transferConnection.edges;
      
      for (final edge in transactions) {
        final tx = edge.node;
        print('Amount: ${tx.value / 100} G1');
        print('Comment: ${tx.comment ?? 'No comment'}');
        print('From: ${tx.from}');
        print('To: ${tx.to}');
        print('---');
      }
    }
  } catch (e) {
    print('Error getting transaction history: $e');
  }
}

Network Configuration

Durt2 automatically discovers and manages endpoints for different networks. The configuration is handled through JSON files, which are used only to boostrap network scan and fallback:

  • config/duniter_endpoints.json: WebSocket endpoints for Duniter nodes
  • config/squid_endpoints.json: GraphQL endpoints for Squid indexers
  • config/datapod_endpoints.json: GraphQL endpoints for Datapod services

You can also set custom endpoints programmatically:

// Switch networks
await Durt.i.switchNetwork(Networks.gdev);

// Test endpoint connectivity
final isWorking = await Durt.i.testDuniterEndpoint('wss://example.com/ws');

// Set a fixed endpoint
await Durt.i.setFixedEndpoint('wss://custom-node.com/ws');

Connection Status Monitoring

void monitorConnectionStatus() {
  final durt = Durt.i;
  
  // Get current status
  print('Current connection status: ${duniterServiceConnectionStatus}');
  print('Is connected: ${isConnected}');
  
  // Listen to status changes
  duniterServiceConnectionStatusStream.listen((status) {
    switch (status) {
      case ConnectionStatus.connected:
        print('✅ Connected to Duniter network');
        break;
      case ConnectionStatus.connecting:
        print('🔄 Connecting to Duniter network...');
        break;
      case ConnectionStatus.disconnected:
        print('❌ Disconnected from Duniter network');
        break;
      case ConnectionStatus.error:
        print('⚠️ Connection error');
        break;
    }
  });
  
  // Also monitor Squid connection
  squidServiceConnectionStatusStream.listen((status) {
    print('Squid indexer status: $status');
  });
}

Advanced Features

Multi-language Mnemonic Support

// Generate mnemonic in user's language
final durt = Durt.i;
final mnemonic = await walletService.generateMnemonic(
  language: BidouilleLang.french, // or .english, .spanish, etc.
);

// Import wallet with automatic language detection
final wallet = await walletService.importWallet(
  mnemonic: 'words in any supported language',
  name: 'My Wallet',
);

Safe Management

// Create a new safe
final durt = Durt.i;
final safe = await walletService.createSafe(
  name: 'My Safe',
  password: 'secure_password',
);

// Set default safe
walletService.setDefaultSafeBoxNumber(safe.id);

Architecture

Durt2 follows a service-oriented architecture:

  • ConnectionManager: Handles network connections and endpoint discovery
  • WalletService: Manages wallets, safes, and cryptographic operations
  • DuniterService: Provides blockchain transaction capabilities
  • DuniterStorageService: Caches blockchain data with real-time subscriptions
  • SquidService: GraphQL client for transaction indexing
  • DatapodService: GraphQL client for profile and avatar services

All services are accessed through the main Durt singleton and integrated with Riverpod providers for reactive state management.

Libraries

durt2
objectbox.g