Skip to main content

getETAIntoATAWithdrawerFunction

Import: @umbra-privacy/sdk/withdrawal
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.

Deps

All fields are optional.
  • accountInfoProvider?: AccountInfoProviderFunction.
  • getLatestBlockhash?: GetLatestBlockhash.
  • transactionForwarder?: TransactionForwarder.

Returns

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)

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

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.

Example

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.