# featherChat Help Reference featherChat (codename: warzone) = E2E encrypted messenger. TUI client, web client (WASM), federated servers. Crypto: X3DH key exchange + Double Ratchet. Identity = Ed25519 keypair from 24-word seed. ## Commands cmd | action | example --- | --- | --- /help, /? | show help | /help /info | show your fp | /info /eth | show ETH addr | /eth /seed | show 24-word recovery mnemonic | /seed /peer , /p | set DM peer | /peer abc123 or /peer @alice /reply, /r | reply to last DM sender | /r /dm | switch to DM mode (clear peer) | /dm /contacts, /c | list contacts + msg counts | /c /history, /h [fp] | show conversation history (50 msgs) | /h abc123 /alias | register alias for yourself | /alias alice /aliases | list all registered aliases | /aliases /unalias | remove your alias | /unalias /friend | list friends + online status | /friend /friend | add friend | /friend @bob /unfriend | remove friend | /unfriend @bob /devices | list active device sessions | /devices /kick | kick a device session | /kick dev_abc /g | switch to group (auto-join) | /g ops /gcreate | create group | /gcreate ops /gjoin | join group | /gjoin ops /glist | list all groups | /glist /gleave | leave current group | /gleave /gkick | kick member (creator only) | /gkick abc123 /gmembers | list group members + status | /gmembers /file | send file (max 10MB, 64KB chunks) | /file ./doc.pdf /quit, /q | exit | /q Navigation: PageUp/PageDown scroll msgs, Up/Down scroll by 1 (empty input), Ctrl+C or Esc quit. ## Addressing Format | Example | Notes --- | --- | --- Fingerprint | abc123def456... | hex string, derived from Ed25519 pubkey ETH address | 0x742d35Cc... | derived from same seed, checksum format @alias | @alice | 1-32 alphanum chars, globally unique, 365d TTL All 3 formats work in /peer. Aliases resolve to fp via server. One alias per user. Register with /alias, recover with recovery key. Bot alias reservation: names ending in Bot, bot, or _bot are reserved for the Bot API. Non-bot users cannot register these aliases. ## Quick Start 1. `warzone init` -- generates seed, saves identity.seed, prints 24-word mnemonic. WRITE IT DOWN. 2. `warzone register --server https://srv.example.com` -- uploads prekey bundle to srv 3. `warzone tui --server https://srv.example.com` -- opens TUI, connects WebSocket 4. `/peer @alice` or `/peer ` -- set recipient 5. Type msg, press Enter -- encrypted + sent Recovery: `warzone recover` -- enter 24 words to restore identity on new device. ## Groups - /gcreate -- create, you become creator + first member - /gjoin -- join existing (or auto-join via /g ) - type msg in group mode -- fan-out encrypted per-member (sender keys) - /gleave -- leave current group - /gmembers -- shows fp, alias, online status, creator flag - /gkick -- creator only, removes member Groups auto-create on join if they don't exist. Server fans out per-member encrypted msgs. ## Files /file -- sends to current peer/group. Max 10MB. Auto-chunked at 64KB. Includes filename, size, SHA-256 hash. Receiver auto-reassembles. ## Friends - /friend -- list all friends with online/offline status - /friend -- add (fp, ETH, or @alias) - /unfriend -- remove - Friend list stored encrypted on srv (only you can decrypt with your seed) - Shows alias resolution + presence status ## Devices - /devices -- list active WS connections (device_id, connected_at) - /kick -- revoke specific device - Max 5 concurrent device sessions - /devices/revoke-all API endpoint = panic button (kills all except current) ## Security - Seed = 24-word BIP39 mnemonic = master key. Derives Ed25519 identity + ETH wallet. - NEVER share seed. Only way to recover account. - X3DH key exchange establishes sessions. Double Ratchet provides forward secrecy. - All DMs E2E encrypted. Group msgs encrypted per-member. - Server sees: metadata (who talks to whom, timestamps), encrypted blobs, presence. - Server cannot read msg content. - Pre-keys: signed pre-key + 10 one-time pre-keys uploaded on register. - Bot msgs: clients auto-detect bot aliases, send plaintext (no E2E). Server can read bot msgs. - E2E bots possible (register with seed+bundle) but standard bots are plaintext. ## Federation - 2 servers connected via persistent WebSocket - Config: JSON file with server_id, shared_secret, peer URL - Messages auto-route across servers (srv checks remote presence) - Aliases globally unique across federation - @alias resolution checks local first, then federated peer - Same client commands work regardless of which srv peer is on - Auto-reconnects on connection failure ## Web Client - Browser access at server root URL (/) - WASM-compiled client, same crypto as TUI - PWA: installable, offline-capable (service worker caches shell) - Same E2E encryption as native client - Deep links: navigate to specific peers/groups via URL ## Troubleshooting Problem | Cause | Fix --- | --- | --- "peer not registered" | recipient hasn't run register yet | they need to `warzone register` "session reset" | crypto session re-established | normal after key rotation or recovery, msgs continue "connection lost" | WS disconnected | auto-reconnects, no action needed "alias already taken" | someone else has it | pick different name or wait for 365d expiry + 30d grace "not a member" | sending to group you left | /gjoin first "invalid token" | bot token expired or wrong | re-register bot "file too large" | over 10MB | split file manually no prekeys available | recipient's one-time prekeys exhausted | they need to re-register or come online ## Bot API (Telegram-compatible) ### Creating a Bot Server must run with `--enable-bots`. Then in chat: ``` /peer @botfather /newbot MyWeatherBot → BotFather replies with token ``` BotFather commands: /newbot, /mybots, /deletebot , /token , /help Bot names must end with bot/Bot/_bot. Only @botfather can create bots. ### Plaintext Bot Messaging Clients auto-detect bot aliases (names ending in Bot/bot/_bot) and send messages unencrypted (plaintext JSON). No E2E session is established for standard bot interactions. ### E2E Bot Option Bots can optionally participate in E2E encryption by registering with a seed and prekey bundle. Pass `e2e: true` + `bundle` + `eth_address` in the registration request. Users messaging an E2E bot establish a normal X3DH session. ### Bot Bridge `tools/bot-bridge.py` provides Telegram library compatibility. It translates between featherChat Bot API and standard TG bot libraries (python-telegram-bot, aiogram, Telegraf). ### Endpoints |Endpoint|Method|Body| |---|---|---| |/bot/:token/getMe|GET|--| |/bot/:token/getUpdates|POST|{"timeout":50}| |/bot/:token/sendMessage|POST|{"chat_id":"","text":"Hello","parse_mode":"HTML"}| |/bot/:token/setWebhook|POST|{"url":"https://..."}| |/bot/:token/deleteWebhook|POST|--| |/bot/:token/getWebhookInfo|GET|--| - Token format: fp_prefix:random_hex - getUpdates: long-poll (max 50s), returns then deletes queued msgs - sendMessage: plaintext JSON, NOT E2E encrypted (unless E2E bot) - Bot msgs delivered via same routing (WS push or DB queue) - Webhooks: updates are delivered live to the registered URL (POST with JSON body) - chat_id: accepts hex fingerprint or numeric ID (TG compatibility) - parse_mode: `HTML` renders basic HTML tags (, , , ) in clients - from.id is per-bot unique numeric (bots can't correlate users cross-bot, no raw fingerprint exposed) Update types in getUpdates: - Encrypted msg: text=null, raw_encrypted=base64 - Bot msg (plaintext): text="actual text", from.is_bot=true - Call signal: text="/call_Offer", call_signal={type,payload} - File: document={file_name,file_size} Echo bot (Python): ```python import requests, time TOKEN = "your_token" API = f"http://srv:7700/v1/bot/{TOKEN}" while True: for u in requests.post(f"{API}/getUpdates",json={"timeout":50}).json().get("result",[]): m = u["message"] if m.get("text"): requests.post(f"{API}/sendMessage",json={"chat_id":m["chat"]["id"],"text":"Echo: "+m["text"]}) time.sleep(1) ``` ## Voice Calls ### Architecture Call signaling flows through the featherChat WebSocket (offer/answer/hangup/reject/ringing/busy). Audio flows through a separate WZP relay infrastructure: ``` Browser A <--WS--> wzp-web <--QUIC--> wzp-relay <--QUIC--> wzp-web <--WS--> Browser B | | featherChat server (/v1/auth/validate) ``` ### Key files - Call signaling: `warzone-server/src/routes/ws.rs` (WireMessage::CallSignal handling) - Call state: `warzone-server/src/state.rs` (CallState, active_calls) - Relay config: `warzone-server/src/routes/wzp.rs` (token issuance) - Web audio: `warzone-server/src/routes/web.rs` (startAudio/stopAudio functions) - TUI calls: `warzone-client/src/tui/commands.rs` (/call, /accept, /reject, /hangup) - Protocol: `warzone-protocol/src/message.rs` (CallSignal, CallSignalType) ### Environment - `WZP_RELAY_ADDR` -- tells featherChat server where wzp-web bridge is (e.g., `127.0.0.1:8080`) - Without this, `/v1/wzp/relay-config` returns default `127.0.0.1:4433` ### Commands cmd | action | example --- | --- | --- /call | start voice call with current peer | /call /call | start voice call with specific peer | /call @alice /accept | accept incoming call | /accept /reject | reject incoming call | /reject /hangup | end current call | /hangup ## Server API (other endpoints) - POST /v1/register -- upload prekey bundle - GET /v1/keys/:fp -- fetch prekeys for peer - POST /v1/send -- send encrypted msg - GET /v1/receive/:fp -- poll msgs (WS preferred) - WS /v1/ws?fp=&token= -- real-time connection - GET /v1/presence/:fp -- check online status - GET/POST /v1/friends -- encrypted friend list - GET /v1/devices -- list sessions - POST /v1/devices/:id/kick -- kick device - Alias routes under /v1/alias/* - Group routes under /v1/groups/*