Xandeum Dart SDK

Xandeum Dart SDK

Build decentralized storage applications on Solana with Dart & Flutter

pub package License Dart Flutter Solana

Installation • Quick Start • API Reference • Examples


What is Xandeum?

Xandeum is a scalable storage layer for Solana dApps - think of it as a second tier of Solana accounts that can grow to exabytes and beyond. This SDK enables you to create file systems, manage files and directories, and store data on Xandeum's decentralized network of storage nodes (pNodes).

Use Cases

  • Decentralized Apps - Store user data, media files, and configurations
  • NFT Metadata - Host images, videos, and attributes off-chain
  • Web3 Games - Save game states, assets, and player data
  • DeFi Platforms - Archive transaction logs and historical data
  • Social Apps - Manage user-generated content at scale

Why Use This SDK?

  • Production Ready - Comprehensive error handling and path validation
  • Cross-Platform - Works with Flutter on iOS, Android, Web, and Desktop
  • Type-Safe - Full Dart type safety with null safety support
  • Real-Time - WebSocket subscriptions for transaction monitoring
  • Complete - All 18 storage operations supported

Installation

Add to your pubspec.yaml:

dependencies:
  xandeum: ^1.0.0
  solana: ^0.32.0

Install:

dart pub get

Quick Start

import 'package:xandeum/xandeum.dart';
import 'package:solana/solana.dart';

Future<void> main() async {
  final client = RpcClient('https://api.devnet.solana.com');
  final wallet = await Ed25519HDKeyPair.random();
  
  // 1. Create a file system
  final message = bigbang(replicaCount: 3, wallet: wallet.publicKey);
  
  // 2. Compile with blockhash
  final blockhash = await client.getRecentBlockhash();
  final compiled = message.compile(
    recentBlockhash: blockhash,
    feePayer: wallet.publicKey,
  );
  
  // 3. Sign and send
  final signedTx = SignedTx(message: compiled, signers: [wallet]);
  final signature = await client.sendTransaction(signedTx);
  
  print('File system created! Signature: $signature');
}

API Reference

File System Operations

bigbang() Create a new file system with replica count
armageddon() Destroy a file system and all its contents

File Operations

createFile() Create a new file at specified path
removeFile() Delete a file from the file system
renamePath() Rename or move a file/directory
copyPath() Copy a file or directory
move() Move a file or directory to new location

Directory Operations

createDirectory() Create a new directory
removeDirectory() Remove an empty directory
listDirectoryEntry() List all files and subdirectories

Content Operations

peek() Read file content between byte offsets
poke() Write data to file at specified position

Metadata Operations

exists() Check if file or directory exists
getMetadata() Retrieve file/directory metadata
assignCoowner() Assign co-owner permissions
getXandeumResult() Get transaction result with delay

Real-Time Subscriptions

subscribeResult() Subscribe to transaction results via WebSocket
unsubscribeResult() Unsubscribe from transaction results

Examples

Complete File Lifecycle

import 'package:xandeum/xandeum.dart';
import 'package:solana/solana.dart';

Future<void> fileLifecycle() async {
  final client = RpcClient('https://api.devnet.solana.com');
  final wallet = await Ed25519HDKeyPair.random();
  final rpcUrl = 'https://api.devnet.solana.com';
  
  // Create file
  final createMsg = createFile(
    fsid: '12345',
    path: '/documents',
    name: 'hello.txt',
    wallet: wallet.publicKey,
  );
  
  final blockhash = await client.getRecentBlockhash();
  final compiled = createMsg.compile(
    recentBlockhash: blockhash,
    feePayer: wallet.publicKey,
  );
  final signedTx = SignedTx(message: compiled, signers: [wallet]);
  await client.sendTransaction(signedTx);
  
  // Check if file exists
  final fileExists = await exists(
    rpcUrl: rpcUrl,
    path: '/documents/hello.txt',
  );
  print('File exists: $fileExists');
  
  // Get metadata
  final metadata = await getMetadata(
    rpcUrl: rpcUrl,
    path: '/documents/hello.txt',
  );
  print('Metadata: $metadata');
  
  // Remove file
  final removeMsg = removeFile(
    fsid: '12345',
    path: '/documents/hello.txt',
    wallet: wallet.publicKey,
  );
  // ... compile and send
}

Real-Time Transaction Monitoring

Future<void> monitorTransactions() async {
  final rpcEndpoint = 'https://api.devnet.solana.com';
  final transactionId = 'your-transaction-signature';
  
  await subscribeResult(
    rpcEndpoint: rpcEndpoint,
    tx: transactionId,
    onResult: (result) {
      print('Transaction confirmed!');
      print('Status: ${result.status}');
      print('Data: ${result.data}');
    },
    onError: (error) => print('Error: $error'),
    onClose: () => print('Connection closed'),
  );
}

Batch Operations

Future<void> batchOperations() async {
  final wallet = await Ed25519HDKeyPair.random();
  
  // Create multiple files in sequence
  final files = ['doc1.txt', 'doc2.txt', 'doc3.txt'];
  
  for (final filename in files) {
    final message = createFile(
      fsid: '12345',
      path: '/batch',
      name: filename,
      wallet: wallet.publicKey,
    );
    
    // Compile and send each message
    // ... (compile and send logic)
  }
}

Path Validation

All paths are automatically validated:

  • Valid: /documents/file.txt
  • Valid: /path/to/data.json
  • Invalid: ../etc/passwd (path traversal)
  • Invalid: /path//double (consecutive slashes)
  • Invalid: /path<invalid> (illegal characters)

Paths must:

  • Not be empty
  • Not contain .. (path traversal)
  • Not have consecutive slashes
  • Only use: alphanumeric, /, _, -, .
  • Component length ≤ 255 bytes
  • Total length ≤ 4096 bytes

Testing

Run the test suite:

dart test

Quick verification:

dart run scripts/verify_sdk.dart

Contributing

Contributions welcome! Please open issues or submit pull requests on GitHub.

Resources

License

Apache 2.0 - See LICENSE for details.


Built with 💜 for the Solana ecosystem

Libraries

xandeum
Xandeum SDK for Dart