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

# Withdraw (/reference/withdraw)

A withdrawal runs in a context made from the session. [Withdraw](https://sdk.nimbusprivacy.xyz/withdraw) walks through the flow.

## createWithdrawalContext

Create one from the session before a withdrawal. It picks the pool the withdrawal spends from.

```ts
function createWithdrawalContext(
  session: NimbusSession,
  options?: NimbusContextOptions,
): Promise<WithdrawalContext>;
```

Creates the context a session withdraws in.

Without `options.poolIndex` the pools' accounts are read from the RPC once, and the highest open
pool is chosen; the nodes and guardian cluster default to the cluster's preset.

**Parameters**

| Parameter  | Type                   | Description                                                               |
| ---------- | ---------------------- | ------------------------------------------------------------------------- |
| `session`  | `NimbusSession`        | The opened session.                                                       |
| `options?` | `NimbusContextOptions` | The pool, the screener and data endorser nodes, and the guardian cluster. |

**Returns**

`Promise<WithdrawalContext>`

The context.

**Throws**

[`NimbusSdkError`](https://sdk.nimbusprivacy.xyz/reference/errors#nimbussdkerror) with reason `"misconfigured"` when an option is out of range or no
pool is open; `"service-unavailable"` or `"unreadable"` when the RPC cannot be read.

**Example**

```ts
import { createWithdrawalContext } from "@umbra/nimbus-solana-web";
import type { NimbusSession } from "@umbra/nimbus-solana-web";

declare const session: NimbusSession;
const context = await createWithdrawalContext(session);
```

Generated from the TSDoc in `sdks/typescript/nimbus-solana-web/src/contexts.ts`.

## withdraw

Use it to move tokens out of the private balance to any Solana address.

```ts
function withdraw(
  context: WithdrawalContext,
  args: {
    readonly mint: Address;
    readonly amount: bigint;
    readonly recipient: Address;
  },
  options?: WithdrawOptions,
): Promise<WithdrawalResult>;
```

Withdraws `amount` of `mint` from the session's notes in the context's pool to `recipient`'s
token account, through the relayer.

First syncs the note store until it is caught up, unless `sync: false`, and spends the largest
notes the session may spend; the committee endorses, the spend is proved, and the relayer
submits it. Unless `follow: false`, it then follows the relay until it lands at `commitment`
and syncs again, so a `relayed` result's `settlement` says it landed and the spent notes are
no longer reserved; with `follow: false` they stay reserved until a later sync sees them spent. When the largest three notes cannot cover the withdrawal but all of them
can, less the relayer's fee for each merge, it first merges them, each merge a transfer to the
session's own identity that it waits on, syncing the note store, until the merged note is
spendable; `onProgress` sees each merge's `merge-prepared`, `merge-relayed` and `merge-settled`
before the withdrawal's stages.

**Parameters**

| Parameter  | Type                                                                                                                                                                                                                                                                                                                                                                                                                          | Description                                                                                                                                                                                                                                                         |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context`  | `WithdrawalContext`                                                                                                                                                                                                                                                                                                                                                                                                           | The withdrawal context.                                                                                                                                                                                                                                             |
| `args`     | ``{ /** The mint withdrawn, of the session's notes. */ readonly mint: Address; /** * In base units of the mint: under `fees: "deducted"` what leaves the session's notes, every * fee taken from it; under `added`, what the token account receives. */ readonly amount: bigint; /** * The wallet address paid: its associated token account, unless `recipientTokenAccount` names * one. */ readonly recipient: Address; }`` | The mint, the amount in its base units, and the wallet address paid.                                                                                                                                                                                                |
| `options?` | `WithdrawOptions`                                                                                                                                                                                                                                                                                                                                                                                                             | The progress hook, which also sees `synced` and `settled`; whether to sync first and to follow the relay, and the commitment followed to; who pays the fees, the submitter's fee and its mint, the zone, the token account paid, and each merge's timeout in slots. |

**Returns**

`Promise<WithdrawalResult>`

`relayed` with the relayer's admission and how following it settled, the payment
known made once the settlement is `landed`; `refused` with a [`SpendRefusal`](https://sdk.nimbusprivacy.xyz/reference/types#spendrefusal) when nothing
was asked of the committee, whose `insufficient` names the total of every note the session may
spend in the pool, zone and mint; `relay-refused` when the relayer refused it; `unsent` when
the note store would not mark it sent; or `merge-failed` with the merges completed and the
[`MergeFailureCause`](https://sdk.nimbusprivacy.xyz/reference/types#mergefailurecause) of the next.

**Throws**

[`NimbusSdkError`](https://sdk.nimbusprivacy.xyz/reference/errors#nimbussdkerror) with reason `"misconfigured"` when an address is not base58, the
mint does not exist, or no prover worker or committee endpoint was configured;
`"service-unavailable"` or `"unreadable"` when a service or the RPC cannot answer, and
`"unreadable"` too when the note store cannot be synced before it starts;
`"unauthorized"` when a gateway service refuses the session's gateway token or the session has
none; `"dependency-nonconforming"` when a proving key or the prover breaks its contract;
`"account-unregistered"` when the context API answers that the session's identity or the
connected wallet has no registration in the pool, before anything is relayed;
[`NimbusSolanaFlowError`](https://sdk.nimbusprivacy.xyz/reference/types#nimbussolanaflowerror) when the protocol refuses the withdrawal.

**Example**

```ts
import { createWithdrawalContext, withdraw } from "@umbra/nimbus-solana-web";
import type { NimbusSession } from "@umbra/nimbus-solana-web";
import type { Address } from "@solana/kit";

declare const session: NimbusSession;
declare const mint: Address;
const result = await withdraw(await createWithdrawalContext(session), {
  amount: 500_000n,
  mint,
  recipient: session.walletAddress,
});
```

Generated from the TSDoc in `sdks/typescript/nimbus-solana-web/src/flows.ts`.


Last updated 21 October 2026
