> For AI agents: the documentation index is at https://docs.umbraprivacy.com/llms.txt, and every page is available as Markdown at its URL with .md appended.

# Deposit (/docs/operations/deposit)

> **Umbra's clients, not the protocol**
>
> Umbra's SDKs and client interfaces derive your keys from your account signature and deposit from your platform wallet, a keypair derived from it. The protocol enforces neither: the pool needs a depositor that signs and a proof built from keys that match your identity commitment, however those keys were made. Other clients can follow their own standard.

A deposit moves tokens from your platform wallet into the pool token account for that token and gives you notes worth the same amount, less any protocol fee. The deposit itself is public: the wallet that deposits, the token account the tokens leave, the token and the amount all appear on chain. Who receives the new notes, how the value is split and which zone it lands in are private.

## Summary

A deposit is `process_3x3x2x2`, the pool's single value instruction, run with a deposit lane active: a public channel that brings tokens in from an ordinary Solana token account. Every transaction has the same fixed shape, with two deposit lanes, two withdrawal lanes, three input slots and three output slots.

In a first deposit the input slots hold dummy notes of amount zero. The SDK may instead merge in up to three of your existing notes of the same token and zone, and from the outside the two cases look the same.

One transaction, the same shape every time. Notes spent: 0 input notes and 3 dummy. Deposit lanes: 1 deposit and 1 dummy. Notes created: 1 output note and 2 dummy. Withdrawal lanes: 0 withdrawals and 2 dummy.

*A first deposit to yourself: one deposit lane and one new note. The other slots carry dummy notes and the other three lanes are idle.*

