# 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`) 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. This documentation covers the SDK API, protocol concepts, indexer REST API, and relayer API for building privacy-preserving Solana applications. ## Requirements and Constraints - **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 - **Mixer limits**: Max 1,048,576 UTXOs per Merkle tree (depth-20), max 8 batch proofs per request - **ZK provers**: Must be supplied explicitly — no default. Use `@umbra-privacy/web-zk-prover` (2-8s browser, 1-3s Node.js) - **Relayer**: Required for claim operations (relayer pays Solana tx fees to preserve privacy) - **Indexer**: Required for UTXO scanning. Mainnet: `utxo-indexer.api.umbraprivacy.com`, Devnet: `utxo-indexer.api-devnet.umbraprivacy.com` - **Supported tokens (mainnet)**: USDC (`EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`), USDT (`Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB`), wSOL (`So11111111111111111111111111111111111111112`), UMBRA (`PRVT6TB7uss3FrUd2D9xs2zqDBsa3GbMJMwCQsgmeta`) - **Rate limiting**: All API endpoints subject to rate limits (429 on exceed) ## Examples ### Install and create a client ```typescript import { createInMemorySigner, getUmbraClient } from "@umbra-privacy/sdk"; const signer = await createInMemorySigner(); 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", }); ``` ### Register, deposit, and withdraw ```typescript import { getUserRegistrationFunction, getPublicBalanceToEncryptedBalanceDirectDepositorFunction, getEncryptedBalanceToPublicBalanceDirectWithdrawerFunction, } from "@umbra-privacy/sdk"; // Register (idempotent, safe to call multiple times) const register = getUserRegistrationFunction({ client }); await register({ confidential: true, anonymous: true }); // Deposit 1 USDC into encrypted balance const deposit = getPublicBalanceToEncryptedBalanceDirectDepositorFunction({ client }); const depositResult = await deposit( signer.address, "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" as Address, 1_000_000n as U64, ); console.log(depositResult.queueSignature, depositResult.callbackSignature); // Withdraw back to public wallet const withdraw = getEncryptedBalanceToPublicBalanceDirectWithdrawerFunction({ client }); const withdrawResult = await withdraw( signer.address, "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" as Address, 1_000_000n as U64, ); ``` ### Create a UTXO and claim it ```typescript import { getPublicBalanceToReceiverClaimableUtxoCreatorFunction, getClaimableUtxoScannerFunction, getReceiverClaimableUtxoToEncryptedBalanceClaimerFunction, getUmbraRelayer, } from "@umbra-privacy/sdk"; import { getCreateReceiverClaimableUtxoFromPublicBalanceProver } from "@umbra-privacy/web-zk-prover"; // Create UTXO (requires zkProver dependency) const zkProver = getCreateReceiverClaimableUtxoFromPublicBalanceProver(); const createUtxo = getPublicBalanceToReceiverClaimableUtxoCreatorFunction( { client }, { zkProver }, ); await createUtxo({ destinationAddress: recipientAddress, mint: USDC, amount: 500_000n as U64 }); // Scan for claimable UTXOs const scan = getClaimableUtxoScannerFunction({ client }); const { received } = await scan(0 as U32, 0 as U32); // Claim into encrypted balance (requires relayer) const relayer = getUmbraRelayer({ apiEndpoint: "https://relayer.api.umbraprivacy.com" }); const claim = getReceiverClaimableUtxoToEncryptedBalanceClaimerFunction( { client }, { zkProver: claimProver, relayer }, ); await claim([received[0]]); ``` ## 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): Encrypted balances + mixer privacy model, MPC dual-instruction pattern (handler → callback), MXE vs Shared encryption modes - [Encrypted Balances](https://docs.umbraprivacy.com/concepts/encrypted-balances): Encrypted Token Accounts (ETAs), MXE-only vs Shared mode, nonces and replay protection, balance queries via Rescue cipher decryption - [UTXOs and Mixer](https://docs.umbraprivacy.com/concepts/utxos-and-mixer): Indexed Merkle Tree (depth-20, 1M leaves), nullifier treaps, UTXO types (self-claimable, receiver-claimable), X25519 ciphertext discovery ## Getting Started - [Installation](https://docs.umbraprivacy.com/sdk/installation): Install @umbra-privacy/sdk, sub-path imports (/types, /interfaces, /utils, /constants, /errors, /crypto, /pda, /solana, /math) - [Quickstart](https://docs.umbraprivacy.com/quickstart): End-to-end example — getUmbraClient, register, deposit (DepositResult), withdraw (WithdrawResult), create UTXO, fetch, claim - [Creating a Client](https://docs.umbraprivacy.com/sdk/creating-a-client): getUmbraClient(args, deps?) — signer, network, rpcUrl, rpcSubscriptionsUrl, indexerApiEndpoint, per-call commitment model - [Wallet Adapters](https://docs.umbraprivacy.com/sdk/wallet-adapters): IUmbraSigner interface, createInMemorySigner, createSignerFromWalletAccount, UMBRA_MESSAGE_TO_SIGN consent message - [Supported Tokens](https://docs.umbraprivacy.com/supported-tokens): USDC, USDT, wSOL, UMBRA — all SPL, confidentiality + mixer enabled ## Registration & Account State - [Registration](https://docs.umbraprivacy.com/sdk/registration): getUserRegistrationFunction — 3-step idempotent flow (account init, X25519 key, user commitment with ZK proof) - [Account State](https://docs.umbraprivacy.com/sdk/account-state): getUserAccountQuerierFunction — query EncryptedUserAccount (X25519 key, user commitment, generation index, status flags) ## Encrypted Balance Operations - [Deposit](https://docs.umbraprivacy.com/sdk/deposit): getPublicBalanceToEncryptedBalanceDirectDepositorFunction → DepositResult {queueSignature, callbackSignature} - [Withdraw](https://docs.umbraprivacy.com/sdk/withdraw): getEncryptedBalanceToPublicBalanceDirectWithdrawerFunction → WithdrawResult {queueSignature, callbackSignature} - [Query Balances](https://docs.umbraprivacy.com/sdk/query): getEncryptedBalanceQuerierFunction (shared-mode decryption via Rescue cipher), getUserAccountQuerierFunction - [Conversion](https://docs.umbraprivacy.com/sdk/conversion): getNetworkEncryptionToSharedEncryptionConverterFunction (MXE→Shared), getMintEncryptionKeyRotatorFunction ## Mixer (UTXO) Operations - [Mixer Overview](https://docs.umbraprivacy.com/sdk/mixer/overview): 4 creation variants × 3 claim variants, self vs receiver claimable, encrypted vs public balance source/destination - [Creating UTXOs](https://docs.umbraprivacy.com/sdk/mixer/creating-utxos): getEncryptedBalanceToSelfClaimableUtxoCreatorFunction, getEncryptedBalanceToReceiverClaimableUtxoCreatorFunction, getPublicBalanceToSelfClaimableUtxoCreatorFunction, getPublicBalanceToReceiverClaimableUtxoCreatorFunction - [Fetching UTXOs](https://docs.umbraprivacy.com/sdk/mixer/fetching-utxos): getClaimableUtxoScannerFunction(treeIndex: U32, startInsertionIndex: U32) → ScannedUtxoResult {selfBurnable, received, publicSelfBurnable, publicReceived} - [Claiming UTXOs](https://docs.umbraprivacy.com/sdk/mixer/claiming-utxos): getSelfClaimableUtxoToEncryptedBalanceClaimerFunction, getReceiverClaimableUtxoToEncryptedBalanceClaimerFunction, getSelfClaimableUtxoToPublicBalanceClaimerFunction — requires zkProver + relayer deps - [Privacy Analysis](https://docs.umbraprivacy.com/sdk/mixer/privacy-analysis): 3-tier privacy model — Tier 1 (ETA↔ETA strongest), Tier 2 (mixed), Tier 3 (ATA↔ATA weakest) ## Compliance - [Compliance Overview](https://docs.umbraprivacy.com/sdk/compliance): Two mechanisms — hierarchical viewing keys (off-chain) + X25519 compliance grants (on-chain re-encryption) - [Viewing Keys](https://docs.umbraprivacy.com/sdk/compliance-viewing-keys): MVK → Mint → Yearly → Monthly → Daily hierarchy, Poseidon-derived, one-directional - [X25519 Grants](https://docs.umbraprivacy.com/sdk/compliance-x25519-grants): getComplianceGrantIssuerFunction, getComplianceGrantRevokerFunction, getUserComplianceGrantQuerierFunction, getSharedCiphertextReencryptorForUserGrantFunction ## SDK Architecture - [Factory Pattern](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/overview): get[Source]To[Target][Verb]Function naming, args (client) + deps (overrides) pattern - [Types](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/types): Address, TransactionSignature, branded integers (U64, U128, U256), field elements - [Branded Types](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/branded-types): createU64, createBn254FieldElement, createX25519PublicKey — phantom symbol branding for compile-time safety - [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 UTXO keys, Rescue blinding factors - [ZK Provers](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/zk-provers): IZkProverSuite, @umbra-privacy/web-zk-prover, Groth16 circuits, CDN asset provider, web worker pattern - [Callbacks](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/callbacks): TransactionCallbacks {pre, post} hooks for registration, UTXO, and single-tx operations - [Key Rotation](https://docs.umbraprivacy.com/sdk/understanding-the-sdk/key-rotation): U512 offset-based rotation for 7 key types, requires re-registration after rotation ## Advanced - [Key Derivation](https://docs.umbraprivacy.com/sdk/advanced/key-derivation): KMAC256 master seed from wallet signature, BN254 field sampling, full key hierarchy diagram - [Recovery](https://docs.umbraprivacy.com/sdk/advanced/recovery): Deterministic recovery from same wallet + network, UTXO rescan via getClaimableUtxoScannerFunction - [ZK Provers (Advanced)](https://docs.umbraprivacy.com/sdk/advanced/zk-provers): Custom provers, web worker setup with comlink, remote prover over HTTP, 2-8s browser / 1-3s Node.js - [Token-2022](https://docs.umbraprivacy.com/advanced/token-2022): Transfer fee handling, epochInfoCommitment, fee deduction before protocol fees ## API Reference - [Client Reference](https://docs.umbraprivacy.com/reference/client): getUmbraClient full signature, IUmbraClient fields, IUmbraSigner interface - [Registration Reference](https://docs.umbraprivacy.com/reference/registration): getUserRegistrationFunction — options, deps, return type - [Deposit Reference](https://docs.umbraprivacy.com/reference/deposit): All 5 deposit functions (direct + 4 UTXO creation) — signatures, options, return types - [Withdraw Reference](https://docs.umbraprivacy.com/reference/withdraw): getEncryptedBalanceToPublicBalanceDirectWithdrawerFunction — WithdrawResult - [Query Reference](https://docs.umbraprivacy.com/reference/query): getEncryptedBalanceQuerierFunction + getUserAccountQuerierFunction - [Conversion Reference](https://docs.umbraprivacy.com/reference/conversion): getNetworkEncryptionToSharedEncryptionConverterFunction + getMintEncryptionKeyRotatorFunction - [Mixer Reference](https://docs.umbraprivacy.com/reference/mixer): getClaimableUtxoScannerFunction + 3 claim functions — full signatures - [Compliance Reference](https://docs.umbraprivacy.com/reference/compliance): All grant + re-encryption functions, viewing key generators - [Errors Reference](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, mixer SOL fee, Token-2022 interaction ## Indexer API - [Indexer 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) - [Stats](https://docs.umbraprivacy.com/indexer/api-reference/stats): GET /v1/stats — total_utxos, latest_absolute_index - [Health](https://docs.umbraprivacy.com/indexer/api-reference/health/basic): GET /health — basic health check - [Tree Metadata](https://docs.umbraprivacy.com/indexer/api-reference/tree-metadata): GET /v1/trees/{tree_index} — num_leaves, root, utxo_count - [Tree UTXOs](https://docs.umbraprivacy.com/indexer/api-reference/tree-utxos): GET /v1/trees/{tree_index}/utxos — paginated, row/columnar layout - [Merkle Proofs](https://docs.umbraprivacy.com/indexer/api-reference/merkle-proofs): GET /v1/trees/{tree_index}/proof/{insertion_index} — 20-sibling authentication path - [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) - [Global UTXOs](https://docs.umbraprivacy.com/indexer/api-reference/utxos): GET /v1/utxos — paginated across all trees by absolute index - [Single UTXO](https://docs.umbraprivacy.com/indexer/api-reference/utxo-single): GET /v1/utxos/{absolute_index} — point lookup ## Relayer API - [Relayer Overview](https://docs.umbraprivacy.com/relayer/overview): Async claim submission at relayer.api.umbraprivacy.com, lifecycle statuses, SDK integration via getUmbraRelayer - [Relayer Info](https://docs.umbraprivacy.com/relayer/api-reference/info): GET /v1/relayer/info — address, supported_mints, active_stealth_pool_indices - [Submit Claim](https://docs.umbraprivacy.com/relayer/api-reference/submit-claim): POST /v1/claims — proof_account_data, utxo_slot_data, fee_proof_data → 202 {request_id} - [Claim Status](https://docs.umbraprivacy.com/relayer/api-reference/claim-status): GET /v1/claims/{request_id} — status lifecycle, tx_signature, callback_signature, failure_reason - [Relayer Health](https://docs.umbraprivacy.com/relayer/api-reference/health): GET /v1/health — basic health check ## 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` (v3.0.0) - ZK Prover Package: `@umbra-privacy/web-zk-prover` (v2.0.1) ## 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, balance encryption - [Poseidon Hash](https://docs.umbraprivacy.com/sdk/advanced/cryptography/poseidon): ZK-friendly hash over BN254, commitments, nullifiers, user identity - [Indexed Merkle Tree](https://docs.umbraprivacy.com/sdk/advanced/cryptography/indexed-merkle-tree): On-chain UTXO commitment store, 2^148 total capacity across trees