Skip to main content

PoolSession

PoolSession is the main runtime object. It is built by PoolSessionBuilder, carries the wired services, and exposes the user-facing operations as methods. Usage walkthroughs live on the Operations pages; this page is the method reference. Parameter and result shapes are defined in the types reference.

All methods return promises except getRevocableKeyIndex(), the facade's only synchronous method. Most listed errors are exported from the package as types only, so catch them by matching error.name rather than instanceof (see errors).

Deposit

deposit(params: DepositParams): Promise<TxReceipt>
prepareDeposit(params: DepositParams): Promise<PrepareDepositResult>
executeDeposit(result: PrepareDepositResult): Promise<TxReceipt>
depositFor(params: DepositForParams): Promise<TxReceipt>
prepareDepositFor(params: DepositForParams): Promise<PrepareDepositResult>
  • deposit runs prepare and execute in one step and resolves once the deposit transaction is mined.
  • prepareDeposit builds the deposit witness, proof, and calldata without submitting. For an ERC20 whose allowance is too low, the result carries an approvalTx that executeDeposit submits first.
  • depositFor deposits on behalf of another recipient, identified blindly by noteAddressHash or through discoveryData.

Throws: InvalidDepositParams (parameter validation), AssetNotEnabled (asset disabled on the Entrypoint), BelowMinimumAmount, AllowanceCheckFailed, DepositWitnessFailed, DepositProofFailed, DepositRecipientViewingKeyUnregistered (depositFor with an unregistered recipient), UnexpectedTransactionTarget (prepared calldata fails the target check at execute time).

Transfer and payment requests

prepareTransfer(params: TransferParams): Promise<PrepareTransferResult>
relayTransfer(params: RelayTransferParams): Promise<TransferResult>
transfer(params: TransferParams): Promise<TransferResult>
executeTransfer(opts: ExecuteTransferParams): Promise<TransferResult>
prepareColdStartTransfer(params: ColdStartTransferParams): Promise<PrepareTransferResult>
generatePaymentRequest(params: GeneratePaymentRequestParams): Promise<PaymentRequest>
prepareFulfillPaymentRequest(params: FulfillPaymentRequestParams): Promise<PrepareTransferResult>
  • prepareTransfer builds a private transfer (a transact proof with zero public output) and returns executeOptions for self-submission plus one relayOptions entry per configured relayer.
  • relayTransfer re-proves against the chosen relayer's processor and fee commitment, submits through that relayer, and settles local note state.
  • transfer and executeTransfer are the self-submit path: the prepared proof defaults its processor to your own address, so submission works but your wallet is publicly visible as the sender.
  • prepareColdStartTransfer targets a recipient by EVM address with no keystore lookup at all, generating the note secrets for you to deliver out-of-band.
  • generatePaymentRequest is the recipient side of payment requests (five note slots by default).
  • prepareFulfillPaymentRequest is the payer side, and its result is submitted with relayTransfer or executeTransfer like any transfer.

Throws: InvalidTransactParams (validation, including a fee-commitment asset that differs from tokenId), TransactNoteNotActive (an input is not ACTIVE), InsufficientTransactValue, RecipientViewingKeyUnregistered (recipient unregistered and allowOutOfBandFallback not set), WitnessPreparationFailed (including the unregistered-sender case, surfaced as a "Leaf not found in tree" message), FeeCommitmentExpired (quote expired before submission), RelayerRequestFailed / RelayerRejected (relayer transport and rejection), InvalidPaymentRequestParams.

Withdraw

prepareWithdraw(params: WithdrawParams): Promise<PrepareWithdrawResult>
relayWithdraw(params: ExecuteWithdrawRelayerParams): Promise<TxReceipt>
withdraw(params: WithdrawParams): Promise<TxReceipt>
executeWithdraw(result: PrepareWithdrawResult): Promise<TxReceipt>
  • prepareWithdraw builds a transact proof with a public output leg bound to recipientAddress.
  • relayWithdraw submits a prepared withdrawal through the relayer in the selected quote.
  • For self-submission, pass processorAddress: yourWalletAddress into prepareWithdraw or withdraw. By default the prepared calldata binds the zero address as processor and reverts on-chain with PoolVault_InvalidProcessor.

