docs(dht): Phase 4 plan (paid streaming/relay/IndeeHub + cross-mint) + RESUME update
phase4-streaming-ecash-plan.md: design for ecash-paid swarm transport, paying across different mints (§2a, Lightning-bridged swaps), networking-through-nodes relay, and an IndeeHub "Archipelago" content source. Records the resolved iroh-blobs paid-serving spike. dht-RESUME.md: task #12 + step F marked done. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
75b78325e4
commit
1f3b03bc6d
+37
-22
@@ -58,31 +58,46 @@ Design doc: `docs/dht-distribution-design.md` (the full plan).
|
||||
|
||||
All tests green at each step. Total new modules: `trust/`, `content_hash.rs`, `swarm/`.
|
||||
|
||||
## NEXT STEP — task #12 (Phase 3 glue + wiring)
|
||||
## task #12 — Phase 3 glue + wiring — DONE (2026-06-17, NOT yet committed)
|
||||
|
||||
Implement, in the worktree:
|
||||
Implemented in the worktree, **uncommitted** (release in flight — do not commit/merge
|
||||
until the user says so). Verified: default `cargo build` clean, `cargo build
|
||||
--features iroh-swarm` clean, `cargo test --bin archipelago -- swarm::` → **8/8 pass**.
|
||||
|
||||
1. **`NostrSeedDiscovery`** (feature-gated, in `swarm/iroh_provider.rs` or a new
|
||||
`swarm/discovery.rs`): implement the `ProviderDiscovery` trait by querying relays
|
||||
with `seed_advert::advertisement_filter(hash)`, then
|
||||
`seed_advert::endpoint_ids_from_events(...)` → parse each string into
|
||||
`iroh::EndpointId` (`EndpointId::from_str` / parse). Skip ids that don't parse.
|
||||
- **NOTE:** `ProviderDiscovery::providers_for` is currently **sync**. The relay
|
||||
query is async → either change the trait to `#[async_trait] async fn`, or back
|
||||
it with an in-memory cache refreshed by a background subscription. Async trait
|
||||
is cleaner (the caller `try_fetch` is already async).
|
||||
2. **Publish path:** when a node finishes downloading / already holds a public
|
||||
release/app-image blob, publish `seed_advert::advertisement_builder(blake3, my_endpoint_id)`
|
||||
signed with the node's Nostr key (`nostr_discovery.rs` has the
|
||||
`load_or_create_nostr_keys` + `Client` + `send_event_builder` patterns to reuse).
|
||||
Scope: **releases/catalog blobs only** — never private user blobs.
|
||||
3. **Wire `swarm::providers()`** to construct an `IrohProvider` (with the
|
||||
`NostrSeedDiscovery`) from runtime config — needs an enable flag + relay list +
|
||||
data_dir. Likely make `providers()` async / build it once at startup and pass a
|
||||
handle into the update path. Until this is wired, `providers()` returns empty and
|
||||
everything uses origin (safe).
|
||||
1. **`NostrSeedDiscovery`** (`swarm/iroh_provider.rs`) — `ProviderDiscovery` made
|
||||
**async** (`#[async_trait]`); impl queries relays via the new
|
||||
`seed_advert::fetch_seed_endpoint_ids` and parses each string with
|
||||
`EndpointId::from_str` (`EndpointId = PublicKey`, has `FromStr`/`Display`),
|
||||
skipping unparseable. `try_fetch` now `.await`s discovery.
|
||||
2. **Publish path** — dep-free `seed_advert::fetch_seed_endpoint_ids` +
|
||||
`publish_seed_advert` (reuse now-`pub(crate)` `build_nostr_client` /
|
||||
`load_or_create_nostr_keys`); `IrohProvider::seed_and_advertise` imports the blob
|
||||
into the FsStore (`blobs().add_path` → `TagInfo`) with a defensive hash-match,
|
||||
then publishes. Scope: releases/catalog only.
|
||||
3. **Wiring** — `swarm::init()` builds the `IrohProvider` once at startup into a
|
||||
`OnceLock<SwarmRuntime>` (keeps endpoint/router alive → keeps seeding);
|
||||
`providers()` returns the registered provider; `announce_held_blob()` is called
|
||||
from `update.rs` after each release component passes both hash gates. New config
|
||||
`swarm_enabled` (`ARCHIPELAGO_SWARM_ENABLED`, default false); `server.rs` calls
|
||||
`swarm::init`. All iroh code stays behind `iroh-swarm`; default build inert.
|
||||
|
||||
Then verify: `cargo build --features iroh-swarm` + `cargo test --bin archipelago -- swarm::`.
|
||||
**iroh-blobs paid-serving spike (open Q#1) — RESOLVED:** `BlobsProtocol::new(&store,
|
||||
Some(EventSender))` + `EventMask` intercept gives native per-request allow/deny
|
||||
(`RequestMode::Intercept` → `Result<(), AbortReason>`), connection-level reject
|
||||
(`ConnectMode::Intercept`), and per-request throttle/meter (`ThrottleMode::Intercept`).
|
||||
|
||||
## NEW: Phase 4+ plan (paid streaming / relay / IndeeHub) — `docs/phase4-streaming-ecash-plan.md`
|
||||
|
||||
Design for: (1) ecash-paid swarm transport, (2) networking through nodes / relay,
|
||||
(3) IndeeHub "Archipelago" content source (signed Nostr film catalog, kind 30082).
|
||||
Headline: ~80% already exists (Cashu wallet, `streaming/` payment gate + metering,
|
||||
4-tier transport, the swarm above). Also shipped this session: a **Networking Profits
|
||||
→ Settings** UI in `neode-ui` (new `views/web5/Web5NetworkingProfitsSettings.vue` +
|
||||
route + button in `Web5QuickActions.vue` + `common.settings` i18n) that drives the
|
||||
existing `streaming.list-services`/`configure-service` RPCs; free-everything is the
|
||||
default (all services ship `enabled:false`). Frontend typechecks clean (pre-existing
|
||||
`Web5ConnectedNodes.vue` `.did` errors are NOT ours). `neode-ui` deps were
|
||||
`npm install`ed to complete a partial install.
|
||||
|
||||
## After Phase 3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user