> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dzap.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Deposit

> Zap any token into an LP or vault position in one flow: quote, authorize, build, execute.

A deposit (Zap In) takes a plain token and lands you in a DeFi position: an LP pool, a lending market, or a vault. The router swaps, bridges, and enters the position in a single build. The destination is the position address (`destToken = pool.address`); set `destChainId` to a different chain and the same call becomes a cross-chain deposit. Pick a chain below; the tabs stay in sync across Setup, Steps, and End-to-end.

<Note>EVM deposits use Permit2 for token allowance (no EIP-2612). Solana deposits carry no approval step, you sign and send the built transactions directly.</Note>

## Setup

<Snippet file="install-sdk.mdx" />

<Tabs>
  <Tab title="EVM">
    A same-chain deposit on Base: 500 USDC into a USDC/WETH pool.

    ```ts theme={null}
    import { DZapClient, Services, ApprovalModes, PermitTypes, TxnStatus } from '@dzapio/sdk';
    import { createWalletClient, http } from 'viem';
    import { base } from 'viem/chains';
    import { privateKeyToAccount } from 'viem/accounts';

    const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
    const walletClient = createWalletClient({ account, chain: base, transport: http() });
    const dzap = DZapClient.getInstance();

    const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
    const POOL = '0xd0b53D9277642d899DF5C87A3966A349A798F224';   // USDC/WETH pool on Base
    const AMOUNT = '500000000';                                  // 500 USDC (6 decimals)
    ```

    <Note>
      Find pool and position addresses to use as `destToken` with [`getZapPools`](/sdk/zap/request-quotes) and the protocols that back them with [`getZapProviders`](/sdk/zap/request-quotes).
    </Note>
  </Tab>

  <Tab title="Solana">
    A same-chain deposit on Solana: USDC into Jupiter Lend. Needs `@solana/web3.js` alongside the SDK.

    ```ts theme={null}
    import { DZapClient } from '@dzapio/sdk';
    import { Connection, VersionedTransaction } from '@solana/web3.js';

    const dzap = DZapClient.getInstance();
    const connection = new Connection('https://api.mainnet-beta.solana.com');

    // your Solana wallet adapter (wallet-standard, Keypair, etc.)
    const account = wallet.publicKey.toBase58();
    const USDC_SOL = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
    const JUP_LEND_USDC = '9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D';
    const AMOUNT = '959349';                                     // 0.96 USDC (6 decimals)
    ```

    <Note>
      Find pool and position addresses to use as `destToken` with [`getZapPools`](/sdk/zap/request-quotes) and the protocols that back them with [`getZapProviders`](/sdk/zap/request-quotes).
    </Note>
  </Tab>
</Tabs>

## Steps

