import { PublicKey, type Connection } from "@solana/web3.js"; import { type SwapProofBuilder } from "../proofs/swap.js"; import { relayerMintParam, type ClientProvingDeps, type ClientProvingFailure, type ClientProvingNote, type ClientProvingOutputNote, type ClientSpendRecovery, type NoteCipherRecipient } from "./shared.js"; export interface SwapWithClientProofParams { connection: Connection; /** One or two notes of `sourceMint`. Merge down first with `consolidateNotes`. */ notes: ClientProvingNote[]; sourceMint?: PublicKey; destMint: PublicKey; /** Base units of the source mint to swap. The rest of the notes comes back as change. */ swapAmount: bigint; slippageBps: number; /** * The least destination amount, net of the relayer fee, you will accept. * * The relayer prices the swap and the proof fixes that price, so this is the * user's only slippage protection: a quote below it is refused before * anything is proved. */ minDestAmount: bigint; /** Refuse any quote whose fee (paid in the destination mint) exceeds this. */ maxFee?: bigint; userPublicKey: string; /** Who can decrypt the change and destination notes from chain data. */ cipherRecipient: NoteCipherRecipient; /** Owner key of both output notes. Defaults to the first input note's key. */ ownerPrivateKey?: bigint; /** Awaited before proving; if it throws, nothing is submitted. */ persistRecovery(recovery: ClientSpendRecovery): Promise | void; /** * Accept a transaction without on-chain note ciphers when the route leaves no * room for them, as native-SOL swaps currently do under the legacy size * limit. Default false: the relayer refuses with `NOTE_CIPHERS_DO_NOT_FIT` * and nothing is spent. * * Only set this when `persistRecovery` stores to somewhere that survives the * device (a synced backup). Without ciphers, that material is the only way to * find the output notes again. */ allowWithoutNoteCiphers?: boolean; /** Defaults to snarkjs with the SDK's pinned swap artifacts. */ prover?: SwapProofBuilder; indexTimeoutMs?: number; /** @internal Clock for the deadline check. */ now?: () => number; } interface SwapResultBase { quoteId: string; /** Relayer fee, in destination-mint base units. */ fee: bigint; /** The swapped output. `treeId` stays null unless the swap landed. */ destNote: ClientProvingOutputNote; /** Null when the whole of the notes was swapped. */ changeNote: ClientProvingOutputNote | null; recovery: ClientSpendRecovery; } /** * Same outcome semantics as `ClientWithdrawResult`. A `rejected` swap with code * `SWAP_PRICE_MOVED` means the market moved between quote and submit: nothing * was spent, and a fresh quote and proof will do. */ export type ClientSwapResult = (SwapResultBase & { status: "landed"; txSignature: string; noteCiphersIncluded: boolean; }) | (SwapResultBase & { status: "unconfirmed"; txSignature: string; }) | (SwapResultBase & { status: "unknown"; error: ClientProvingFailure; }) | (SwapResultBase & { status: "rejected"; error: ClientProvingFailure; }); /** * Swap between two privacy pools with a proof generated on this device. * * The relayer quotes a route and prices the output; the device checks that * price against `minDestAmount`, proves, and submits. The relayer executes the * route and cannot deliver less than the proven `destAmount`: the program * reverts the whole swap first. * * Throws only while nothing has been submitted; see `ClientSwapResult`. */ export declare function swapWithClientProof(params: SwapWithClientProofParams): Promise; /** @internal */ export declare function runSwapWithClientProof(params: SwapWithClientProofParams, deps: ClientProvingDeps): Promise; export { relayerMintParam };