> ## 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.

# Execute Zap

> Execute complex multi-step zap transactions using the DZap SDK

> Execute complex DeFi operations by building transaction data and sending it with your wallet signer. The SDK handles transaction building, gas estimation, and execution automatically.

The `zap` method combines transaction building and execution into a single operation. This approach simplifies complex DeFi workflows while maintaining full control over transaction parameters.

<Note>
  Before executing zaps, tokens typically require approval to allow the DZap
  contracts to spend them on your behalf. Learn more about gas-optimized
  approval mechanisms in the [Approval Mechanisms](/sdk/approval-mechanisms)
  section.
</Note>

## Zap Execution

Execute a zap using the zap method:

```typescript theme={null}
import { DZapClient, ZapBuildTxnRequest, ZapTransactionStep } from "@dzapio/sdk";

const dZap = DZapClient.getInstance();

const zapRequest: ZapBuildTxnRequest = {
  srcChainId: 1,
  destChainId: 1,
  account: userAccount,
  srcToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
  destToken: "0x724dc807b04555b71ed48a6896b6F41593b8C637", // Protocol-specific token
  amount: "1000000000", // 1000 USDC
  recipient: userAccount,
  refundee: userAccount,
  slippage: 1.0,
};

// Option 1: Build and execute in one call

const result = await dZap.zap({
  request: zapRequest,
  signer: signer,
});

if (result.status === "success") {
  console.log("Zap executed successfully:", result.txnHash);
} else {
  console.error("Zap execution failed:", result.errorMsg);
}

// Option 2: Build steps first, then execute

let buildResponse: ZapBuildTxnResponse;
try {
  buildResponse = await dZap.buildZapTxn(zapRequest);
} catch (error) {
  console.error("Zap build failed:", error);
  return;
}

console.log("Build response:");
buildResponse.output.forEach((out) => {
  console.log(`Expected output: ${out.amount} ${out.asset.symbol}`);
});
console.log(`Number of executable steps: ${buildResponse.steps.length}`);
console.log(`Number of path steps: ${buildResponse.path.length}`);

// Execute with pre-built steps
const txnResponse = await dZap.zap({
  request: zapRequest,
  steps: buildResponse.steps,
  signer: signer,
});

if (txnResponse.status === "success") {
  console.log("Zap executed successfully:", txnResponse.txnHash);
} else {
  console.error("Zap execution failed:", txnResponse.errorMsg);
}
```

## Parameters

The `zap` function expects an object with these parameters:

### Required Parameters

| Parameter | Type                                   | Required | Description                                                            |
| --------- | -------------------------------------- | -------- | ---------------------------------------------------------------------- |
| `request` | ZapBuildTxnRequest \| ZapBundleRequest | yes      | The zap build request (single operation or bundled actions)            |
| `signer`  | Signer \| WalletClient                 | yes      | Ethers signer or viem wallet client for transaction execution          |
| `steps`   | ZapTransactionStep\[]                  | no       | Pre-built transaction steps (if not provided, will build from request) |

### ZapBuildTxnRequest Structure

| Parameter         | Type                           | Required | Description                                                   |
| ----------------- | ------------------------------ | -------- | ------------------------------------------------------------- |
| `srcChainId`      | number                         | yes      | Source chain ID                                               |
| `destChainId`     | number                         | yes      | Destination chain ID                                          |
| `account`         | string                         | yes      | User account address                                          |
| `srcToken`        | string                         | yes      | Source token address                                          |
| `destToken`       | string                         | yes      | Destination token/protocol address                            |
| `recipient`       | string                         | yes      | Address to receive the result                                 |
| `refundee`        | string                         | yes      | Address to receive refunds                                    |
| `slippage`        | number                         | yes      | Slippage tolerance percentage                                 |
| `amount`          | string                         | no       | Amount to zap (in token units); not needed for NFT operations |
| `permitData`      | string                         | no       | Pre-signed permit data for gasless approvals                  |
| `estimateGas`     | boolean                        | no       | Whether to estimate gas for the transaction                   |
| `positionDetails` | ZapRouteRequestPositionDetails | no       | Position-specific details for liquidity positions             |
| `poolDetails`     | ZapRouteRequestPoolDetails     | no       | Pool-specific details for liquidity pool operations           |
| `allowedBridges`  | string\[]                      | no       | Array of allowed bridge protocols for cross-chain operations  |
| `allowedDexes`    | string\[]                      | no       | Array of allowed DEX protocols for swapping operations        |
| `integrator`      | ZapIntegratorConfig            | no       | Integrator fee configuration for earning fees on transactions |

### Additional Type Definitions

```typescript theme={null}
type ZapRouteRequestPositionDetails = {
  nftId: string; // NFT ID for existing liquidity positions
};

type ZapRouteRequestPoolDetails = {
  lowerTick: number; // Lower tick for liquidity range
  upperTick: number; // Upper tick for liquidity range
  metadata?: unknown; // Additional pool metadata, sent in quotes response
};

type ZapIntegratorConfig = {
  id: string;     // Unique integrator identifier
  feeBps: number; // Fee in basis points (1 bps = 0.01%)
  wallet: string; // Wallet address to receive integrator fees
};
```

