iroh_quic 1.0.1 copy "iroh_quic: ^1.0.1" to clipboard
iroh_quic: ^1.0.1 copied to clipboard

Pure-Dart binding for iroh 1.0 - peer-to-peer QUIC networking with endpoints, connections, streams, relays, and address lookup over the Rust core. No Flutter: load a signed prebuilt native library via [...]

iroh_quic #

Pure-Dart binding for iroh 1.0 - peer-to-peer QUIC networking (endpoints, connections, streams, relays, address lookup) on desktop Linux, macOS, and Windows. No Flutter required. For Android / iOS, use the companion iroh_flutter plugin — same API, native build bundled into your app.

iroh_quic wraps the iroh Rust core; it does not re-implement iroh in Dart. The Dart API mirrors iroh 1.0's nouns exactly (Endpoint / EndpointId / EndpointAddr, addressLookup), so iroh's docs and the n0 examples transfer directly.

Quick start #

Download the signed prebuilt native library for your platform once — no Rust toolchain needed:

dart pub add iroh_quic
dart run iroh_quic:setup   # downloads + verifies the prebuilt lib into a per-user cache

(Prefer to build it yourself? cd rust && cargo build --release instead — the loader finds that too.)

import 'dart:typed_data';
import 'package:iroh_quic/iroh_quic.dart';

Future<void> main() async {
  // Loads the native library + verifies the ABI handshake. With no arguments the loader checks, in
  // order: a local `cargo build` (rust/target/{debug,release}), the `iroh_quic:setup` cache, and a
  // lib bundled next to the executable. Pass libraryPath: for a custom location.
  await Iroh.init();

  // Identity & addressing (pure data, no runtime).
  final secret = SecretKey.generate();
  print('my id: ${secret.publicKey.toZ32()}'); // publicKey == EndpointId

  // A server that echoes one bidirectional stream.
  const alpn = 'my-app/echo/0';
  final server = await Endpoint.bind(alpns: [alpn.codeUnits]);
  final serving = () async {
    final conn = await server.accept();
    final (send, recv) = await conn!.acceptBi();
    await send.writeAll(await recv.readToEnd(1 << 20));
    await send.finish();
  }();

  // A client that connects and reads the echo back.
  final client = await Endpoint.bind();
  final conn = await client.connect(server.addr, alpn.codeUnits);
  final (send, recv) = await conn.openBi();
  await send.writeAll(Uint8List.fromList('hello'.codeUnits));
  await send.finish();
  print(String.fromCharCodes(await recv.readToEnd(1 << 20))); // hello
  await serving;

  await client.close();
  await server.close();
}

Platforms #

Signed prebuilt libraries (downloaded by dart run iroh_quic:setup) cover the desktop targets a pure-Dart program actually runs on:

Linux x64 Linux arm64 macOS x64 macOS arm64 Windows x64 Windows arm64

The loader finds the prebuilt in its cache, a local cargo build under rust/target/{debug,release}/libirohdart_ffi.{so,dylib,dll}, or a copy next to your compiled executable — or pass an explicit libraryPath:.

Mobile (Android / iOS): these are not dart run targets. Use the iroh_flutter plugin, which compiles and bundles the native library into your app automatically.

Building the native library yourself #

Don't want the prebuilt download (offline build, full audit, an unpublished arch, or a custom profile)? Compile the crate from source — a Rust toolchain is the only prerequisite. The command installs the library into the same cache iroh_quic:setup uses, so Iroh.init() finds it automatically:

dart run iroh_quic:build            # cargo build --release, then install
dart run iroh_quic:build --debug    # faster, unoptimized

Equivalently, build by hand and point the loader at the result:

cd rust && cargo build --release    # produces target/release/libirohdart_ffi.{so,dylib,dll}

The loader finds rust/target/{debug,release}/ automatically when you run from the package root, or pass await Iroh.init(libraryPath: '/path/to/libirohdart_ffi.so') for any location.

API surface #

  • Identity & addressing - SecretKey, PublicKey / EndpointId, Signature, EndpointAddr, RelayUrl, RelayMode, RelayMap.
  • Endpoint - Endpoint.bind({secretKey, alpns, relayMode}), close, isClosed, setAlpns, boundSockets, addr, connect, accept, acceptIncoming.
  • Connection & streams - openBi/openUni/acceptBi/acceptUni, datagrams, stats, remoteId, alpn, closed; SendStream (writeAll/finish/reset), RecvStream (read/readExact/readToEnd/stop).
  • Accept filter - Incoming (remoteAddr, accept/refuse/retry/ignore).
  • Reactive streams - Endpoint.watchAddr(), Endpoint.homeRelayStatus(), Connection.pathEvents() (sealed PathEvent).
  • Multi-protocol routing - Endpoint.router() -> RouterBuilder.accept(alpn, handler) -> spawn()/Router.shutdown(): register a Dart handler per ALPN and let iroh's Router dispatch.
  • Custom address lookup - Endpoint.bindWithAddressLookup(resolve:): dial peers known only by their EndpointId, resolving their EndpointAddr in Dart.

Lazy-stream footgun: a freshly opened SendStream is invisible to the peer until the first writeAll.

Run the bundled headless example (dart run, no Flutter):

cd rust && cargo build --release && cd ..
dart pub get
dart run example/echo.dart

Develop #

dart pub get
cargo install flutter_rust_bridge_codegen --version '^2'  # standalone cargo binary
./tool/frb_codegen.sh   # regen FRB glue after editing rust/src/api/*
./tool/check.sh         # cargo build+test, then dart analyze + dart test

Requires Rust >= 1.91 (edition 2024; pinned to 1.96.0) and, for Android, NDK r28+.

License #

Apache-2.0 - see LICENSE. The iroh crate is MIT OR Apache-2.0.

0
likes
140
points
0
downloads

Documentation

API reference

Publisher

verified publishersnowpine.io

Weekly Downloads

Pure-Dart binding for iroh 1.0 - peer-to-peer QUIC networking with endpoints, connections, streams, relays, and address lookup over the Rust core. No Flutter: load a signed prebuilt native library via `dart run iroh_quic:setup` (or build it with cargo), loaded over dart:ffi (flutter_rust_bridge runtime).

Repository (GitHub)
View/report issues

Topics

#iroh #p2p #networking #quic #ffi

License

Apache-2.0 (license)

Dependencies

cryptography, flutter_rust_bridge

More

Packages that depend on iroh_quic