GitHub - geograms/i2p-dart: Pure-Dart I2P node: decentralized, NAT-traversing, content-addressed file sharing — no native binaries, no router install, no config. · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
geograms
i2p-dart
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>2 Commits<br>2 Commits
example
example
lib
lib
test
test
.gitignore
.gitignore
CHANGELOG.md
CHANGELOG.md
LICENSE
LICENSE
README.md
README.md
analysis_options.yaml
analysis_options.yaml
pubspec.yaml
pubspec.yaml
View all files
Repository files navigation
i2p
A pure-Dart I2P node . Decentralized, NAT-traversing, content-addressed file<br>sharing — with no native binaries, no separate router install, and no router<br>configuration . The full I2P client runs in plain Dart, so it works in any Dart<br>or Flutter application (desktop, mobile, server) by just adding a package.
This package was extracted from the Aurora<br>project so it can be reused as a standalone library.
What it does
NTCP2 transport — Noise XK handshake + data phase against the live network.
Tunnels — builds inbound and outbound tunnels (ECIES short build records),<br>with gateway diversity, rotation and health scoring.
netDB — reseeds over HTTPS (multi-operator), looks up and publishes<br>LeaseSet2 records to the floodfill DHT.
Repliable signed datagrams — Ed25519-signed GET/DAT by sha256.
Content discovery — an IPFS-style provider DHT (PROVIDE / FINDPROV):<br>find a blob by its sha256 without knowing which device holds it.
Swarm — a BitTorrent-style piece swarm so large files download collectively<br>from many devices in parallel, each piece sha256-verified.
Background isolate — the node runs off the UI isolate, with cooperative<br>pause() / resume() for CPU / battery governors.
Everything is content-addressed by sha256 : you serve and fetch opaque blobs<br>by hash. Mapping hashes to your app's files/messages is left to you.
Install
dependencies:<br>i2p:<br>git:<br>url: https://github.com/geograms/i2p-dart.git
Quick start
get(String sha256B64u) async { /* return bytes or null */ }<br>@override<br>Future put(Uint8List bytes, String ext) async { /* persist bytes */ }
final i2p = I2pService(store: MyStore(), log: print);
await i2p.ensureStarted(); // reseed + build tunnels (idempotent)<br>print('reachable at ${i2p.b32}.b32.i2p');
// Make a blob discoverable by its hash:<br>await i2p.announce(sha256Bytes);
// Fetch by hash from anyone on the network who has it:<br>await i2p.discover(sha256Bytes, 'jpg');
// Or fetch directly from a known peer's address:<br>await i2p.fetchByB32('.b32.i2p', sha256Bytes, 'jpg');
i2p.pause(); // under battery / CPU pressure — cheap to resume()<br>await i2p.resume();<br>i2p.stop();">import 'dart:typed_data';<br>import 'package:i2p/i2p.dart';
// Back the node with your own storage (keyed by sha256, base64url, no padding).<br>class MyStore implements I2pContentStore {<br>@override<br>FutureUint8List?> get(String sha256B64u) async { /* return bytes or null */ }<br>@override<br>Futurevoid> put(Uint8List bytes, String ext) async { /* persist bytes */ }
final i2p = I2pService(store: MyStore(), log: print);
await i2p.ensureStarted(); // reseed + build tunnels (idempotent)<br>print('reachable at ${i2p.b32}.b32.i2p');
// Make a blob discoverable by its hash:<br>await i2p.announce(sha256Bytes);
// Fetch by hash from anyone on the network who has it:<br>await i2p.discover(sha256Bytes, 'jpg');
// Or fetch directly from a known peer's address:<br>await i2p.fetchByB32('.b32.i2p', sha256Bytes, 'jpg');
i2p.pause(); // under battery / CPU pressure — cheap to resume()<br>await i2p.resume();<br>i2p.stop();
If you don't want to implement the interface, use the callback form:
myMap[k],<br>onPut: (bytes, ext) async => myMap[hashOf(bytes)] = bytes,<br>),<br>);">final i2p = I2pService(<br>store: I2pCallbackStore(<br>onGet: (k) async => myMap[k],<br>onPut: (bytes, ext) async => myMap[hashOf(bytes)] = bytes,<br>),<br>);
A runnable end-to-end demo is in example/i2p_example.dart.
API surface
Most apps only need I2pService (the facade) and...