Files
waste-go/FUTURE.md
Fredrik Johansson 5421352e62 docs: update FUTURE.md to reflect current shipped state
Mark web UI, peer gossip, and identity backup as shipped. Expand TURN
section with concrete implementation notes (one-liner ICEServers change +
3 daemon flags). Add per-network share directories and additional
channels/rooms as next items. Remove stale "not implemented" notes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 20:40:33 +02:00

6.9 KiB

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. Three-pane layout: rooms, messages, peers. Supports group chat, DMs, room switching, invite generation. Works over SSH.

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:

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