docs/ARCHITECTURE.md (531 lines): System design, ASCII diagrams, crypto stack, dual-curve identity, wire protocol (7 WireMessage variants), server/client architecture, data flow diagrams, storage model, extensibility points docs/USAGE.md (550 lines): Complete user guide: installation, all CLI commands (10), all TUI commands (20+), all web commands, file transfer, identity management, aliases, groups, multi-device, backup, keyboard shortcuts docs/INTEGRATION.md (542 lines): WarzonePhone concept, Ethereum/Web3, OIDC, DNS federation, transport abstraction, multi-server mode, custom clients, ntfy, how-to guides for extending message types/commands/storage docs/PROGRESS.md (234 lines): Timeline, Phase 1 (16 features), Phase 2 (16 features), v0.0.20, 28 tests, bugs fixed, known limitations, Phase 3-7 roadmap docs/SECURITY.md (438 lines): Threat model, 8 crypto primitives, key derivation paths, forward secrecy, Sender Keys trade-offs, seed security, server trust, WASM security, known weaknesses, comparison with Signal/Matrix/SimpleX Total: 3,751 lines across 8 doc files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15 KiB
Warzone Messenger (featherChat) — Usage Guide
Version: 0.0.20
Installation
Build from Source
Requirements: Rust 1.75+, cargo
# 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
Build the WASM Module (Web Client)
Requirements: wasm-pack
cd crates/warzone-wasm
wasm-pack build --target web
# Output in pkg/ — copy to web client directory
Server Configuration
The server accepts two flags:
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 |
Environment variables:
| Variable | Default | Description |
|---|---|---|
WARZONE_ADMIN_PASSWORD |
admin |
Password for admin alias ops |
RUST_LOG |
info |
Log level filter |
Quick Start
CLI Quick Start
# 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
- 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 via the displayed hex seed - Use
/peer <fingerprint>or/peer @aliasto select a chat partner - Type messages and press Enter to send
CLI Commands
warzone init
Generate a new identity (seed + keypair + pre-keys).
$ 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.
The seed is stored at ~/.warzone/identity.seed, encrypted with Argon2id + ChaCha20-Poly1305.
warzone recover <words...>
Recover an identity from a BIP39 mnemonic.
$ 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 info
Display your fingerprint and public keys.
$ warzone info
Fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
Signing key: 3a7b...
Encryption key: 9f2c...
warzone eth
Display your Ethereum-compatible address derived from the same seed.
$ warzone eth
Warzone fingerprint: a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
Ethereum address: 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
Same seed, dual identity.
warzone register
Register your pre-key bundle with a server.
$ warzone register --server http://localhost:7700
warzone send <recipient> <message>
Send an encrypted message. Recipient can be a fingerprint or @alias.
$ 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.
$ warzone recv --server http://localhost:7700
warzone chat [peer]
Launch the interactive TUI client.
$ 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).
$ 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.
$ warzone restore my-backup.wzb
Restored 12 entries from my-backup.wzb
TUI Commands
The TUI is launched with warzone chat. All commands start with /.
Peer & Navigation
| 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 |
/peer a3f8:c912:44be:7d01:9e5a:3b2c:7f80:12d4
/p @alice
/r
/dm
Alias Management
| 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 |
/gcreate ops-team
/g ops-team
/gjoin ops-team
/gmembers
/gkick a3f8c91244be7d01
/gleave
/glist
Group messages are prefixed with #groupname in the UI. The current target shows in the header bar.
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+FileChunkwire messages - SHA-256 verification on receipt
- Received files are saved to the current directory
Input Editing
The TUI supports full readline-style editing:
| 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 |
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) |
Web Client Commands
The web client supports the same commands as the TUI, plus additional web-specific commands:
Standard Commands (same as TUI)
/peer, /p, /alias, /unalias, /r, /reply, /contacts, /c,
/history, /h, /g, /gcreate, /gjoin, /gleave, /gkick, /gmembers,
/glist, /file, /eth, /info, /quit, /dm
Alias Resolution
Both TUI and web support @alias syntax:
/peer @alice # Resolves alias to fingerprint
/p @bob # Short form
Web-Only Commands
| 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) |
Web Client Storage
The web client stores data in localStorage:
| 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 |
Identity Management
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:
File format: WZS1(4 bytes) + salt(16) + nonce(12) + ciphertext(48)
Encryption: Argon2id(passphrase, salt) → 32-byte key
ChaCha20-Poly1305(key, nonce, seed) → ciphertext
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.
Membership
- Creator can kick members with
/gkick <fingerprint> - Any member can leave with
/gleave /gmembersshows all members with their aliases (if registered)
Sender Keys (Implemented in Protocol)
The protocol implements Sender Keys for efficient group encryption:
- Each member generates a
SenderKey(random 32-byte chain key) - The key is distributed to all members via 1:1 encrypted channels (
SenderKeyDistribution) - Group messages are encrypted once with the sender's key (
GroupSenderKey) - On member join/leave, all members rotate their sender keys
This provides O(1) encryption per message instead of O(N) per-member encryption.
Multi-Device Setup
Current Support
The server stores per-device bundles (device:<fp>:<device_id>). Multiple WebSocket connections per fingerprint are supported — all connected devices receive messages.
Setting Up a Second Device
- On the new device, recover from mnemonic:
warzone recover <24 words> - Register with the server:
warzone register --server http://... - 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
Encrypted Backup & Restore
Creating a Backup
warzone backup my-backup.wzb
This exports:
- All ratchet sessions (Double Ratchet state)
- All pre-key secrets (signed + one-time)
- Encrypted with HKDF(seed, info="warzone-history") + ChaCha20-Poly1305
Restoring a Backup
warzone restore my-backup.wzb
Requires the same seed (passphrase prompt). Merges data without overwriting existing entries.
Backup File Format
WZH1(4 bytes) + nonce(12) + ciphertext
Plaintext: JSON {
"version": 1,
"sessions": { "<fp>": "base64_bincode", ... },
"pre_keys": { "spk:1": "base64_bytes", "otpk:1": "base64_bytes", ... }
}