Protocol
The Humanity Ledger platform paper
A technical description of the platform: its design goals, each subsystem, the threat model and the open problems.
Revised 21 October 2026. This revision replaces earlier versions that described components the product does not use, such as Waku routing and a Double Ratchet over X3DH. The current design is described below.
Abstract
Humanity Ledger is a communication platform in which an Ethereum address is the account. Ledger Chat, its first application, offers direct messages encrypted with MLS through the XMTP network, communities, WebRTC calls and payments signed by the user's own wallet. This paper describes each subsystem, states what each party can observe, and lists the properties the system does not yet provide.
1. Design goals
- No phone number, no password. Possession of a wallet is sufficient to create and use an account.
- Content belongs to the endpoints. Our servers should not be able to read direct messages.
- No custody. The platform never holds user funds or keys that can move them.
- Stated limits. Where a goal is not met, the product says so in the interface and in this paper.
2. Identity and sessions
Authentication follows EIP-4361. The client requests a nonce from the server, which returns it together with a cookie sealed by the server and valid for ten minutes, so only a nonce the server issued can be used. The client constructs a Sign in with Ethereum message containing the domain, the address, the nonce, the issue time and the chain, and the wallet signs it. The server checks the domain against its configured address (with or without www.), checks the nonce and its age, marks the nonce as used so it cannot be used twice, and recovers the signer, which must match the address in the message. Smart contract wallets are checked on their own chain (ERC-1271 and ERC-6492). Any EVM chain is accepted, since a wallet signature does not depend on the chain.
Sessions are JSON Web Tokens signed with HMAC-SHA256 and held in a cookie unavailable to scripts, valid for seven days. A perimeter function in front of every route removes identity headers supplied by the client and attaches the address taken from the verified token. Routes read identity only from that value.
Accounts can also be created with an email address and a one time code. Such accounts are identified internally by a random identifier rather than an address, and are marked so that routes requiring a wallet can refuse them explicitly.
3. Direct messages
Direct messages use the XMTP network, which implements the Messaging Layer Security protocol (RFC 9420). Each browser installation generates its own key material after the user authorises it with a wallet signature. Conversations are MLS groups; the epoch key schedule gives forward secrecy and post compromise security at the granularity of group updates.
XMTP nodes store ciphertext so that offline recipients can collect it. At the time of writing they are operated by a single company and retain payloads without a time limit. Decrypted history is stored in the browser.
Normal path
- Encrypts the message
- Stores it until collected
- Decrypts it with its own keys
Fallback path, only if the normal path fails
- Sends the text as written
- Can read it
- Labels it in the chat
- Shows the label
3.1 The fallback relay
When delivery through XMTP fails, typically because the recipient has no XMTP installation yet, the client may submit the message to our server. The server stores it in PostgreSQL and in a Redis sorted set with a seven day expiry until the recipient collects it. Messages on this path are readable by the server. The client labels them on both sides of the conversation.
A guard on the server rejects or reports any message body that is not a sealed envelope of the form hlv1.<algorithm>.<payload>. In its default mode it records that a readable body arrived without recording the body. Rejection is enabled with a configuration flag once clients seal fallback messages.
4. Communities
Communities, channels, members and roles are rows in PostgreSQL, and permissions are enforced by the server on every request. Invite links carry an HMAC-SHA256 tag so they cannot be forged, and can be revoked. Community posts and channel messages are currently stored in readable form on the server.
5. Calls
Calls use WebRTC. Session descriptions and candidates are exchanged through the public PeerJS signalling service. Connectivity uses Google STUN servers and, when a direct path is unavailable, the public OpenRelay TURN service. Media is encrypted with DTLS-SRTP negotiated between the browsers, so neither signalling nor relays can decode it. A setting forces relay only connections, which prevents the remote party from learning the user's IP address.
6. Payments
Payments are ordinary EVM transactions constructed by the client with wagmi and viem and signed by the user's wallet through EIP-1193 or WalletConnect. Native transfers use value transfers; ERC-20 transfers call transfer(address,uint256). The server never receives a signing key. After confirmation the client sends a receipt into the conversation. Payment requests can be encoded as EIP-681 URIs for display as QR codes.
7. Private payments
A private payments wallet runs on the Aztec test network, version 6.0.0, which settles on Ethereum Sepolia. The client derives the secret of a Schnorr account contract from an EIP-712 signature by the user's wallet using HKDF-SHA256, so the same wallet always recovers the same account and the server never holds a spending key. A Private eXecution Environment runs in the browser with IndexedDB storage, decrypts the user's notes and generates proofs locally. Account deployment and transaction fees are paid by Aztec's sponsored fee payment contract.
Balances are held in instances of Aztec's standard token contract. Shielding calls transfer_to_private, unshielding calls transfer_to_public, and a private payment calls transfer_private_to_private. Shielding and unshielding reveal the address and the amount by construction; a private payment reveals only that a transaction occurred. Transaction history is assembled by the client from its own notes and receipts. A bridge to Ethereum is not built, the tokens are test tokens without value, and the contracts have not been independently audited.
8. Device protection
Access to Ledger Chat on a device is gated by a six digit PIN. The server stores Argon2id of the PIN with a per account salt and a server held pepper, limits concurrent hashing work, and allows eight attempts per five minute window. The PIN gates the interface; it is not used to derive message keys.
9. Threat model
| Adversary | Can | Cannot |
|---|---|---|
| Someone with full control of our servers | Read fallback messages, community posts, attachments, contacts and account data. See who is online. Deny service. | Read direct messages delivered through XMTP. Sign as a user. Move user funds. |
| An XMTP node operator | See encrypted messages, their size and timing, and the conversations they belong to. | Read them. |
| An observer on the user's network | See which services the user connects to and when. | Read any content protected by TLS. |
| Someone with the user's unlocked device | Open Ledger Chat if they know the PIN. Read data stored by the browser with developer tools, even without it. | Sign in on another device without the wallet. |
| Malware on the user's device | Everything the user can see. | Nothing prevents this. No software only design can. |
10. Scaling
Web servers are stateless. PostgreSQL is reached through a connection pooler, with a direct connection reserved for migrations. Online status is written to Redis with an expiry rather than to the database. Remaining single instance state, such as device linking codes held in memory, and polling in parts of the interface are the current limits on horizontal scaling.
11. Open problems
- Removing the readable fallback path, by sealing fallback messages on the client or by ensuring both parties have XMTP installations.
- Encrypting community content end to end, for example as MLS groups.
- Encrypting attachments before upload.
- An independent audit of the contracts and a penetration test of the application.
- Self hosted call signalling, so that call setup does not depend on a public service.
