Skip to main content
A deposit, or Zap In, turns a token you hold into a DeFi position: a liquidity pool, a lending market or a vault. DZap swaps into what the position needs, bridges first when the position is on another chain, and deposits. You name the position by its address in destToken. Pick EVM or Solana in any tab, and the rest of the page switches with it.

Setup

This example deposits 100 USDC into the Uniswap v3 WETH/USDC pool on Base, signing with walletClient, a viem wallet client built from the private key in PRIVATE_KEY. Amounts are strings in the token’s smallest unit, and no API key is needed.
Find position addresses for destToken with getZapPools, and the providers each chain supports with getZapChains.

Steps

1

Quote

getZapQuote returns the route into the position without touching your wallet. quote.path lists each step of the route, and quote.output is the position you’ll hold, with its value in USD. To deposit on another chain, set destChainId to it; the route then bridges first.
On a concentrated-liquidity pool like this one, DZap picks a narrow range around the current price. To set your own, add poolDetails: { lowerTick, upperTick } to the request; getZapPoolDetails returns the current tick in slot0.tick.
2

Approve

The zap contract needs permission to move your USDC. Its address is the quote’s approvalData[0].approveTo: pass it as spender, so the allowance goes to the contract that will spend it. getAllowance reads the current allowance, and if it’s too low, approve() approves exactly the deposit amount. Native ETH has nothing to approve, and its approvalData is empty.
3

Build & send

buildZapTxn builds the deposit and checks it against your wallet, so it throws if the deposit would fail. zap() then signs and sends it. The swap and the deposit happen in that one transaction: the position goes to recipient, and whatever doesn’t fit into it comes back to you.
4

Status

Poll getZapTxnStatus with the transaction hash until the status leaves PENDING; COMPLETED means every step finished, and status.steps reports each one. DZap answers 404 until it sees the transaction, and 429 once its rate limit is used up, so the catch skips only those two and rethrows anything else. The loop gives up after 5 minutes (raise it if the route bridges), and the check after it throws unless the status is COMPLETED.

End-to-end

API usage

The same flow over REST, on the zap API at https://zap.dzap.io/v1. Each response wraps its result in data.
Approve the quote’s approvalData[0].approveTo for the USDC before building, since the build checks the allowance. Then send the build’s steps[0].data (callTo, callData, value) from your wallet. Full reference: Quote, Build Tx, Status.

What can go wrong

  • buildZapTxn throws Execution reverted: the build checks the deposit against your wallet, so the USDC and the allowance must be in place first. The error response’s message has the revert reason.
  • Only a swap, no deposit: destToken was a plain token rather than a position. quote.path ends with a deposit step when it’s right.
  • Some of the USDC comes back: the deposit takes only what fits the position’s price range when it executes and returns the rest. The default range is narrow, so a small price move can leave a large share behind; a wider poolDetails range keeps more of it in the position.
  • Several Solana transactions: some Solana routes return two or more transactions with isJitoTx: true, which have to land together as a Jito bundle. The SDK can’t submit bundles yet, so the code here covers single-transaction routes like Jupiter Lend.
  • Blockhash not found on Solana: the transaction expired before you sent it. Build and sign again right away.
  • Not completed: no status: DZap never returned a status, usually because the transaction failed on-chain. On Solana, query by the signature; the build’s txnId returns Failed to process transaction.
  • HTTP 429: the zap API allows 60 requests a minute.
See Error codes for the full catalog.
Last modified on October 1, 2026