Skip to content

Complete TypeScript SDK for interacting with PancakeSwap V2 on Binance Smart Chain (BSC). Trade tokens, manage liquidity, and monitor on-chain events with ease.

License

Notifications You must be signed in to change notification settings

0xfnzero/pancakeswap-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🥞 PancakeSwap V2 SDK

A comprehensive TypeScript SDK for seamless PancakeSwap V2 trading on BSC

Integrate PancakeSwap V2 trading, liquidity management, and event monitoring into your applications with powerful tools and unified interfaces.

npm version npm downloads License GitHub stars GitHub forks

TypeScript Binance Smart Chain PancakeSwap DEX Trading

中文 | English | Website | Telegram | Discord


🚀 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

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

🎯 Quick Start

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

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)

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

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

// 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

// 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();
// 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

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
// 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
// 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

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

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

// 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:

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)

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

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

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

💡 Common Patterns

Safe Trading with Slippage Protection

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

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

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

// 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

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


Built with ❤️ for the DeFi community

About

Complete TypeScript SDK for interacting with PancakeSwap V2 on Binance Smart Chain (BSC). Trade tokens, manage liquidity, and monitor on-chain events with ease.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •