Walrus Dart SDK
A Dart client SDK for Walrus, the decentralized storage protocol built on Sui blockchain.
Note: This is a community-maintained SDK. For official SDKs, see Walrus Documentation.
Features
Store - Upload blobs to the Walrus networkRead - Retrieve blobs by their IDEncryption - Client-side AES-GCM encryption supportStreaming - Handle large files with streaming upload/downloadAsync/Await - Modern Dart async patternsFlutter Ready - Works seamlessly with Flutter mobile apps
Installation
Add walrus to your pubspec.yaml:
dependencies:
walrus: ^0.0.1
Then run:
dart pub get
# or for Flutter
flutter pub get
π Quick Start
Basic Usage
import 'package:walrus/walrus.dart';
void main() async {
// Initialize the client
final walrus = WalrusClient();
// Upload data
final data = Uint8List.fromList(utf8.encode('Hello, Walrus!'));
final result = await walrus.store(data);
print('Blob ID: ${result.blobId}');
print('URL: ${walrus.getBlobUrl(result.blobId)}');
// Download data
final retrieved = await walrus.read(result.blobId);
print('Content: ${utf8.decode(retrieved)}');
}
Upload an Image
import 'dart:io';
import 'package:walrus/walrus.dart';
void main() async {
final walrus = WalrusClient();
// Read image file
final imageBytes = await File('photo.jpg').readAsBytes();
// Upload with 5 epochs storage duration
final result = await walrus.store(
imageBytes,
epochs: 5,
);
print('Image URL: ${walrus.getBlobUrl(result.blobId)}');
}
Encrypted Storage
import 'package:walrus/walrus.dart';
void main() async {
// Initialize with encryption
final walrus = WalrusClient(
encryption: AesGcmEncryption(),
);
final sensitiveData = Uint8List.fromList(utf8.encode('Secret message'));
// Encrypt and upload
final result = await walrus.storeEncrypted(sensitiveData);
print('Blob ID: ${result.blobId}');
// Save these for later decryption!
print('Key: ${base64Encode(result.encryptionKey)}');
print('IV: ${base64Encode(result.iv)}');
// Decrypt and download
final decrypted = await walrus.readEncrypted(
result.blobId,
encryptionKey: result.encryptionKey,
iv: result.iv,
);
print('Decrypted: ${utf8.decode(decrypted)}');
}
Custom Configuration
final walrus = WalrusClient(
// Use mainnet endpoints
publisherUrl: 'https://publisher.walrus.site',
aggregatorUrl: 'https://aggregator.walrus.site',
// Or use testnet (default)
// publisherUrl: 'https://publisher.walrus-testnet.walrus.space',
// aggregatorUrl: 'https://aggregator.walrus-testnet.walrus.space',
);
π API Reference
WalrusClient
Constructor
WalrusClient({
String publisherUrl, // Publisher node URL
String aggregatorUrl, // Aggregator node URL
WalrusEncryption? encryption, // Optional encryption handler
Dio? dio, // Custom Dio instance
})
Methods
| Method | Description | Returns |
|---|---|---|
store(Uint8List data, {int? epochs, bool deletable}) |
Upload blob to network | Future<StoreResponse> |
storeFile(String path, {int? epochs, bool deletable}) |
Upload file by path | Future<StoreResponse> |
storeEncrypted(Uint8List data, {int? epochs}) |
Encrypt and upload | Future<EncryptedStoreResponse> |
read(String blobId) |
Download blob by ID | Future<Uint8List> |
readEncrypted(String blobId, {required key, required iv}) |
Download and decrypt | Future<Uint8List> |
getBlobUrl(String blobId) |
Get HTTP URL for blob | String |
getMetadata(String blobId) |
Get blob metadata | Future<BlobMetadata> |
exists(String blobId) |
Check if blob exists | Future<bool> |
StoreResponse
class StoreResponse {
final String blobId; // Unique blob identifier
final String? objectId; // Sui Object ID
final int? endEpoch; // Storage expiration epoch
final bool isNew; // True if newly created
}
EncryptedStoreResponse
class EncryptedStoreResponse {
final String blobId; // Blob ID on Walrus
final Uint8List encryptionKey; // AES key (keep secret!)
final Uint8List iv; // Initialization vector
}
π§ Flutter Integration
Display Walrus Images
import 'package:cached_network_image/cached_network_image.dart';
class WalrusImage extends StatelessWidget {
final String blobId;
final WalrusClient walrus = WalrusClient();
WalrusImage({required this.blobId});
@override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: walrus.getBlobUrl(blobId),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
}
Upload from Camera/Gallery
import 'package:image_picker/image_picker.dart';
Future<String?> uploadImage() async {
final picker = ImagePicker();
final image = await picker.pickImage(source: ImageSource.gallery);
if (image == null) return null;
final bytes = await image.readAsBytes();
final walrus = WalrusClient();
final result = await walrus.store(bytes);
return result.blobId;
}
π Network Endpoints
| Network | Publisher | Aggregator |
|---|---|---|
| Testnet | https://publisher.walrus-testnet.walrus.space |
https://aggregator.walrus-testnet.walrus.space |
| Mainnet | https://publisher.walrus.site |
https://aggregator.walrus.site |
π‘οΈ Error Handling
try {
final result = await walrus.store(data);
} on WalrusException catch (e) {
print('Walrus error: ${e.message}');
} on DioException catch (e) {
print('Network error: ${e.message}');
}
πΊοΈ Roadmap
Basic store/read operationsAES-GCM encryptionStreaming upload/download for large filesSui blockchain integration (Object management)Walrus Sites supportDeletable blobs managementMulti-publisher supportRetry with exponential backoff
π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create an issue (main)
- Create your feature branch (
git checkout -b feature/feature-name) - Commit your changes (
git commit -m 'Add some feature') - Push to the branch (
git push origin feature/feature-name) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/keem-hyun/walrus_dart.git
cd walrus
# Get dependencies
dart pub get
# Run tests
dart test
# Check formatting
dart format --set-exit-if-changed .
# Analyze code
dart analyze
π License
This project is licensed under the MIT License - see the LICENSE file for details.
π Links
π¬ Support
- π« Open an issue for bug reports
- π‘ Start a discussion for feature requests
- β Star this repo if you find it useful!