๐ŸŒŠ Coral XYZ Anchor for Dart

pub package style: very good analysis License: MIT

A comprehensive Dart client for Anchor programs on Solana, bringing the power and ease of the TypeScript @coral-xyz/anchor package to the Dart ecosystem.

โšก Quick Start

Add to your pubspec.yaml:

dependencies:
  coral_xyz: ^1.0.0

Simple counter example:

import 'package:coral_xyz/coral_xyz_anchor.dart';

void main() async {
  // Connect to Solana devnet
  final connection = Connection('https://api.devnet.solana.com');

  // Set up your wallet
  final wallet = Keypair.fromSecretKey(yourSecretKey);
  final provider = AnchorProvider(connection, wallet);

  // Load your program
  final program = Program(idl, programId, provider);

  // Initialize counter
  await program.methods
    .initialize()
    .accounts({'counter': counterKeypair.publicKey})
    .signers([counterKeypair])
    .rpc();

  // Increment counter
  await program.methods
    .increment()
    .accounts({'counter': counterKeypair.publicKey})
    .rpc();

  // Fetch counter value
  final account = await program.account.counter.fetch(counterKeypair.publicKey);
  print('Counter value: ${account.count}');
}

๐Ÿš€ Features

  • ๐Ÿ”’ Type-Safe: Full type safety with Dart's null safety and strong typing system
  • ๐Ÿ“‹ IDL-Based: Automatic generation of type-safe program interfaces from Anchor IDL files
  • ๐ŸŒ Cross-Platform: Works on mobile (Flutter), web, and desktop applications
  • โšก Modern Async: Built with Dart's excellent async/await support
  • ๐ŸŽฏ TypeScript Parity: Feature-complete implementation matching @coral-xyz/anchor
  • ๐Ÿ‘จโ€๐Ÿ’ป Developer-Friendly: Intuitive API design that feels natural to Dart developers
  • ๐Ÿ“Š Event System: Comprehensive event listening and parsing capabilities
  • ๐Ÿ”ง Extensible: Built-in support for custom coders and advanced use cases

๐Ÿ“š Documentation

Core Concepts

๐Ÿ”Œ Provider

The provider manages your connection to the Solana cluster and wallet:

// Connect to different networks
final devnetConnection = Connection('https://api.devnet.solana.com');
final mainnetConnection = Connection('https://api.mainnet-beta.solana.com');

// Create provider with wallet
final provider = AnchorProvider(connection, wallet, AnchorProviderOptions(
  commitment: Commitment.confirmed,
  preflightCommitment: Commitment.confirmed,
));

๐Ÿ“ Program

Load and interact with Anchor programs:

// Load program from IDL
final program = Program(idl, programId, provider);

// Call program methods
final signature = await program.methods
  .myInstruction(arg1, arg2)
  .accounts({
    'account1': publicKey1,
    'account2': publicKey2,
  })
  .signers([additionalSigner])
  .rpc();

// Fetch account data
final accountData = await program.account.myAccount.fetch(accountAddress);

// Listen to program events
program.addEventListener('MyEvent', (event, slot, signature) {
  print('Event received: ${event.data}');
});

๐Ÿ“„ IDL Management

Work with Interface Definition Language files:

// Load from JSON
final idl = Idl.fromJson(idlJsonString);

// Fetch from on-chain
final idl = await Idl.fetchFromAddress(programId, provider);

// Validate IDL structure
final validationResult = IdlUtils.validateIdl(idl);
if (validationResult.hasErrors) {
  print('IDL validation errors: ${validationResult.errors}');
}

๐Ÿ—๏ธ Advanced Usage

๐Ÿ”— Custom Account Resolution

final result = await program.methods
  .complexInstruction()
  .accountsResolver((accounts) async {
    // Derive PDAs dynamically
    final (derivedAccount, bump) = await PublicKey.findProgramAddress(
      [utf8.encode('seed'), userPublicKey.toBytes()],
      programId
    );

    return {
      ...accounts,
      'derivedAccount': derivedAccount,
    };
  })
  .rpc();

๐Ÿ”จ Transaction Building

// Build transaction manually
final transaction = await program.methods
  .myInstruction()
  .accounts(accounts)
  .transaction();

// Add additional instructions
transaction.add(SystemProgram.transfer(
  fromPubkey: wallet.publicKey,
  toPubkey: recipient,
  lamports: amount,
));

// Send with custom options
final signature = await provider.sendAndConfirm(
  transaction,
  signers: [wallet],
  options: ConfirmOptions(commitment: Commitment.finalized),
);

๐Ÿ“ฆ Batch Operations

// Send multiple transactions in parallel
final signatures = await provider.sendAll([
  SendTxRequest(
    tx: await program.methods.instruction1().transaction(),
    signers: [keypair1],
  ),
  SendTxRequest(
    tx: await program.methods.instruction2().transaction(),
    signers: [keypair2],
  ),
]);

๐ŸŽฏ Event Filtering and Aggregation

// Advanced event filtering
program.addEventListener('Transfer', (event, slot, signature) {
  final transfer = event.data as TransferEvent;
  if (transfer.amount > 1000000) { // Only large transfers
    print('Large transfer detected: ${transfer.amount} lamports');
  }
});

// Event aggregation
final eventStats = await program.getEventStatistics(
  eventName: 'Transfer',
  startSlot: startSlot,
  endSlot: endSlot,
);

๐Ÿ”„ TypeScript Anchor Compatibility

