A complete, production-ready IPFS (InterPlanetary File System) implementation in Dart, supporting offline, gateway, and full P2P modes. Built for mobile (Flutter), desktop, and web platforms.
TL;DR: A pure-Dart IPFS node for mobile, desktop, and web. Supports offline content-addressable storage, full P2P networking with NAT traversal, HTTP gateways, and production-grade security.
- Wiki β Guides, Installation, Architecture
- API Reference β Auto-generated Dart docs
- What's New in v1.8
- Features
- Quick Start
- Configuration
- Use Cases
- Architecture
- Security
- Performance
- Known Limitations
- Troubleshooting
- Examples
- Contributing
- Roadmap
- License
| Feature | Description |
|---|---|
| Native libp2p Core | Fully migrated to dart_libp2p for standard IPFS networking |
| 95% Router Coverage | Core Libp2pRouter achieves 95.6% test coverage |
| Stability Baseline | 100% pass rate confirmed across 1098 unit/integration tests |
| Cleanup | Removed all legacy p2plib dependencies and shims |
| Feature | Status | Details |
|---|---|---|
| Protobuf 6.0.0 | β COMPATIBLE | Full support for latest protobuf version |
| dart_libp2p Integration | β FIXED | Resolved PbList/createRepeated() issues |
| Any/Timestamp Types | β RESOLVED | Fixed import conflicts in 5 critical files |
| Test Suite | β 1098 TESTS PASSING | Verified comprehensive functionality |
| Backward Compatibility | β MAINTAINED | Seamless upgrade from protobuf 5.x |
- Well-known types: Use
package:protobuf/well_known_types/google/protobuf/[type].pb.dart - Import patterns: Avoid local copies of
any.pb.dart/timestamp.pb.dart - Dependency: Updated to
protobuf: ^6.0.0inpubspec.yaml
| Feature | Description |
|---|---|
| libp2p Bridge | TCP/Noise transport to connect with standard libp2p nodes |
| Circuit Relay v2 | Full HOP/STOP/RESERVE implementation for hole-punching |
| AutoNAT | Automatic NAT type detection (symmetric/restricted/none) |
| S/Kademlia PoW | Sybil attack protection for DHT routing |
| Encrypted Keystore | AES-256-GCM with PBKDF2 key derivation |
- SEC-001: Secure random number generation
- SEC-002: NAT traversal security controls
- SEC-004: Hardened command execution
- SEC-005: S/Kademlia Proof-of-Work
- SEC-008: Encrypted key storage
- SEC-010: DHT rate limiting
- 1098 tests passing
- Resolved 50+ issues since v1.7.0
- Protocol compliance with go-ipfs (Kubo)
- Content-Addressable Storage: CID v0 and v1 support
- UnixFS: Full file system implementation with chunking
- DAG-PB: MerkleDAG operations and IPLD traversal
- CAR Files: Import/export support
- Pinning: Content persistence management
- Bitswap 1.2.0: Efficient block exchange with wantlist management
- Kademlia DHT: Distributed hash table for peer/content routing
- AutoNAT: Automatic NAT type detection
- Direct connectivity testing
- Symmetric NAT detection
- Periodic dialback verification
- UPnP/NAT-PMP: Automatic port mapping via
NatTraversalService - Circuit Relay v2: Hole-punching via relay peers
- HOP protocol (relay serving)
- STOP protocol (connection handling)
- RESERVE protocol (relay reservations)
- libp2p Core: Native TCP/Noise transport for standard P2P networking
- PubSub: Real-time messaging (Gossipsub)
- mDNS: Local peer discovery
- Bootstrap Peers: Network connectivity initialization
- HTTP Gateway: Read-only and writable modes
- RPC API: Compatible with go-ipfs API
- IPNS: Mutable naming system with Ed25519 signatures
- DNSLink: Domain-based content resolution
- GraphSync: Efficient graph synchronization protocol
- Metrics: Prometheus-compatible monitoring
- Production Cryptography
- secp256k1 key exchange (128-bit security)
- ChaCha20-Poly1305 AEAD encryption
- SHA-256 content hashing
- Ed25519 IPNS signatures
- Encrypted Keystore (SEC-008)
- AES-256-GCM encryption
- PBKDF2 key derivation
- Automatic key rotation
- Memory zeroing on lock
- Sybil Protection (SEC-005)
- S/Kademlia Proof-of-Work for PeerId verification
- Configurable difficulty via
SecurityConfig.dhtDifficulty
- Rate Limiting
- Per-client authentication throttling
- DHT provider announcement limits
- Content Verification
- Automatic CID validation
- Merkle tree verification
- Block integrity checks
IPFSWebNode: Browser-compatible implementation- IndexedDB Storage: Persistent local storage
- WebSocket Transport: Networking via secure relays
- Bitswap & PubSub: Full protocol support in browsers
Add to your pubspec.yaml:
dependencies:
dart_ipfs: ^1.9.0Or from Git for latest development:
dependencies:
dart_ipfs:
git:
url: https://github.com/jxoesneon/IPFS.gitThen run:
dart pub getImportant: On Windows, P2P networking requires libsodium for cryptography.
β
Automatic Setup: dart_ipfs automatically detects and installs libsodium via winget on first run.
Manual Installation (if auto-install fails):
# Via winget (recommended)
winget install jedisct1.libsodium
# Or use offline mode (no P2P)
IPFSConfig(offline: true)import 'package:dart_ipfs/dart_ipfs.dart';
void main() async {
final node = await IPFSNode.create(
IPFSConfig(
dataDir: './ipfs_data',
offline: true, // No P2P networking
),
);
await node.start();
// Add content
final cid = await node.add('Hello, IPFS!');
print('Added with CID: $cid');
// Retrieve content
final retrieved = await node.cat(cid);
print('Retrieved: $retrieved');
await node.stop();
}final node = await IPFSNode.create(
IPFSConfig(
dataDir: './gateway_data',
offline: true,
gateway: GatewayConfig(
enabled: true,
port: 8080,
),
),
);
await node.start();
print('Gateway running at http://localhost:8080');
// Access content at: http://localhost:8080/ipfs/<CID>final node = await IPFSNode.create(
IPFSConfig(
dataDir: './p2p_data',
offline: false, // Enable P2P networking
network: NetworkConfig(
bootstrapPeers: [
'/dnsaddr/bootstrap.libp2p.io/p2p/...',
],
enableNatTraversal: true, // UPnP/NAT-PMP
),
),
);
await node.start();
print('P2P Node ID: ${node.peerID}');
// Node participates in DHT, Bitswap, PubSubimport 'package:dart_ipfs/src/core/ipfs_node/ipfs_web_node.dart';
void main() async {
final node = IPFSWebNode(
bootstrapPeers: ['wss://relay.node.address/p2p/...'],
);
await node.start();
final cid = await node.add(Uint8List.fromList('Hello Web!'.codeUnits));
print('Added: $cid');
final data = await node.get(cid.encode());
print('Retrieved: ${String.fromCharCodes(data!)}');
}IPFSConfig(
// Storage
dataDir: './ipfs_data',
// Networking
offline: false,
network: NetworkConfig(
bootstrapPeers: [...],
listenAddresses: ['/ip4/0.0.0.0/tcp/4001'],
enableNatTraversal: true, // UPnP/NAT-PMP port mapping
),
// Gateway
gateway: GatewayConfig(
enabled: true,
port: 8080,
writable: false,
cacheSize: 1024 * 1024 * 1024, // 1GB
),
// RPC API
rpc: RPCConfig(
enabled: true,
port: 5001,
),
// DHT
dht: DHTConfig(
mode: DHTMode.server, // client, server, or auto
bucketSize: 20,
),
// Security
security: SecurityConfig(
dhtDifficulty: 16, // S/Kademlia PoW difficulty
rateLimitWindow: Duration(minutes: 1),
maxAuthAttempts: 5,
keyRotationInterval: Duration(days: 30),
),
// Logging
debug: false,
verboseLogging: false,
)final file = File('document.pdf');
final bytes = await file.readAsBytes();
final cid = await node.addBytes(bytes);
print('Document CID: $cid');
// Content is permanently addressablefinal config = IPFSConfig(
gateway: GatewayConfig(
enabled: true,
port: 8080,
cacheSize: 1024 * 1024 * 1024,
),
);// PubSub messaging
await node.pubsub.subscribe('my-topic', (message) {
print('Received: $message');
});
await node.pubsub.publish('my-topic', 'Hello, peers!');final websiteDir = Directory('./my-website');
final rootCID = await node.addDirectory(websiteDir);
// Access via: http://gateway/ipfs/<rootCID>/index.htmlβββββββββββββββββββββββββββββββββββββββ
β Application Layer β
β (Your Dart/Flutter Application) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β dart_ipfs Public API β
β (IPFSNode, add, cat, pin, etc.) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Service Layer β
β Gateway β RPC β PubSub β IPNS β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Protocol Layer β
β Bitswap β DHT β GraphSync β Relay β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Transport Layer β
β P2P (Native libp2p) β
β AutoNAT β Circuit Relay v2 β
β Crypto (Ed25519 + Noise) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Storage Layer β
β UnixFS β DAG-PB β BlockStore β
β Datastore (Hive) β Pinning β
βββββββββββββββββββββββββββββββββββββββ
IMPORTANT: Production use requires strict sandboxing. See
docker-compose.ymlfor a secure reference implementation.
- Immutable Filesystem: Run with a read-only root
- Non-Root Execution: Use UID > 1000 (e.g.,
10001) - Network Isolation: Bind ports to localhost (
127.0.0.1) only - IP Diversity Limits: Max 5 peers/IP to prevent routing table poisoning
// Unlock keystore with password
await node.securityManager.unlockKeystore('your-password');
// Keys are encrypted at rest with AES-256-GCM
// Master key derived via PBKDF2
// Automatic memory zeroing on lock// Enable Sybil protection in DHT
SecurityConfig(
dhtDifficulty: 16, // Require 16-bit PoW prefix
)
// Peers with insufficient PoW are rejected from routing table| Metric | Value |
|---|---|
| Content Hashing | ~50 MB/s (SHA-256) |
| Block Storage | ~1000 ops/sec (Hive) |
| Gateway Latency | <10ms (local cache hit) |
| P2P Handshake | <100ms (secp256k1 ECDH) |
| Memory Baseline | ~50MB + content cache |
None.
Symptom: Hangs during startup
Solution: Install libsodium:
winget install jedisct1.libsodiumSymptom: Peers can't connect to you
Solution: Enable port mapping:
NetworkConfig(enableNatTraversal: true)Symptom: findProviders takes >30s
Solution: Ensure bootstrap peers are reachable and check dhtDifficulty isn't too high.
Symptom: Content not found even though added
Solution: Check if content is pinned:
await node.pin(cid);See the example/ directory for full applications:
- π± Premium Dashboard: Flutter desktop app with glassmorphism UI
- π CLI Dashboard: Matrix-style terminal interface
Other examples:
- Basic Usage
- Offline Blog
- P2P Networking
- HTTP Gateway
- Full Node
- Keystore Unlock
- libp2p Bridge Verification
Run examples:
dart run example/blog_use_case.dart
dart run example/online_test.dart# Run all tests
dart test
# Run with verbose output
dart test -r expanded
# Static analysis
dart analyzeExpected results:
- β 0 errors
- β 0 warnings
- β 1098 tests pass
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure
dart analyzeanddart testpass - Submit a pull request
- Core IPFS protocols (Bitswap, DHT, PubSub)
- Offline, Gateway, and P2P modes
- Production cryptography
- Web platform support
- libp2p core migration
- Circuit Relay v2
- AutoNAT
- Encrypted keystore
- S/Kademlia PoW
- 95%+ Router Coverage
- Mobile optimization (Flutter performance)
- QUIC transport (native, beyond libp2p bridge)
- Full WebRTC transport
- Filecoin integration
| Feature | dart_ipfs | go-ipfs (Kubo) |
|---|---|---|
| Content Storage | β | β |
| UnixFS | β | β |
| CID v0/v1 | β | β |
| Bitswap 1.2.0 | β | β |
| Kademlia DHT | β | β |
| HTTP Gateway | β | β |
| RPC API | β | β |
| PubSub | β | β |
| IPNS | β | β |
| GraphSync | β | β |
| Circuit Relay v2 | β | β |
| AutoNAT | β | β |
| Language | Dart | Go |
| Mobile Support | β Flutter | β |
| Web Support | β Dart Web | β |
MIT License β see LICENSE file for details
Built with:
- dart_libp2p β Native P2P networking
- pointycastle β Cryptography
- hive β Storage
- protobuf β Protocol buffers
Inspired by:
- go-ipfs (Kubo) β Reference implementation
- js-ipfs β JavaScript implementation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- IPFS Docs: docs.ipfs.tech
Ready to build decentralized applications? Get started with dart_ipfs today! π