# Umbra Privacy SDK > Umbra is a privacy protocol for Solana that shields SPL and Token-2022 token balances using Arcium multi-party computation (MPC) and zero-knowledge proofs. The TypeScript SDK (`@umbra-privacy/sdk@5.0.0-rc.6`) wraps all protocol operations into async factory functions for Node.js 18+ and modern browser environments. Requires a Solana wallet (Ed25519 signer) and an RPC endpoint. All amounts use base units (e.g., 1 USDC = 1_000_000n). All operations are non-custodial — private keys never leave the client. **The standalone `@umbra-privacy/web-zk-prover` package no longer exists**; the prover ships inside the SDK at `@umbra-privacy/sdk/zk-prover`. This documentation covers the SDK API, protocol concepts, indexer REST API, and relayer API for building privacy-preserving Solana applications. ## Key terms - **ATA** — `AssociatedTokenAccount`. A standard SPL ATA. - **ETA** — `EncryptedTokenAccount`. Umbra-managed encrypted balance, two modes (MXE-only and Shared). - **Stealth Pool Note** — a commitment leaf in the mixer's Indexed Merkle Tree (the SDK surfaces it as a "note"). - **Burn** — consuming a note: reveals its nullifier on-chain and credits the destination balance. The wire protocol retains `/v1/claims` and `submitClaim` / `pollClaimStatus`; the burner-factory `relayer` dep uses TypeScript aliases `submitBurn` / `pollBurnStatus` that re-export the claim methods. ## Requirements and Constraints - **Install (current release `5.0.0-rc.6`)**: pin the SDK to the exact version. No package-manager overrides or dist patches are needed — the earlier `rc.3`/`rc.4` codama PDA bug (`ConstraintSeeds 2006` on deposit) and the columnar `scan()` BigInt-on-base64 bug are both fixed in rc.6. - **Runtime**: Node.js 18+ or modern browser with BigInt support. - **TypeScript**: 5.0+ required (branded types use phantom symbols). - **Wallet**: must implement `IUmbraSigner` (signTransaction, signTransactions, signMessage). - **RPC**: any Solana JSON-RPC endpoint (HTTP + WebSocket required). - **Amounts**: always in token base units as branded `U64` bigint (e.g., 1 USDC = `1_000_000n as U64`). - **Commitment**: no client-level default — each function accepts per-call `accountInfoCommitment`, `epochInfoCommitment` (default: `"confirmed"`). - **Fees**: protocol fee = `floor(amount × bps / 16384)` where `BPS_DIVISOR` = 16,384 (2^14), not 10,000. - **Stealth Pool limits**: max 1,048,576 notes per Merkle tree (depth-20), max 8 batch proofs per request, max 4 receiver-burnable notes per ZK proof. - **ZK provers**: must be supplied explicitly — no default. Use per-circuit factories from `@umbra-privacy/sdk/zk-prover` (2-8s browser, 1-3s Node.js). - **Relayer**: required for burning Stealth Pool Notes. The burner factory's `relayer` dep takes `{ submitBurn, pollBurnStatus, getRelayerAddress }`. - **Indexer**: required for note scanning + burning. Mainnet: `utxo-indexer.api.umbraprivacy.com`, Devnet: `utxo-indexer.api-devnet.umbraprivacy.com`. - **Store adapters (browser)**: wire `utxoDataStore` + `nullifierStore` via `createShardedUtxoDataStore` / `createShardedNullifierStore` from `@umbra-privacy/sdk/store-adapters`. Without them every `scan()` walks every active tree from genesis. - **Supported tokens (mainnet)**: wSOL (`So11111111111111111111111111111111111111112`), USDC (`EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`), USDT (`Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB`), UMBRA (`PRVT6TB7uss3FrUd2D9xs2zqDBsa3GbMJMwCQsgmeta`), CASH (`CASHx9KJUStyftLFWGvEVf59SGeG9sh5FfcnZMVPCASH`), ZINC (`zinc155BS4mSPk8GXQj4R5hkVDQXcW253pTYq5SGyfi`). - **Supported tokens (devnet/localnet)**: wSOL only. - **Rate limiting**: all API endpoints subject to rate limits (429 on exceed). ## Subpath imports Operation factories require subpath imports — the main barrel only re-exports `getUmbraClient`, signers, `Result`, errors, and infrastructure (indexer / relayer / arcium / solana / zk-prover). - `@umbra-privacy/sdk` — `getUmbraClient`, signer factories, `getUmbraRelayer`, `getUmbraIndexer`. - `@umbra-privacy/sdk/registration` — `getUserRegistrationFunction` + executors. - `@umbra-privacy/sdk/deposit` — `getATAIntoETADirectDepositorFunction` + 4 Stealth Pool Note creators. - `@umbra-privacy/sdk/withdrawal` — `getETAIntoATAWithdrawerFunction`. - `@umbra-privacy/sdk/burn` — `getBurnableStealthPoolNoteScannerFunction` + 3 burner factories + `enrichWithMerkleProof`. - `@umbra-privacy/sdk/query` — `getUserAccountQuerierFunction`, `getEncryptedBalanceQuerierFunction`. - `@umbra-privacy/sdk/conversion` — `getNetworkEncryptionToSharedEncryptionConverterFunction`. - `@umbra-privacy/sdk/compliance` — grant issuer / revoker / 3 reencryptors / 3 queriers. - `@umbra-privacy/sdk/account` — `getStagedSpl/SolRecovererFunction`, key rotators, maintenance. - `@umbra-privacy/sdk/zk-prover` — one factory per Groth16 circuit (`getATAIntoStealthPoolNoteCreatorProver`, `getClaimReceiverClaimableUtxoIntoEncryptedBalanceProver`, etc. — legacy burner-prover names retained). - `@umbra-privacy/sdk/zk-prover/cdn` — `getCdnZkAssetProvider`. - `@umbra-privacy/sdk/store-adapters` — `createBrowserStorageBackend`, `createShardedUtxoDataStore`, `createShardedNullifierStore`. - `@umbra-privacy/sdk/shared` — `UMBRA_MESSAGE_TO_SIGN`. - `@umbra-privacy/sdk/errors`, `@umbra-privacy/sdk/types`, `@umbra-privacy/sdk/constants`, `@umbra-privacy/sdk/converters`, `@umbra-privacy/sdk/crypto/*` — utilities. ## Examples ### Install and create a client (browser) ```typescript import { getUmbraClient, createInMemorySigner } from "@umbra-privacy/sdk"; import { createBrowserStorageBackend, createShardedUtxoDataStore, createShardedNullifierStore, } from "@umbra-privacy/sdk/store-adapters"; const signer = await createInMemorySigner(); const storageBackend = createBrowserStorageBackend({ dbName: "umbra" }); const utxoDataStore = createShardedUtxoDataStore({ storageBackend }); const nullifierStore = createShardedNullifierStore({ storageBackend }); const client = await getUmbraClient({ signer, network: "mainnet", rpcUrl: "https://api.mainnet-beta.solana.com", rpcSubscriptionsUrl: "wss://api.mainnet-beta.solana.com", indexerApiEndpoint: "https://utxo-indexer.api.umbraprivacy.com", relayerApiEndpoint: "https://relayer.api.umbraprivacy.com", utxoDataStore, nullifierStore, }); ``` ### Register, deposit, and withdraw ```typescript import { getUserRegistrationFunction } from "@umbra-privacy/sdk/registration"; import { getATAIntoETADirectDepositorFunction } from "@umbra-privacy/sdk/deposit"; import { getETAIntoATAWithdrawerFunction } from "@umbra-privacy/sdk/withdrawal"; // Register (idempotent). const register = getUserRegistrationFunction({ client }); await register({ confidential: true, anonymous: true }); const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // Deposit 1 USDC ATA → ETA. const deposit = getATAIntoETADirectDepositorFunction({ client }); await deposit(signer.address, USDC, 1_000_000n); // Withdraw ETA → ATA. const withdraw = getETAIntoATAWithdrawerFunction({ client }); await withdraw(signer.address, USDC, 1_000_000n); ``` ### Create a Stealth Pool Note and burn it ```typescript import { getATAIntoReceiverBurnableStealthPoolNoteCreatorFunction } from "@umbra-privacy/sdk/deposit"; import { getBurnableStealthPoolNoteScannerFunction, getReceiverBurnableStealthPoolNoteIntoETABurnerFunction, } from "@umbra-privacy/sdk/burn"; import { getUmbraRelayer } from "@umbra-privacy/sdk"; import { getATAIntoStealthPoolNoteCreatorProver, getClaimReceiverClaimableUtxoIntoEncryptedBalanceProver, } from "@umbra-privacy/sdk/zk-prover"; // Create a receiver-burnable note (requires recipient to have all three registration sub-step flags). const createNote = getATAIntoReceiverBurnableStealthPoolNoteCreatorFunction( { client }, { zkProver: getATAIntoStealthPoolNoteCreatorProver() }, ); await createNote({ destinationAddress: recipient, mint: USDC, amount: 500_000n }); // Scan (zero-arg, cursor in client.utxoDataStore). const scan = getBurnableStealthPoolNoteScannerFunction({ client }); const result = await scan(); // Burn into recipient's ETA. const r = getUmbraRelayer({ apiEndpoint: "https://relayer.api.umbraprivacy.com" }); const burn = getReceiverBurnableStealthPoolNoteIntoETABurnerFunction( { client }, { fetchBatchMerkleProof: client.fetchBatchMerkleProof!, zkProver: getClaimReceiverClaimableUtxoIntoEncryptedBalanceProver(), relayer: { submitBurn: r.submitClaim, pollBurnStatus: r.pollClaimStatus, getRelayerAddress: r.getRelayerAddress, }, }, ); if (result.ataToStealthPoolReceiverBurnable.length > 0) { await burn(result.ataToStealthPoolReceiverBurnable); } ``` ## AI Agent Resources - [Full Documentation](https://docs.umbraprivacy.com/llms-full.txt): complete inline documentation for LLM consumption. ## Core Concepts - [How Umbra Works](https://docs.umbraprivacy.com/concepts/how-umbra-works): EncryptedTokenAccounts + Stealth Pool privacy model, MPC dual-instruction pattern, MXE vs Shared encryption modes. - [Encrypted Balances](https://docs.umbraprivacy.com/concepts/encrypted-balances): ETAs, MXE-only vs Shared, nonces, balance queries via Rescue cipher decryption. - [Stealth Pool Notes](https://docs.umbraprivacy.com/concepts/utxos-and-mixer): Indexed Merkle Tree (depth-20, 1M leaves), nullifier treaps, 4 note variants (self / receiver × ATA / ETA), recipient pre-check. ## Getting Started - [Installation](https://docs.umbraprivacy.com/sdk/installation): install `@umbra-privacy/sdk`; the subpath table (`/registration`, `/deposit`, `/withdrawal`, `/burn`, `/query`, `/conversion`, `/compliance`, `/account`, `/zk-prover`, `/store-adapters`, `/shared`, …). - [Quickstart](https://docs.umbraprivacy.com/quickstart): end-to-end example — getUmbraClient, register, deposit, withdraw, create note, scan, burn. - [Creating a Client](https://docs.umbraprivacy.com/sdk/creating-a-client): `getUmbraClient(args, deps?)` — signer, network, rpcUrl, rpcSubscriptionsUrl, indexerApiEndpoint, relayerApiEndpoint, utxoDataStore, nullifierStore. - [Wallet Adapters](https://docs.umbraprivacy.com/sdk/wallet-adapters): `IUmbraSigner` interface, `createInMemorySigner`, `createSignerFromWalletAccount`, `UMBRA_MESSAGE_TO_SIGN` from `@umbra-privacy/sdk/shared`. - [Supported Tokens](https://docs.umbraprivacy.com/supported-tokens): mainnet wSOL/USDC/USDT/UMBRA/CASH/ZINC, devnet/localnet wSOL only. ## Registration & Account State - [Registration](https://docs.umbraprivacy.com/sdk/registration): `getUserRegistrationFunction` — 2-step idempotent flow (confidential usage + anonymous usage via MPC + ZK). - [Account State](https://docs.umbraprivacy.com/sdk/account-state): `getUserAccountQuerierFunction` — query `EncryptedUserAccount` (X25519 key, user commitment, generation index, status flags). Pre-check the recipient before receiver-burnable creates. ## Encrypted Balance Operations - [Deposit](https://docs.umbraprivacy.com/sdk/deposit): `getATAIntoETADirectDepositorFunction` → `DepositResult { signatures, queueSignature, callback?, rentClaim? }`. `callback` is discriminated: `{ status: "finalized", signature?, elapsedMs }` | `{ status: "pruned", elapsedMs }` | `{ status: "timed-out", elapsedMs }`. `rentClaim` is best-effort: `{ claimed: true, signature }` | `{ claimed: false, reason }`. - [Withdraw](https://docs.umbraprivacy.com/sdk/withdraw): `getETAIntoATAWithdrawerFunction` → `WithdrawResult`. Dropped-callback recovery via `getStagedSpl/SolRecovererFunction` from `@umbra-privacy/sdk/account`. - [Query Balances](https://docs.umbraprivacy.com/sdk/query): `getEncryptedBalanceQuerierFunction` (Shared-mode local decryption), `getUserAccountQuerierFunction`. - [Conversion](https://docs.umbraprivacy.com/sdk/conversion): `getNetworkEncryptionToSharedEncryptionConverterFunction` (MXE→Shared). `getMintEncryptionKeyRotatorFunction` from `@umbra-privacy/sdk/account` for per-mint key rotation. ## Stealth Pool Operations - [Overview](https://docs.umbraprivacy.com/sdk/mixer/overview): 4 creator factories × 3 shipped burner factories. Native batching for receiver→ETA (≤4 per proof); single-note for self→ETA / self→ATA. - [Writing Notes](https://docs.umbraprivacy.com/sdk/mixer/creating-utxos): `getATAIntoSelf/ReceiverBurnableStealthPoolNoteCreatorFunction`, `getETAIntoSelf/ReceiverBurnableStealthPoolNoteCreatorFunction` (MPC). Recipient pre-check rubric for receiver-burnable creates. - [Scanning](https://docs.umbraprivacy.com/sdk/mixer/fetching-utxos): `getBurnableStealthPoolNoteScannerFunction({ client })()` — **zero-arg**, returns `ScannedStealthPoolNoteResult` with 4 long-form keys (`etaToStealthPoolSelfBurnable`, `etaToStealthPoolReceiverBurnable`, `ataToStealthPoolSelfBurnable`, `ataToStealthPoolReceiverBurnable`) + `scannedTrees`. Cursor in `client.utxoDataStore`. - [Burning](https://docs.umbraprivacy.com/sdk/mixer/claiming-utxos): `getReceiverBurnableStealthPoolNoteIntoETABurnerFunction`, `getSelfBurnableStealthPoolNoteIntoETABurnerFunction`, `getSelfBurnableStealthPoolNoteIntoATABurnerFunction` — require `fetchBatchMerkleProof`, `zkProver`, and `relayer: { submitBurn, pollBurnStatus, getRelayerAddress }`. - [Privacy Analysis](https://docs.umbraprivacy.com/sdk/mixer/privacy-analysis): 3-tier model — Tier 1 ETA↔ETA strongest, Tier 2 mixed, Tier 3 ATA↔ATA weakest. ## Compliance - [Overview](https://docs.umbraprivacy.com/sdk/compliance): two independent mechanisms — Stealth Pool viewing keys (off-chain Poseidon hierarchy) + X25519 compliance grants (on-chain re-encryption). They cover different data (notes vs ETAs). - [Viewing Keys](https://docs.umbraprivacy.com/sdk/compliance-viewing-keys): MVK → Mint → Yearly → Monthly → Daily → Hourly → Minute → Second hierarchy. Derivers from `@umbra-privacy/sdk/crypto/key-derivation`. - [X25519 Grants](https://docs.umbraprivacy.com/sdk/compliance-x25519-grants): `getComplianceGrantIssuerFunction`, `getComplianceGrantRevokerFunction`, `getUser/Network/SharedComplianceGrantQuerierFunction`, `getSharedCiphertextReencryptorForUserGrantFunction`, `getNetworkCiphertextReencryptorForNetworkGrantFunction`, `getSharedCiphertextReencryptorForNetworkGrantFunction`. Nonces are stream-cipher critical — never reuse. ## SDK Architecture - [Factory Pattern](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/overview): long verbose factory names that spell out the data flow. `args` (client) + `deps` (overrides + required `zkProver` + required burner `relayer` adapter). - [Types](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/types): `Address`, `TransactionSignature`, branded integers (U64, U128, U256), field elements. Function types ship alongside their factories in each subpath. - [Branded Types](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/branded-types): `createU64`, `createBn254FieldElement`, `createX25519PublicKey` — phantom-symbol branding from `@umbra-privacy/sdk/types`. - [Dependency Injection](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/dependency-injection): `accountInfoProvider`, `blockhashProvider`, `transactionForwarder`, `epochInfoProvider`, `masterSeedStorage` overrides. - [Key Generators](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/key-generators): KMAC256-based derivers — MVK, Poseidon private key, X25519 keypairs, ephemeral-note keys, Rescue blinding factors. - [ZK Provers](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/zk-provers): 8 per-circuit prover interfaces. Per-circuit factories at `@umbra-privacy/sdk/zk-prover`. Groth16, CDN asset provider, Web Worker pattern. - [Callbacks](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/callbacks): `TransactionCallbacks { pre, post }` hooks for single transactions. `BurnHooks` (per-event hooks like `onKeyDerivationStart`, `onBatchSubmitted`, `onBatchComplete`, `onComplete`, `onError`) for the relayer-managed burn pipeline. The `onError.phase` enum is `"keyDerivation"` | `"batchAssembly"` | `"zkProofGeneration"` | `"batchSubmission"` | `"batchPolling"`. - [Key Rotation](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/key-rotation): U512 offset-based rotation for 7 key types + active on-chain rotators in `@umbra-privacy/sdk/account`. Full per-factory deps table. ## Advanced - [Key Derivation](https://docs.umbraprivacy.com/sdk/advanced/key-derivation): KMAC256 master seed from `signer.signMessage(UMBRA_MESSAGE_TO_SIGN)`, BN254 field sampling, full key hierarchy diagram. - [Recovery](https://docs.umbraprivacy.com/sdk/advanced/recovery): deterministic recovery from same wallet + network; zero-arg scanner; dropped-callback recovery via `getStagedSpl/SolRecovererFunction`; failed-create recovery via `closeProofAccount` (proof orphan) or replay-with-same-`generationIndex` (input-buffer orphan). - [ZK Provers](https://docs.umbraprivacy.com/sdk/advanced/zk-provers): custom provers, comlink Web Worker setup, remote prover over HTTP, CDN asset provider override. - [Token-2022](https://docs.umbraprivacy.com/advanced/token-2022): transfer fee handling, `epochInfoCommitment`, fee deduction before protocol fees. ## API Reference - [Client](https://docs.umbraprivacy.com/reference/client): `getUmbraClient` full signature, `IUmbraClient` fields, `IUmbraSigner` interface. - [Registration](https://docs.umbraprivacy.com/reference/registration): `getUserRegistrationFunction` — options, deps, return type. Rotators + recoverers under `@umbra-privacy/sdk/account`. - [Deposit](https://docs.umbraprivacy.com/reference/deposit): the direct depositor + 4 Stealth Pool Note creators — signatures, options, return types. - [Withdrawal](https://docs.umbraprivacy.com/reference/withdraw): `getETAIntoATAWithdrawerFunction` — `WithdrawResult`. - [Query](https://docs.umbraprivacy.com/reference/query): `getEncryptedBalanceQuerierFunction` + `getUserAccountQuerierFunction`. - [Conversion](https://docs.umbraprivacy.com/reference/conversion): `getNetworkEncryptionToSharedEncryptionConverterFunction` + `getMintEncryptionKeyRotatorFunction`. - [Stealth Pool (Mixer)](https://docs.umbraprivacy.com/reference/mixer): `getBurnableStealthPoolNoteScannerFunction` + 3 burner factories — full signatures. - [Compliance](https://docs.umbraprivacy.com/reference/compliance): all grant + re-encryption + querier functions, viewing-key derivers. - [Errors](https://docs.umbraprivacy.com/reference/errors): `UmbraError` hierarchy, staged errors (`EncryptedDepositError`, `ClaimUtxoError`, etc.), retry guidance. - [Pricing](https://docs.umbraprivacy.com/pricing): `BPS_DIVISOR=16384`, protocol-fee formula, relayer fees, Stealth Pool SOL fee, Token-2022 interaction. ## Indexer API - [Overview](https://docs.umbraprivacy.com/indexer/overview): REST API at `utxo-indexer.api.umbraprivacy.com`, Protobuf responses, tree structure (depth-20, 1M leaves per tree). Burner factories fetch per-batch Merkle proofs at burn time; the scanner does **not** pre-bundle proofs. - [Stats](https://docs.umbraprivacy.com/indexer/api-reference/stats): `GET /v1/stats`. - [Health](https://docs.umbraprivacy.com/indexer/api-reference/health/basic): `GET /health`. - [Tree Metadata](https://docs.umbraprivacy.com/indexer/api-reference/tree-metadata): `GET /v1/trees/{tree_index}`. - [Tree Notes](https://docs.umbraprivacy.com/indexer/api-reference/tree-utxos): `GET /v1/trees/{tree_index}/utxos`. - [Merkle Proofs](https://docs.umbraprivacy.com/indexer/api-reference/merkle-proofs): `GET /v1/trees/{tree_index}/proof/{insertion_index}` (single-leaf, not used by SDK). - [Batch Proofs](https://docs.umbraprivacy.com/indexer/api-reference/batch-proofs): `POST /v1/trees/{tree_index}/proofs` — atomic multi-proof under same root (max 8). The burner factory uses this. - [Global Notes](https://docs.umbraprivacy.com/indexer/api-reference/utxos): `GET /v1/utxos` — paginated across all trees. - [Single Note](https://docs.umbraprivacy.com/indexer/api-reference/utxo-single): `GET /v1/utxos/{absolute_index}` — point lookup. ## Relayer API - [Overview](https://docs.umbraprivacy.com/relayer/overview): async burn submission at `relayer.api.umbraprivacy.com`, lifecycle statuses, SDK integration via `getUmbraRelayer` + the burner-factory `relayer` dep. - [Relayer Info](https://docs.umbraprivacy.com/relayer/api-reference/info): `GET /v1/relayer/info` — `address`, `supported_mints` (authoritative), `active_stealth_pool_indices`. - [Submit Burn](https://docs.umbraprivacy.com/relayer/api-reference/submit-claim): `POST /v1/claims` (legacy wire path) — `proof_account_data`, `utxo_slot_data`, `fee_proof_data` → `202 { request_id }`. `409 DUPLICATE_OFFSET` is idempotent retry signal. - [Burn Status](https://docs.umbraprivacy.com/relayer/api-reference/claim-status): `GET /v1/claims/{request_id}` — status lifecycle, `tx_signature`, `callback_signature`, `failure_reason`. `NullifierAlreadyBurnt` is idempotent success. - [Health](https://docs.umbraprivacy.com/relayer/api-reference/health): `GET /v1/health`. ## Protocol Constants - Program ID (Mainnet): `UMBRAD2ishebJTcgCLkTkNUx1v3GyoAgpTRPeWoLykh`. - Program ID (Devnet): `DSuKkyqGVGgo4QtPABfxKJKygUDACbUhirnuv63mEpAJ`. - BPS Divisor: 16,384 (2^14). - Indexer (Mainnet): `https://utxo-indexer.api.umbraprivacy.com`. - Indexer (Devnet): `https://utxo-indexer.api-devnet.umbraprivacy.com`. - Relayer (Mainnet): `https://relayer.api.umbraprivacy.com`. - Relayer (Devnet): `https://relayer.api-devnet.umbraprivacy.com`. - NPM Package: `@umbra-privacy/sdk` (`5.0.0-rc.6` — pin to exact version; pins `@umbra-privacy/umbra-codama@3.0.0-rc.6`, no override needed). ## Migrations - [V4 → V5 Migration](https://docs.umbraprivacy.com/migrations/v4-to-v5): step-by-step upgrade from `@umbra-privacy/sdk@4.x` (V13) to `@umbra-privacy/sdk@5.x` (V18). Covers package consolidation (`@umbra-privacy/web-zk-prover` deleted), subpath imports, every factory rename, zero-arg scanner + long-form result keys, the new burner-factory `relayer` dep shape with `submitBurn`/`pollBurnStatus`/`getRelayerAddress` aliases, browser store-adapter wiring, mint-list changes, and end-to-end before/after. ## Optional - [Cryptography Overview](https://docs.umbraprivacy.com/sdk/advanced/cryptography/overview): X25519, Poseidon, KMAC256, Groth16, Rescue cipher, Arcium MPC — implementation details. - [Rescue Cipher](https://docs.umbraprivacy.com/sdk/advanced/cryptography/rescue-cipher): algebraic cipher over p=2^255−19, constant-time, ETA balance encryption. - [Poseidon Hash](https://docs.umbraprivacy.com/sdk/advanced/cryptography/poseidon): ZK-friendly hash over BN254 for Stealth Pool Note commitments, nullifiers, user identity. - [Indexed Merkle Tree](https://docs.umbraprivacy.com/sdk/advanced/cryptography/indexed-merkle-tree): on-chain Stealth Pool Note commitment store, 2^148 total capacity across trees.