The new notes can belong to you, another registered identity or a Solana address such as a program, and appear on chain only as note commitments (see [notes](https://docs.umbraprivacy.com/docs/state/notes)). The tokens go to a pool token account whose authority is a program-derived address of the shielded pool program, and SOL to the pool's lamport account. No person holds a key to either: only the pool program's rules and the powers governance has over it can move them (see [governance and upgrades](https://docs.umbraprivacy.com/docs/security/governance)).

## Before you start

- **You are registered.** Your identity commitment, and that of anyone receiving an identity-owned note, must be in the pool's identity tree (see [register](https://docs.umbraprivacy.com/docs/operations/register)).
- **The token is on the allowlist.** Governance grants and revokes each mint's allowance. SPL Token and Token-2022 mints are supported except Token-2022's native mint, and SOL can come from plain SOL, wrapped SOL or both (see [pool token accounts and tokens](https://docs.umbraprivacy.com/docs/state/tokens)).
- **The tokens are in your platform wallet.** It is the depositor on chain, and the SDK tops it up from your main wallet in the same transaction.
- **Every attester is available.** All three guardian nodes, the screener, the fee enclave and the data endorser must sign, and the guardian cluster and the fee enclave must be Active.

A deposit is never relayed: the depositor must sign the recent blockhash, which a relayer would choose, so Umbra's relayer refuses deposits. The SDK sends one Solana v1 transaction of up to 4,096 bytes by default; with the older v0 format the funding and the deposit go as two transactions.

## How a deposit runs

Your device prepares the transaction, collects six attester signatures while it makes two proofs, and sends it. The shielded pool checks everything before it moves a token.

```mermaid
flowchart LR
A["Prepare on your device"] --> B["Collect six signatures"]
A --> C["Make two proofs"]
B --> D["Send the transaction"]
C --> D
D --> E["Pool checks and settles"]
```

*The three phases of a deposit. Signing by the attesters and proving on the device run at the same time.*

One value ties the phases together: the context digest, a Keccak-256 hash of the instruction payload and every account address in the instruction (see [hash functions](https://docs.umbraprivacy.com/docs/cryptography/hashing)). Every attester signs it and the transaction proof takes it as a public input, so no party can change anything the others approved.

## Phase 1: preparing on your device

Most of the preparation is local. The device reads from the indexer once and, outside zone 0, asks the zone authority for a signature.

```mermaid
sequenceDiagram
participant U as Your device
participant I as Indexer
participant Z as Zone authority
U->>U: select notes, derive keys
U->>I: one read for paths and gaps
I-->>U: paths, gaps, registrations
U->>U: build notes and digest
opt zone is not zone 0
  U->>Z: authorisation message
  Z->>Z: sign with EdDSA
  Z-->>U: signature
end
```

*Preparing a deposit: one read from the indexer, and a zone signature only outside zone 0.*

### 1. Your device selects notes and derives its keys

The SDK picks up to three of your largest notes in the target zone to merge, derives your keys and draws fresh randomness, so all three nullifiers the transaction will publish are known before the network read.

### 2. The indexer returns paths and witnesses

One request returns the Merkle paths for the notes being spent, a non-membership witness for each nullifier, your identity tree path and the recipient's registration. A wrong answer cannot pass, because proofs built on it fail against the roots the pool accepts, but the indexer does learn what you asked for.

### 3. Your device builds the notes, the record and the digest

The SDK prices the protocol fee, builds the output notes and encrypts each to its owner, and builds the sender record, splitting the per-transaction viewing key that decrypts it into three shares, one per guardian node. The context digest comes last, because it hashes the finished notes.

### 4. The zone authority signs, outside zone 0

Outside zone 0, a signer from the zone's authorised signer set signs a message derived from the context digest, and the source side needs a signature too when merged notes come from a non-zero zone. Only the transaction proof checks these signatures, never the chain, so the signer stays private (see [zones](https://docs.umbraprivacy.com/docs/zones)).

## Phase 2: collecting signatures and proving

Each attester needs only the context digest and its own part of the transaction, so the SDK asks all of them at once and proves while it waits.

```mermaid
sequenceDiagram
participant U as Your device
participant G as Guardian nodes
participant A as Other attesters
Note over A: screener, fee enclave, data endorser
par attest
  U->>G: one encrypted share each
  G-->>U: three BLS signatures
  U->>A: what each one checks
  A-->>U: three BLS signatures
and prove
  U->>U: freshness proof
  U->>U: transaction proof
end
U->>U: combine six signatures
```

*Collecting signatures: the guardian nodes and the three other attesters each sign the context digest while the device proves.*

### 5. Each guardian node checks its share and signs

Each guardian node receives its share of the viewing key encrypted to it alone, checks it against what the transaction commits to, escrows it and signs the context digest. It does not check the proof, the screening or any amount (see [what a guardian node checks](https://docs.umbraprivacy.com/docs/guardian-nodes#what-they-check)).

### 6. The screener screens the submitter and deposit parties

The screener takes its subjects from the transaction itself: the submitter, and for each deposit lane the depositing wallet and the owner of the source token account. It signs only on a Clear verdict; Deny (a wallet was flagged) or Indeterminate (a check went unanswered) blocks the deposit (see [screening](https://docs.umbraprivacy.com/docs/screening)).

### 7. The fee enclave opens the fee commitments and signs

The fee enclave opens the three fee commitments, applies its discount schedule and checks that every active lane's token is a fee token. It signs only commitments it recomputed itself, so fees that do not match what it saw cannot carry its signature (see [the fee enclave](https://docs.umbraprivacy.com/docs/fees/fee-enclave)).

### 8. The data endorser checks the encrypted notes and signs

The data endorser checks that the encrypted notes match the memo digest the transaction commits to and archives them before it signs. That archive is how recipients find their notes (see [receive and sync](https://docs.umbraprivacy.com/docs/operations/receive-and-sync)).

### 9. Your device proves and combines the signatures

The device first makes the cheaper of its two Groth16 proofs, the nullifier freshness proof, which shows no nullifier is already in the nullifier tree, so a stale indexer answer fails early. It then makes the transaction proof, which shows the notes, amounts, fees, zone signatures and identities are consistent (see [the transaction circuit](https://docs.umbraprivacy.com/docs/proofs/transaction-circuit)), and adds the six BLS signatures into one combined attester signature.

## Phase 3: sending and settling

Your wallets now sign and send. Everything after this happens inside the shielded pool program, in one instruction that either completes or changes nothing.

```mermaid
sequenceDiagram
participant W as Your wallets
participant P as Shielded pool
participant T as Pool token account
W->>P: signed transaction
P->>P: check the transaction
P->>T: checked transfer in
T-->>P: measured increase
P->>P: verify both proofs
P->>P: stage nullifiers, append
```

*Settling a deposit: the pool checks, pulls the tokens in, measures them, then verifies both proofs.*

### 10. Your main wallet and platform wallet sign and send

Your main wallet signs first and pays the Solana fee, and your platform wallet signs as submitter and depositor. In a v1 transaction the funding instructions ride ahead of the deposit.

### 11. The shielded pool checks the transaction

The program checks, in a fixed order, that the submitter signed, the deposited tokens are allowed, the guardian cluster and the other attesters are active, the tree roots are still recent and the note tree has room. The slot the proof names must also fall within the proof-age window, which governance sets between 300 and 216,000 slots.

### 12. The shielded pool pulls the tokens in and measures them

For each deposit lane the program checks the depositor's signature, moves the tokens in and measures how much the pool token account, or for SOL the lamport account, actually grew. The proof must account for that measured amount, so a Token-2022 mint with a transfer fee credits only what arrived (see [SOL](https://docs.umbraprivacy.com/docs/state/tokens#sol)).

### 13. The shielded pool verifies both proofs and the combined signature

The transaction proof verifies against public inputs the program builds from its own reads, such as the roots, the clock, the measured amounts and the depositor addresses, so a proof made for one deposit cannot pass for another. The combined attester signature passes only if all six attesters signed the same digest, and one pairing check covers both proofs and the signature.

### 14. The shielded pool records the result

The nullifiers are staged in the nullifier staging buffer, which refuses a duplicate. The note commitments are appended to the note tree and the fee commitments are staged for the fee commitment tree, and the program logs both so indexers learn of the new leaves.

## What a chain observer sees

**Deposit: Everything a chain observer can read**

| Field                       | On chain                                                                      |
| --------------------------- | ----------------------------------------------------------------------------- |
| Program                     | Shielded pool, process_3x3x2x2                                                |
| Fee payer                   | Your main wallet                                                              |
| Depositor                   | Your platform wallet                                                          |
| Source token account        | The account the tokens leave                                                  |
| Token                       | The mint deposited                                                            |
| Amount                      | The amount deposited                                                          |
| Nullifiers                  | Three field elements. Padding nullifiers are indistinguishable from real ones |
| New note commitments        | Three field elements                                                          |
| Fee commitments             | Three field elements                                                          |
| Recipient                   | Private                                                                       |
| Split between the new notes | Private                                                                       |
| Existing notes merged in    | Private                                                                       |
| Protocol fee                | Private. Inside the fee commitments                                           |
| Zone                        | Private                                                                       |

*The deposit's public side is the lane. Everything about the notes it creates is private.*

## What can go wrong

- **An attester does not sign.** A Deny or Indeterminate screening verdict, an offline attester or an inactive guardian cluster stops the deposit on your device, and nothing moves.
- **The token is not allowed.** The pool refuses a mint that is not on the allowlist.
- **The proof is stale.** A proof outside the proof-age window, or built on a root the pool no longer accepts, is refused.
- **The funding lands without the deposit.** A v1 transaction undoes both, but with v0 the tokens can be left in your platform wallet until a refund returns them to your main wallet.
- **The staging buffer is full.** If its two batches of 30,000 nullifiers fill before the [forester](https://docs.umbraprivacy.com/docs/state/forester) moves them into the nullifier tree, deposits wait.

The [escape hatch](https://docs.umbraprivacy.com/docs/operations/escape-hatch), the only operation that needs no attester, takes notes out rather than in.

## Privacy notes

- **A deposit is attributable.** Registration publicly links your main wallet, platform wallet and identity commitment, so anyone can see that you deposited, which token and how much.
- **Amounts and timing correlate.** A similar withdrawal soon after a deposit invites the obvious inference (see [how privacy is lost](https://docs.umbraprivacy.com/docs/privacy/leaks)).
- **Merging is not visible.** Every deposit publishes three nullifiers, so a first deposit looks like one that spent three of your notes.
- **The indexer sees your request.** The read in step 2 carries your identity commitment, the notes you are merging, their nullifiers and the recipient together.

## Related

- [Private transfer (Private Send)](https://docs.umbraprivacy.com/docs/operations/private-send): Spending notes to another registered identity, relayed.
- [The fee model](https://docs.umbraprivacy.com/docs/fees/fee-model): How the deposit fee is priced and paid.
- [Pool token accounts and tokens](https://docs.umbraprivacy.com/docs/state/tokens): The allowlist and the token rules the pool enforces.
- [How privacy is lost](https://docs.umbraprivacy.com/docs/privacy/leaks): Why deposits are attributable and what that implies.


Last updated 12 October 2026
