Xandeum Dart SDK

Build decentralized storage applications on Solana with Dart & Flutter
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