Throws: InvalidTransactParams (validation, including amountSent not equal to amount + feeAmount, and quote fields diverging from the fee commitment), TransactNoteNotActive, InsufficientTransactValue, WitnessPreparationFailed, FeeCommitmentExpired.

Batch withdraw

prepareBatchWithdraw(params: BatchWithdrawSessionParams): Promise<PrepareBatchWithdrawResult>
relayBatchWithdraw(params: PrepareBatchWithdrawResult): Promise<TxReceipt>
selfSubmitBatchWithdraw(params: SelfSubmitBatchParams): Promise<TxReceipt>
prepareSelfSubmitBatch(params: SelfSubmitBatchParams): Promise<SelfSubmitBatchPrepareResult>
executeSelfSubmitBatch(prepared: SelfSubmitBatchPrepareResult): Promise<TxReceipt>
  • prepareBatchWithdraw partitions the asset's ACTIVE notes into single-label groups of at most five, requests one aggregate relayer quote, and builds one proof per group bound to its signed per-item routing. No local mutation.
  • relayBatchWithdraw submits the single relayBatch and, once the receipt's Transacted logs confirm every nullifier, persists the batch's note-state changes; unconfirmed nullifiers are warned about and left for discoverNotes().
  • The self-submit trio proves zero-fee items and submits relayBatch as your own transaction; SelfSubmitBatchParams adds relayContractAddress.

