A Next.js (App Router) demo of end-to-end encrypted chat built on PrivMX Threads, with MongoDB-backed sign-up and a key-based, challenge-response sign-in. Private keys never leave the browser.
| Route | What it does |
|---|---|
/signup |
Generate or paste a PrivMX private key, derive the public key, create the account in MongoDB, and register the user in Context via PrivMX Bridge (context/addUserToContext). |
/signin |
Challenge-response auth: the server issues a one-time nonce, the browser signs it with the private key, and the server verifies the signature against the stored public key, then sets a session cookie. |
/chat |
Session-gated. End-to-end encrypted messaging over PrivMX Threads — create/select threads, send messages, and receive them live via thread events. |
- PrivMX Endpoint (the encryption SDK) runs client-side as WebAssembly.
Its assets are copied into
public/privmx-assetsautomatically on install (postinstall→scripts/copy-privmx-assets.mjs), and/chatis served with theCross-Origin-Opener-Policy/Cross-Origin-Embedder-Policyheaders the WASM requires (configured innext.config.js). - Keys are standard secp256k1 — private key in WIF, public key as
base58check. Signing and verification are done in pure JS (
lib/keys.ts, using@noble/curves), so the server can verify sign-in signatures without the browser-only SDK. - MongoDB (
lib/mongodb.ts, native driver) stores three collections:accounts,auth_challenges(with a TTL index that auto-expires nonces), Collections and indexes are created on first use — there is no migration step. - PrivMX Bridge management API is called only from the server
(
lib/privmx-bridge.ts, HTTP Basic auth) so API-key secrets stay off the client.
- Node.js 20+
- A MongoDB instance
- A running PrivMX Bridge (provides a Solution + Context and an API key)
-
Start MongoDB (e.g. via Docker):
docker run --name mongo -p 27017:27017 -d mongo:8
-
Set up PrivMX Bridge by following the installation guide. It creates a Solution and a Context during initialization and gives you an API key (ID + secret).
-
Configure environment. Copy
.env.exampleto.env.localand fill in the MongoDB connection, the PrivMX Bridge URL / Solution ID / Context ID, the server-side API key, and aSESSION_SECRET:cp .env.example .env.local
-
Install dependencies (also copies the PrivMX WASM assets):
pnpm install
-
Start the dev server:
pnpm dev
Then open http://localhost:3000, sign up to create an account (save the private key it shows you), sign in with that key, and you'll land on the chat.
See .env.example for the full list and comments. In short:
MONGODB_URI,MONGODB_DB— database connection.NEXT_PUBLIC_PRIVMX_*— client-side chat connection (Bridge URL, Solution ID, Context ID; optional prefills).PRIVMX_BRIDGE_API_URL,PRIVMX_API_KEY_ID,PRIVMX_API_KEY_SECRET,PRIVMX_CONTEXT_ID— server-side PrivMX Bridge management API (sign-up).SESSION_SECRET— signs the session cookie.