Skip to main content

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.

Zap lets users go from any token into a DeFi position (lending, staking, LP, etc.) in a single transaction on Solana. Key differences from EVM:
  • No token approvals needed — Solana SPL tokens don’t require a separate approval step
  • Transactions are base64-encoded Solana transactions, not EVM calldata
  • Some transactions are routed through Jito for MEV protection
  • Multiple transactions in one operation use Solana’s signAllTransactions

Chain ID

Use 7565164 as both srcChainId and destChainId for Solana.

Step 1 — Get Quote

Use getZapQuote to fetch the best route for your zap.
import { DZapClient } from "@dzapio/sdk";

const dZap = DZapClient.getInstance();

const zapQuote = await dZap.getZapQuote({
  srcChainId: 7565164,      // Solana
  destChainId: 7565164,     // Same chain for zap
  account: "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
  srcToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",  // USDC
  destToken: "9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D",  // Jupiter Lend USDC
  amount: "959349",         // 0.96 USDC (6 decimals)
  recipient: "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
  refundee: "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
  slippage: 1,              // 1% slippage
});

console.log("Zap route:", zapQuote.data.path.map((p) => p.protocol.name).join(" → "));

Key Response Fields

FieldDescription
approvalDataAlways empty [] on Solana — no approvals needed
pathSteps the zap will execute (swap, deposit, stake, etc.)
path[].actionType of operation
path[].protocolProtocol used for this step
path[].input / outputToken amounts and USD values for each step
path[].estimatedDurationEstimated time in seconds

Step 2 — Execute Zap

Use zap to build and execute the transaction. The SDK returns base64-encoded Solana transactions that you sign and send.
const zapResult = await dZap.zap({
  request: {
    srcChainId: 7565164,
    destChainId: 7565164,
    account: "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
    srcToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    destToken: "9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D",
    amount: "959349",
    recipient: "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
    refundee: "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
    slippage: 1,
  },
  signer: walletAdapter,    // Solana wallet adapter
});

// zapResult contains steps with Solana transactions to sign
const step = zapResult.steps[0].data;

Key Response Fields

FieldDescription
typeAlways "svm" for Solana transactions
txnIdDZap’s internal transaction ID — use this for status tracking
dataArray of base64-encoded Solana transactions to sign and send
isJitoTxtrue if the transaction must be sent via Jito
estimatedGasEstimated compute units
data may contain more than one transaction. Each must be signed and sent in order.

Step 3 — Sign and Send

The signing and sending method depends on two things: how many transactions there are, and whether isJitoTx is true.

Single transaction (non-Jito)

import { Connection, VersionedTransaction } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");
const txBase64 = step.data[0];
const txBuffer = Buffer.from(txBase64, "base64");

// Deserialize
const transaction = VersionedTransaction.deserialize(txBuffer);

// Sign
const signedTx = await wallet.signTransaction(transaction);

// Send via standard RPC
const signature = await connection.sendRawTransaction(signedTx.serialize());
await connection.confirmTransaction(signature, "confirmed");

console.log("Transaction signature:", signature);

Multiple transactions

If step.data contains more than one transaction, sign all of them at once using signAllTransactions.
const txBuffers = step.data.map((b64) =>
  VersionedTransaction.deserialize(Buffer.from(b64, "base64"))
);

// Sign all in one wallet prompt
const signedTxs = await wallet.signAllTransactions(txBuffers);

// Send each in order
for (const signedTx of signedTxs) {
  const sig = await connection.sendRawTransaction(signedTx.serialize());
  await connection.confirmTransaction(sig, "confirmed");
  console.log("Sent:", sig);
}

When isJitoTx: true

Jito transactions need to go through a Jito block engine. The SDK’s zap method handles this automatically — it returns the transaction ready for Jito submission. Sign and send via your Jito provider.
const txBase64 = step.data[0];
const txBuffer = Buffer.from(txBase64, "base64");
const transaction = VersionedTransaction.deserialize(txBuffer);
const signedTx = await wallet.signTransaction(transaction);

