> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.umbraprivacy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The SDK Pattern

> SDK architecture (V18): factory pattern with verbose flow-based names, args (required params) vs deps (injectable providers), per-call commitment overrides, and subpath imports for every operation family.

## Design Philosophy

The Umbra SDK is written in the same **functional, dependency-injected style** as [Anza's `@solana/kit`](https://github.com/anza-xyz/solana-web3.js). Every capability is either a pure function or a factory that returns one. There are no classes with internal state, no singletons, and no implicit globals. Dependencies are explicit, injectable, and testable.

This mirrors the architecture of `@solana/kit` itself — functions like `getTransferSolInstruction` and `createSolanaRpc` follow the same closure-based factory pattern you will find throughout the Umbra SDK.

## The Factory Pattern

Every SDK operation follows the same two-step pattern:

```typescript theme={null}
import { getATAIntoETADirectDepositorFunction } from "@umbra-privacy/sdk/deposit";

// 1. Build the function once, at setup time.
const deposit = getATAIntoETADirectDepositorFunction({ client });

// 2. Call it at runtime.
const result = await deposit(destinationAddress, mint, amount);
```

The factory call (`get*Function`) is cheap — it binds configuration and resolves defaults. The returned function is what does the actual async work: sending transactions, generating proofs, querying the indexer, polling the relayer.

This is the same pattern `@solana/kit` uses for its instruction builders:

```typescript theme={null}
// @solana/kit instruction builder
const ix = getTransferSolInstruction({ source, destination, amount });

// Umbra SDK factory function — same pattern, describing the data flow end-to-end.
const withdraw = getETAIntoATAWithdrawerFunction({ client });
```

## Naming Conventions (V18)

Names are long, but they spell out the exact data flow.

* **Deposit family** (`@umbra-privacy/sdk/deposit`)
  * `getATAIntoETADirectDepositorFunction` — ATA → ETA.
  * `getATAIntoSelfBurnableStealthPoolNoteCreatorFunction` — ATA → self-burnable Stealth Pool Note.
  * `getATAIntoReceiverBurnableStealthPoolNoteCreatorFunction` — ATA → receiver-burnable Stealth Pool Note.
  * `getETAIntoSelfBurnableStealthPoolNoteCreatorFunction` — ETA → self-burnable Stealth Pool Note (MPC).
  * `getETAIntoReceiverBurnableStealthPoolNoteCreatorFunction` — ETA → receiver-burnable Stealth Pool Note (MPC).

* **Withdrawal family** (`@umbra-privacy/sdk/withdrawal`)
  * `getETAIntoATAWithdrawerFunction` — ETA → ATA.

* **Burn family** (`@umbra-privacy/sdk/burn`)
  * `getBurnableStealthPoolNoteScannerFunction` — zero-arg scanner, cursor in `client.utxoDataStore`.
  * `getReceiverBurnableStealthPoolNoteIntoETABurnerFunction` — receiver-burnable → ETA.
  * `getSelfBurnableStealthPoolNoteIntoETABurnerFunction` — self-burnable → ETA.
  * `getSelfBurnableStealthPoolNoteIntoATABurnerFunction` — self-burnable → ATA.
  * (Receiver-burnable → ATA exists on-chain but is not yet shipped in the SDK.)

* **Registration** (`@umbra-privacy/sdk/registration`) — `getUserRegistrationFunction`.

* **Query** (`@umbra-privacy/sdk/query`) — `getUserAccountQuerierFunction`, `getEncryptedBalanceQuerierFunction`.

* **Conversion** (`@umbra-privacy/sdk/conversion`) — `getNetworkEncryptionToSharedEncryptionConverterFunction`.

* **Compliance** (`@umbra-privacy/sdk/compliance`) — grant issuer / revoker / re-encryptors / queriers.

* **Account** (`@umbra-privacy/sdk/account`) — staged-token recoverers (`getStagedSplRecovererFunction`, `getStagedSolRecovererFunction`), key rotators, maintenance helpers.

You read each name as `[verb] from [source] (into|to) [destination]` or `[verb] [object]`. Factory names use the abbreviations `ATA` (`AssociatedTokenAccount`) and `ETA` (`EncryptedTokenAccount`) — e.g. `getATAIntoETADirectDepositorFunction` — so they stay short while remaining searchable and self-describing in code.

## V18 vocabulary

* **Stealth Pool Note** replaces V13's "UTXO" in factory names and types. The wire protocol and on-chain instructions retain `claim_*` / `utxo_*` spellings for compatibility.
* **Burn** replaces V13's "claim" in factory names. The relayer endpoint is still `/v1/claims`, and the burner factory's `relayer` dep takes `{ submitBurn, pollBurnStatus, getRelayerAddress }` — `submitBurn` and `pollBurnStatus` are TypeScript aliases of `submitClaim` and `pollClaimStatus`, so the relayer client's existing methods plug in unchanged under the renamed property names.

## args and deps

Every factory accepts two arguments:

```typescript theme={null}
const fn = getOperationFunction(args, deps?);
```

* **`args`** — required. Always contains `client: IUmbraClient` and any fixed configuration for this operation (e.g. a specific mint).
* **`deps`** — optional. Contains every infrastructure provider, key generator, ZK prover, and relayer adapter used internally. All `deps` fields have sensible defaults derived from the `client`. The only exceptions are **ZK provers and the burner factory `relayer` adapter**, which have no built-in defaults and must always be supplied explicitly.

```typescript theme={null}
// Using all defaults.
const deposit = getATAIntoETADirectDepositorFunction({ client });

// Overriding the transaction forwarder (e.g. Jito bundles).
const deposit = getATAIntoETADirectDepositorFunction(
  { client },
  { transactionForwarder: jitoForwarder },
);
```

Function-level `deps` override client-level `deps`. Client-level `deps` override built-in defaults.

<Note>
  The **Advanced** section covers dependency injection internals, key generators, ZK provers, transaction callbacks, and key rotation in depth. Most applications do not need those details to get started.
</Note>
