Files
waste-go/FUTURE.md

130 lines
6.9 KiB
Markdown
Raw Normal View History

# Future Vision
WASTE's design philosophy is still sound: small trusted groups, no central server, encrypted everything, equal nodes. That's essentially what Signal's sealed sender and private groups do today, just without a self-hosted option. This gap is worth filling.
---
## Architecture
Two clean layers, connected by the IPC port.
### Daemon
The real application. A long-running background process that handles everything:
- Peer mesh and connection management (WebRTC DataChannels, DTLS, ICE)
- Cryptography and handshake (Ed25519 identity, nacl/box signaling, YAW/2.1 FS)
- NAT traversal (ICE/STUN via pion/webrtc — no custom relay needed)
- File transfer (dedicated binary DataChannels per transfer)
Exposes a local JSON API over TCP (`127.0.0.1:17337`). Can run headlessly — SSH into a box and the mesh stays alive even with no UI attached.
### UI Layer
Talks to the daemon over the IPC port. The separation means the UI is replaceable without touching the core.
Target: a web frontend (React or similar) wrapped in a native binary using a Tauri-style approach — native packaging, OS webview, no Electron weight. Avoids the wxWidgets ugliness of the old wxWASTE fork and the Qt licensing headaches of the VIA fork.
#### TUI ✅ (shipped)
A terminal UI (`cmd/tui`) using [Bubble Tea](https://github.com/charmbracelet/bubbletea). Three-pane layout: rooms, messages, peers. Supports group chat, DMs, room switching, invite generation. Works over SSH.
2026-06-21 16:20:59 +02:00
#### Web UI ✅ (shipped)
React + Vite frontend. Two modes:
- **Browser mode** — runs entirely in-browser, connects directly to the anchor via WebSocket. No daemon required. Identity persists in `localStorage`. File sharing, file push, per-peer ICE/NAT status.
- **Daemon mode** — web UI connects to a local daemon over WebSocket IPC. Same UI, different adapter.
---
## Protocol
### NAT Traversal ✅ (WebRTC ICE/STUN)
Solved by using WebRTC DataChannels via pion. ICE gathers host + server-reflexive (STUN) candidates and performs UDP hole punching automatically. The anchor (`cmd/anchor`) doubles as a STUN server on UDP/3478.
### TURN relay (symmetric NAT pairs)
The one remaining gap: two peers both behind symmetric NAT (common on mobile/CGNAT) will fail to hole-punch. TURN recovers this.
**How to add it:** `internal/anchor/client.go` already has the `ICEServers` slice. Adding a TURN entry is a one-liner:
```go
ICEServers: []webrtc.ICEServer{
{URLs: []string{"stun:stun.l.google.com:19302"}},
{URLs: []string{"turn:your-vps:3478"}, Username: "waste", Credential: "secret"},
},
```
Expose as daemon flags (`-turn-url`, `-turn-user`, `-turn-credential`) and wire into the anchor client config. Run `coturn` in relay-only mode on the same VPS as the anchor. The relay sees only opaque DTLS-encrypted blobs. Opt-in, off by default.
### Signaling ✅ YAW/2.1 (shipped)
Forward-secret signaling via per-session ephemeral X25519 keys. Falls back transparently to 2.0 static-key sealing for peers that don't speak 2.1.
### Multi-Network Support ✅ (shipped)
One daemon, multiple simultaneously-joined networks. Per-network HKDF-derived identities prevent cross-network correlation. Network-scoped SQLite stores.
### Invite System ✅ (shipped)
`waste:<base64>` URIs encoding anchor URL + network name. `--join` flag on daemon and TUI. `Ctrl+I` in TUI or `generate_invite` via IPC.
### File Transfer ✅ (shipped)
Dedicated binary DataChannel per transfer (`f:<xid>`). SHA-256 integrity verification. 64 KiB chunks with backpressure. Auto-accept. In browser mode: both pull (browse peer's shared folder) and push (📎 send directly to a peer).
### Peer Gossip ✅ (shipped)
When a new peer connects, the mesh immediately gossips the full peer list to them (`peer_gossip` wire message). New arrivals discover existing peers without needing the anchor to re-introduce them. The anchor becomes optional once the first handshake has happened — the mesh self-heals around anchor downtime.
---
## Remaining Work
### Per-Network Share Directories (next)
The IPC plumbing is done (`set_share_dir`, `ShareDir` on `NetworkInfo`, per-network mesh), but the web UI's folder picker is a single global share applied to all peers on all networks. The fix: track share state per `network_id` in the store and pass the active network's share when browsing or accepting get requests.
### Additional Channels / Rooms (next)
Currently each network has a hardcoded `#general` room. The protocol supports arbitrary room names already (messages carry a `room` field). What's missing:
- IPC command `create_room {network_id, name}` / `list_rooms {network_id}`
- Daemon stores room list per network in SQLite
- TUI: room creation input
- Web UI: `+` button in the Rooms sidebar section → prompt for name → `create_room`
Room names are just strings — no server coordination needed. Any peer that sends to a room name causes it to appear on the recipient's side automatically. The only thing to add is persistence and a creation UI.
### File Transfer UX
- Manual accept/reject (currently auto-accept everywhere)
- Transfer cancellation via `file-cancel`
- Progress indicator in TUI and web UI
- Resume after disconnection
- Daemon-side: write received files to `<data-dir>/downloads-<netid>/` (browser is limited to download prompt)
### Native UI
Web frontend (React, already built) + Tauri shell for native packaging. The IPC protocol is the full boundary — the UI is already a pure consumer. Main work: Tauri setup, system tray, OS notifications.
---
## Roadmap
| Status | Item |
|---|---|
| ✅ shipped | Daemon + anchor server |
| ✅ shipped | WebRTC DataChannels (ICE/STUN hole punching) |
| ✅ shipped | Ed25519 identity, nacl/box signaling (YAW/2.0 + 2.1) |
| ✅ shipped | IPC protocol — join/leave/chat/DM/state |
| ✅ shipped | Message persistence (SQLite, per-network) |
| ✅ shipped | TUI (`cmd/tui`, Bubble Tea) |
| ✅ shipped | Invite system (`waste:` URI, `--join` flag) |
| ✅ shipped | Multi-network support (HKDF derived identities) |
| ✅ shipped | File transfer (binary DataChannels, pull + push) |
| ✅ shipped | Forward-secret signaling (YAW/2.1 ephemeral X25519) |
| ✅ shipped | Peer gossip (anchor-free mesh reconnection) |
| ✅ shipped | Web UI — browser mode + daemon mode |
| ✅ shipped | Per-peer NAT/ICE status, identity backup/restore |
| next | Per-network share directories (web UI wiring) |
| next | Additional channels/rooms per network |
| next | TURN relay (3 flags + coturn on VPS) |
| next | File transfer UX (progress, cancel, manual accept) |
| future | Native UI (React + Tauri) |
---
## What to Keep from WASTE
- **Small group** — not a public network, not federated, not discoverable
- **No registration** — no phone number, no email, no central service
- **Encrypted everything** — at rest and in transit, end to end
- **Equal nodes** — no peer is "the server"; the anchor is dumb infrastructure
- **The soul** — a private overlay for people you actually trust