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>
97 lines
4.0 KiB
Markdown
97 lines
4.0 KiB
Markdown
# flit
|
|
|
|
Self-hosted, ephemeral, end-to-end encrypted file transfer between your own
|
|
devices — regardless of architecture. Think "AirDrop, but self-hosted and
|
|
cross-platform," built on the WebRTC/Ed25519 plumbing already proven out in
|
|
waste-go.
|
|
|
|
## Why
|
|
|
|
[Zipline](https://github.com/diced/zipline) already covers persistent,
|
|
link-based "upload once, share via URL" — good for sharing *to others* or
|
|
storing semi-long-term. This tool is different: ad hoc, point-to-point
|
|
transfer between *your own* devices (dev box → homelab box → laptop →
|
|
phone), without anything landing on a server's disk if it can be avoided.
|
|
|
|
Two use cases to design for:
|
|
1. **Desktop ↔ desktop** — browser tab or small CLI on each end.
|
|
2. **Desktop ↔ mobile (Android)** — the share-sheet flow is the whole point.
|
|
|
|
No iOS constraint — Android + desktop only. This drops a meaningful chunk of
|
|
complexity (no Safari/PWA quirks, no manual-code fallback needed for pairing).
|
|
|
|
## How
|
|
|
|
You can take a look at ../waste-go for inspiration, it does parts of this already.
|
|
|
|
## Non-goals
|
|
|
|
- No persistent storage, no accounts, no link sharing with third parties.
|
|
- Not a Zipline replacement — strictly "get a file from my hand to my other
|
|
hand."
|
|
|
|
|
|
## Architecture
|
|
|
|
**Transport**: WebRTC data channels for the actual file bytes, P2P whenever
|
|
NAT traversal allows it.
|
|
|
|
- A lightweight **signaling server** (self-hosted, homelab) exchanges
|
|
SDP/ICE candidates between peers. Stateless, ephemeral rooms, no file data
|
|
ever touches it.
|
|
- A **TURN relay fallback** (coturn, self-hosted) for when direct P2P fails
|
|
— common on mobile networks/CGNAT. Data stays E2E encrypted across the
|
|
relay, so it just shovels encrypted bytes.
|
|
|
|
**Identity & security**: reuse the Ed25519 keypair model from waste-go. Each
|
|
device has a long-lived identity key; pairing two devices derives a session
|
|
key (X25519 ECDH) so transfers are E2E encrypted even across the TURN relay.
|
|
No accounts, no passwords.
|
|
|
|
**Pairing UX**: QR code as the default everywhere, since there's no need to
|
|
support a browser that handles it poorly (no iOS).
|
|
|
|
- Generate an ephemeral room code / QR code on the sending device.
|
|
- Scan it on the receiving device to join the WebRTC session.
|
|
- Once paired, drag-and-drop (desktop) or native share sheet (Android) to
|
|
send.
|
|
|
|
**Clients**:
|
|
|
|
- **PWA** — covers desktop browsers and Android. Installable on Android home
|
|
screen, registered as a **Web Share Target** so "Share → flit" works
|
|
directly from any app's OS share sheet (Photos, Files, browser downloads,
|
|
anything). This is the primary mobile flow, not a fallback.
|
|
- **Go CLI** — for headless machines (homelab boxes, servers without a GUI),
|
|
reusing waste-go's transport/identity code directly. `flit send file.tar.gz`
|
|
prints a code/QR for the other end to scan.
|
|
|
|
## Build plan
|
|
|
|
1. **Scaffold the repo.** Reuse waste-go's Ed25519 identity + WebRTC
|
|
handshake code as a starting library if cleanly extractable; otherwise
|
|
port the logic.
|
|
2. **Signaling server** — minimal Go service, WebSocket-based room exchange
|
|
(peer A creates room, gets code; peer B joins with code; server relays
|
|
SDP/ICE only, then gets out of the way). Deploy alongside Zipline in the
|
|
homelab.
|
|
3. **PWA client** — file picker + drag-drop, QR code generation/scanning
|
|
(camera access for scan), Web Share Target manifest entry, WebRTC data
|
|
channel transfer with progress UI.
|
|
4. **Go CLI** — thin wrapper sharing core logic with the
|
|
signaling/transport layer, for headless homelab boxes.
|
|
5. **TURN fallback** — coturn instance, only invoked when direct P2P ICE
|
|
candidates fail.
|
|
6. **Stretch**: chunked transfer + resume for large files over flaky mobile
|
|
connections; multi-file/folder zip-on-the-fly.
|
|
|
|
## Open question
|
|
|
|
Host the PWA under goonk.se (e.g. `/flit`, alongside Pitwall/Delve as a
|
|
public-facing sub-site with a project badge) or keep it standalone on a
|
|
homelab subdomain as a personal tool rather than a portfolio piece? This
|
|
decides whether the implementing work also touches the goonk.se repo's
|
|
project content collection.
|
|
|
|
|