npm package: @fnzero/pancakeswap-sdk
Description: TypeScript SDK for PancakeSwap V2 on BSC - Trading, Liquidity Management, and Event Monitoring with Performance Optimizations
Author: fnzero
Latest version: 1.1.2

<div align="center">
    <h1>🥞 PancakeSwap V2 SDK</h1>
    <h3><em>A comprehensive TypeScript SDK for seamless PancakeSwap V2 trading on BSC</em></h3>
</div>

<p align="center">
    <strong>Integrate PancakeSwap V2 trading, liquidity management, and event monitoring into your applications with powerful tools and unified interfaces.</strong>
</p>

<p align="center">
    <a href="https://www.npmjs.com/package/pancakeswap-sdk">
        <img src="https://img.shields.io/npm/v/pancakeswap-sdk.svg" alt="npm version">
    </a>
    <a href="https://www.npmjs.com/package/pancakeswap-sdk">
        <img src="https://img.shields.io/npm/dm/pancakeswap-sdk.svg" alt="npm downloads">
    </a>
    <a href="https://github.com/0xfnzero/pancakeswap-sdk/blob/main/LICENSE">
        <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
    </a>
    <a href="https://github.com/0xfnzero/pancakeswap-sdk">
        <img src="https://img.shields.io/github/stars/0xfnzero/pancakeswap-sdk?style=social" alt="GitHub stars">
    </a>
    <a href="https://github.com/0xfnzero/pancakeswap-sdk/network">
        <img src="https://img.shields.io/github/forks/0xfnzero/pancakeswap-sdk?style=social" alt="GitHub forks">
    </a>
</p>

<p align="center">
    <img src="https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript">
    <img src="https://img.shields.io/badge/BSC-F0B90B?style=for-the-badge&logo=binance&logoColor=white" alt="Binance Smart Chain">
    <img src="https://img.shields.io/badge/PancakeSwap-633001?style=for-the-badge&logo=pancakeswap&logoColor=white" alt="PancakeSwap">
    <img src="https://img.shields.io/badge/DEX-4B8BBE?style=for-the-badge&logo=bitcoin&logoColor=white" alt="DEX Trading">
</p>

<p align="center">
    <a href="https://github.com/0xfnzero/pancakeswap-sdk/blob/main/README_CN.md">中文</a> |
    <a href="https://github.com/0xfnzero/pancakeswap-sdk/blob/main/README.md">English</a> |
    <a href="https://fnzero.dev/">Website</a> |
    <a href="https://t.me/fnzero_group">Telegram</a> |
    <a href="https://discord.gg/vuazbGkqQE">Discord</a>
</p>

---

## 🚀 Features

- 🔄 **Token Swaps** - All swap variants with slippage protection
- 💧 **Liquidity Management** - Add/remove liquidity with precise calculations
- 📊 **Price Calculator** - Advanced price quotes and impact analysis
- 📡 **WebSocket Events** - Real-time event monitoring (optional)
- 🧮 **AMM Math Utilities** - Built-in constant product formula calculations
- 🔍 **Query Functions** - Comprehensive price, reserve, and token info queries
- ⛽ **Gas Management** - Flexible gas configuration (legacy & EIP-1559)
- 📜 **Historical Events** - Query past events with block range filters
- 🛡️ **Type Safety** - Full TypeScript support with comprehensive types
- 🧰 **Utility Functions** - Amount conversion, validation, and formatting helpers
- ⚡ **Performance Optimized** - Allowance caching and provider sharing for 50-70% faster operations
- 🎯 **Unified SDK Entry** - Single entry point with automatic approval management

## 📦 Installation

```bash
npm install @fnzero/pancakeswap-sdk
# or
yarn add @fnzero/pancakeswap-sdk
# or
pnpm add @fnzero/pancakeswap-sdk
```

## 🎯 Quick Start

```typescript
import { PancakeSwapSDK } from '@fnzero/pancakeswap-sdk';
import { ethers } from 'ethers';

// Initialize SDK with single entry point
const sdk = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  wssUrl: 'wss://bsc-rpc.publicnode.com', // Optional: for real-time events
  privateKey: 'YOUR_PRIVATE_KEY', // Optional: required for trading
});

// Swap 0.1 BNB for tokens with slippage tolerance
const bnbAmount = ethers.parseEther('0.1');
await sdk.swapExactETHForTokens(
  bnbAmount,
  [sdk.WBNB, TOKEN_ADDRESS],
  1  // 1% slippage tolerance
);

// Monitor real-time price changes
const pair = sdk.getPair(PAIR_ADDRESS);
pair.onSwap((event) => console.log('Swap detected!', event));
```