This package provides 1:1 feature parity with the TypeScript @coral-xyz/anchor package:

TypeScript Feature Dart Equivalent Status
Program.methods program.methods โœ… Complete
Program.account program.account โœ… Complete
Program.instruction program.instruction โœ… Complete
Program.transaction program.transaction โœ… Complete
Program.rpc program.rpc โœ… Complete
Program.simulate program.simulate โœ… Complete
Program.addEventListener program.addEventListener โœ… Complete
AnchorProvider AnchorProvider โœ… Complete
Wallet interface Wallet interface โœ… Complete
IDL types Idl classes โœ… Complete
BorshCoder BorshCoder โœ… Complete
AccountsCoder AccountsCoder โœ… Complete
EventParser EventParser โœ… Complete

๐Ÿ“ฑ Flutter Integration

Perfect for mobile dApps:

// Flutter example
class SolanaCounterApp extends StatefulWidget {
  @override
  _SolanaCounterAppState createState() => _SolanaCounterAppState();
}

class _SolanaCounterAppState extends State<SolanaCounterApp> {
  late Program counterProgram;
  int currentCount = 0;

  @override
  void initState() {
    super.initState();
    _initializeProgram();
  }

  Future<void> _initializeProgram() async {
    final connection = Connection('https://api.devnet.solana.com');
    final provider = AnchorProvider(connection, wallet);
    counterProgram = Program(counterIdl, counterProgramId, provider);

    // Listen for counter updates
    counterProgram.addEventListener('CounterUpdated', (event, slot, signature) {
      setState(() {
        currentCount = event.data.newValue;
      });
    });
  }

  Future<void> _incrementCounter() async {
    await counterProgram.methods
      .increment()
      .accounts({'counter': counterAddress})
      .rpc();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Solana Counter')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Counter: $currentCount', style: Theme.of(context).textTheme.headlineMedium),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _incrementCounter,
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

๐Ÿ—๏ธ Examples

Explore comprehensive examples in the example/ directory:

More Flutter Example Apps: You can find additional Flutter integration examples and sample apps at: https://github.com/Immadominion/coral-xyz-examples

The voting_app showcases the revolutionary simplicity of dart-coral-xyz:

  • 57% Less Code: 327 lines vs 766+ lines compared to manual Solana integration
  • Real-time Updates: Live vote count updates using automatic Borsh deserialization
  • Production Ready: Modern Flutter UI with error handling and state management
  • Type Safety: Full Dart type safety with automatic IDL-driven development

Before dart-coral-xyz (Manual Implementation):

// ๐Ÿ˜ฐ Hundreds of lines of manual Borsh serialization
List<int> accountBytes = base64Decode(data);
final dataBytes = accountBytes.sublist(8);
int offset = 0;
// ... 400+ more lines of error-prone parsing

After dart-coral-xyz:

// ๐ŸŽ‰ Simple, clean, reliable
final accountData = await program.account['Poll']!.fetch(pollAddress);
// Vote counts are ALWAYS accurate - no manual parsing!

๐Ÿงช Testing

This package includes comprehensive test coverage:

# Run all tests
dart test

# Run specific test categories
dart test test/idl_test.dart          # IDL parsing and validation
dart test test/program_test.dart      # Program interaction
dart test test/event_test.dart        # Event system
dart test test/integration_test.dart  # Integration tests

All tests use mocks and do not require a local Solana validator.

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development Setup

  1. Clone the repository:

    git clone https://github.com/coral-xyz/dart-coral-xyz.git
    cd dart-coral-xyz
    
  2. Install dependencies:

    dart pub get
    
  3. Run tests:

    dart test
    
  4. Run analysis:

    dart analyze
    dart format --set-exit-if-changed .
    

Code Standards

  • Follow Effective Dart guidelines
  • Maintain 100% test coverage for new features
  • Add comprehensive dartdoc comments for public APIs
  • Ensure all changes pass CI checks

๐Ÿ“Š Performance

Optimized for production use:

  • Memory Efficient: Minimal memory footprint with efficient object pooling
  • Network Optimized: Intelligent batching and caching of RPC calls
  • Type Safe: Zero runtime type errors with compile-time guarantees
  • Async First: Non-blocking operations with proper error handling

๐Ÿ” Security

Security best practices built-in:

  • Secure by Default: Safe defaults for all operations
  • Input Validation: Comprehensive validation of all inputs
  • Error Handling: Graceful handling of network and program errors
  • Audit Trail: Comprehensive logging for debugging and monitoring

๐Ÿ“‹ Roadmap

  • x Phase 1: Core IDL and program infrastructure
  • x Phase 2: Borsh serialization and type system
  • x Phase 3: Provider and connection management
  • x Phase 4: Namespace generation and method builders
  • x Phase 5: Event system and parsing
  • x Phase 6: Advanced features and optimizations
  • Phase 7: Flutter-specific optimizations
  • Phase 8: Advanced CPI and large transaction support
  • Phase 9: Performance monitoring and analytics

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments

  • Coral XYZ for the original TypeScript implementation
  • Solana Foundation for the Solana blockchain
  • The Dart and Flutter communities for their excellent tooling
  • All contributors who have helped improve this package

Built with โค๏ธ for the Solana ecosystem

โญ Star us on GitHub | ๐Ÿ› Report Issues | ๐Ÿ’ฌ Join Discord

Libraries

coral_xyz
Coral XYZ Anchor for Dart