Throws: BatchWithdrawBaseError subclasses EmptyBatchSelection, BatchTooLarge, AssetNotRelayable (a nonzero maxRelayFee below relay cost), InfeasibleBatchFee (a fee above its item's output), BatchRoutingMismatch, BatchRoutingInvalid (the relayer's signed routing disagrees with the SDK's recomputed fees); RelayerInteractorBaseError; PoolSessionTransactBaseError when the batch delegate is not configured. See Batch withdraw.

Withdraw and swap, reshield, swap and deposit

prepareSwapQuote(params: PrepareSwapQuoteParams): Promise<PreparedSwapQuote>
relayWithdrawAndSwap(params: ExecuteWithdrawAndSwapRelayerParams): Promise<TxReceipt>
estimateReshieldAmount(params: EstimateReshieldParams): Promise<ReshieldEstimate>
prepareReshieldQuote(params: PrepareReshieldQuoteParams): Promise<PreparedReshieldQuote>
relayReshield(params: ReshieldParams): Promise<TxReceipt>
estimateReshieldCrosschainAmount(params: EstimateReshieldCrosschainParams): Promise<ReshieldCrosschainEstimate>
prepareReshieldCrosschainQuote(params: PrepareReshieldCrosschainQuoteParams): Promise<PreparedReshieldCrosschainQuote>
relayReshieldCrosschain(params: ReshieldCrosschainParams): Promise<TxReceipt>
prepareSwapAndDeposit(params: SwapAndDepositParams): Promise<PrepareSwapAndDepositResult>
executeSwapAndDeposit(result: PrepareSwapAndDepositResult): Promise<TxReceipt>
swapAndDeposit(params: SwapAndDepositParams): Promise<TxReceipt>
  • prepareSwapQuote runs the relayer fee estimate, the aggregator quote, and the committed relayer quote, then validates every field of the signed commitment; relayWithdrawAndSwap proves and submits through RelaySwaps. Both need withSwapQuoteProvider(...).
  • The reshield trio adds a contractCalls quote whose final step deposits the swapped output; you build the deposit proof yourself with prepareDeposit and pass it as depositResult. Needs withSwapAndDepositQuoteProvider(...) too. The ...Crosschain trio takes toChainId and a destination-scoped depositResult, with an optional dustRescue stealth opt-in.
  • prepareSwapAndDeposit / executeSwapAndDeposit is the inbound, wallet-funded path: no transact, no relayer; the aggregator transaction's last step is the deposit.

Throws: PoolSessionTransactBaseError (a provider or delegate not configured); SwapQuoteProviderBaseError subclasses SwapQuoteFailed, SwapStatusFailed, UnallowedLiFiAddress (target or approval address outside approvedRouters), RelaySwapsLayoutMismatch (the contract's ROUTING_TYPEHASH disagrees with the SDK's encoding), LiFiDepositCalldataNotFound, LiFiDepositTargetNotFound, LiFiRecipientNotFound; PoolSessionSwapDepositBaseError subclasses InvalidSwapAndDepositParams, SwapAndDepositQuoteFailed. See Withdraw and swap, Reshield, Swap and deposit.

Yield

readonly yield?: YieldSessions // the first configured deployment, if any
readonly yields: readonly YieldSessions[] // every configured deployment, in configuration order
yieldFor(tokenAddress: Address): YieldSessions | undefined

Yield is a namespace per deployment rather than a set of session methods. yieldFor matches the share token or its underlying (case-insensitively) and returns { chainId, deployment, deposit, withdraw, token, router }; deposit and withdraw are the yield sessions, token and router the PPYieldToken and PPRouter interactors.

yieldFor(t).deposit.sharesForUnderlying(underlyingAmount: bigint): Promise<bigint>
yieldFor(t).deposit.sizeSharesForBudget(budget: bigint, headroomPpm?: bigint): Promise<BudgetSizedYieldDeposit>
yieldFor(t).deposit.prepareYieldDeposit(params: YieldDepositParams): Promise<PreparedYieldDeposit>
yieldFor(t).withdraw.prepareYieldWithdraw(params: YieldWithdrawParams): Promise<PreparedYieldWithdraw>
yieldFor(t).withdraw.prepareYieldWithdrawRelay(params: YieldWithdrawRelayParams): Promise<PreparedYieldWithdrawRelay>
  • Deposits are sized in shares: sharesForUnderlying is previewDeposit exactly; sizeSharesForBudget fits the router's full price plus a rate headroom inside an all-in budget. prepareYieldDeposit builds the standard deposit proof, re-targets it at PPRouter.depositExactShares, and returns approvalTxs, depositTx, and pendingNote.
  • prepareYieldWithdraw builds the standard withdrawal proof against the router, sizes minUnderlyingOut from quoteWithdraw minus slippageBps, and returns a single withdrawTx. prepareYieldWithdrawRelay binds the relayer's signed fee commitment instead and returns typed relay params carrying processorAddress = PPRouter and minUnderlyingOut.

Configure with withYieldDeployment(s) on the builder, or let it derive deployments from the relayer's /v1/details. Throws: YieldSessionBaseError subclasses InvalidYieldAmount (non-positive shares, or a cap below the quote), UnexpectedDepositCalldata / UnexpectedWithdrawCalldata, InvalidYieldAddress, DuplicateYieldDeployment. See Yield deposit and Yield withdraw.

Ragequit

rageQuit(params: RageQuitParams): Promise<TxReceipt>
prepareRageQuit(params: RageQuitParams): Promise<PrepareRageQuitResult>
executeRageQuit(result: PrepareRageQuitResult): Promise<TxReceipt>

Recovers a note's full value to its recorded owner; the circuit forces the destination, and the SDK method is camelCase while the contract method is ragequit. On a confirmed receipt the note is marked EXITED locally.

Throws: InvalidRageQuitParams, NoteNotFoundError (commitment not in the local note set), RagequitNoteAlreadyExitedError, RagequitAddresslessNoteError (a note whose ownerAddress is the zero address can never ragequit), WitnessPreparationFailed (including the unregistered-owner case), UnexpectedTransactionTarget.

Keystore

isKeystoreRegistered(): Promise<boolean>
registerKeystore(options?: RegisterKeystoreOptions): Promise<TxReceipt[]>
prepareRegisterKeystore(options?: RegisterKeystoreOptions): Promise<RegisterKeystoreResult>
executeRegisterKeystore(result: RegisterKeystoreResult): Promise<TxReceipt[]>
getRevocableKeyIndex(): Hex
discoverRevocableKeyIndex(config: Omit<DeriveFromSignatureConfig, "revocableKeyIndex">, gapLimit?: number): Promise<Hex>
rotateRevocableKey(config: RotateRevocableKeyConfig): Promise<RotateRevocableKeyOutcome>
prepareRotateRevocableKey(config: RotateRevocableKeyConfig): Promise<RotateRevocableKeyResult>
executeRotateRevocableKey(result: RotateRevocableKeyResult): Promise<RotateRevocableKeyOutcome>
  • isKeystoreRegistered reads the session owner's on-chain nullifying-key hash (a zero value means unregistered) and takes no argument.
  • registerKeystore submits setAuthPolicy and, unless includeViewingKey: false, setViewingKey; it returns one receipt per transaction and handles the already-registered case, including partial registration where only the viewing key is missing. Registration is never automatic: no deposit, transfer, or session-construction path registers for you.
  • discoverRevocableKeyIndex recovers a rotated account's current index cold, scanning candidate indices up to gapLimit (default 20).
  • rotateRevocableKey advances the index by one and re-derives the key from a fresh wallet signature; persist newRevocableKeyIndex from the outcome, because future sessions must be built with it.

Throws: RegistrationCheckFailed (RPC failure during the status read), KeystoreNotRegistered (rotation or index discovery on an unregistered account), RevocableKeyIndexNotFound (no index matched within gapLimit), CurrentLeafNotFound, RotationKeyMismatch, UnexpectedTransactionTarget.

Discovery and note management

discoverNotes(params?: DiscoverNotesParams): Promise<Note[]>
purgePhantomNotes(params?: PurgePhantomNotesParams): Promise<Hash[]>
addNotes(params: AddNoteParams[]): Promise<void>
markNotesSpent(params: MarkNoteSpentParams[]): Promise<void>
markNotesExited(params: MarkNoteExitedParams[]): Promise<void>
  • discoverNotes scans Note and Transacted events from the persisted sync cursor (or fromBlock when given), matches open payment requests, reconciles statuses, and advances the cursor.
  • purgePhantomNotes deletes locally stored notes whose commitments do not exist on-chain. It is never called implicitly, supports dryRun: true, and must not run while a transaction is in flight.
  • addNotes, markNotesSpent, and markNotesExited are bookkeeping for integrators who broadcast their own transactions: addNotes inserts owned outputs as PENDING (the transaction must already be mined), markNotesSpent records external spends, and markNotesExited records external ragequits.
  • After a ragequit, use markNotesExited, not markNotesSpent: SPENT is terminal, and the wrong mark wedges later discovery.

Throws: NoteDiscoveryScanFailed, StateInvariantViolation (an on-chain event contradicts terminal local state), InvalidAddNoteParams, NoteCommitmentNotMined, InvalidMarkNoteSpentParams, InvalidMarkNoteExitedParams, NoteNotFoundError, InvalidStatusTransitionError, InvalidNoteError.

Export and import

exportAccount(): Promise<AccountExport>
importAccount(data: AccountExport): Promise<void>
importReceivedNote(note: Note): Promise<void>
  • exportAccount serializes notes, lineages, the sync cursor, and pending payment requests, stamped with owner and chain id. Keys are excluded.
  • importAccount replaces local note and payment-request state with an export.
  • importReceivedNote claims a note delivered out-of-band: the SDK verifies the owner matches the session and recomputes the noteAddressHash and commitment bindings before storing it as PENDING, and the next discoverNotes() promotes it.

Throws: AccountExportMismatch (export stamped for a different owner or chain), InvalidNoteError (shape, owner, or commitment binding fails), NoteConflictError.

Lifecycle and persistence

Build one PoolSession per wallet-and-chain pair and reuse it for the user's session; constructing one instantiates services (Poseidon hashing is async, the NoteManager loads from storage, relayer configs are parsed). NoteManager state goes to the configured persistent-storage adapter; the browser default is localStorage under privacy-pool:v1:note-manager-state:{chainId}:{ownerAddress} (lowercase, with per-owner keying so multi-account sessions don't collide). See Integration architecture for what to persist and when.