> ## 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.

# Withdrawal

> V18 API reference: getETAIntoATAWithdrawerFunction returns WithdrawResult with queueSignature and callbackSignature via Arcium MPC.

## getETAIntoATAWithdrawerFunction

**Import:** `@umbra-privacy/sdk/withdrawal`

```typescript theme={null}
function getETAIntoATAWithdrawerFunction(
  args: { client: IUmbraClient },
  deps?: GetETAIntoATAWithdrawerFunctionDeps,
): ETAIntoATAWithdrawerFunction;
```

Withdraws tokens from the caller's ETA to a destination ATA. This is the primary withdrawal path — no ZK proof required. The withdrawal queues an Arcium MPC computation; the network processes it and calls back on-chain to execute the transfer. Follows the [dual-instruction pattern](/concepts/how-umbra-works#the-dual-instruction-pattern).

### Deps

All fields are optional.

* `accountInfoProvider?: AccountInfoProviderFunction`.
* `getLatestBlockhash?: GetLatestBlockhash`.
* `transactionForwarder?: TransactionForwarder`.

### Returns

```typescript theme={null}
type ETAIntoATAWithdrawerFunction = (
  destinationAddress: Address,
  mint: Address,
  withdrawalAmount: U64,
  options?: ETAIntoATAWithdrawerOptions,
) => Promise<WithdrawResult>;
```

* `destinationAddress: Address` — wallet whose ATA receives the tokens.
* `mint: Address` — token mint address.
* `withdrawalAmount: U64` — amount in base token units to withdraw from the ETA.

### Options (`ETAIntoATAWithdrawerOptions`)

```typescript theme={null}
interface ETAIntoATAWithdrawerOptions {
  readonly optionalData?: OptionalData32;
  readonly accountInfoCommitment?: Commitment;
  readonly computationOffset?: U64;
  readonly mpcCallbackDataOffset?: U128;
  readonly feeVaultOffset?: U128;                  // default 0n (sentinel: no fee-vault interaction)
  readonly destinationProgram?: Address;           // default System Program (sentinel: no observer CPI)
  // plus observer-CPI passthrough accounts and a `hooks?: WithdrawalHooks`
}
```

* `optionalData` — 32-byte caller metadata. **Pre-hashed only.** Default 32 zero bytes.
* `accountInfoCommitment` — per-call commitment for RPC account reads.
* `computationOffset`, `mpcCallbackDataOffset` — PDA offsets. Default to fresh CSPRNG values per call.
* `feeVaultOffset`, `destinationProgram` — observer-forward CPI configuration. Leave at defaults unless you are intentionally routing post-callback into another program.
* `hooks` — per-phase lifecycle hooks (`onValidationStart`, `onAccountFetchComplete`, `queueComputation`, `onComplete`, `onError`, etc.).

There are no `priorityFees`, `awaitCallback`, `skipPreflight`, `maxRetries`, or `epochInfoCommitment` options on the V18 withdrawer.

### WithdrawResult

```typescript theme={null}
interface WithdrawResult {
  readonly signatures: readonly TransactionSignature[];
  readonly queueSignature: TransactionSignature;
  readonly callback?: CallbackOutcome;
  readonly rentClaim?: RentClaimOutcome;
}

type CallbackOutcome =
  | { readonly status: "finalized"; readonly signature?: TransactionSignature; readonly elapsedMs: number }
  | { readonly status: "pruned";    readonly elapsedMs: number }
  | { readonly status: "timed-out"; readonly elapsedMs: number };

type RentClaimOutcome =
  | { readonly claimed: true;  readonly signature: TransactionSignature }
  | { readonly claimed: false; readonly reason: string };
```

### Errors

Throws `EncryptedWithdrawalError`. See [Errors](./errors#encryptedwithdrawalerror).

### Example

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

const withdraw = getETAIntoATAWithdrawerFunction({ client });

const result = await withdraw(
  destinationWallet,   // tokens land in this wallet's ATA
  mintAddress,
  500_000n,
);
console.log("Queue signature:", result.queueSignature);
if (result.callback?.status === "finalized") {
  console.log("Callback signature:", result.callback.signature);
}
```

### Dropped-callback recovery

If the handler succeeds but the Arcium callback never lands, tokens stay staged in the pool ATA. Reclaim them with `getStagedSplRecovererFunction` / `getStagedSolRecovererFunction` from `@umbra-privacy/sdk/account` — synchronous, no MPC, no ZK proof.

***

## EncryptedWithdrawalError

Thrown by the withdrawer factory.

Stage values: `"initialization"` | `"validation"` | `"mint-fetch"` | `"pda-derivation"` | `"instruction-build"` | `"transaction-build"` | `"transaction-compile"` | `"transaction-sign"` | `"transaction-send"`.

See [Errors](./errors#encryptedwithdrawalerror).
