Architecture
One Anchor 0.31.1 program, program id xk7UkNkjzd9axDvF1eLrUqoVbyjaEaVJwj8siR3mXhK (not deployed yet). No backend: the app reads accounts straight from an RPC and signs with the user's wallet.
Accounts
| Account | Seeds | What it holds |
|---|---|---|
| Config | ["config"] | D00R mint, burn pools (USDC, wSOL), name price, D00R burned by fees and by names. Written once at launch. |
| Treasury | ["treasury", mint] | Per accepted mint: outstanding (sum of open bonds), fees_collected, fees_spent. |
| Bond vault | ["bonds", mint] | SPL token account holding every open bond of that mint. Owner: the authority PDA. |
| Fee vault | ["fees", mint] | SPL token account holding spam fees not yet burned. |
| Authority | ["authority"] | Signs vault transfers, the burn swap and the burn. No data. |
| Bought | ["bought"] | D00R token account the crank buys into and burns from in the same instruction. |
| Inbox | ["inbox", owner] | Terms (mint, bond, window, X25519 key, accepting) and public counters. One per wallet, never closable. |
| Knock | ["knock", recipient, sender] | One open message: sender, mint, bond, knocked_at, expires_at, reply_key, ciphertext. Closed when it ends; rent goes back to the sender. |
| NameRecord | ["name", name] | Owner of a claimed name, 3 to 20 characters of a-z, 0-9 and underscore. |
Accepted mints
Bonds are locked in exactly two mints, both on the classic SPL Token program:
| Mint | Address | Smallest bond |
|---|---|---|
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | 1 USDC |
| Wrapped SOL | So11111111111111111111111111111111111111112 | 0.01 SOL |
USDC and SOL have separate vaults and separate books. No instruction converts one into the other, so a bond always comes back in the mint and amount it was locked in.
Message storage
Messages are stored as ciphertext inside the Knock account. Replies ride in the reply transaction's data and are never stored in an account.
- Privacy: the sender encrypts to the inbox's X25519 public key. Only the holder of the matching secret can read. The program stores opaque bytes and never sees plaintext.
- No backend: an inbox loads with one
getProgramAccountscall (memcmp onrecipientat offset 8). - Thread history: the knock address is the pair, so
getSignaturesForAddress(knock)lists every knock and reply the two wallets ever exchanged. - Cost is temporary: the account deposit is refunded on reply, spam mark and expiry alike.
Rent, quoted from mainnet on 2026-10-17
| Account | Bytes | SOL locked |
|---|---|---|
| Knock, 1-byte message | 166 | 0.00149352, refunded |
| Knock, 280-byte message | 445 | 0.00291084, refunded |
| Knock, 560-byte message | 725 | 0.00433324, refunded |
| Inbox | 202 | 0.00167640, kept: inboxes never close |
| NameRecord | 65 | 0.00098044, refunded on release |
Compute
| Instruction | Compute units |
|---|---|
open_inbox | 9.5k |
send_knock | 22.6k |
reply | 20.2k |
mark_spam | 24.7k |
expire | 20.0k |
claim_name | 18.0k |
crank_burn | 72k to 75k |