Stealth & announce

Hiding the amount is half the problem. If a payment still lands at a recipient's known address, the graph gives them away. Protocol15 sends every payment to a fresh one-time address that only the recipient can derive, and uses a single shared anchor to let them find it.

Keys from one signature

Everything derives from one ed25519 signature. The wallet signs a fixed message and that signature seeds a small hierarchy of keys: a scan key, a spend key, and the secrets that protect notes. There are no seed phrases to manage, and any wallet that can sign a message works.

These keys are organized into epochs. Bumping the epoch produces a fully independent set of keys and a new public address, while everything from earlier epochs stays valid. Epochs are the containment primitive: if a key is exposed, you rotate to a new epoch instead of moving funds.

Meta-address

Your public identity in the protocol is a meta-address: a bech32m string that encodes your scan and spend public keys. You share it once. Senders use it to pay you, but a meta-address is not where funds land. It is the input from which a sender computes a unique one-time address for each payment.

Two payments to the same meta-address produce two unrelated on-chain addresses. Nobody can tell they went to the same person.

The announce anchor

A one-time address is unlinkable, which creates a discovery problem: how does the recipient know a payment exists? Every blind transfer also sends one lamport to a single fixed anchor address, carrying an encrypted memo. Recipients scan the history of that one address, decrypt the memos addressed to them, and recover their payments. A short public view tag lets a scanner skip memos that are not theirs cheaply, so misses are fast.

Both sides from one scan

The sender posts two memos in the same transaction. One is encrypted to the recipient's scan key; the other is a self-receipt encrypted to the sender's own scan key. So both sides of every transfer are recoverable purely by scanning, with no device-local history to lose. A single scan of the anchor returns both the payments you received and the ones you sent.

For wallets that do not want to make many RPC calls, an optional indexer pre-collects the anchor's encrypted memos and serves them in one request. Decryption always stays on the client; the indexer only ever sees ciphertext and the public view tag. See the Indexer deploy guide.

Finality

Live outputs are non-revocable. The one-time account is owned by a key the recipient alone can produce, and release requires that key as a signer, which the sender cannot generate. Payments are final. A sender cannot claw a payment back, and funds sent to a dead address are lost. That is the cost of making delivery unlinkable and trustless at the same time.