From payment to spendable funds
The protocol has six stages. Each one exists to separate public discovery from private ownership while keeping the result usable in today’s wallets.Stage 1: Generate your keys
The backend generates two ML-KEM-768 keypairs:- Spending keypair (
spending_pk/spending_sk) - determines where money lands - Viewing keypair (
viewing_pk/viewing_sk) - lets you find your payments
meta_address, spending_pk, spending_sk, viewing_pk, viewing_sk.

Stage 2: Publish your meta-address
Make your meta-address discoverable. Two options: ENS (Ethereum): Upload meta-address to IPFS, set your ENS text record to point at the IPFS CID. Senders resolvealice.eth to your meta-address automatically.
SuiNS (Sui): Same pattern with Sui name records.
Or just share the raw meta-address string directly. Name services are convenient, not required.
Stage 3: Sender creates the payment
This is where ML-KEM does its work. The sender:- Reads your
viewing_pkfrom the meta-address - Runs ML-KEM encapsulation to produce:
- A ciphertext (1,088 bytes) - this is the encrypted hint
- A shared secret (32 bytes) - known to both sender and recipient
- Computes a 1-byte view tag from the shared secret
- Derives a stealth address (Ethereum and/or Sui) from the shared secret + your
spending_pk
stealth_address.

Stage 4: Sender posts an announcement
The announcement is the public breadcrumb. It contains:| Field | Purpose |
|---|---|
ephemeral_key | The ML-KEM ciphertext (encrypted shared secret) |
view_tag | 1-byte filter for fast scanning |
tx_hash | Transaction reference (optional) |
amount | Payment amount (optional) |
chain | Target chain (optional) |
channel_id | Yellow channel link (optional) |
Stage 5: Recipient scans
This is the discovery process. The recipient:- Loads announcements from the registry
- For each announcement, decapsulates the ciphertext using
viewing_sk - Computes the expected view tag from the shared secret
- Fast path: if the view tag doesn’t match, skip (filters ~99.6% of announcements)
- Full path: if it matches, derive the stealth address and compare

Stage 6: Spend the funds
The scan returns everything needed to spend:| Field | What it is |
|---|---|
stealth_address | The Ethereum address holding the funds |
stealth_sui_address | The Sui address (if applicable) |
eth_private_key | The derived private key for spending |
The three objects that matter
| Object | What it does | Who holds it |
|---|---|---|
| Meta-address | Public receiving profile | Published by recipient, read by senders |
| Announcement | Encrypted breadcrumb for discovery | Published by sender, scanned by recipient |
| Stealth private key | Controls the funds | Only the recipient |
What sender and recipient each see
- Sender's perspective
- Recipient's perspective
- Observer's perspective
The sender needs only the recipient’s meta-address or name.They never learn the recipient’s real wallet address. They derive a fresh stealth address, send funds to it, and post an announcement. From their side, it’s three API calls.
The security split
The receiving path (stages 1-5) uses ML-KEM-768 and is post-quantum safe. The spending path (stage 6) produces a secp256k1 key for Ethereum wallet compatibility. That part is classical. Read Security Boundaries for why this split exists and how it could be resolved.Post-quantum crypto details
What ML-KEM-768 actually does under the hood.
Try the full flow
Run every stage against the live API.
