> For the complete documentation index, see [llms.txt](https://parad0xlabs.gitbook.io/parad0xlabs-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://parad0xlabs.gitbook.io/parad0xlabs-docs/dark-null-protocol-zk-privacy-and-identity/stealth-nullpay.md).

# Stealth / NullPay

**For someone new to crypto:** on a normal blockchain, paying someone by name is like mailing cash to a sign on their front door. Everyone walking past can see the sign, see that cash arrived, and watch every other payment land at the same door. NullPay changes the destination, not the doorbell. You type a friend's name — `alice.null` — and your wallet quietly works out a brand-new, one-time address that only Alice can recognise and only Alice can open. The money lands there. An outside observer sees a payment to some fresh address they've never seen before, with no visible link to `alice.null` and no visible link to the last time someone paid her. Pay Alice ten times and that's ten unrelated-looking addresses on the chain.

**For the technically inclined:** NullPay is a dual-key Ed25519 stealth-address scheme (scan/view key + spend key) bound to a `.null` name. The recipient publishes a meta-address `(spend_pub, view_pub)`. The sender draws fresh ephemeral randomness `r`, computes a one-time destination `P = spend_pub + H(r·view_pub)·B`, sends there, and announces the ephemeral point `R = r·B` on-chain. The recipient scans with the view key (`v·R = r·view_pub`), recognises payments addressed to them, and recovers the matching one-time spend scalar `p = (spend + H(shared)) mod L`. The same arithmetic runs in the Rust crate `dark-stealth-ed25519` and in a byte-compatible browser port — same domain tags, same wide SHA-512 reduction — so the wallet derives the address client-side with no server in the loop.

## What you actually get today

This is a **devnet** rail. You can resolve a real `.null` name to its on-chain stealth meta-address, derive a one-time address in your browser, send SOL to it, and verify the result on Solana Explorer.

| Step    | Who              | What happens                                                                                                       |
| ------- | ---------------- | ------------------------------------------------------------------------------------------------------------------ |
| Publish | Recipient        | Sets a `(spend_pub, view_pub)` meta-address on their `.null` name (once, from their wallet).                       |
| Resolve | Sender's wallet  | Reads the name's meta-address from chain.                                                                          |
| Derive  | Sender's browser | Picks fresh randomness `r`, computes the one-time address `P` and ephemeral `R`. Pure client-side math.            |
| Pay     | Sender           | One transaction: transfer to `P`, plus a memo `nullpay:v1:alice.null:R=…` carrying `R`. Signed once in the wallet. |
| Scan    | Recipient        | Walks announced `R` values with the view key, finds payments that are theirs.                                      |
| Spend   | Recipient        | Recovers the one-time spend scalar for `P` and moves the funds.                                                    |

The view key can **scan but not spend** — useful for a light wallet that needs to spot incoming payments without holding the key that moves money.

## The flow

```mermaid
sequenceDiagram
    participant S as Sender's wallet
    participant C as Solana (devnet)
    participant R as Recipient
    S->>C: resolve alice.null → (spend_pub, view_pub)
    Note over S: derive in browser:<br/>P = spend_pub + H(r·view_pub)·B<br/>R = r·B
    S->>C: transfer SOL → P  (+ memo R)
    Note over C: observer sees only:<br/>a payment to a fresh address P
    R->>C: scan announced R with view key
    Note over R: v·R = r·view_pub → P is mine
    R->>C: recover spend scalar, move funds
```

An observer learns that *some* address received a payment. They do not learn it belongs to `alice.null`, and they cannot tie it to any other payment Alice has received.

## What it hides — and what it doesn't

NullPay hides the **recipient**, not the sender. This is identity privacy for the person being paid:

* ✅ The receiving address is unlinkable to the `.null` name.
* ✅ Two payments to the same name share no on-chain address.
* ✅ No exchange, mixer, or custodian — it is wallet-to-key math.
* ⚠️ **The sender is still visible.** You pay from your own normal wallet, and that wallet appears on-chain as the payer. The amount is also visible in the plain SOL transfer.

Hiding the sender (and the amount) is a *different* job — that's the shielded-pool / `eNULL` rail. Combine NullPay with the shielded pool and you can break the sender link too; on its own, NullPay only darkens the receiving side. In the portal this is shown as two tiers: **basic** (live, recipient-private) and **max private** (the shielded-pool route, not yet shipped).

The crate carries a `mainnet_ready = false` flag on every object it produces, by design, until this leaves devnet.

## What this is *not*

* Not a mixer or tumbler — there is no pooling of other people's funds in the basic rail; your coins go straight to the recipient's one-time address.
* Not sender-anonymous — see the caveat above.
* Not yet trustless about amounts — the basic SOL transfer shows the value on-chain.
* Not a claim of being "the only" or "the first" anything — it's a standard dual-key stealth construction (the kind used by other privacy systems) wired to `.null` names and exercised on devnet.

## Status

* **Live on devnet:** Ed25519 dual-key stealth addressing; resolve-a-`.null`-name → derive one-time address in-browser → pay → recover. Recipient/identity privacy only. Verifiable on Solana Explorer.
* **In-design / not shipped:** the **max-private** tier that routes through the shielded pool to also hide the sender and amount. The button is present but disabled.
* **Not on mainnet:** the rail runs on devnet; mainnet is gated on further work, including the shielded-pool privacy settlement.
* **Audit:** Public Beta, non-custodial, not yet audited.

Send a payment on devnet and watch the funds land at an address with no visible tie to the name.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://parad0xlabs.gitbook.io/parad0xlabs-docs/dark-null-protocol-zk-privacy-and-identity/stealth-nullpay.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
