Skip to main content
A migrate exits one position and enters another in a single zap, a withdraw and a deposit in one. srcToken is the position you’re leaving and destToken the one you’re entering; DZap swaps in between, and bridges when the new position is on another chain, EVM or Solana. Pick EVM or Solana in any tab, and the rest of the page switches with it.

Setup

This example moves a Uniswap position on Base into the Uniswap v3 WETH/USDC pool, signing with walletClient, a viem wallet client built from the private key in PRIVATE_KEY. No API key is needed.
getZapChains lists the provider IDs each chain supports, and getZapPools lists the positions you can enter.

Steps

1

Find the position

getZapPositions lists your open positions with one provider on one chain. Uniswap positions are NFTs, so each carries nftDetails: the NFT’s id and its manager contract.
2

Quote

getZapQuote returns the route and the new position you’ll hold. srcToken is the old position, positionDetails.nftId names its NFT, and destToken is the new position; with no amount, the whole position moves. To enter a position on another chain, set destChainId to it and recipient to your address there; the route then bridges in between.
The new position is in a concentrated-liquidity pool, so DZap picks a narrow price range for it. Add poolDetails: { lowerTick, upperTick } to the request to set your own, as on the deposit page.
3

Approve

The zap contract, the quote’s approvalData[0].approveTo, needs permission to move the old position’s NFT. approve() handles NFTs too: pass the NFT’s manager as the token and its id as the amount.
Leaving an ERC-20 position, such as a vault share or a lending token? Leave out positionDetails, set amount, and approve the token with getAllowance and approve() as on the deposit page.
4

Build & send

buildZapTxn builds the move and checks it against your wallet, so it throws if it would fail. zap() then signs and sends it: one transaction exits the old position, swaps, and opens the new one for recipient.
5

Status

Poll getZapTxnStatus with the transaction hash until the status leaves PENDING; COMPLETED means every step finished. status.steps reports each leg: the exit, the swap and the deposit, plus the bridge on a cross-chain move. 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 old position’s NFT for the quote’s approvalData[0].approveTo and wait for it to confirm before building, since the build checks it. Then send the build’s steps[0].data (callTo, callData, value) from your wallet. Full reference: Positions, Quote, Build Tx, Status.

What can go wrong

  • NFT id not found: the old position is an NFT and the request has no positionDetails.nftId.
  • Amount not found or Token amount not found: the old position is a token and the request has no amount.
  • Route is not supported: DZap has no route between the two positions.
  • buildZapTxn throws Execution reverted: the build checks the move against your wallet, so the old position’s approval must be confirmed first. The error response’s message has the revert reason.
  • positions is empty: the wallet has no open position with that provider on that chain. getZapChains lists the provider IDs each chain supports.
  • 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 this one.
  • Blockhash not found or ComputationalBudgetExceeded on Solana: the transaction expired before you sent it, or needed more compute than the build allowed. 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