// Submit to Jito block engine
const jitoResponse = 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(signedTx.serialize()).toString("base64"),
        { encoding: "base64" },
      ],
    }),
  }
);

Broadcast decision summary

ConditionHow to send
isJitoTx: false, single txconnection.sendRawTransaction
isJitoTx: false, multiple txssignAllTransactions → send each in order
isJitoTx: trueYour own Jito provider

Step 4 — Track Status

Use getZapTxnStatus to check the zap status using the txnId from the zap result.
const status = await dZap.getZapTxnStatus({
  chainId: 7565164,
  txnHash: step.txnId,
});

console.log("Status:", status.status);
// "PENDING" | "COMPLETED" | "FAILED" | "REFUNDED"
For operations that may take a few seconds to confirm, poll until you reach a terminal state.
async function waitForZap(txnId: string, timeoutMs = 60_000) {
  const interval = 5_000; // 5 seconds — Solana confirms fast
  const start = Date.now();

  while (Date.now() - start < timeoutMs) {
    const status = await dZap.getZapTxnStatus({
      chainId: 7565164,
      txnHash: txnId,
    });

    if (status.status === "COMPLETED") return status;
    if (status.status === "FAILED") throw new Error("Zap failed");
    if (status.status === "REFUNDED") {
      console.log("Zap refunded — funds returned");
      return status;
    }

    await new Promise((r) => setTimeout(r, interval));
  }

  throw new Error("Zap timed out");
}

Status values

StatusDescription
PENDINGTransaction submitted, waiting for confirmation
COMPLETEDZap executed successfully
FAILEDZap failed — check steps for which step errored
REFUNDEDZap could not complete, funds returned to refundee

API Reference

The SDK wraps these endpoints:
SDK MethodAPI EndpointPurpose
getZapQuotePOST /v1/quoteGet best route and pricing
zapPOST /v1/buildTxBuild and return transactions
getZapTxnStatusGET /v1/statusTrack transaction status

Full Example

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");

const walletAddress = wallet.publicKey.toString();

// 1. Get quote
const zapQuote = await dZap.getZapQuote({
  srcChainId: 7565164,
  destChainId: 7565164,
  account: walletAddress,
  srcToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  destToken: "9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D",
  amount: "959349",
  recipient: walletAddress,
  refundee: walletAddress,
  slippage: 1,
});

console.log("Route:", zapQuote.data.path.map((p) => p.protocol.name).join(" → "));

// 2. Execute zap (builds transactions)
const zapResult = await dZap.zap({
  request: {
    srcChainId: 7565164,
    destChainId: 7565164,
    account: walletAddress,
    srcToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    destToken: "9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D",
    amount: "959349",
    recipient: walletAddress,
    refundee: walletAddress,
    slippage: 1,
  },
  signer: wallet,
});

const step = zapResult.steps[0].data;

// 3. Sign and send
const txBuffers = step.data.map((b64) =>
  VersionedTransaction.deserialize(Buffer.from(b64, "base64"))
);

if (step.isJitoTx) {
  // Submit via Jito
  const signed = await wallet.signTransaction(txBuffers[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 if (txBuffers.length === 1) {
  const signed = await wallet.signTransaction(txBuffers[0]);
  const sig = await connection.sendRawTransaction(signed.serialize());
  await connection.confirmTransaction(sig, "confirmed");
  console.log("Signature:", sig);
} else {
  const signedAll = await wallet.signAllTransactions(txBuffers);
  for (const tx of signedAll) {
    const sig = await connection.sendRawTransaction(tx.serialize());
    await connection.confirmTransaction(sig, "confirmed");
    console.log("Signature:", sig);
  }
}

// 4. Track status
const finalStatus = await waitForZap(step.txnId);
console.log("Zap status:", finalStatus.status);