Add invite strings (waste: URI) for peer onboarding

- internal/invite: Encode/Decode waste:<base64json{anchor,network}>
- proto: CmdGenerateInvite + EvtInviteGenerated + InviteString field
- ipc: track active network name; handle generate_invite (returns invite
  string when joined to a network, errors if not joined or no anchor)
- daemon: --join <invite> flag — decodes anchor URL + network name,
  sets anchor and auto-joins on startup
- tui: --join <invite> flag — extracts network name, skips -network
  requirement; ctrl+i generates invite and shows it full-screen;
  Esc dismisses the invite overlay
- FUTURE.md: document multi-network derived-identity design

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-06-21 18:56:24 +02:00
parent 5a0bcee8c6
commit abc6bf46ce
7 changed files with 229 additions and 14 deletions

View File

@@ -59,6 +59,33 @@ No DHT needed at small group scale (1050 nodes). Keep it simple:
- Public key = stable identity, not a mutable nickname
- No phone number, no central registry — closer to Signal's model than WASTE's original unregistered aliases
### Multi-Network Support
A single client should be able to participate in multiple networks simultaneously (e.g. "work" and "friends") without leaking that both identities belong to the same person.
**Privacy constraint:** if the same Ed25519 keypair is used across networks, any peer who is a member of both networks can trivially correlate you. The anchor also sees the same public key across networks.
**Solution — per-network derived identities:**
- One master Ed25519 seed in `identity.json`
- Per-network keypair = `HKDF(masterSeed, "yaw2-net", networkHash)`
- Same master + same network name = same derived keypair (stable identity within a network)
- Different networks = different peer IDs; correlation is impossible without knowing both network names
- The anchor sees only the derived public key
**Daemon changes:**
- Replace the single `networkCancel` with a `map[networkID]*networkCtx`
- Each context holds its own: derived identity, mesh, anchor connection, store (`messages-<netHash>.db`)
- `join_network` returns a `network_id` token used to scope subsequent commands
**IPC changes (breaking):**
- All commands and events gain a `network_id` field
- `get_state` returns an array of all joined networks
- `join_network` responds with `network_joined` carrying the derived peer ID for that network
**TUI changes:**
- Top-level network switcher (e.g. `[work] [friends]`)
- Rooms and peers are scoped per network underneath
### Transport (Long-term)
Current transport is TCP with custom framing. QUIC is worth revisiting once the core is solid — it gives multiplexing and better NAT traversal behavior essentially for free.