## 📚 Core Features

### 1️⃣ Unified SDK Entry Point

```typescript
import { PancakeSwapSDK } from '@fnzero/pancakeswap-sdk';

// Single initialization for all features
const sdk = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  wssUrl: 'wss://bsc-rpc.publicnode.com', // Optional
  privateKey: 'YOUR_PRIVATE_KEY', // Optional
});

// All features available from one instance
console.log('Wallet:', sdk.getWalletAddress());
console.log('WBNB:', sdk.WBNB);
console.log('Router:', sdk.ROUTER);
```

### 2️⃣ Token Swaps (With Slippage Protection)

```typescript
import { ethers } from 'ethers';

// BNB → Token
const bnbAmount = ethers.parseEther('0.1');
await sdk.swapExactETHForTokens(
  bnbAmount,
  [sdk.WBNB, TOKEN_ADDRESS],
  1 // 1% slippage tolerance
);

// Token → BNB
const tokenAmount = ethers.parseUnits('100', 18);
await sdk.swapExactTokensForETH(
  TOKEN_ADDRESS,
  tokenAmount,
  1 // 1% slippage tolerance
);

// Token → Token (auto routing via WBNB if needed)
const swapAmount = ethers.parseUnits('100', 18);
await sdk.swapExactTokensForTokens(
  TOKEN_A,
  TOKEN_B,
  swapAmount,
  0.5 // 0.5% slippage tolerance
);
```

### 3️⃣ Liquidity Management

```typescript
import { ethers } from 'ethers';

// Add Token + Token liquidity
const amountA = ethers.parseUnits('100', 18);
const amountB = ethers.parseUnits('100', 18);
await sdk.addLiquidity(
  TOKEN_A,
  TOKEN_B,
  amountA,
  amountB,
  1 // 1% slippage tolerance
);

// Add Token + BNB liquidity
const tokenAmount = ethers.parseUnits('100', 18);
const bnbAmount = ethers.parseEther('0.1');
await sdk.addLiquidityETH(
  TOKEN,
  tokenAmount,
  bnbAmount,
  1 // 1% slippage tolerance
);

// Remove liquidity
const lpAmount = ethers.parseUnits('1', 18);
await sdk.removeLiquidity(
  TOKEN_A,
  TOKEN_B,
  lpAmount,
  1 // 1% slippage tolerance
);
```

### 4️⃣ Advanced Price Calculator

```typescript
// Get pair instance
const pair = sdk.getPair(PAIR_ADDRESS);

// Get price quote with slippage
const quote = await pair.quoteSwapWithSlippage(
  BigInt('100000000000000000'), // 0.1 BNB in wei
  1, // 1% slippage
  18, 18 // Decimals
);

console.log(`Expected: ${quote.expectedAmount}`);
console.log(`Min Output: ${quote.minAmount}`);
console.log(`Price Impact: ${quote.priceImpact}%`);

// Get current spot price
const price = await pair.getSpotPrice(18, 18);
console.log(`Spot Price: ${price}`);
```

### 5️⃣ Real-Time WebSocket Events

```typescript
// Enable WebSocket in SDK config
const sdk = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  wssUrl: 'wss://bsc-rpc.publicnode.com', // ✅ Enable real-time events
  privateKey: 'YOUR_PRIVATE_KEY',
});

// Get pair and subscribe to events
const pair = sdk.getPair(PAIR_ADDRESS);

// Real-time swap events
const swapId = pair.onSwap((event) => {
  console.log('🔄 Swap detected!');
  console.log(`Amount In: ${event.amount0In}`);
  console.log(`Amount Out: ${event.amount1Out}`);
});

// Real-time liquidity events
const mintId = pair.onMint((event) => {
  console.log('💧 Liquidity added!');
  console.log(`Amount0: ${event.amount0}`);
  console.log(`Amount1: ${event.amount1}`);
});

// Unsubscribe when done
pair.off(swapId);
pair.off(mintId);

// Or cleanup all resources
sdk.cleanup();
```

