# Swap and deposit

> Enter the pool from any wallet token: swap through an aggregator and deposit the output as a shielded note in one wallet transaction.

Swap-and-deposit is the inbound sibling of [reshield](/operations/reshield). You hold token X in a wallet and want a shielded note in token Y. Rather than swapping in one transaction and [depositing](/operations/deposit) in another, the SDK fetches an aggregator `contractCalls` quote whose post-swap step is the deposit itself, and you submit that single transaction from your wallet.

This path does not touch `PoolVault.transact` or a relayer. It is a wallet-funded swap whose final call is `Entrypoint.deposit` (or `PPRouter.depositExactShares` when the target is a [yield share](/concepts/yield-shares)), so your wallet is the public depositor exactly as it is for a plain deposit.

## How it works

1.  **Prove the deposit.** The SDK builds a standard deposit proof for `depositToken` and `depositAmount`; the note it describes is the one you will hold.
2.  **Quote.** The aggregator returns calldata that swaps `inputToken` into enough `depositToken` to cover the deposit value plus the on-chain vetting fee, then calls the deposit with your proof and note data. The SDK verifies the deposit calldata and target it finds in that quote match what it built (`LiFiDepositCalldataNotFound` / `LiFiDepositTargetNotFound` otherwise).
3.  **Approve and submit.** You approve the aggregator for the input token if needed, then send the aggregator transaction. Swap and deposit land together; the pool inserts your commitment.

## How to swap in

```ts
// At session build time:
//   builder.withSwapAndDepositQuoteProvider(new LiFiSwapQuoteProvider({ integrator, apiKey }))

const prepared = await session.prepareSwapAndDeposit({
    fromChainId: 42161,               // where the input token lives
    inputToken: arbUsdcAddress,       // what your wallet holds
    depositToken: poolUsdtAddress,    // the shielded asset you end up with
    depositAmount: depositValue,      // Hex, in depositToken
});

console.log("will spend about", prepared.estimatedInputAmount, "of the input token");
console.log("estimated duration (s):", prepared.estimatedDuration);

// Submits prepared.approvalTxs in order, then the aggregator transaction,
// and persists prepared.pendingNote once mined.
const receipt = await session.executeSwapAndDeposit(prepared);
console.log("tx:", receipt.txHash);
```

`swapAndDeposit(params)` runs both steps in one call. The prepared result exposes the raw pieces (`transactionTo`, `transactionData`, `msgValue`, `depositCallData`, `depositTarget`) for integrators who broadcast themselves.

When `fromChainId` differs from the pool's chain the aggregator bridges first; configure the session's `sourceChain` (a wallet and RPC for the source chain) so the approval and the aggregator transaction are sent there, and set `fallbackAddress` for a failed bridge leg.

## Constraints

-   **Your wallet is public.** This is a deposit. The depositor address and the swapped-in value are visible on-chain like any deposit's; privacy begins once the note is attested, not at entry.
-   **Sizing is approximate on the input side.** The deposit value is exact (it is in the proof); the input amount is the aggregator's estimate plus slippage, and any surplus output beyond the deposit and its vetting fee is handled by the aggregator's route.
-   **Vetting fee is included automatically.** The SDK reads `Entrypoint.assets(depositToken).vettingFeeBPS` and sizes the swap so the deposit call receives value plus fee.
-   **Yield targets need a configured deployment.** Landing as ppUSDC embeds a `PPRouter` call, so the session must know the router (`withYieldDeployments`, or derived from the relayer's `/v1/details`).
-   **The note is `PENDING`.** Awaiting [ASP attestation](/concepts/asp-attestation), as any deposit.

## Behind the scenes

SDK call `session.prepareSwapAndDeposit(...)` then `session.executeSwapAndDeposit(...)`, or `session.swapAndDeposit(...)`. Requires `withSwapAndDepositQuoteProvider(...)`.
Contract method The aggregator's entry point, whose route ends in [`Entrypoint`](/protocol/contracts/entrypoint)`.deposit(proof, noteData, aspCiphertext)` or [`PPRouter`](/protocol/contracts/pp-router)`.depositExactShares(...)`. No pool `transact` and no `RelaySwaps` execution is involved.
Circuit [`deposit`](/protocol/circuits/deposit) only.

## What's next

-   [Manage notes](manage-notes): discovery promotes the attested note into your spendable set.
-   [Reshield](reshield): change asset again later without leaving the pool.
