Protocol
Architecture overview
The parts that make up Humanity Ledger, where each one runs, and what each one can see.
Humanity Ledger is a web application that connects your device to a small set of our own services and to two open networks. The most useful way to understand it is to ask, for each part, what it holds and what it can read.
- Ledger Chat in your browser
- Message keys and history
- Your wallet, which signs
- Sign in and sessions
- Profiles and contacts
- Communities
- Fallback relay, readable
- Stores encrypted messages
- Cannot read them
- Ethereum and layer 2 networks
- Aztec, experimental
The parts
| Part | What it holds | Can it read your direct messages? |
|---|---|---|
| Your browser | The Ledger Chat app, your message keys and your conversation history. | Yes. This is where messages are encrypted and decrypted. |
| Your wallet | The private key for your address. It signs sign in messages and payments. | No. It is never given message content. |
| Humanity Ledger servers | Accounts, sessions, profiles, contacts, communities, the hash of your PIN and the fallback relay. | Only messages that took the fallback path, which are labelled. |
| XMTP network | Encrypted messages waiting to be collected. | No. |
| Ethereum and layer 2 networks | Public payments you send from your wallet. | No. Payments themselves are public. |
| Aztec network | Private payment notes, in our experimental integration. | No. |
Our servers
The web application runs on Next.js. A PostgreSQL database holds accounts and community data, and a Redis cache holds short lived state such as rate limits, online status and fallback messages waiting for delivery.
The identity perimeter
Every request passes through one piece of code before it reaches any route. It deletes any identity headers the browser sent, verifies the session cookie, and only then attaches the verified address for the route to use. A route cannot be tricked into acting for someone else by a forged header or a parameter in the address bar.
- Requests that change data must come from our own origin, which blocks cross site request forgery.
- A content security policy with a fresh nonce on every request limits which scripts the page can run.
- Sign in, email codes and PIN checks are rate limited.
Services we rely on
| Service | Used for | What it receives |
|---|---|---|
| XMTP | Delivering direct messages | Encrypted messages and the time they were sent. |
| Reown WalletConnect | Connecting wallets on other devices | Your wallet address and connection requests. |
| Resend | Sending sign in codes by email | Your email address and the code. |
| Cloudflare Turnstile | Stopping automated email sign ups | Browser signals used to tell people from bots. |
| Cloudflare R2 | Storing attachments | The files you attach. |
| PeerJS, Google STUN, OpenRelay TURN | Setting up and relaying calls | Connection details and, for relayed calls, encrypted media. |
| Public blockchain RPC providers | Reading balances and sending transactions | Your address and the transactions you send. |
Known limits at scale
The web servers are stateless and can be run as many copies as needed. A few parts are not ready for that yet, and we list them so nobody is surprised:
- Device linking codes and some rate limit counters live in the memory of a single server, so they do not follow a request to another copy.
- Some views refresh by polling rather than by push, which adds load as the number of people online grows.
- Community posts are served from the database on every request without a cache in front.