```typescript
// Balance queries
const bnbBalance = await sdk.getBNBBalance();
const tokenBalance = await sdk.getTokenBalance(TOKEN_ADDRESS);

// Wallet address
const wallet = sdk.getWalletAddress();

// Pair queries
const pairAddress = await sdk.getPairAddress(TOKEN_A, TOKEN_B);
const pair = await sdk.getPairForTokens(TOKEN_A, TOKEN_B);

// Factory queries
const totalPairs = await sdk.getAllPairsLength();
const pairAtIndex = await sdk.getPairAtIndex(0);

// Price quotes
const amounts = await sdk.getAmountsOut('100', [TOKEN_A, TOKEN_B]);
```

### 7️⃣ Utility Functions

```typescript
import {
  parseBNB,
  parseTokenAmount,
  formatBNB,
  formatTokenAmount,
  calculatePriceChange,
  calculatePriceImpact,
  getAmountOut,
  isValidAddress,
} from '@fnzero/pancakeswap-sdk';

// Amount conversion
const bnbWei = parseBNB('1.5');              // 1.5 BNB to wei
const tokenWei = parseTokenAmount('100', 18); // 100 tokens to wei
const bnbStr = formatBNB(bnbWei);            // wei to BNB string
const tokenStr = formatTokenAmount(tokenWei, 18); // wei to token string

// Price calculations
const priceChange = calculatePriceChange(oldPrice, newPrice);
const impact = calculatePriceImpact(reserve, amountIn);

// AMM math
const amountOut = getAmountOut(amountIn, reserveIn, reserveOut);

// Validation
const valid = isValidAddress('0x...');
```

## ⚡ Performance Optimizations

The SDK includes built-in performance optimizations for production use:

### Allowance Caching
- **50-70% faster** repeated swap operations
- Automatic caching of token allowances with 5-minute TTL
- Eliminates redundant blockchain queries
- First swap: ~7s, subsequent swaps: ~3.5s

```typescript
// Automatic allowance management - no manual approval needed!
await sdk.swapExactTokensForTokens(TOKEN_A, TOKEN_B, amount, 1);
// SDK checks cache first, only approves if needed
```

### Provider Sharing
- **33% memory reduction** through shared provider instances
- **6x faster** SDK initialization
- Single connection pooled across all components
- Automatic resource optimization

```typescript
// All components share a single provider instance
const sdk = new PancakeSwapSDK({ rpcUrl, privateKey });
// Router, Factory, and all Pairs use the same connection
```

## 🔧 Advanced Usage

### Price Impact Analysis

```typescript
import { PancakePair, parseBNB, calculatePriceImpact } from '@fnzero/pancakeswap-sdk';

const pair = new PancakePair({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  pairAddress: PAIR_ADDRESS,
});

const reserves = await pair.getReserves();
const amountIn = parseBNB('1');

// Calculate price impact
const impact = calculatePriceImpact(reserves.reserve0, amountIn);
console.log(`Price Impact: ${impact}%`);

if (impact > 5) {
  console.warn('High price impact! Consider reducing trade size.');
}
```

### Historical Event Analysis

```typescript
import { PancakePair } from '@fnzero/pancakeswap-sdk';

const pair = new PancakePair({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  pairAddress: PAIR_ADDRESS,
});

// Get recent swaps
const latestBlock = await pair['provider'].getBlockNumber();
const swaps = await pair.getSwapEvents(latestBlock - 1000, 'latest');

console.log(`Found ${swaps.length} swaps in last 1000 blocks`);

// Analyze swap volume
const totalVolume = swaps.reduce((sum, swap) =>
  sum + swap.amount0In + swap.amount1In, 0n
);
console.log(`Total Volume: ${formatBNB(totalVolume)} BNB`);
```

### Multi-Hop Swaps

```typescript
// Swap TOKEN_A → WBNB → TOKEN_B
const path = [TOKEN_A_ADDRESS, PancakeRouter.WBNB, TOKEN_B_ADDRESS];

// Get expected output
const amounts = await router.getAmountsOut('100', path);
console.log(`Token A → Token B: ${amounts[2]}`);

// Execute multi-hop swap
await router.swapExactTokensForTokens({
  amountIn: '100',
  amountOutMin: calculateMinAmount(amounts[2], 1).toString(),
  path,
  to: router.getWalletAddress(),
});
```

## 📖 API Reference

### PancakeSwapSDK (Unified Entry)

**Initialization:**
```typescript
const sdk = new PancakeSwapSDK({
  rpcUrl: string,          // Required: HTTP RPC endpoint
  wssUrl?: string,         // Optional: WebSocket for real-time events
  privateKey?: string,     // Optional: Required for trading
  routerAddress?: string,  // Optional: Custom router
  factoryAddress?: string, // Optional: Custom factory
});
```

