feat: friend list, bot API, ETH addressing, deep links, docs overhaul
Tier 1 — New features: - E2E encrypted friend list: server stores opaque blob (POST/GET /v1/friends), protocol-level encrypt/decrypt with HKDF-derived key, 4 tests - Telegram Bot API compatibility: /bot/register, /bot/:token/getUpdates, sendMessage, getMe — TG-style Update objects with proper message mapping - ETH address resolution: GET /v1/resolve/:address (0x.../alias/@.../fp), bidirectional ETH↔fp mapping stored on key registration - Seed recovery: /seed command in TUI + web client - URL deep links: /message/@alias, /message/0xABC, /group/#ops - Group members with online status in GET /groups/:name/members Tier 2 — UX polish: - TUI: /friend, /friend <addr>, /unfriend <addr> with presence checking - Web: friend commands, showGroupMembers() on group join - Web: ETH address in header, clickable addresses (click→peer or copy) - Bot: full WireMessage→TG Update mapping (encrypted base64, CallSignal, FileHeader, bot_message JSON) Documentation: - USAGE.md rewritten: complete user guide with all commands - SERVER.md rewritten: full admin guide with all 50+ endpoints - CLIENT.md rewritten: architecture, commands, keyboard, storage - LLM_HELP.md created: 1083-word token-optimized reference for helper LLM Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Warzone Messenger (featherChat) — Usage Guide
|
||||
# featherChat Usage Guide
|
||||
|
||||
**Version:** 0.0.20
|
||||
**Version:** 0.0.21
|
||||
|
||||
---
|
||||
|
||||
@@ -11,540 +11,390 @@
|
||||
Requirements: Rust 1.75+, cargo
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repo-url>
|
||||
cd warzone
|
||||
|
||||
# Build all binaries
|
||||
cargo build --release
|
||||
|
||||
# Binaries are in target/release/
|
||||
# warzone-server — server
|
||||
# warzone-client — CLI/TUI client
|
||||
# Binaries output to target/release/:
|
||||
# warzone-server — relay server (with embedded web client)
|
||||
# warzone-client — CLI / TUI client
|
||||
```
|
||||
|
||||
### Build the WASM Module (Web Client)
|
||||
### WASM Build (Web Client)
|
||||
|
||||
Requirements: wasm-pack
|
||||
|
||||
```bash
|
||||
cd crates/warzone-wasm
|
||||
wasm-pack build --target web
|
||||
# Output in pkg/ — copy to web client directory
|
||||
# Output in pkg/ — copy to the web client directory
|
||||
```
|
||||
|
||||
### Linux Cross-Compile
|
||||
|
||||
The `scripts/build-linux.sh` script builds Linux x86_64 binaries on a Hetzner Cloud VPS.
|
||||
|
||||
```bash
|
||||
# Full pipeline: create VM, build, download binaries
|
||||
./scripts/build-linux.sh --all
|
||||
|
||||
# Or step by step:
|
||||
./scripts/build-linux.sh --prepare # Create VM, install deps, upload source
|
||||
./scripts/build-linux.sh --build # Build release binaries on the VM
|
||||
./scripts/build-linux.sh --transfer # Download binaries to target/linux-x86_64/
|
||||
./scripts/build-linux.sh --destroy # Delete the VM
|
||||
|
||||
# One-command ship to all production servers:
|
||||
./scripts/build-linux.sh --ship # prepare + build + transfer + deploy + destroy
|
||||
```
|
||||
|
||||
### Server Configuration
|
||||
|
||||
The server accepts two flags:
|
||||
|
||||
```bash
|
||||
warzone-server --bind 0.0.0.0:7700 --data-dir ./warzone-data
|
||||
```
|
||||
|
||||
| Flag | Default | Description |
|
||||
|--------------|-------------------|-----------------------|
|
||||
| `--bind` | `0.0.0.0:7700` | Listen address |
|
||||
| `--data-dir` | `./warzone-data` | sled database path |
|
||||
| Flag | Default | Description |
|
||||
|--------------|------------------|--------------------|
|
||||
| `--bind` | `0.0.0.0:7700` | Listen address |
|
||||
| `--data-dir` | `./warzone-data` | sled database path |
|
||||
|
||||
Environment variables:
|
||||
|
||||
| Variable | Default | Description |
|
||||
|-------------------------|----------|----------------------------|
|
||||
| `WARZONE_ADMIN_PASSWORD`| `admin` | Password for admin alias ops|
|
||||
| `RUST_LOG` | `info` | Log level filter |
|
||||
| Variable | Default | Description |
|
||||
|--------------------------|---------|------------------------------|
|
||||
| `WARZONE_ADMIN_PASSWORD` | `admin` | Password for admin alias ops |
|
||||
| `RUST_LOG` | `info` | Log level filter |
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
## Identity
|
||||
|
||||
### CLI Quick Start
|
||||
### Generate a New Identity
|
||||
|
||||
```bash
|
||||
# 1. Generate a new identity
|
||||
warzone init
|
||||
# → Prompts for passphrase
|
||||
# → Displays fingerprint and 24-word mnemonic
|
||||
# → SAVE THE MNEMONIC — it is your identity
|
||||
|
||||
# 2. Register with a server
|
||||
warzone register --server http://your-server:7700
|
||||
|
||||
# 3. Show your identity
|
||||
warzone info
|
||||
# Fingerprint: a3f8:c912:44be:7d01:...
|
||||
# Signing key: ...
|
||||
# Encryption key: ...
|
||||
|
||||
# 4. Send a message
|
||||
warzone send a3f8:c912:44be:7d01:... "Hello!" --server http://your-server:7700
|
||||
|
||||
# 5. Receive messages
|
||||
warzone recv --server http://your-server:7700
|
||||
|
||||
# 6. Launch interactive TUI
|
||||
warzone chat --server http://your-server:7700
|
||||
warzone chat a3f8:c912:44be:7d01:... --server http://your-server:7700
|
||||
warzone chat @alice --server http://your-server:7700
|
||||
```
|
||||
|
||||
### Web Client Quick Start
|
||||
|
||||
1. Navigate to the server URL in a browser (e.g., `http://your-server:7700`)
|
||||
2. The web client generates a new identity automatically on first visit
|
||||
3. Your seed is stored in `localStorage` — back it up via the displayed hex seed
|
||||
4. Use `/peer <fingerprint>` or `/peer @alias` to select a chat partner
|
||||
5. Type messages and press Enter to send
|
||||
|
||||
---
|
||||
|
||||
## CLI Commands
|
||||
|
||||
### `warzone init`
|
||||
|
||||
Generate a new identity (seed + keypair + pre-keys).
|
||||
|
||||
```bash
|
||||
$ warzone init
|
||||
Set passphrase (empty for no encryption): ****
|
||||
Confirm passphrase: ****
|
||||
|
||||
Your identity:
|
||||
Fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
Mnemonic: abandon ability able about above absent absorb abstract ...
|
||||
|
||||
SAVE YOUR MNEMONIC — it is the ONLY way to recover your identity.
|
||||
warzone-client init
|
||||
# Prompts for passphrase
|
||||
# Displays fingerprint + 24-word BIP39 mnemonic
|
||||
# SAVE THE MNEMONIC — it is the only way to recover your identity
|
||||
```
|
||||
|
||||
The seed is stored at `~/.warzone/identity.seed`, encrypted with Argon2id + ChaCha20-Poly1305.
|
||||
|
||||
### `warzone recover <words...>`
|
||||
|
||||
Recover an identity from a BIP39 mnemonic.
|
||||
### Recover from Mnemonic
|
||||
|
||||
```bash
|
||||
$ warzone recover abandon ability able about above absent absorb abstract ...
|
||||
Set passphrase (empty for no encryption): ****
|
||||
Confirm passphrase: ****
|
||||
Identity recovered. Fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
warzone-client recover abandon ability able about above absent absorb abstract ...
|
||||
# Prompts for passphrase, restores the same identity
|
||||
```
|
||||
|
||||
### `warzone info`
|
||||
|
||||
Display your fingerprint and public keys.
|
||||
### View Your Identity
|
||||
|
||||
```bash
|
||||
$ warzone info
|
||||
Fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
Signing key: 3a7b...
|
||||
Encryption key: 9f2c...
|
||||
warzone-client info
|
||||
# Fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
```
|
||||
|
||||
### `warzone eth`
|
||||
In the TUI, use `/info` to display your fingerprint, `/seed` to display your 24-word recovery mnemonic, and `/eth` to display your Ethereum address.
|
||||
|
||||
Display your Ethereum-compatible address derived from the same seed.
|
||||
### Ethereum Address
|
||||
|
||||
Your ETH address is derived from the same seed via domain-separated HKDF. One seed, dual identity.
|
||||
|
||||
```bash
|
||||
$ warzone eth
|
||||
Warzone fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
Ethereum address: 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
|
||||
Same seed, dual identity.
|
||||
warzone-client eth
|
||||
# Fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
# Ethereum: 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
|
||||
```
|
||||
|
||||
### `warzone register`
|
||||
### Addressing
|
||||
|
||||
Register your pre-key bundle with a server.
|
||||
featherChat supports three addressing modes. All three work anywhere a peer address is accepted:
|
||||
|
||||
```bash
|
||||
$ warzone register --server http://localhost:7700
|
||||
```
|
||||
|
||||
### `warzone send <recipient> <message>`
|
||||
|
||||
Send an encrypted message. Recipient can be a fingerprint or `@alias`.
|
||||
|
||||
```bash
|
||||
$ warzone send a3f8:c912:44be:7d01:... "Hello!" --server http://localhost:7700
|
||||
$ warzone send @alice "Hello!" --server http://localhost:7700
|
||||
```
|
||||
|
||||
### `warzone recv`
|
||||
|
||||
Poll the server for messages and decrypt them.
|
||||
|
||||
```bash
|
||||
$ warzone recv --server http://localhost:7700
|
||||
```
|
||||
|
||||
### `warzone chat [peer]`
|
||||
|
||||
Launch the interactive TUI client.
|
||||
|
||||
```bash
|
||||
$ warzone chat --server http://localhost:7700
|
||||
$ warzone chat @alice --server http://localhost:7700
|
||||
$ warzone chat a3f8:c912:... --server http://localhost:7700
|
||||
```
|
||||
|
||||
### `warzone backup [output]`
|
||||
|
||||
Export an encrypted backup of local data (sessions, pre-keys).
|
||||
|
||||
```bash
|
||||
$ warzone backup my-backup.wzb
|
||||
Backup saved to my-backup.wzb (4096 bytes encrypted)
|
||||
```
|
||||
|
||||
The backup is encrypted with your seed via HKDF(info="warzone-history") + ChaCha20-Poly1305.
|
||||
|
||||
### `warzone restore <input>`
|
||||
|
||||
Restore from an encrypted backup. Requires the same seed.
|
||||
|
||||
```bash
|
||||
$ warzone restore my-backup.wzb
|
||||
Restored 12 entries from my-backup.wzb
|
||||
```
|
||||
| Format | Example | Description |
|
||||
|--------|---------|-------------|
|
||||
| Fingerprint | `a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4` | SHA-256 of Ed25519 pubkey, 8 groups of 4 hex digits |
|
||||
| Alias | `@alice` | Human-readable, server-resolved |
|
||||
| ETH address | `0x71C7...976F` | Ethereum address derived from the same seed |
|
||||
|
||||
---
|
||||
|
||||
## TUI Commands
|
||||
## TUI Client
|
||||
|
||||
The TUI is launched with `warzone chat`. All commands start with `/`.
|
||||
Launch the interactive terminal UI:
|
||||
|
||||
### Peer & Navigation
|
||||
```bash
|
||||
warzone-client chat --server http://your-server:7700
|
||||
warzone-client chat @alice --server http://your-server:7700
|
||||
warzone-client chat a3f8:c912:... --server http://your-server:7700
|
||||
```
|
||||
|
||||
| Command | Short | Description |
|
||||
|------------------------|-------|----------------------------------------------|
|
||||
| `/peer <fp_or_alias>` | `/p` | Set the active peer (fingerprint or @alias) |
|
||||
| `/dm` | | Switch to DM mode (clear group context) |
|
||||
| `/r` or `/reply` | | Switch to last person who DM'd you |
|
||||
| `/info` | | Display your fingerprint |
|
||||
| `/eth` | | Display your Ethereum address |
|
||||
| `/quit` | `/q` | Exit the TUI |
|
||||
### Complete Command Reference
|
||||
|
||||
#### Peer and Navigation
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/peer <fingerprint>` | Set DM peer by fingerprint |
|
||||
| `/p @alias` | Set DM peer by alias (short form of `/peer`) |
|
||||
| `/peer 0x...` | Set DM peer by ETH address |
|
||||
| `/r [message]` | Reply to last DM sender; optionally include an inline message |
|
||||
| `/dm` | Switch to DM mode (clear group context) |
|
||||
|
||||
```
|
||||
/peer a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
/p @alice
|
||||
/peer 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
|
||||
/r
|
||||
/r hey, got your message
|
||||
/dm
|
||||
```
|
||||
|
||||
### Alias Management
|
||||
#### Groups
|
||||
|
||||
| Command | Description |
|
||||
|-----------------------|--------------------------------------------|
|
||||
| `/alias <name>` | Register an alias for your fingerprint |
|
||||
| `/unalias` | Remove your alias |
|
||||
| `/aliases` | List all registered aliases |
|
||||
|
||||
```
|
||||
/alias alice
|
||||
/unalias
|
||||
/aliases
|
||||
```
|
||||
|
||||
When you register an alias, the server returns a **recovery key** (32 hex chars). Save it — it is the only way to reclaim the alias if you lose access to your identity.
|
||||
|
||||
### Contacts & History
|
||||
|
||||
| Command | Short | Description |
|
||||
|------------------------|-------|------------------------------------------|
|
||||
| `/contacts` | `/c` | List all contacts with message counts |
|
||||
| `/history [peer]` | `/h` | Show message history (last 50 messages) |
|
||||
|
||||
```
|
||||
/contacts
|
||||
/c
|
||||
/history a3f8c91244be7d01
|
||||
/h
|
||||
```
|
||||
|
||||
If a peer is already set, `/h` without arguments shows that peer's history.
|
||||
|
||||
### Group Commands
|
||||
|
||||
| Command | Description |
|
||||
|------------------------|------------------------------------------|
|
||||
| `/g <name>` | Switch to group (auto-join) |
|
||||
| `/gcreate <name>` | Create a new group |
|
||||
| `/gjoin <name>` | Join an existing group |
|
||||
| `/gleave` | Leave the current group |
|
||||
| `/gkick <fp_or_alias>` | Kick a member (creator only) |
|
||||
| `/gmembers` | List members of the current group |
|
||||
| `/glist` | List all groups on the server |
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/g <name>` | Switch to group (auto-joins if not a member) |
|
||||
| `/gcreate <name>` | Create a new group (you become creator) |
|
||||
| `/gjoin <name>` | Join an existing group |
|
||||
| `/gleave` | Leave the current group |
|
||||
| `/gkick <fp_or_alias>` | Kick a member (creator only) |
|
||||
| `/gmembers` | List members of the current group with online status |
|
||||
| `/glist` | List all groups on the server |
|
||||
|
||||
```
|
||||
/gcreate ops-team
|
||||
/g ops-team
|
||||
/gjoin ops-team
|
||||
/gmembers
|
||||
/gkick a3f8c91244be7d01
|
||||
/gkick @mallory
|
||||
/gleave
|
||||
/glist
|
||||
```
|
||||
|
||||
Group messages are prefixed with `#groupname` in the UI. The current target shows in the header bar.
|
||||
When in a group, the header bar shows `#groupname` and all messages are sent to that group.
|
||||
|
||||
### File Transfer
|
||||
#### Alias Management
|
||||
|
||||
| Command | Description |
|
||||
|-------------------|----------------------------------------------|
|
||||
| `/file <path>` | Send a file to the current peer or group |
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/alias <name>` | Register an alias for your fingerprint |
|
||||
| `/aliases` | List all registered aliases |
|
||||
| `/unalias` | Remove your alias |
|
||||
|
||||
Alias rules: 1-32 alphanumeric characters (plus `_` and `-`), case-insensitive, normalized to lowercase. TTL is 365 days of inactivity, with a 30-day grace period. Registration returns a recovery key — save it.
|
||||
|
||||
#### File Transfer
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/file <path>` | Send a file to the current peer or group |
|
||||
|
||||
```
|
||||
/file /path/to/document.pdf
|
||||
/file ./photo.jpg
|
||||
```
|
||||
|
||||
Constraints:
|
||||
- Maximum file size: 10 MB
|
||||
- Chunk size: 64 KB
|
||||
- Files are sent as `FileHeader` + `FileChunk` wire messages
|
||||
- SHA-256 verification on receipt
|
||||
- Received files are saved to the current directory
|
||||
Files are split into 64 KB chunks, each encrypted with the Double Ratchet session key. The recipient reassembles and verifies a SHA-256 hash over the complete file. Maximum file size is 10 MB. Received files are saved to the current directory.
|
||||
|
||||
### Input Editing
|
||||
#### Contacts and History
|
||||
|
||||
The TUI supports full readline-style editing:
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/contacts` or `/c` | List all contacts with message counts |
|
||||
| `/history` or `/h` | Show message history for current peer (last 50) |
|
||||
| `/history <fp>` | Show history for a specific peer |
|
||||
|
||||
| Key | Action |
|
||||
|-----------------|------------------------------|
|
||||
| Left/Right | Move cursor |
|
||||
| Home / Ctrl-A | Move to beginning of line |
|
||||
| End / Ctrl-E | Move to end of line |
|
||||
| Backspace | Delete character before cursor|
|
||||
| Delete | Delete character at cursor |
|
||||
| Ctrl-U | Clear entire input |
|
||||
| Ctrl-W | Delete word before cursor |
|
||||
| Enter | Send message / execute command|
|
||||
| Ctrl-C | Quit |
|
||||
#### Identity and Security
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/info` | Show your fingerprint |
|
||||
| `/eth` | Show your Ethereum address |
|
||||
| `/seed` | Show your 24-word recovery mnemonic |
|
||||
| `/devices` | List your active device sessions |
|
||||
| `/kick <device_id>` | Revoke a specific device session |
|
||||
|
||||
#### Friend List
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/friend` | List friends with online/offline status |
|
||||
| `/friend <address>` | Add a friend by fingerprint or alias |
|
||||
| `/unfriend <address>` | Remove a friend |
|
||||
|
||||
The friend list is end-to-end encrypted and stored on the server as an opaque blob. The server cannot read it. Presence status (online/offline) is shown next to each friend.
|
||||
|
||||
#### General
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/help` or `/?` | Show command list |
|
||||
| `/quit` or `/q` | Exit the TUI |
|
||||
|
||||
### Keyboard Navigation
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| PageUp / PageDown | Scroll messages by 10 |
|
||||
| Up / Down (when input is empty) | Scroll messages by 1 |
|
||||
| Ctrl+End | Snap scroll to bottom |
|
||||
| Left / Right | Move cursor in input |
|
||||
| Home / Ctrl-A | Beginning of line |
|
||||
| End / Ctrl-E | End of line |
|
||||
| Ctrl-U | Clear input |
|
||||
| Ctrl-W | Delete word before cursor |
|
||||
| Ctrl-C | Quit |
|
||||
|
||||
### Receipt Indicators
|
||||
|
||||
Sent messages display receipt status:
|
||||
|
||||
| Indicator | Meaning |
|
||||
|-----------|----------------------------|
|
||||
| (tick) | Sent (no confirmation yet) |
|
||||
| (double tick, gray) | Delivered (decrypted by recipient) |
|
||||
| (double tick, blue) | Read (viewed by recipient) |
|
||||
| Indicator | Meaning |
|
||||
|-----------|---------|
|
||||
| Single tick | Sent (no confirmation yet) |
|
||||
| Double tick (gray) | Delivered (decrypted by recipient) |
|
||||
| Double tick (blue) | Read (viewed by recipient) |
|
||||
|
||||
---
|
||||
|
||||
## Web Client Commands
|
||||
## Web Client
|
||||
|
||||
The web client supports the same commands as the TUI, plus additional web-specific commands:
|
||||
### Access
|
||||
|
||||
### Standard Commands (same as TUI)
|
||||
Navigate to the server URL in a browser (e.g., `http://your-server:7700`). The web client generates a new identity automatically on first visit. Your seed is stored in `localStorage` — back it up using `/seed`.
|
||||
|
||||
`/peer`, `/p`, `/alias`, `/unalias`, `/r`, `/reply`, `/contacts`, `/c`,
|
||||
`/history`, `/h`, `/g`, `/gcreate`, `/gjoin`, `/gleave`, `/gkick`, `/gmembers`,
|
||||
`/glist`, `/file`, `/eth`, `/info`, `/quit`, `/dm`
|
||||
The web client uses the same E2E encryption as the TUI, compiled to WASM.
|
||||
|
||||
### Alias Resolution
|
||||
### URL Deep Links
|
||||
|
||||
Both TUI and web support `@alias` syntax:
|
||||
The web client supports deep links for direct navigation:
|
||||
|
||||
```
|
||||
/peer @alice # Resolves alias to fingerprint
|
||||
/p @bob # Short form
|
||||
```
|
||||
| URL | Effect |
|
||||
|-----|--------|
|
||||
| `/message/@alice` | Opens a DM with the alias `@alice` |
|
||||
| `/message/0xABC...` | Opens a DM with an ETH address |
|
||||
| `/group/#ops` | Opens the group `#ops` |
|
||||
|
||||
### Web-Only Commands
|
||||
Share these links to let someone jump straight into a conversation.
|
||||
|
||||
| Command | Description |
|
||||
|-------------------|----------------------------------------------------|
|
||||
| `/selftest` | Run WASM crypto self-test (X3DH + ratchet cycle) |
|
||||
| `/bundleinfo` | Debug: show bundle details (keys, sizes) |
|
||||
| `/debug` | Toggle debug mode (verbose output) |
|
||||
| `/reset` | Clear identity and all local data |
|
||||
| `/install` | Show PWA installation instructions |
|
||||
| `/sessions` | List active ratchet sessions |
|
||||
| `/admin-unalias` | Admin: remove any alias (requires admin password) |
|
||||
### Clickable Addresses
|
||||
|
||||
### Web Client Storage
|
||||
Fingerprints and addresses displayed in messages are clickable. Clicking an address sets it as your DM peer. If you are currently typing, clicking copies the address instead.
|
||||
|
||||
The web client stores data in `localStorage`:
|
||||
### Supported Commands
|
||||
|
||||
| Key | Value | Purpose |
|
||||
|----------------------|--------------------------------|----------------------------|
|
||||
| `wz_seed` | hex seed (64 chars) | Identity seed |
|
||||
| `wz_spk_secret` | hex SPK secret (64 chars) | Signed pre-key secret |
|
||||
| `wz_session:<fp>` | base64 ratchet state | Per-peer session |
|
||||
| `wz_contacts` | JSON contact list | Contact metadata |
|
||||
The web client supports the same slash commands as the TUI: `/peer`, `/p`, `/r`, `/dm`, `/g`, `/gcreate`, `/gjoin`, `/gleave`, `/gkick`, `/gmembers`, `/glist`, `/alias`, `/aliases`, `/unalias`, `/file`, `/contacts`, `/c`, `/history`, `/h`, `/info`, `/eth`, `/seed`, `/friend`, `/unfriend`, `/devices`, `/kick`, `/help`, `/quit`.
|
||||
|
||||
---
|
||||
|
||||
## Identity Management
|
||||
## Groups
|
||||
|
||||
### Seed
|
||||
|
||||
Your identity is a 32-byte seed. All keys are deterministically derived from it. **Lose the seed = lose the identity forever.**
|
||||
|
||||
### Mnemonic Backup
|
||||
|
||||
The seed is displayed as a 24-word BIP39 mnemonic during `warzone init`. Write it down on paper and store securely. You can recover your full identity from the mnemonic using `warzone recover`.
|
||||
|
||||
### Passphrase Encryption
|
||||
|
||||
The seed file (`~/.warzone/identity.seed`) is encrypted at rest:
|
||||
### Creating and Using Groups
|
||||
|
||||
```
|
||||
File format: WZS1(4 bytes) + salt(16) + nonce(12) + ciphertext(48)
|
||||
|
||||
Encryption: Argon2id(passphrase, salt) → 32-byte key
|
||||
ChaCha20-Poly1305(key, nonce, seed) → ciphertext
|
||||
/gcreate ops-team # Create (you become creator)
|
||||
/g ops-team # Switch to group (auto-joins if needed)
|
||||
/gjoin ops-team # Explicitly join an existing group
|
||||
```
|
||||
|
||||
An empty passphrase stores the seed in plaintext (for testing only).
|
||||
|
||||
### Ethereum Address
|
||||
|
||||
Your Ethereum address is derived from the same seed with domain-separated HKDF. Use `warzone eth` or `/eth` in the TUI to display it.
|
||||
|
||||
### Fingerprint Format
|
||||
|
||||
Fingerprints are `SHA-256(Ed25519_pubkey)[:16]` displayed as 8 groups of 4 hex digits:
|
||||
|
||||
```
|
||||
a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alias System
|
||||
|
||||
Aliases provide human-readable names for fingerprints.
|
||||
|
||||
### Registration
|
||||
|
||||
```
|
||||
/alias alice
|
||||
```
|
||||
|
||||
Returns a **recovery key** — save it securely. One alias per fingerprint. One fingerprint per alias.
|
||||
|
||||
### Rules
|
||||
|
||||
- Aliases are 1-32 alphanumeric characters (plus `_` and `-`)
|
||||
- Case-insensitive, normalized to lowercase
|
||||
- TTL: 365 days of inactivity (auto-renewed on any message activity)
|
||||
- Grace period: 30 days after expiry before reclamation
|
||||
- Recovery key: allows reclaiming an expired alias
|
||||
|
||||
### Recovery
|
||||
|
||||
If you lose access to your identity but have the recovery key, the server provides an alias recovery endpoint. This is an HTTP API operation:
|
||||
|
||||
```
|
||||
POST /v1/alias/recover
|
||||
{
|
||||
"alias": "alice",
|
||||
"recovery_key": "a1b2c3...",
|
||||
"new_fingerprint": "new_fp_hex"
|
||||
}
|
||||
```
|
||||
|
||||
The recovery key is rotated on each recovery.
|
||||
|
||||
### Admin Operations
|
||||
|
||||
An admin (with `WARZONE_ADMIN_PASSWORD`) can remove any alias:
|
||||
|
||||
```
|
||||
POST /v1/alias/admin-remove
|
||||
{
|
||||
"alias": "alice",
|
||||
"admin_password": "admin"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Group Management
|
||||
|
||||
### Creating and Joining
|
||||
|
||||
```
|
||||
/gcreate ops-team # Create a group (you become creator)
|
||||
/g ops-team # Switch to group (auto-joins if not a member)
|
||||
/gjoin ops-team # Explicitly join
|
||||
```
|
||||
|
||||
Groups auto-create on first join if they do not exist.
|
||||
|
||||
### Messaging
|
||||
|
||||
When the peer is set to a group (shows as `#groupname` in the header), all messages go to that group. The server fans out to all members.
|
||||
Once in a group, all messages you type go to that group. The server fans out to all members.
|
||||
|
||||
### Membership
|
||||
|
||||
- Creator can kick members with `/gkick <fingerprint>`
|
||||
- Any member can leave with `/gleave`
|
||||
- `/gmembers` shows all members with their aliases (if registered)
|
||||
- `/gmembers` shows all members with aliases and online status.
|
||||
- The creator can kick members with `/gkick <fingerprint_or_alias>`.
|
||||
- Any member can leave with `/gleave`.
|
||||
|
||||
### Sender Keys (Implemented in Protocol)
|
||||
### Sender Keys
|
||||
|
||||
The protocol implements Sender Keys for efficient group encryption:
|
||||
|
||||
1. Each member generates a `SenderKey` (random 32-byte chain key)
|
||||
2. The key is distributed to all members via 1:1 encrypted channels (`SenderKeyDistribution`)
|
||||
3. Group messages are encrypted once with the sender's key (`GroupSenderKey`)
|
||||
4. On member join/leave, all members rotate their sender keys
|
||||
|
||||
This provides O(1) encryption per message instead of O(N) per-member encryption.
|
||||
The protocol uses Sender Keys for efficient group encryption. Each member generates a random 32-byte chain key, distributes it to all other members over 1:1 encrypted channels, and encrypts group messages with their sender key. This gives O(1) encryption cost per message instead of O(N). Sender keys are rotated on member join or leave.
|
||||
|
||||
---
|
||||
|
||||
## Multi-Device Setup
|
||||
## File Transfer
|
||||
|
||||
### Current Support
|
||||
Files are transferred end-to-end encrypted through the relay server.
|
||||
|
||||
The server stores per-device bundles (`device:<fp>:<device_id>`). Multiple WebSocket connections per fingerprint are supported — all connected devices receive messages.
|
||||
1. The sender reads the file and splits it into 64 KB chunks.
|
||||
2. A `FileHeader` message is sent with the filename, total size, chunk count, and SHA-256 hash.
|
||||
3. Each `FileChunk` is encrypted with the Double Ratchet session and sent sequentially.
|
||||
4. The recipient reassembles all chunks and verifies the SHA-256 hash.
|
||||
5. The completed file is saved to the current directory.
|
||||
|
||||
### Setting Up a Second Device
|
||||
|
||||
1. On the new device, recover from mnemonic: `warzone recover <24 words>`
|
||||
2. Register with the server: `warzone register --server http://...`
|
||||
3. Both devices now share the same fingerprint and receive messages
|
||||
|
||||
### Limitations
|
||||
|
||||
- Ratchet sessions are per-device (not synchronized between devices)
|
||||
- Starting a new session on one device does not invalidate the other's session
|
||||
- Encrypted backup/restore can transfer session state between devices
|
||||
Maximum file size: **10 MB**. Chunk size: **64 KB**.
|
||||
|
||||
---
|
||||
|
||||
## Encrypted Backup & Restore
|
||||
## Friend List
|
||||
|
||||
### Creating a Backup
|
||||
The friend list provides presence tracking for contacts you care about.
|
||||
|
||||
```bash
|
||||
warzone backup my-backup.wzb
|
||||
```
|
||||
- `/friend <address>` adds a friend (by fingerprint or alias).
|
||||
- `/friend` lists all friends with their current online/offline status.
|
||||
- `/unfriend <address>` removes a friend.
|
||||
|
||||
This exports:
|
||||
- All ratchet sessions (Double Ratchet state)
|
||||
- All pre-key secrets (signed + one-time)
|
||||
- Encrypted with HKDF(seed, info="warzone-history") + ChaCha20-Poly1305
|
||||
The friend list is encrypted client-side and stored on the server as an opaque blob. The server relays it but cannot read its contents.
|
||||
|
||||
### Restoring a Backup
|
||||
---
|
||||
|
||||
```bash
|
||||
warzone restore my-backup.wzb
|
||||
```
|
||||
## Federation
|
||||
|
||||
Requires the same seed (passphrase prompt). Merges data without overwriting existing entries.
|
||||
Federation connects two featherChat servers so that users on different servers can message each other transparently.
|
||||
|
||||
### Backup File Format
|
||||
### Setup
|
||||
|
||||
```
|
||||
WZH1(4 bytes) + nonce(12) + ciphertext
|
||||
Each server needs a federation config file:
|
||||
|
||||
Plaintext: JSON {
|
||||
"version": 1,
|
||||
"sessions": { "<fp>": "base64_bincode", ... },
|
||||
"pre_keys": { "spk:1": "base64_bytes", "otpk:1": "base64_bytes", ... }
|
||||
```json
|
||||
{
|
||||
"server_id": "alpha",
|
||||
"shared_secret": "long-random-string-shared-between-both-servers",
|
||||
"peer": {
|
||||
"id": "bravo",
|
||||
"url": "http://10.0.0.2:7700"
|
||||
},
|
||||
"presence_interval_secs": 5
|
||||
}
|
||||
```
|
||||
|
||||
Start the server with federation enabled:
|
||||
|
||||
```bash
|
||||
warzone-server --bind 0.0.0.0:7700 --federation federation.json
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
The two servers maintain a persistent WebSocket connection between them. When a client on server Alpha sends a message to a fingerprint registered on server Bravo, server Alpha forwards the message over the federation link. The recipient's server delivers it via their normal WebSocket connection. Presence information is exchanged on a configurable interval.
|
||||
|
||||
From the user's perspective, federation is transparent. You address peers the same way regardless of which server they are on.
|
||||
|
||||
---
|
||||
|
||||
## Multi-Device
|
||||
|
||||
### Setup
|
||||
|
||||
1. On the new device, recover from mnemonic: `warzone-client recover <24 words>`
|
||||
2. Register with the server: `warzone-client register --server http://...`
|
||||
3. Both devices share the same fingerprint and receive messages.
|
||||
|
||||
### Device Management
|
||||
|
||||
- `/devices` lists all active sessions for your identity.
|
||||
- `/kick <device_id>` revokes a specific device session.
|
||||
|
||||
Ratchet sessions are per-device and not synchronized between devices. Use encrypted backup/restore (`warzone-client backup` / `warzone-client restore`) to transfer session state.
|
||||
|
||||
---
|
||||
|
||||
## Encrypted Backup and Restore
|
||||
|
||||
```bash
|
||||
# Export sessions and pre-keys, encrypted with your seed
|
||||
warzone-client backup my-backup.wzb
|
||||
|
||||
# Restore on another device (requires same seed)
|
||||
warzone-client restore my-backup.wzb
|
||||
```
|
||||
|
||||
The backup contains all Double Ratchet sessions and pre-key secrets. It is encrypted with HKDF(seed, info="warzone-history") + ChaCha20-Poly1305.
|
||||
|
||||
Reference in New Issue
Block a user