## Complete Example with Quotes and Approvals

Here's a full example that gets quotes, handles approvals, and executes a zap:

```typescript theme={null}
import { DZapClient, Services } from "@dzapio/sdk";
import {
  ZapQuoteRequest,
  ZapBuildTxnRequest,
  ApprovalModes,
  PermitTypes,
} from "@dzapio/sdk";

const dZap = DZapClient.getInstance();

// Step 1: Get zap quote
const quoteRequest: ZapQuoteRequest = {
  srcChainId: 42161, // Arbitrum
  destChainId: 42161,
  account: userAccount,
  srcToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
  destToken: "0x724dc807b04555b71ed48a6896b6F41593b8C637", // Aave USDC
  amount: "1000000", // 1 USDC
  recipient: userAccount,
  slippage: 1,
};

const zapQuote = await dZap.getZapQuote(quoteRequest);
console.log("Zap quote received");
console.log("Expected output:", zapQuote.output);
console.log("Path steps:", zapQuote.path);

// Step 2: Handle approvals
const tokens = [
  {
    address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    amount: "1000000",
  },
];

// zapQuote.approvalData is an array (one entry per token needing approval)
const spender = zapQuote.approvalData[0]?.approveTo;

// Check current allowances
const allowanceCheck = await dZap.getAllowance({
  chainId: 42161,
  sender: userAccount,
  spender,
  tokens: tokens,
  service: Services.zap,
  mode: ApprovalModes.AutoPermit, // Automatically selects optimal approval method
});

console.log("Allowance check:", allowanceCheck.data);

let permitData: string | undefined;

// allowanceCheck.data is keyed by token address: { allowance: bigint, type: 'dzap' | 'permit2' | 'eip2612' }
const isApprovalNeeded = tokens.some((t) => {
  const entry = allowanceCheck.data[t.address];
  return entry && entry.type !== "eip2612" && entry.allowance < BigInt(t.amount);
});

const isSignatureNeeded = tokens.some(
  (t) => allowanceCheck.data[t.address]?.type !== "dzap"
);

if (isApprovalNeeded) {
  await dZap.approve({
    chainId: 42161,
    signer: signer,
    sender: userAccount,
    tokens: tokens,
    service: Services.zap,
    mode: ApprovalModes.AutoPermit, // Uses optimal approval strategy
    approvalTxnCallback: async ({ txnDetails, address }) => {
      console.log(`Approval for ${address}:`, txnDetails);
    },
  });

  console.log("Approvals completed");
}

// Handle permit signatures if possible (gasless)
if (isSignatureNeeded) {
  const signatures = await dZap.sign({
    chainId: 42161,
    sender: userAccount,
    tokens: tokens,
    signer: signer,
    spender,
    service: Services.zap,
    permitType: PermitTypes.AutoPermit, // Automatically selects optimal permit type
  });
  if (signatures.status === "success" && "tokens" in signatures) {
    permitData = signatures.tokens?.[0]?.permitData;
  }
  console.log("Permits signed");
}

// Step 3: Build zap request
const request: ZapBuildTxnRequest = {
  srcChainId: 42161,
  destChainId: 42161,
  account: userAccount,
  srcToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destToken: "0x724dc807b04555b71ed48a6896b6F41593b8C637",
  amount: "1000000",
  recipient: userAccount,
  refundee: userAccount,
  slippage: 1,
  permitData, // Include permit data if available
  integrator: {
    id: "my-integration-id",
    feeBps: 10, // 0.1% fee
    wallet: "0x1234567890123456789012345678901234567890"
  }
};

// Step 4: Execute zap
const zapResult = await dZap.zap({
  request: request,
  signer: signer,
});

if (zapResult.status === "success") {
  console.log("Zap completed successfully!");
  console.log("Transaction hash:", zapResult.txnHash);
} else {
  console.error("Zap failed:", zapResult.errorMsg);
}
```

## Best Practices

1. **Always get quotes first** to understand the expected outcome and fees
2. **Validate balances** before execution to ensure sufficient funds
3. **Check allowances** and execute approvals/permits if needed
4. **Implement proper error handling** with retry logic for failed zaps
5. **Use appropriate slippage settings** based on market conditions and complexity
6. **Monitor transaction status** for zap completion and position updates

## Next Steps

* [Monitor Zap Status](/sdk/zap/status-tracking) - Track execution progress and final positions

<Warning>
  Always ensure users have sufficient balance for both the zap amount and gas
  fees before execution. Zap operations can be complex and may require multiple
  transactions.
</Warning>

<Tip>
  Use the `buildZapTxn` method first to understand the steps involved before
  executing. This helps with user experience and debugging complex zap
  operations.
</Tip>
