A Dart/Flutter client library for Storacha Network (formerly web3.storage). Upload files to IPFS and Filecoin with ease using UCAN delegations.
Note: This package is under active development. APIs may change as new features are added and the implementation is refined. Check the Development Status section for current capabilities.
- π¦ Space Management - Create and manage isolated storage namespaces
- π€ File Uploads - Upload files to IPFS/Filecoin via Storacha Network
- π UCAN Delegation Support - Work with delegations from Storacha CLI
- π Multi-platform - iOS, Android, Web, Windows, macOS, Linux
- π― Type-safe - Full Dart type safety with null safety
- π± Mobile-optimized - Efficient memory usage and chunked uploads
Current implementation status:
- β UCAN delegation support - Full support for delegations from Storacha CLI
- β Single file uploads - Upload files to IPFS/Filecoin
- β Parallel batch uploads - Upload up to 50 files concurrently with optimized polling
- β Space management - Create and manage storage spaces
- β Progress tracking - Per-file and aggregated progress for batch uploads
- π§ Backend workaround available - Optional backend proxy for enhanced reliability (see Configuration section)
- π In progress - Email-based authentication (use Storacha CLI delegations for now)
- π Planned - Directory uploads as unified DAG structures
To use this package with the production Storacha Network, you need:
-
Storacha CLI installed and configured:
npm install -g @storacha/cli storacha login [email protected]
-
A Storacha space created via the CLI:
storacha space create my-app-space
-
UCAN delegations created for your app's agent DID (see Usage section)
Note: This package is not yet published to pub.dev. Install directly from GitHub.
Add to your pubspec.yaml:
dependencies:
storacha_dart:
git:
url: https://github.com/QuantumAgentic/storacha_dart.git
ref: main # or specify a tag/commit for stabilityThen run:
flutter pub getFor production use, it's recommended to pin to a specific commit or tag:
dependencies:
storacha_dart:
git:
url: https://github.com/QuantumAgentic/storacha_dart.git
ref: 9050c9b # Specific commit hashYour app needs a unique identifier (DID) to receive delegations:
import 'package:storacha_dart/storacha_dart.dart';
// Generate a new agent (save this for later use!)
final agent = await Ed25519Signer.generate();
print('Agent DID: ${agent.did().did()}');
// Example output: did:key:z6MkqTtiRFtW67NtYNgGD5mGWCh3UJbYwLDNmXbQFjz4zqrzImportant: Save the agent's private key securely. You'll need it each time your app runs.
Use the Storacha CLI to delegate permissions to your agent:
# Create delegation with required capabilities
storacha delegation create <YOUR_AGENT_DID> \
--can 'space/blob/add' \
--can 'upload/add' \
--can 'space/index/add' \
--output delegation.carThis creates a delegation.car file that grants your agent permission to upload to your space.
Load the delegation and upload files:
import 'dart:io';
import 'dart:typed_data';
import 'package:storacha_dart/storacha_dart.dart';
// Load the delegation
final delegation = await Delegation.fromFile('delegation.car');
// Create client configuration
final agent = await Ed25519Signer.generate(); // Or load your saved agent
final config = ClientConfig(
principal: agent,
defaultProvider: 'did:web:up.storacha.network',
);
// Initialize client with delegation
final client = StorachaClient(config, delegations: [delegation]);
// Extract space DID from delegation
final spaceDid = delegation.capabilities.first.with_;
// Add and select the space
final space = Space(
did: spaceDid,
name: 'My Space',
signer: agent,
createdAt: DateTime.now(),
);
client.addSpace(space);
client.setCurrentSpace(spaceDid);
// Upload a file
final file = MemoryFile(
name: 'hello.txt',
bytes: Uint8List.fromList('Hello, Storacha!'.codeUnits),
);
final cid = await client.uploadFile(file);
print('Uploaded! CID: $cid');
print('View at: https://w3s.link/ipfs/$cid');
// Clean up
client.close();A space is an isolated storage namespace in Storacha. Each space has:
- A unique DID (Decentralized Identifier)
- Its own storage quota
- Independent access control via UCAN delegations
Create a space via the Storacha CLI:
storacha space create my-app-spaceUCAN (User Controlled Authorization Network) is a decentralized authorization system. Instead of sharing your credentials, you create delegations that grant specific permissions to other DIDs.
Required capabilities for uploads:
space/blob/add- Upload raw data blobsupload/add- Register uploaded contentspace/index/add- Create searchable indexes
Files are identified by their CID (Content Identifier):
- CIDs are derived from file content using cryptographic hashing
- Same content always produces the same CID
- CIDs are universally unique and verifiable
Access uploaded files via IPFS gateways:
https://w3s.link/ipfs/<CID>
https://ipfs.io/ipfs/<CID>
final config = ClientConfig(
principal: agent, // Your agent's signer
defaultProvider: 'did:web:up.storacha.network', // Storacha service DID
);
β οΈ Temporary Solution: This workaround ensures immediate IPFS retrieval while native receipt handling is being finalized.
If you experience issues with IPFS retrieval after upload, you can use a backend proxy:
final config = ClientConfig(
principal: agent,
defaultProvider: 'did:web:up.storacha.network',
backendUrl: 'https://your-backend.vercel.app', // Optional backend proxy
);The backend acts as a bridge to the official JavaScript client. This workaround will be removed in future versions once the native Dart flow is fully stable.
final options = UploadFileOptions(
chunkSize: 256 * 1024, // 256 KiB chunks (default)
onUploadProgress: (status) {
print('Progress: ${status.percentage?.toStringAsFixed(1)}%');
},
);
final cid = await client.uploadFile(file, options: options);Upload multiple files concurrently with optimized performance:
final files = [
MemoryFile(name: 'photo1.jpg', bytes: photo1Bytes),
MemoryFile(name: 'photo2.jpg', bytes: photo2Bytes),
MemoryFile(name: 'photo3.jpg', bytes: photo3Bytes),
];
final results = await client.uploadFiles(
files,
maxConcurrent: 10, // Upload up to 10 files simultaneously
onProgress: (loaded, total) {
print('Overall: ${(loaded / total * 100).toStringAsFixed(1)}%');
},
onFileComplete: (filename, cid) {
print('β $filename: $cid');
},
onFileError: (filename, error) {
print('β $filename failed: $error');
},
);
print('Uploaded ${results.length} files successfully');Performance: Optimized polling intervals (500ms) and timeouts (5s) provide 8-10x faster uploads compared to sequential processing.
See the example/ directory for complete examples:
- delegation_example.dart - UCAN delegation workflow
- upload_example.dart - File upload examples
Run examples:
dart run example/delegation_example.dart
dart run example/upload_example.dartThe package is organized into modules:
lib/src/
βββ client/ # Main client and configuration
βββ crypto/ # Signers and DID generation (Ed25519)
βββ ipfs/ # IPFS data structures (CID, CAR, UnixFS)
βββ ucan/ # UCAN delegation and invocation
βββ transport/ # HTTP communication with Storacha
βββ upload/ # Upload logic and blob handling
βββ filecoin/ # Filecoin piece CID calculation
Run tests:
dart testRun integration tests (requires valid delegation):
dart test test/integration/| Feature | Status | Notes |
|---|---|---|
| UCAN delegations | β Working | CAR and base64 formats supported |
| Single file upload | β Working | With temporary backend workaround |
| Batch parallel uploads | β Working | Up to 50 files concurrently, 8-10x faster |
| Space management | β Working | Local space management |
| Progress tracking | β Working | Per-file and aggregated progress |
| Optimized polling | β Working | 500ms intervals, 5s timeouts |
| Directory upload | β³ Planned | Unified DAG structure |
| Email authentication | β³ Planned | Use Storacha CLI for now |
| Receipt handling | π§ In Progress | Some edge cases remain |
| IPFS retrieval | π§ In Progress | Backend workaround available |
Contributions are welcome! This package is actively maintained by QuantumAgentic.
To contribute:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
Please note that APIs may evolve as new features are added and the implementation is refined.
MIT License with trademark restriction - see LICENSE file.
The name "QuantumAgentic" and associated trademarks may not be used to endorse products derived from this software without permission.
This is a community-driven Dart/Flutter implementation for Storacha Network. This package is not affiliated with or endorsed by Storacha Network or Protocol Labs.
For the official JavaScript implementation:
Made with β€οΈ by the QuantumAgentic team