The anchor keys its clients map by peer ID. With the daemon joining one room per trusted peer, both sessions authenticated with the same real Ed25519 ID — the second register() overwrote the first, orphaning the earlier room's WS connection. Fix mirrors waste-go/internal/netmgr: derive a deterministic per-room Ed25519 keypair from HKDF(master_private_key, room_hash). Same inputs always produce the same derived ID; different rooms produce different IDs. No anchor changes required. cli/internal/crypto: add DeriveForNetwork (HKDF-SHA256, same KDF as waste-go) so the daemon can derive stable per-room signaling identities. cli/internal/transport: Join derives a per-room signaling identity before calling dialSignaling. Real identity is still used for hello verification and seal/open crypto inside the DataChannel. pwa/src/transport/flit.ts: split PeerConn.peerId into signalingId (anchor routing) and cryptoId (seal/open, hello). In pair-room mode the daemon's signaling ID differs from its real ID, so connectTo and _onFrom now use trustedPeerId as the cryptoId regardless of what the anchor reports as the sender. offerByOrder comparison uses real IDs (trustedPeerId ?? signalingId) so both sides agree. hello verification now also checks the Ed25519 signature, not just the claimed ID. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
flit — PWA
React/TypeScript/Vite frontend. See the root README for the full project overview.
Development
npm install
npm run dev # dev server at localhost:5173
npm run build # output to dist/
npm run lint
public/config.js sets the anchor and TURN URLs at runtime and is excluded from production deploys (so the host copy isn't overwritten). The repo's default points at the live anchor — fine for local dev.
Deploy
See ../deploy-pwa.sh and ../serve-pwa.sh at the repo root.