Why (two reasons, both hard)
- Relay sunset. n0 sunsets public-relay support for iroh 0.35-era clients on 2026-12-31. After that the app loses WAN relay connectivity. This migration is not optional.
- Browser receiver. The v0.9.0 headline "receive in any browser" only exists on the iroh 1.0 / iroh-blobs 0.103 line, and a 1.0 browser peer can't talk to a 0.35 app (iroh 0.91 broke the relay wire protocol). The app must be 1.0 for the browser feature to work.
Already de-risked
The feasibility spike is GO — see docs/browser-receiver-spike.md. The whole browser data path compiles to wasm32-unknown-unknown, and the web-receiver/ crate is built and unit-tested. That doc contains the fully verified 0.35 -> 1.0 API map — use it as the migration checklist.
Scope (files, in order)
Compatibility callout
v0.9.0 cannot transfer with <=v0.8.x peers (relay + protocol break). Release notes + in-app updater nudge required.
Then: ship the browser receiver
Verify
Full pnpm check + cargo clippy --all-targets -- -D warnings post-migration; benchmark-local re-baseline; cross-device matrix (Win/mac/Linux/Android v0.9 sender -> Chrome/Firefox/Safari receiver, LAN + forced relay); cancel mid-fetch; oversize refusal; zero CSP console errors on a Netlify preview.
Why (two reasons, both hard)
Already de-risked
The feasibility spike is GO — see
docs/browser-receiver-spike.md. The whole browser data path compiles towasm32-unknown-unknown, and theweb-receiver/crate is built and unit-tested. That doc contains the fully verified 0.35 -> 1.0 API map — use it as the migration checklist.Scope (files, in order)
src-tauri/Cargo.toml: iroh1.0, iroh-blobs0.103(fs-store), drop theiroh-quinn-proto = 0.13pin, bumpn0-future.node/endpoint.rs(epicenter):Endpoint::builder(presets::N0)+address_lookup/MemoryLookup;BlobsProtocol::new(&store, events)+api::Store+Downloader;endpoint.online()/addr(); watcher renames.transfer/sender.rs:add_from_path/scan_path/WrapOption->store.blobs().add_path(_with_opts); collection creation.transfer/receiver.rs+transfer/swarm.rs:download_with_opts/DownloadProgressenum ->Downloader.download(HashAndFormat, providers)(DownloadProgress: IntoFuture); preserve retry/cancel/swarm semantics.transfer/export.rs: new export API.transfer/ticket.rs: 1.0BlobTicket(EndpointAddr); bump fd2 feature flags; unparseable-old-ticket -> friendly "sender needs to update" error.node/nearby_protocol.rs: re-verify the 1.0ProtocolHandlersignature.benchmark-localand update the honesty notes honestly.bin/benchmark_local.rs: recompile + re-baseline.Compatibility callout
v0.9.0 cannot transfer with <=v0.8.x peers (relay + protocol break). Release notes + in-app updater nudge required.
Then: ship the browser receiver
wasm-bindgenthe existingweb-receiver/crate intopublic/webrx(build in GitHub Actions, not Netlify — CI has clang forring);netlify-cli deploy.src/components/ReceiveHandoffPage.tsx: "Receive in this browser (beta)" below the native CTA; lazy-import wasm on click; size gate (warn >500 MB, refuse >~1-2 GB); File System Access API save + Blob fallback; "BLAKE3 verified" state.netlify.toml:script-src 'wasm-unsafe-eval',connect-src wss://relay hosts.Verify
Full
pnpm check+cargo clippy --all-targets -- -D warningspost-migration;benchmark-localre-baseline; cross-device matrix (Win/mac/Linux/Android v0.9 sender -> Chrome/Firefox/Safari receiver, LAN + forced relay); cancel mid-fetch; oversize refusal; zero CSP console errors on a Netlify preview.