Architecture Overview
Design Principles
Section titled “Design Principles”- Privacy-first: No central servers, no telemetry, no metadata leakage
- Encrypted everywhere: at-rest (SQLCipher), in-transit (Tor), end-to-end (Signal Protocol)
- Pure P2P: Each user = one Tor hidden service
- Unix-focused: Linux, macOS, BSD
High-Level Data Flow
Section titled “High-Level Data Flow”User → TUI (ratatui) ─┐CLI → Unix socket ─────┤→ Signal Protocol (E2E) → Tor Hidden Service → PeerMCP → Unix socket ─────┘When you send a message:
- You type in the TUI input bar
- The message is encrypted with Signal Protocol (Double Ratchet via libsignal-dezire)
- The ciphertext is wrapped in a versioned
MessageEnvelopewith protocol version, ratchet header, and type metadata - It’s sent via the connection pool (reuses cached Tor circuits)
- If the peer is offline, it’s queued in the message queue with retries
- The peer’s Tor hidden service receives the envelope
- The peer decrypts with their Signal Protocol session
- The plaintext is stored in the encrypted SQLCipher database
Key Components
Section titled “Key Components”Application State (src/app.rs)
Section titled “Application State (src/app.rs)”The central App struct owns all runtime state: settings, database, identity keys, Tor client, hidden service, and message queue. App::new() initializes synchronously; Tor bootstrapping happens asynchronously via init_tor().
Database Layer (src/db/)
Section titled “Database Layer (src/db/)”SQLCipher provides at-rest encryption. The schema (currently v9) includes tables for friends, conversations, messages, signal sessions, blocked users, channels, and a key-value settings store. FTS5 virtual tables enable full-text message search with auto-sync triggers.
Migrations run automatically from v2 through v9 on startup.
Networking (src/net/)
Section titled “Networking (src/net/)”- Connection Pool (
pool.rs): Uses DashMap for lock-free concurrent access. Caches Tor circuits per peer (max 50). Idle connections evicted after 5 minutes. Retry-on-stale: dead connections are evicted and retried with a fresh circuit. - Rate Limiter (
rate_limit.rs): Per-peer token bucket rate limiter (5 req/s sustained, 20 burst) to prevent abuse. - Message Queue (
queue.rs): FIFO queue persisted in the database. Exponential backoff retries (30s base, doubles each attempt, capped at 15min, 24h expiry). - Framing (
framing.rs): Length-prefixed TCP framing for message I/O over Tor streams.
Protocol (src/protocol/)
Section titled “Protocol (src/protocol/)”13 message types: FriendRequest, FriendRequestAccept, FriendRequestReject, TextMessage, DeliveryReceipt, ReadReceipt, ChannelSubscribe, ChannelUnsubscribe, ChannelPost, ChannelSyncRequest, ChannelSyncResponse, ChannelPostReceipt, Presence.
All messages are wrapped in a versioned MessageEnvelope and JSON-serialized. Encrypted messages include a Double Ratchet header, base64-encoded ciphertext, and a type flag (PreKeyMessage or Message).
Message Handlers (src/handlers/)
Section titled “Message Handlers (src/handlers/)”Extracted handler functions for friend requests, messaging, and channel sync. These are shared by both the TUI and daemon — ensuring consistent behavior regardless of how you interact with chattor.
Daemon Mode (src/daemon/)
Section titled “Daemon Mode (src/daemon/)”A headless background process for scripting and automation. The daemon owns the same App state as the TUI but exposes it over a JSON-RPC 2.0 Unix socket instead of a terminal UI. Components:
- Event Loop (
event_loop.rs):tokio::select!loop handling incoming Tor messages, queue commands, presence ticks, and shutdown signals. Broadcasts message events to streaminglistenclients. - RPC Server (
rpc.rs,socket.rs): 15 JSON-RPC methods covering friends, messaging, channels, settings, and status. Unix socket with 0600 permissions (owner-only access). - PID File (
pid.rs): Mutual exclusion — only one daemon per data directory. - Background Tasks (
tasks.rs): Channel sync (every 5 min) and heartbeat presence.
CLI Client (src/client.rs)
Section titled “CLI Client (src/client.rs)”Thin client that connects to the daemon’s Unix socket and issues JSON-RPC calls. Each CLI subcommand maps to one RPC method, formats the response, and exits. The listen subcommand streams incoming messages in real time.
MCP Server (src/mcp/)
Section titled “MCP Server (src/mcp/)”Model Context Protocol server over stdio for AI agent integration. Exposes 9 tools (send_message, receive_messages, list_friends, etc.) that delegate to the daemon via the same Unix socket as the CLI. Protocol version 2024-11-05.
UI (src/ui/)
Section titled “UI (src/ui/)”Built with ratatui. Layout: friends sidebar (left) + conversation/channel view (right). Modals for add friend, friend requests, identity, settings, and channel subscribe. Theme engine with 7 presets and TOML config override.
Project Structure
Section titled “Project Structure”src/├── app.rs # Application state├── cli.rs # CLI parsing (clap, 12 subcommands)├── client.rs # JSON-RPC client for daemon IPC├── main.rs # Entry point, subcommand routing├── crypto/ # Ed25519 identity, Signal Protocol├── daemon/ # Headless daemon mode│ ├── event_loop.rs # tokio::select! main loop│ ├── pid.rs # PID file mutual exclusion│ ├── rpc.rs # JSON-RPC 2.0 dispatch (15 methods)│ ├── socket.rs # Unix socket server│ └── tasks.rs # Background tasks (sync, heartbeat)├── db/ # SQLCipher database, queries, schema├── handlers/ # Shared message handlers (TUI + daemon)│ ├── channels.rs # Channel sync requests│ ├── friend_request.rs # Friend request lifecycle│ └── messaging.rs # Message send/receive/queue├── mcp/ # Model Context Protocol server│ ├── server.rs # MCP stdio transport│ └── tools.rs # 9 tool definitions + RPC mapping├── net/ # Connection pool, message queue, framing├── protocol/ # Friend codes, messages, friend requests├── tor/ # Arti client, onion service, connections└── ui/ # TUI layout, themes, modals