Core Architecture

System Overview

High-level components, state management structure, and end-to-end data flow in Wiltkey.

Overview

Wiltkey is a decentralized, ephemeral messaging app designed to minimize metadata and completely avoid long-term account state. The system consists of a Flutter Client (which stores key bytes and encrypted chat histories locally at rest) and a Go Blind Relay Server (which is strictly memory-only and coordinates connections and queues, storing no persistent chat history).

Authentication is tied entirely to local cryptographic identity keypairs (Ed25519) swapped in person over BLE. The server acts as a blind mailbox. Messages are padded, encrypted using a local One-Time Pad, and routed either directly (if the recipient is online) or enqueued temporarily (up to 24 hours) in a Redis mailbox on the relay.

End-to-End Data Flow

Sender Client Local SQLite DB WS (AUTH) Blind Relay websocket.go Redis Queue NEW_MSG Recipient Local Pad 1. BLE Handshake (Exchange Keys & Seed)

Core Components

1. Client State Model (AppState)

The client uses a unified AppState singleton that implements ChangeNotifier. The class is split across multiple `part of 'state.dart'` extension files to prevent monolithic file growth. AppState handles WebSocket reconnection, local UI coordination, and lazy message pagination.

2. Database Layer (WiltkeyDatabase)

A unified SQLite database (wiltkey.db) managed by WiltkeyDatabase. It caches contacts and persists received messages. Plaintext message bodies are never written directly; they are either kept encrypted in transit (OTP ciphertext) or re-encrypted using the user's master key at rest.

3. Blind Relay Server

The Go relay server coordinates blind message forwarding. Clients authenticate their WebSocket sessions by solving an Ed25519 signature challenge. The server maintains client lists strictly in memory. Offline messages are temporarily stashed in a Redis queue with a hard 24-hour Time-To-Live (TTL).

Key Files & Symbols

File Path Symbol Name Description
wiltkey_client/lib/main.dart main() Initializes application binding, loads locale and themes, and starts the lock screen.
wiltkey_client/lib/core/state.dart AppState Main singleton class coordinating connection, contact, and message state.
wiltkey_server/main.go main() Starts the blind Go HTTP/WebSocket server and connects to the Redis backend.

Gotchas & Edge Cases

⚠️ FALLBACK RELAY BEHAVIOR
If the client's configured relay (including optional local dev relays) is unreachable, the WebSocket client falls back to peer-advertised relays, and finally to the hardcoded default `https://api.wiltkey.org`. This creates a gap where a user's connection destination changes automatically without manual input.