**Trading Methods:**
- `swapExactETHForTokens(bnbAmount: bigint, path, slippage?, gasOptions?)` - BNB to tokens
- `swapExactTokensForETH(token, amount: bigint, slippage?, gasOptions?)` - Tokens to BNB
- `swapExactTokensForTokens(tokenIn, tokenOut, amount: bigint, slippage?, gasOptions?)` - Token to token

**Liquidity Methods:**
- `addLiquidity(tokenA, tokenB, amountA: bigint, amountB: bigint, slippage?, gasOptions?)` - Add token liquidity
- `addLiquidityETH(token, tokenAmount: bigint, bnbAmount: bigint, slippage?, gasOptions?)` - Add BNB liquidity
- `removeLiquidity(tokenA, tokenB, liquidity: bigint, slippage?, gasOptions?)` - Remove token liquidity
- `removeLiquidityETH(token, liquidity: bigint, slippage?, gasOptions?)` - Remove BNB liquidity

**Query Methods:**
- `getWalletAddress()` - Get wallet address
- `getBNBBalance()` - Get BNB balance
- `getTokenBalance(address)` - Get token balance
- `getPairAddress(tokenA, tokenB)` - Get pair address
- `getPairForTokens(tokenA, tokenB)` - Get pair instance
- `getAmountsOut(amountIn, path)` - Calculate output amounts
- `getAmountsIn(amountOut, path)` - Calculate required input
- `getAllPairsLength()` - Get total pairs count
- `getPairAtIndex(index)` - Get pair at index

**Pair Management:**
- `getPair(address)` - Get or create pair instance
- `getPriceCalculator(address)` - Get price calculator

**Advanced Access:**
- `getRouter()` - Direct router access
- `getFactory()` - Direct factory access
- `cleanup()` - Cleanup all resources

**Constants:**
- `sdk.WBNB` - WBNB address
- `sdk.ROUTER` - Router address
- `sdk.FACTORY` - Factory address

### PancakePair (via sdk.getPair())

**Price Methods:**
- `getSpotPrice(dec0, dec1)` - Current spot price
- `quoteSwapWithSlippage(amount, slippage, dec0, dec1)` - Quote with slippage
- `getPriceCalculator()` - Get calculator instance

**Query Methods:**
- `getReserves()` - Current reserves
- `getPairInfo()` - Comprehensive info
- `getTokensInfo()` - Token details
- `token0() / token1()` - Token addresses
- `totalSupply()` - LP supply

**Event Subscriptions (WebSocket):**
- `onSwap(listener)` - Subscribe to swaps
- `onMint(listener)` - Subscribe to adds
- `onBurn(listener)` - Subscribe to removes
- `onSync(listener)` - Subscribe to updates
- `off(listenerId)` - Unsubscribe
- `removeAllListeners()` - Cleanup all

**Historical Queries:**
- `getSwapEvents(from, to)` - Past swaps
- `getMintEvents(from, to)` - Past adds
- `getBurnEvents(from, to)` - Past removes
- `getSyncEvents(from, to)` - Past updates

### Utility Functions

**Amount Conversion:**
- `parseBNB(amount)` - BNB to wei
- `parseTokenAmount(amount, decimals)` - Tokens to wei
- `formatBNB(wei)` - Wei to BNB
- `formatTokenAmount(wei, decimals)` - Wei to tokens

**Price Calculations:**
- `calculateMinAmount(amount, slippage)` - Min with slippage
- `calculateMaxAmount(amount, slippage)` - Max with slippage
- `calculatePriceChange(old, new)` - Price change %
- `calculatePriceImpact(reserve, amount)` - Impact %

**AMM Math:**
- `getAmountOut(in, reserveIn, reserveOut)` - Output amount
- `getAmountIn(out, reserveIn, reserveOut)` - Required input
- `quote(amount, reserveIn, reserveOut)` - Simple quote

**Validation:**
- `isValidAddress(address)` - Validate address
- `normalizeAddress(address)` - Checksum format
- `addressEquals(addr1, addr2)` - Compare addresses

## 📋 Contract Addresses (BSC Mainnet)

```typescript
// Router V2
PancakeRouter.DEFAULT_ROUTER = '0x10ED43C718714eb63d5aA57B78B54704E256024E';

// Factory V2
PancakeFactory.DEFAULT_FACTORY = '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73';

// WBNB
PancakeRouter.WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
```

