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:
Siavash Sameni
2026-03-29 07:31:54 +04:00
parent dbf5d136cf
commit 7b72f7cba5
15 changed files with 2181 additions and 1023 deletions

View File

@@ -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.