<Tabs>
  <Tab title="EVM">
    <Steps>
      <Step title="Quote">
        Ask for a route into the position. Read-only: no approvals or signatures. The response carries the expected `output` and the resolved `path`.

        ```ts theme={null}
        const quote = await dzap.getZapQuote({
          srcChainId: 8453,
          destChainId: 8453,        // same chain as srcChainId = same-chain deposit
          account: account.address,
          srcToken: USDC_BASE,
          destToken: POOL,          // the position you are entering
          amount: AMOUNT,
          recipient: account.address,
          refundee: account.address,
          slippage: 1,              // 1 = 1%
        });

        console.log('Route:', quote.path.map((p) => p.protocol.name).join(' -> '));
        console.log('Expected:', quote.output[0]?.amount, quote.output[0]?.asset.symbol);
        ```

        <Note>
          For concentrated-liquidity pools, pass `poolDetails: { lowerTick, upperTick }` to pin the range. Omit it and the router picks a range. Derive the current tick from [`getZapPoolDetails`](/sdk/zap/request-quotes).
        </Note>
      </Step>

      <Step title="Approve">
        Zaps authorize the source token through Permit2. `PermitSingle` approves once on-chain if the allowance is short; native sources (ETH) skip this entirely.

        ```ts theme={null}
        const { data } = await dzap.getAllowance({
          chainId: 8453,
          sender: account.address,
          tokens: [{ address: USDC_BASE, amount: AMOUNT }],
          service: Services.zap,
          mode: ApprovalModes.PermitSingle,
        });

        if (data[USDC_BASE].allowance < BigInt(AMOUNT)) {
          await dzap.approve({
            chainId: 8453,
            signer: walletClient,
            sender: account.address,
            tokens: [{ address: USDC_BASE, amount: AMOUNT }],
            service: Services.zap,
            mode: ApprovalModes.PermitSingle,
          });
        }
        ```
      </Step>

      <Step title="Build & execute">
        Sign the Permit2 `PermitSingle`, attach the returned `permitData` to the request, build the route, and execute its steps in one `zap()` call.

        ```ts theme={null}
        const permit = await dzap.sign({
          chainId: 8453,
          sender: account.address,
          service: Services.zap,
          signer: walletClient,
          tokens: [{ address: USDC_BASE, amount: AMOUNT }],
          permitType: PermitTypes.PermitSingle,
        });

        const request = {
          srcChainId: 8453,
          destChainId: 8453,
          account: account.address,
          srcToken: USDC_BASE,
          destToken: POOL,
          amount: AMOUNT,
          recipient: account.address,
          refundee: account.address,
          slippage: 1,
          permitData: permit.tokens[0].permitData,
        };

        const route = await dzap.buildZapTxn(request);
        const result = await dzap.zap({ request, steps: route.steps, signer: walletClient });
        console.log(`Deposited: ${result.txnHash}`);
        ```

        <Note>
          `zap()` will build from the request itself if you omit `steps`. Passing the pre-built `route.steps` lets you show the user the resolved `output` and `fees` before they commit.
        </Note>
      </Step>

      <Step title="Status">
        Poll to a terminal state. Zap status is uppercase: `PENDING`, `COMPLETED`, `FAILED`, or `REFUNDED`.

        ```ts theme={null}
        const status = await dzap.getZapTxnStatus({
          chainId: 8453,
          txnHash: result.txnHash!,
        });

        console.log(status.status);   // PENDING -> COMPLETED
        ```

        <Note>
          `status.steps` breaks the zap down leg by leg (swap, bridge, deposit) so you can render per-step progress. See [Track zap status](/sdk/zap/status-tracking).
        </Note>
      </Step>
    </Steps>
  </Tab>

  <Tab title="Solana">
    <Steps>
      <Step title="Quote">
        Same call with Solana's chain ID (`7565164`) and base58 addresses. Depositing USDC into Jupiter Lend here.

        ```ts theme={null}
        const quote = await dzap.getZapQuote({
          srcChainId: 7565164,
          destChainId: 7565164,
          account,
          srcToken: USDC_SOL,
          destToken: JUP_LEND_USDC,   // the position you are entering
          amount: AMOUNT,
          recipient: account,
          refundee: account,
          slippage: 1,
        });

        console.log('Route:', quote.path.map((p) => p.protocol.name).join(' -> '));
        ```

        <Note>
          Set `destChainId` to an EVM chain and `destToken`/`recipient` to `0x` addresses to bridge into an EVM position from Solana. Keep `refundee` as your Solana address.
        </Note>
      </Step>

      <Step title="Build">
        No approval on Solana, go straight to build. The step data carries an array of base64 transactions and a `txnId`.

        ```ts theme={null}
        const route = await dzap.buildZapTxn({
          srcChainId: 7565164,
          destChainId: 7565164,
          account,
          srcToken: USDC_SOL,
          destToken: JUP_LEND_USDC,
          amount: AMOUNT,
          recipient: account,
          refundee: account,
          slippage: 1,
        });

        const step = route.steps[0].data;   // SVM step: { data: string[], txnId, isJitoTx }
        ```
      </Step>

      <Step title="Sign & send">
        Deserialize each base64 transaction, sign with your wallet, and broadcast. Jito-routed zaps go through the Jito block engine.

        ```ts theme={null}
        const txns = step.data.map((b64) =>
          VersionedTransaction.deserialize(Buffer.from(b64, 'base64')),
        );

        if (step.isJitoTx) {
          const signed = await wallet.signTransaction(txns[0]);
          await fetch('https://mainnet.block-engine.jito.wtf/api/v1/transactions', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              jsonrpc: '2.0',
              id: 1,
              method: 'sendTransaction',
              params: [Buffer.from(signed.serialize()).toString('base64'), { encoding: 'base64' }],
            }),
          });
        } else {
          const signedAll = await wallet.signAllTransactions(txns);
          for (const tx of signedAll) {
            const sig = await connection.sendRawTransaction(tx.serialize());
            await connection.confirmTransaction(sig, 'confirmed');
          }
        }
        ```
      </Step>

      <Step title="Status">
        Track it with the `txnId` from the build step.

        ```ts theme={null}
        const status = await dzap.getZapTxnStatus({
          chainId: 7565164,
          txnHash: step.txnId,
        });

        console.log(status.status);   // PENDING -> COMPLETED
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

## End-to-end

<Tabs>
  <Tab title="EVM">
    ```ts theme={null}
    import { DZapClient, Services, ApprovalModes, PermitTypes, TxnStatus } from '@dzapio/sdk';
    import { createWalletClient, http } from 'viem';
    import { base } from 'viem/chains';
    import { privateKeyToAccount } from 'viem/accounts';

    const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
    const walletClient = createWalletClient({ account, chain: base, transport: http() });
    const dzap = DZapClient.getInstance();

    const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
    const POOL = '0xd0b53D9277642d899DF5C87A3966A349A798F224';
    const AMOUNT = '500000000'; // 500 USDC

    // 1. Quote
    const quote = await dzap.getZapQuote({
      srcChainId: 8453,
      destChainId: 8453,
      account: account.address,
      srcToken: USDC_BASE,
      destToken: POOL,
      amount: AMOUNT,
      recipient: account.address,
      refundee: account.address,
      slippage: 1,
    });
    console.log('Route:', quote.path.map((p) => p.protocol.name).join(' -> '));

    // 2. Approve (Permit2, on-chain only if short)
    const { data } = await dzap.getAllowance({
      chainId: 8453,
      sender: account.address,
      tokens: [{ address: USDC_BASE, amount: AMOUNT }],
      service: Services.zap,
      mode: ApprovalModes.PermitSingle,
    });
    if (data[USDC_BASE].allowance < BigInt(AMOUNT)) {
      await dzap.approve({
        chainId: 8453,
        signer: walletClient,
        sender: account.address,
        tokens: [{ address: USDC_BASE, amount: AMOUNT }],
        service: Services.zap,
        mode: ApprovalModes.PermitSingle,
      });
    }

    // 3. Sign permit, build, execute
    const permit = await dzap.sign({
      chainId: 8453,
      sender: account.address,
      service: Services.zap,
      signer: walletClient,
      tokens: [{ address: USDC_BASE, amount: AMOUNT }],
      permitType: PermitTypes.PermitSingle,
    });
    const request = {
      srcChainId: 8453,
      destChainId: 8453,
      account: account.address,
      srcToken: USDC_BASE,
      destToken: POOL,
      amount: AMOUNT,
      recipient: account.address,
      refundee: account.address,
      slippage: 1,
      permitData: permit.tokens[0].permitData,
    };
    const route = await dzap.buildZapTxn(request);
    const result = await dzap.zap({ request, steps: route.steps, signer: walletClient });
    if (result.status !== TxnStatus.success) throw new Error(result.errorMsg ?? 'deposit failed');

    // 4. Status
    const status = await dzap.getZapTxnStatus({ chainId: 8453, txnHash: result.txnHash! });
    console.log('settled:', status.status);
    ```
  </Tab>

  <Tab title="Solana">
    ```ts theme={null}
    import { DZapClient } from '@dzapio/sdk';
    import { Connection, VersionedTransaction } from '@solana/web3.js';

    const dzap = DZapClient.getInstance();
    const connection = new Connection('https://api.mainnet-beta.solana.com');

    // your Solana wallet adapter (wallet-standard, Keypair, etc.)
    const account = wallet.publicKey.toBase58();
    const USDC_SOL = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
    const JUP_LEND_USDC = '9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D';
    const AMOUNT = '959349'; // 0.96 USDC

    // 1. Quote
    const quote = await dzap.getZapQuote({
      srcChainId: 7565164,
      destChainId: 7565164,
      account,
      srcToken: USDC_SOL,
      destToken: JUP_LEND_USDC,
      amount: AMOUNT,
      recipient: account,
      refundee: account,
      slippage: 1,
    });
    console.log('Route:', quote.path.map((p) => p.protocol.name).join(' -> '));

    // 2. Build
    const route = await dzap.buildZapTxn({
      srcChainId: 7565164,
      destChainId: 7565164,
      account,
      srcToken: USDC_SOL,
      destToken: JUP_LEND_USDC,
      amount: AMOUNT,
      recipient: account,
      refundee: account,
      slippage: 1,
    });
    const step = route.steps[0].data;

    // 3. Sign and send
    const txns = step.data.map((b64) =>
      VersionedTransaction.deserialize(Buffer.from(b64, 'base64')),
    );
    if (step.isJitoTx) {
      const signed = await wallet.signTransaction(txns[0]);
      await fetch('https://mainnet.block-engine.jito.wtf/api/v1/transactions', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          jsonrpc: '2.0',
          id: 1,
          method: 'sendTransaction',
          params: [Buffer.from(signed.serialize()).toString('base64'), { encoding: 'base64' }],
        }),
      });
    } else {
      const signedAll = await wallet.signAllTransactions(txns);
      for (const tx of signedAll) {
        const sig = await connection.sendRawTransaction(tx.serialize());
        await connection.confirmTransaction(sig, 'confirmed');
      }
    }

    // 4. Status
    const status = await dzap.getZapTxnStatus({ chainId: 7565164, txnHash: step.txnId });
    console.log('settled:', status.status);
    ```
  </Tab>
</Tabs>

## API usage

The zap API lives on `https://zap.dzap.io/v1`. Quote and build are `POST`; status is `GET`.

