npm package: @krystaldefi/zap
Description: A powerful React component for zapping into liquidity pools on Uniswap V3 and compatible platforms. KrystalZap enables users to swap tokens and add liquidity in a single transaction.
Latest version: 0.0.6

# KrystalZap Component

A powerful React component for zapping into liquidity pools on Uniswap V3 and compatible platforms. KrystalZap enables users to swap tokens and add liquidity in a single transaction.

![KrystalZap Component](https://github.com/huy23121994/krystal-zap-coin/raw/main/src/assets/images/krystal.svg)

## Installation

```bash
# Using npm
npm install krystal-zapp

# Using yarn
yarn add krystal-zapp

# Using pnpm
pnpm add krystal-zapp

# Using bun
bun add krystal-zapp
```

## Features

- **Single-Transaction Zapping:** Swap tokens and add liquidity to Uniswap V3 pools in one transaction
- **Multi-Chain Support:** Works across multiple EVM-compatible blockchains
- **Protocol Support:** Compatible with Uniswap V3 and similar DEXs
- **Customizable Price Range:** Set custom price ranges for concentrated liquidity positions
- **Slippage Controls:** Configure separate slippage tolerances for swaps and liquidity provision
- **Theming:** Light and dark mode support with customizable color schemes
- **Token Selection:** Seamless token selection from user wallet balances

## Basic Usage

```tsx
import { KrystalZap } from "krystal-zapp";

// In your component
const MyComponent = () => {
  const handleTxDataReady = (txData) => {
    console.log("Transaction data ready:", txData);
    // Use this data to execute the transaction with your web3 provider
  };

  return (
    <KrystalZap
      platform="uniswapv3"
      chainId={1}
      poolAddress="0x99ac8ca7087fa4a2a1fb6357269965a2014abc35"
      userAddress="0x..."
      onTxDataReady={handleTxDataReady}
      onError={(error) => console.error(error)}
      onLoading={(loading) => console.log("Loading:", loading)}
    />
  );
};
```

## Props

| Prop                | Type                         | Required | Default   | Description                                         |
| ------------------- | ---------------------------- | -------- | --------- | --------------------------------------------------- |
| `platform`          | `string`                     | Yes      | -         | DEX platform ID (e.g., 'uniswapv3')                 |
| `chainId`           | `number`                     | Yes      | -         | Blockchain network ID                               |
| `poolAddress`       | `string`                     | Yes      | -         | Address of the liquidity pool                       |
| `userAddress`       | `string`                     | Yes      | -         | User wallet address                                 |
| `swapSlippage`      | `number`                     | No       | `0.01`    | Slippage tolerance for token swap (1% = 0.01)       |
| `liquiditySlippage` | `number`                     | No       | `0.02`    | Slippage tolerance for adding liquidity (2% = 0.02) |
| `onTxDataReady`     | `(txObj: TxData) => void`    | Yes      | -         | Callback when transaction data is ready             |
| `onError`           | `(error: string) => void`    | Yes      | -         | Callback when an error occurs                       |
| `onLoading`         | `(loading: boolean) => void` | Yes      | -         | Callback for loading state changes                  |
| `poolDetail`        | `PoolDetailType`             | No       | -         | Pre-fetched pool details                            |
| `borderRadius`      | `string`                     | No       | `'12px'`  | Border radius for the component container           |
| `theme`             | `'light' \| 'dark'`          | No       | `'light'` | Component theme                                     |
| `colorScheme`       | `ColorScheme`                | No       | -         | Custom color scheme for theming                     |

## Advanced Configuration

### API Requirements

The component requires access to Krystal API endpoints for fetching pool data, transaction building, and token information. Ensure your application can reach these endpoints:

- Pool details: `/all/v2/lp_explorer/pool_detail`
- Transaction building: `/all/v1/lp_transaction/swap_and_mint`
- Chain configurations: `https://api.krystal.app/all/v1/lp_explorer/configs`

### Supported Chains and Platforms

To get the list of supported chains and protocols:

```tsx
// Fetch supported chains and protocols
const fetchChainConfig = async () => {
  const response = await fetch(
    "https://api.krystal.app/all/v1/lp_explorer/configs"
  );
  const data = await response.json();
  return data.data;
};
```

### Complete Example with Transaction Execution

```tsx
import React, { useState } from "react";
import { KrystalZap } from "krystal-zapp";
import { useSendTransaction, useWaitForTransactionReceipt } from "wagmi";

const ZapComponent = () => {
  const [txData, setTxData] = useState(null);
  const { sendTransactionAsync } = useSendTransaction();
  const [hash, setHash] = useState();
  const { isSuccess: isConfirmed } = useWaitForTransactionReceipt({ hash });
  const [isExecuting, setIsExecuting] = useState(false);
  const [theme, setTheme] = useState("light");

  const handleTxDataReady = (txObj) => {
    console.log("Transaction object:", txObj);
    setTxData(txObj);
  };

  const executeZap = async () => {
    if (!txData) return;

    setIsExecuting(true);
    try {
      const result = await sendTransactionAsync({
        to: txData.to,
        data: txData.data,
        value: BigInt(txData.value || 0),
        chainId: txData.chainId,
      });

      setHash(result);

      // Handle confirmation in a useEffect
      if (isConfirmed) {
        console.log("Transaction confirmed!");
        setIsExecuting(false);
      }
    } catch (error) {
      console.error("Transaction error:", error);
      setIsExecuting(false);
    }
  };

  return (
    <div>
      <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
        Toggle Theme
      </button>

      <KrystalZap
        platform="uniswapv3"
        chainId={1}
        poolAddress="0x99ac8ca7087fa4a2a1fb6357269965a2014abc35"
        userAddress="0x..."
        onTxDataReady={handleTxDataReady}
        onError={(error) => console.error("Zap error:", error)}
        onLoading={(loading) => console.log("Loading:", loading)}
        theme={theme}
        colorScheme={{
          dark: {
            "--card": "230 15% 20%",
            "--card-foreground": "0 0% 98%",
          },
          light: {
            "--card": "0 0% 100%",
            "--card-foreground": "240 10% 15%",
          },
        }}
      />

      <button onClick={executeZap} disabled={!txData || isExecuting}>
        {isExecuting ? "Processing..." : "Execute Zap"}
      </button>
    </div>
  );
};
```

## Pool Detail Type

```typescript
interface PoolDetailType {
  token0: {
    symbol: string;
    address: string;
    logo: string;
    decimals: string;
    balance?: string;
    usdPrice?: string;
  };
  token1: {
    symbol: string;
    address: string;
    logo: string;
    decimals: string;
    balance?: string;
    usdPrice?: string;
  };
  sqrtPrice: string;
  tickSpacing: string;
  tvlUsd?: string;
  volumeUsd24h?: string;
  feeUsd24h?: string;
  apr24h?: number;
  protocolLogo?: string;
  feeTier?: number;
  chainId?: number;
  chainLogo?: string;
  protocolName?: string;
}
```

## Transaction Data Type

```typescript
interface TxData {
  to: string;
  data: string;
  value?: string;
  chainId: number;
}
```

## Color Scheme Customization

The KrystalZap component supports custom color schemes for both light and dark modes:

```typescript
interface ColorScheme {
  light?: Record<string, string>;
  dark?: Record<string, string>;
}
```

Example usage:

```tsx
<KrystalZap
  // ... other props
  theme="dark"
  colorScheme={{
    dark: {
      "--card": "230 15% 20%",
      "--card-foreground": "0 0% 98%",
      "--secondary": "220 15% 30%",
    },
    light: {
      "--card": "0 0% 100%",
      "--card-foreground": "240 10% 15%",
      "--secondary": "240 5% 95%",
    },
  }}
/>
```

The component uses CSS variables compatible with Tailwind CSS. Common variables you can customize include:

- `--card`: Background color for card components
- `--card-foreground`: Text color for card components
- `--secondary`: Secondary/accent color
- `--primary`: Primary color
- `--border`: Border color

## Dependencies

KrystalZap requires the following peer dependencies:

- React (^17 or ^18.3.1 or ^19.0.0)
- React DOM (^17 or ^18.3.1 or ^19.0.0)
- Tailwind CSS (for styling)

## License

MIT

## Support

For any issues or questions, please reach out to the Krystal team or open an issue on our GitHub repository.