## 💡 Common Patterns

### Safe Trading with Slippage Protection

```typescript
import { PancakeSwapSDK } from '@fnzero/pancakeswap-sdk';
import { ethers } from 'ethers';

const sdk = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  privateKey: 'YOUR_PRIVATE_KEY',
});

// Slippage protection with user-defined tolerance
const swapAmount = ethers.parseUnits('100', 18);
await sdk.swapExactTokensForTokens(
  TOKEN_A,
  TOKEN_B,
  swapAmount,
  1 // 1% slippage tolerance (SDK calculates minAmountOut automatically)
);
```

### Price Monitoring Bot with WebSocket

```typescript
import { PancakeSwapSDK, calculatePriceChange, parseTokenAmount } from '@fnzero/pancakeswap-sdk';

const sdk = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  wssUrl: 'wss://bsc-rpc.publicnode.com', // Enable WebSocket
});

const pair = sdk.getPair(PAIR_ADDRESS);
let lastPrice = await pair.getSpotPrice(18, 18);

// Real-time price monitoring
pair.onSync(async () => {
  const newPrice = await pair.getSpotPrice(18, 18);
  const change = calculatePriceChange(
    parseTokenAmount(lastPrice, 18),
    parseTokenAmount(newPrice, 18)
  );

  console.log(`Price: ${newPrice}, Change: ${change}%`);
  lastPrice = newPrice;
});
```

### Complete Trading Bot Example

```typescript
import { ethers } from 'ethers';

const sdk = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  wssUrl: 'wss://bsc-rpc.publicnode.com',
  privateKey: process.env.PRIVATE_KEY,
});

const pair = sdk.getPair(BUSD_WBNB_PAIR);

// Monitor for price opportunities
pair.onSwap(async (event) => {
  const price = await pair.getSpotPrice(18, 18);
  const impact = calculatePriceImpact(event.amount0In, event.amount1Out);

  // Buy when price drops
  if (impact > 2) {
    const buyAmount = ethers.parseEther('0.1');
    await sdk.swapExactETHForTokens(
      buyAmount,
      [sdk.WBNB, BUSD],
      1 // 1% slippage tolerance
    );
  }
});

// Cleanup on exit
process.on('SIGINT', () => {
  sdk.cleanup();
  process.exit(0);
});
```

## ⚙️ Configuration

### Gas Settings

```typescript
// Legacy gas
await router.swapExactETHForTokens({
  amountOutMin: '0',
  path: [PancakeRouter.WBNB, TOKEN],
  to: router.getWalletAddress(),
  gas: {
    gasLimit: 300000,
    gasPrice: '5', // 5 gwei
  }
}, '0.1');

// EIP-1559 gas
await router.swapExactTokensForTokens({
  amountIn: '100',
  amountOutMin: '95',
  path: [TOKEN_A, TOKEN_B],
  to: router.getWalletAddress(),
  gas: {
    maxFeePerGas: '10',
    maxPriorityFeePerGas: '2',
  }
});
```

### WebSocket vs HTTP

```typescript
// HTTP only (no real-time events)
const sdkHTTP = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  privateKey: 'YOUR_PRIVATE_KEY',
});

// WebSocket enabled (real-time events available)
const sdkWS = new PancakeSwapSDK({
  rpcUrl: 'https://bsc-dataseed.binance.org/',
  wssUrl: 'wss://bsc-rpc.publicnode.com', // ✅ Enable real-time!
  privateKey: 'YOUR_PRIVATE_KEY',
});

// All pairs from sdkWS will have WebSocket support
const pair = sdkWS.getPair(PAIR_ADDRESS);
pair.onSwap((event) => console.log('Real-time swap!', event));
```

## 🔒 Security

- **Private Key Safety**: Never commit private keys to version control
- **Slippage Protection**: Always set reasonable `amountOutMin` / `amountInMax`
- **Gas Limits**: Set appropriate limits to prevent stuck transactions
- **Approval Amounts**: Consider approving only needed amounts
- **Test First**: Always test on testnet before mainnet

## 🛠️ Requirements

- Node.js >= 18.0.0
- ethers.js ^6.13.0

## 📄 License

MIT

## 🤝 Contributing

Contributions welcome! Please feel free to submit a Pull Request.

## ⚠️ Disclaimer

This SDK is provided as-is. Use at your own risk. Always test thoroughly before using with real funds.

---

<div align="center">
    <p>Built with ❤️ for the DeFi community</p>
</div>