import { PublicKey, type Connection } from "@solana/web3.js"; import type { TransactionProofBuilder } from "../proofs/types.js"; import { type ClientProvingDeps, type ClientProvingFailure, type ClientProvingNote, type ClientProvingOutputNote, type ClientSpendRecovery, type NoteCipherRecipient } from "./shared.js"; export interface WithdrawWithClientProofParams { /** Used to check the quoted root against the on-chain root history. */ connection: Connection; /** One or two notes of the same mint. Merge down first with `consolidateNotes`. */ notes: ClientProvingNote[]; /** Net base units the recipient receives. The relayer fee comes out of the notes on top. */ amount: bigint; recipient: PublicKey; mintAddress?: PublicKey; /** Account identifier the relayer quotes for. */ userPublicKey: string; /** Who can decrypt the change note from chain data. */ changeCipherRecipient: NoteCipherRecipient; /** Owner key of the change note. Defaults to the first input note's key. */ changeOwnerPrivateKey?: bigint; /** Refuse, before proving, any quote whose fee exceeds this. */ maxFee?: bigint; /** * Durably store the spend before anything is proved or sent. Awaited; if it * throws, nothing is submitted. Without this, a crash after landing would * leave change that exists on-chain but that this device cannot spend. */ persistRecovery(recovery: ClientSpendRecovery): Promise | void; /** Defaults to snarkjs with the SDK's pinned artifacts. */ prover?: TransactionProofBuilder; /** How long to wait for the relayer to index the input notes. Default 90 s. */ indexTimeoutMs?: number; } interface WithdrawResultBase { quoteId: string; fee: bigint; /** Null when the notes are spent exactly. */ changeNote: ClientProvingOutputNote | null; recovery: ClientSpendRecovery; } /** * Every outcome once a proof has been submitted. * * - `landed`: done. The inputs are spent and `changeNote` is spendable. * - `unconfirmed`: sent, may still land. Treat the inputs as neither spent nor * spendable until `resolveClientSpend` settles it. * - `unknown`: the relayer's answer never arrived. Same handling as * `unconfirmed`, without a signature to check. * - `rejected`: the relayer refused before sending. Nothing moved; the inputs * are still spendable and a fresh attempt is safe. */ export type ClientWithdrawResult = (WithdrawResultBase & { status: "landed"; txSignature: string; noteCiphersIncluded: boolean; }) | (WithdrawResultBase & { status: "unconfirmed"; txSignature: string; }) | (WithdrawResultBase & { status: "unknown"; error: ClientProvingFailure; }) | (WithdrawResultBase & { status: "rejected"; error: ClientProvingFailure; }); /** * Withdraw from the privacy pool with a proof generated on this device. * * Quote, verify the quote, persist recovery material, prove locally, submit. * Spending keys and blindings never leave the process; the relayer sees only * the proof and its public inputs. * * Throws `ClientProvingError` (or `VeiloApiError` from quoting) only while * nothing has been submitted. From submission on, every outcome — including a * lost connection — is a returned `ClientWithdrawResult`, so a spend that may * have landed is never reported as a plain failure. */ export declare function withdrawWithClientProof(params: WithdrawWithClientProofParams): Promise; /** @internal */ export declare function runWithdrawWithClientProof(params: WithdrawWithClientProofParams, deps: ClientProvingDeps): Promise; export {};