How it works
Private payments
Send stablecoins to an UMBR address or through a claim link. The amount and the link between sender and receiver stay off the public record.
- Send to
- umbr1q… address or a link
- Hidden
- Amount, sender, receiver
- Memo
- Encrypted to the recipient
How a private payment works#
A private payment moves value from your private balance to someone else's, entirely inside the shielded pool. You spend one or more of your notes and create new ones: one for the recipient, and usually a change note back to you. Your device builds a zero-knowledge proof that the spend is valid, and the pool contract checks it.
Pick notes
The app chooses notes from your private balance that cover the amount plus any relayer fee.Build the new notes
A note for the recipient, encrypted to their viewing key, and a change note for you.Prove
Your browser proves the old notes exist in the pool and are yours, and that value in equals value out. Nothing else is revealed.Submit
The pool checks the proof, marks the old notes spent with their nullifiers and records the new commitments.Recipient syncs
Their wallet scans new pool entries, decrypts the one meant for them and adds it to their balance.
On the explorer this shows up as one pool transaction with some commitments and nullifiers. It carries no amount, no sender and no receiver.
UMBR addresses#
An UMBR address is a private receive address that starts with umbr1q, for example umbr1qexample4h8s2...ana. It is derived from your keys and encodes two public keys: one used to build notes you can spend, and one used to encrypt those notes so only you can find them.
- It is not an account on chain. Nothing is registered, and it never appears in a transaction.
- It is safe to share. Knowing it lets someone pay you; it does not let them see your balance or history.
- It is different from your public
0xwallet. Sending to a0xaddress is an unshield, which is public. - Find yours under Receive in the app, or read
umbr.addressin the SDK.
Claim links#
A claim link pays someone who has no UMBR address yet. You lock an amount into a fresh note and get a URL. Whoever opens it at /claim can move the funds into their own private balance, or unshield them to a public wallet.
https://umbr.trade/claim#k=3f9c0d…e71a- The secret is in the fragment. Everything after
#is the key to the note. Browsers do not send the fragment to the server, so the UMBR site never receives it. - Expiry. You choose how long the link stays claimable. After that, only you can take the funds back.
- Revoke. Until the link is claimed, you can cancel it from your link list. That spends the note back to you, and the link stops working.
- One claim. The note can be spent once. A second person opening the same link sees that it was already claimed.
What keeps a claim link safe#
A claim link is a bearer instrument: anyone holding the full URL can claim it. Treat it like cash in an envelope.
- Send it over a private channel you trust, not a public post or a shared document.
- Keep amounts small and expiries short. A week is plenty for most cases.
- Revoke it if you sent it to the wrong person or suspect someone else saw it. Revoking only works while the link is unclaimed.
- Link previews in some chat apps fetch the URL. They do not see the fragment either, but a careless copy into a search bar or analytics tool can leak it. Paste carefully.
Claiming shows a moment in time
Memos#
A memo is a short note attached to a payment, such as an invoice number. It is encrypted together with the note, to the recipient's key, so only the recipient (and you, from your own history) can read it. The pool stores it as opaque bytes.
- Memos are length-limited. The app counts characters and stops you at the limit.
- Keep personal data out of memos anyway. The recipient may share their history, and encrypted data stored on chain is stored for good.
- Payroll labels travel as memos.
Public send versus private send#
| On the public record | Public stablecoin send | Private UMBR send |
|---|---|---|
| Amount | Visible | Hidden |
| Sender wallet | Visible | Hidden (gas payer visible if you submit without the relayer) |
| Recipient wallet | Visible | Hidden |
| Your balance and history | Readable by anyone who knows your address | Readable only with your keys |
| Timing | Visible | Visible as a pool transaction |
| Cost | One transfer fee | A larger pool transaction, plus a relayer fee if used |
Moving money into the pool and back out is still public at those two edges. See what stays private for the full picture.
Try it#
In the app
- Shield a little test pathUSD or USDG at Shield.
- Go to Pay, paste an UMBR address (or your own, from a second browser profile) and an amount.
- Or switch to As a link, create a claim link and open it in a private window.
From code
// Pay an UMBR address
await umbr.send({
to: "umbr1qexample4h8s2...ana",
asset: "pathUSD",
amount: "40.00",
memo: "Invoice 0192",
});
// Or make a claim link for someone without an address yet
const link = await umbr.links.create({ asset: "pathUSD", amount: "25.00", expiresIn: "7d" });
// link.url -> send it privately; link.id -> keep it to revoke
await umbr.links.revoke(link.id);All of this runs on testnets today. The quickstart covers setup from zero.