Scaffold flit: PWA + Go CLI for ephemeral E2E file transfer
Ports the yaw/2.1 identity/signaling/WebRTC transport from waste-go to both a browser PWA (with QR pairing and Web Share Target) and a headless Go CLI, trimmed to 1:1 ephemeral file transfer only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
49
PROTOCOL.md
Normal file
49
PROTOCOL.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# flit protocol
|
||||
|
||||
flit speaks a trimmed subset of YAW/2.1 (forward-secret signaling) — see
|
||||
`../waste-go/PROTOCOL.md` for the full spec. This file only notes where flit
|
||||
diverges.
|
||||
|
||||
## What's reused as-is
|
||||
|
||||
- Ed25519 device identity; `id = hex(pubkey)`.
|
||||
- Signaling: WebSocket join/challenge, sealed `to`/`from` relay (§5).
|
||||
- yaw/2.1 ephemeral-key (`ekey`) forward-secret signaling, falling back to
|
||||
static (yaw/2.0) seal if the peer doesn't send one (§6′, §6.1).
|
||||
- The `hello` identity-confirm bind over DTLS fingerprints (§6).
|
||||
- File transfer: `file-offer` / `file-accept` / `file-cancel`, chunked
|
||||
64 KiB binary DataChannel labeled `f:<xid>` (§9).
|
||||
|
||||
## What's dropped
|
||||
|
||||
flit has no chat, presence, multi-peer mesh, or file browsing — every
|
||||
session is exactly one peer, ends after one transfer (or a cancel/close).
|
||||
`chat`, `pm`, `reaction`, `peer_gossip`, `browse`/`get`/`files` message
|
||||
types are not implemented.
|
||||
|
||||
## What's flit-specific
|
||||
|
||||
- **Room naming**: flit never uses a human-chosen network name. Rooms are
|
||||
16 random bytes (128 bits), hex-encoded, generated fresh per pairing —
|
||||
`net = sha256("yaw2-net:" + random_hex)`. This is deliberately different
|
||||
from yaw2's named-network convention: a flit room must not be guessable or
|
||||
brute-forceable from the anchor's point of view, since pairing is the only
|
||||
trust mechanism (no keyring-gated network name to fall back on for an
|
||||
ephemeral session).
|
||||
- **Invite encoding**: `flit:<base64url(json)>` where the JSON is
|
||||
`{"anchor": "<wss url>", "room": "<hex>"}`. Distinct from waste-go's
|
||||
`waste:` invite format (which carries a network *name*, not a random room).
|
||||
See `pwa/src/pairing/ephemeral.ts` and `cli/cmd/flit/main.go`.
|
||||
- **Pairing trust**: two independent flows —
|
||||
- *Ephemeral* (above): trust is "whoever shows up in this freshly
|
||||
generated, never-reused room," confirmed by the `hello` signature.
|
||||
- *Persistent keyring* (`pwa/src/pairing/keyring.ts`): optionally
|
||||
remember a peer's `id` after a verified session, for repeat pairing
|
||||
without re-scanning. Not yet wired into the join flow to pin sessions
|
||||
to a specific id — currently advisory/UI-only.
|
||||
- **TURN credentials**: short-lived, minted server-side by the anchor's
|
||||
`GET /turn-credentials` (coturn `use-auth-secret` HMAC; see
|
||||
`waste-go/cmd/anchor/main.go`). The PWA fetches from there. The CLI
|
||||
computes the HMAC locally from `FLIT_TURN_SECRET` env (acceptable for a
|
||||
native binary — unlike browser JS, it isn't visible to anyone who opens
|
||||
the page source).
|
||||
Reference in New Issue
Block a user