Whitepaper
Private money on public chains
The technical and product case for UMBR: private stablecoin payments for people, teams and agents. Private by default, provable on demand.
- Version
- 0.3 · public draft
- Status
- Testnet, not audited
- Networks
- Robinhood Chain 46630 · Tempo Moderato 42431
- Proof system
- Groth16 on BN254
- Live on testnet
- Shield · send · payroll · prove
- Mainnet
- Pools not configured
Draft for a testnet system
1. Abstract
Public chains made settlement open and checkable. They also made every balance and every payment readable by anyone, forever. That is tolerable for speculation and a real cost for ordinary money: salaries, supplier invoices, treasury runway and the purchases an automated agent makes on someone's behalf.
UMBR is a private payments layer for stablecoins on public chains. People, teams and agents shield public stablecoins into a shared pool, pay each other inside it, run payroll from it, and leave it whenever they want. Amounts and the links between payer and payee stay off the public record. When someone has a legitimate need to know, the owner produces a proof of exactly that fact and nothing more. Our short version: private by default, provable on demand.
The cryptography is not new. UMBR uses the note, commitment and nullifier design that shielded pools have used for years, with succinct zero-knowledge proofs checked by on-chain verifiers. The work is in making that design usable for payments: an SDK, an optional relayer, scoped disclosure, and payroll. UMBR currently runs on the Robinhood Chain testnet (chain 46630) and the Tempo Moderato testnet (chain 42431) with test funds.
2. The problem
2.1 A ledger that tells everyone everything
On a transparent chain a payment is not just a transfer of value, it is a publication. Pay a contractor and their rate is public. Pay your team and every colleague can read every salary. Keep a treasury in one address and anyone can estimate your runway. Clustering tools turn these fragments into a profile that follows an address for good.
2.2 Stablecoins made it urgent
Stablecoins are increasingly how businesses settle with each other, and new chains built for payments are arriving. Each of them is public by default. Agents that pay for APIs and data on their own add a new kind of payer with the same exposure: an agent's wallet reveals what it buys, how often, and how much budget it has left.
2.3 Privacy that still answers to someone
Real businesses also need the opposite of secrecy at the right moment: an auditor needs a total, a landlord needs proof of funds, a counterparty needs proof that an invoice was paid. A design that only hides is not enough. It has to hide by default and reveal precisely, under the owner's control.
3. Design principles
- The owner holds the keys. Notes are created and spent on the owner's device. No server, committee or operator holds a spending key or sees the secret inputs to a proof.
- Proven building blocks. Commitments, nullifiers, Merkle membership and Groth16 proofs. We avoid novel cryptography.
- Edges are public, on purpose. Entering and leaving the pool is visible. We say so plainly rather than pretend otherwise.
- Disclosure is a feature. Every private action can later be proven to a chosen reader, for a chosen time, without exposing anything else.
- No pretend success. If a step cannot be done privately yet, the product says so instead of showing a fake result.
4. What private means here
Application-level privacy on a public chain does not make transactions vanish from an explorer. It changes what they say. The table below is the honest split.
| Visible on-chain | Hidden while inside the pool | Weakened in practice by |
|---|---|---|
| That the pool contract was called | Amounts of private sends | A small set of active users |
| Shield and unshield amounts and addresses | Which note paid which recipient | Shielding and unshielding the same amount |
| The account that submits each transaction | Private balances | Predictable timing |
A private send therefore still produces a transaction. What it does not produce is a readable line saying that one address paid another a given amount.
5. System architecture
5.1 Placement
UMBR is a set of contracts and client code on top of an existing chain. Finality and data availability come from that chain. The same contracts and circuits are deployed on each supported network, so an integration written for one works on the other.
5.2 Components
- Client. The app and the SDK. They generate note secrets, rebuild Merkle paths from chain events, make proofs locally and keep notes encrypted at rest.
- Shielded pool. Holds deposited stablecoins, appends commitments to a fixed-depth Merkle tree, keeps a window of recent roots and the set of spent nullifiers, and releases value only against a valid proof. It has no function that lets an administrator withdraw user funds.
- Circuits and verifiers. One circuit per action (shield, transfer, unshield) plus circuits for disclosure statements. Each on-chain circuit has a Groth16 verifier contract.
- Encrypted memos. Each private payment carries a ciphertext only the recipient can open, so they can discover and spend what they were sent.
- Relayer (optional). A service that submits already-proven transactions and pays gas, described in section 7.
5.3 Notes and commitments
Value inside the pool exists as notes. A note binds an owner key, an asset, an amount and a random blinding value. Only its hash, the commitment, is posted, as a new leaf in the tree. The commitment hides the note's contents and binds the owner to them, so neither the chain nor anyone watching it learns the amount or the owner. The hash is Poseidon, chosen because it is cheap to compute inside a circuit.
(owner key, asset, amount, blinding)Kept by the owner, never postedCommitmentH(note)Posted as a leaf in the pool's Merkle treeNullifierH(spend key, leaf position)Posted once when the note is spent5.4 Nullifiers
To spend a note, its owner reveals a nullifier derived from their spending key and the note's position in the tree. The pool records every nullifier and refuses any it has seen before, which stops double spends. Because the nullifier is computed with a secret key, an observer cannot tell which commitment it belongs to.
5.5 Actions
| Action | Public inputs | The proof shows |
|---|---|---|
| Shield | Asset, amount, new commitment | The commitment encodes exactly the deposited amount |
| Private send | Root, nullifiers, new commitments | Inputs are unspent notes in the tree that the sender owns, and value in equals value out |
| Unshield | Root, nullifier, amount, recipient, change commitment | The sender owns the note, and the recipient and amount are the ones bound into the proof |
5.6 Custody and upgrades
UMBR does not take custody in the ordinary sense: the pool contract holds deposits, and only a valid proof from the note owner moves them. Pool parameters such as supported assets are set by the deployer during the testnet. Before any mainnet pool is configured we intend to put rule changes behind a public delay, and the details will be published with that deployment.
6. Proofs and verification
Every state change in the pool is accompanied by a zero-knowledge proof. UMBR uses Groth16 over the BN254 curve: proofs are small, verification is a fixed, modest gas cost, and the tooling is mature. Proofs are generated in the browser or on the integrator's server, so secret inputs never leave the machine that holds them.
6.1 Trusted setup
Groth16 needs a structured reference string per circuit. If the secret randomness used to create it were known to someone, that person could forge proofs, and in a payment pool a forged proof means value created from nothing. The testnet circuits currently use development keys from a single-party setup. They are fine for test funds and must not be trusted with real money. A multi-party ceremony, where the setup is safe as long as one participant was honest, is a precondition for any mainnet pool.
6.2 Verifying on-chain and off
Pool actions are verified by contracts. Disclosure proofs are verified off-chain against the same public parameters and chain state, which anyone can do with the SDK or by pasting a proof at umbr.trade/verify.
7. The relayer
Whoever submits a transaction pays its gas and appears as its sender. If a user submits a private send from their usual wallet, that wallet is linked to the activity. The relayer removes that link by submitting proven transactions on the user's behalf and taking its fee from inside the pool.
- It cannot redirect. The recipient, amount and fee are public inputs to the proof. Changing any of them invalidates it.
- It can refuse or delay. A relayer can censor. Users can always submit directly instead, and the SDK supports both paths.
- It sees metadata. The relayer learns the IP and timing of a request. Users who care should reach it over a privacy-preserving network.
8. Viewing and disclosure keys
Selective disclosure is the half of the design that makes privacy usable for businesses. UMBR separates three kinds of key, each derived from the owner's master secret:
- Spending key. Authorises spending notes. Never shared.
- Viewing key. Decrypts incoming and outgoing memos for an account. Sharing it gives read-only visibility of that account's private history, for example to an in-house accountant. It cannot move funds.
- Disclosure proofs. Narrower than a viewing key. The owner proves one statement, such as “this balance is at least 1,000 USDG”, “this payment of this amount went to this recipient” or “this payroll run totalled this amount”, and nothing else.
Disclosure proofs carry an audience and an expiry inside the statement, so a proof made for one reader cannot simply be forwarded and reused elsewhere as fresh evidence. In the app this lives under Prove; anyone can check a proof at /verify.
A viewing key, once shared, cannot be taken back for the history it already reveals. We recommend disclosure proofs wherever a single fact is enough.
9. Private payroll
Payroll is where public ledgers hurt most, because the people reading the chain include the recipients' own colleagues. A private payroll run spends one or more of the employer's notes into one new note per employee, plus change.
What stays visible: that the employer shielded a sum, and that a pool transaction happened around payday. What stays private: who was paid and how much. The shielded sum is a hint at the total, which employers can blur by keeping a standing private balance.
10. Apps and agents
The same flows are available to developers through @umbr/sdk, a TypeScript client for the browser and for servers. It is in preview and not yet published to npm. The intended surface is small: create a client for a network, then shield, send, unshield and prove. See the SDK overview and the reference.
Agents fit the same model. An agent run server-side holds its own private balance, spends within limits its operator sets, and keeps its keys in the operator's infrastructure. Its operator can later prove what it spent. The agent guide is at /docs/agents.
11. Threat model
11.1 What the design aims to protect against
| Observer | Learns | Does not learn |
|---|---|---|
| Anyone reading the chain | Shields, unshields, pool activity and timing | Private amounts, balances, who paid whom inside the pool |
| The relayer | Request metadata, the fee, the public inputs | Note contents, spending keys, the sender's wallet |
| A payment recipient | The amount they received and any memo | The sender's balance or other payments |
| A disclosure reader | The one statement that was proven | Anything outside that statement |
11.2 Residual leakage
- Shield and unshield are public. Matching amounts and close timing can link them.
- A small anonymity set makes inference easier. Privacy improves as more people use the pool.
- Network metadata (IP addresses, RPC providers) is outside what proofs can hide.
- A compromised device exposes its notes and keys, as with any wallet.
11.3 Out of scope
Cryptography cannot defend against a user publishing their own viewing key, legal process directed at a user, a malicious browser extension, or a stablecoin issuer freezing assets at the contract level. Issuers keep their controls; UMBR does not try to remove them.
12. Limitations and risks
- Not audited. The contracts and circuits have not had an external audit. Bugs in either could lose or lock funds.
- Development keys. Testnet proofs rely on a single-party setup (section 6.1).
- Testnet only. Nothing here should hold real value yet, and testnet state may be reset.
- Key loss. Lose the master secret and the notes are unspendable. There is no recovery by UMBR.
- Relayer availability. The relayer can go down or refuse. Direct submission works but links the submitting wallet.
- Regulation. Rules for privacy tools differ by place and change over time. Users are responsible for using UMBR lawfully.
13. Status and roadmap
| Area | Status |
|---|---|
| Shield, private send, unshield | Live on Robinhood Chain testnet and Tempo Moderato |
| Payroll and payment links | Live on testnet |
| Disclosure proofs and /verify | Live on testnet |
| @umbr/sdk | Preview, not yet on npm |
| Multi-party trusted setup | Planned, required before mainnet |
| External audit | Planned, required before mainnet |
| Mainnet pools | Not configured. See /mainnet |
We do not publish dates for planned items. They ship when they are ready and reviewed.
14. What we do not claim
- UMBR does not make transactions invisible on an explorer.
- UMBR does not promise anonymity against every adversary, at any set size.
- UMBR has not been audited, and nothing in this paper says otherwise.
- UMBR has no token. Nothing here is an offer of anything.
- This paper describes intent and current testnet behaviour, not guaranteed future features.
15. Closing
Money on public chains should not require publishing your payroll, your suppliers or your balance to everyone. It also should not become unaccountable. UMBR's answer is a pool you can hold and pay from privately, with proofs you control for the moments someone genuinely needs to know. Try it with test funds in the app, read the docs, and tell us where this paper is wrong.