<CodeGroup>
  ```bash Quote theme={null}
  curl -X POST https://zap.dzap.io/v1/quote \
    -H "Content-Type: application/json" \
    -d '{
      "srcChainId": 8453,
      "destChainId": 8453,
      "account": "0xUser",
      "srcToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "destToken": "0xd0b53D9277642d899DF5C87A3966A349A798F224",
      "amount": "500000000",
      "recipient": "0xUser",
      "refundee": "0xUser",
      "slippage": 1
    }'
  ```

  ```bash Build theme={null}
  curl -X POST https://zap.dzap.io/v1/buildTx \
    -H "Content-Type: application/json" \
    -d '{
      "srcChainId": 8453,
      "destChainId": 8453,
      "account": "0xUser",
      "srcToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "destToken": "0xd0b53D9277642d899DF5C87A3966A349A798F224",
      "amount": "500000000",
      "recipient": "0xUser",
      "refundee": "0xUser",
      "slippage": 1,
      "permitData": "0x..."
    }'
  ```

  ```bash Status theme={null}
  curl "https://zap.dzap.io/v1/status?chainId=8453&txnHash=0xabc..."
  ```
</CodeGroup>

## Notes

* **Native source** (ETH, SOL): skip the approve and permit steps, there is nothing to authorize.
* **Cross-chain deposit**: set `destChainId` to a different chain. Settlement runs bridge-then-deposit and takes longer; give slippage room (1-2%).
* **Concentrated liquidity**: pass `poolDetails: { lowerTick, upperTick }`; omit for the router default.
* **Confirm the destination**: `destToken` must be a real pool or position address, not just a token.

Read more in [Fuse execution flow](/products/dzap-fuse/execution-flow).
