npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

uniswap-v3-quoter

v0.3.0

Published

TypeScript implementation of Uniswap V3 QuoterV2 with real-time WebSocket updates for BSC

Readme

Uniswap V3 TypeScript Quoter

TypeScript implementation of Uniswap V3 QuoterV2 for local quote calculations without on-chain calls.

Features

Phase 1 (Minimal) - ✅ Complete

  • Local quote calculation: Calculate swap quotes without RPC calls
  • 100% accurate: Direct port from Solidity logic with BigInt precision
  • Lightweight: Minimal dependencies
  • Type-safe: Full TypeScript with strict typing
  • Well-tested: Comprehensive test suite for math libraries

Phase 2 (State Fetching) - ✅ Complete

  • Blockchain integration: Fetch pool state from BSC using ethers.js
  • Multicall3 batching: Efficient state fetching (8 calls -> 1 call)
  • State caching: Cache pool states for better performance
  • Auto-fetch: Quote using just pool address

Phase 3 (WebSocket Real-time) - ✅ Complete

  • WebSocket subscriber: Listen to Swap events in real-time
  • Auto-reconnect: Exponential backoff reconnection logic
  • Event-driven updates: State updates <10ms after swaps
  • Zero polling: Event-driven only, no background polling

Installation

npm install
npm run build

Quick Start

import { QuoterV3, createPoolState, createTickInfo } from './src';

// Create a quoter instance
const quoter = new QuoterV3();

// Create or fetch pool state
const poolState = createPoolState({
  address: '0x...',
  token0: '0x...',
  token1: '0x...',
  fee: 3000,        // 0.3% fee
  tickSpacing: 60,
  sqrtPriceX96: 79228162514264337593543950336n, // Current price
  tick: 0,
  liquidity: 1000000000000000000n,
  ticks: new Map(),
  tickBitmap: new Map(),
});

// Quote a swap
const amountIn = 1000000000000000000n; // 1 token (18 decimals)
const amountOut = quoter.quoteExactInputSingle(
  poolState,
  true,  // zeroForOne (swap token0 -> token1)
  amountIn
);

console.log(`Amount out: ${amountOut}`);

Phase 2: Fetch from Blockchain (New!)

With Phase 2, you can now fetch pool state directly from BSC:

import { ethers } from 'ethers';
import { QuoterV3, StateFetcher, DEFAULT_RPC_URLS } from './src';

// Connect to BSC
const provider = new ethers.JsonRpcProvider(DEFAULT_RPC_URLS.BSC_MAINNET);

// Create StateFetcher
const stateFetcher = new StateFetcher(provider);

// Create Quoter with StateFetcher
const quoter = new QuoterV3(stateFetcher);

// Quote using pool address (auto-fetch state!)
const poolAddress = '0x36696169C63e42cd08ce11f5deeBbCeBae652050'; // USDT/WBNB
const amountIn = 1000000000000000000n; // 1 WBNB

const amountOut = await quoter.quoteExactInputSingle(
  poolAddress,
  false,  // WBNB -> USDT
  amountIn
);

console.log(`Quote: ${amountIn} -> ${amountOut}`);

Features

  • Auto-fetch: Just provide pool address, state is fetched automatically
  • Caching: Pool states are cached for subsequent quotes
  • Multicall3: Batches 8 RPC calls into 1 for efficiency
  • Compatible: Works with existing manual PoolState approach

Environment Variables

# Optional: Use custom RPC endpoint
export BSC_RPC_URL=https://your-bsc-node.com

Phase 3: WebSocket Real-time Updates (New!)

Get instant pool state updates with <10ms latency:

import { ethers } from 'ethers';
import { QuoterV3, StateFetcher, BSC_ADDRESSES } from './src';

// Connect with WebSocket support
const provider = new ethers.JsonRpcProvider('https://bsc-dataseed.binance.org/');

const stateFetcher = new StateFetcher(
  provider,
  undefined,
  {
    wssUrl: process.env.BSC_WSS_URL, // e.g., wss://bsc-mainnet.nodereal.io/ws/v1/YOUR_KEY
    reconnectMaxRetries: 0, // infinite retries
  }
);

const quoter = new QuoterV3(stateFetcher);

// Fetch pool (auto-subscribes to WebSocket)
await stateFetcher.fetchPoolState(BSC_ADDRESSES.USDT_WBNB_500);

// Start WebSocket listener
await stateFetcher.startWebSocket();

// Pool state now updates automatically when swaps occur!
// Latency: <10ms from swap to state update

// Quote with real-time state
const amountOut = await quoter.quoteExactInputSingle(
  BSC_ADDRESSES.USDT_WBNB_500,
  false,
  1000000000000000000n
);

Features

  • Event-driven: Updates only when swaps occur (no polling waste)
  • Low latency: <10ms from swap to state update
  • Auto-reconnect: Exponential backoff reconnection
  • Minimal RPC: Only for initial fetch, then WebSocket only
  • Production-ready: Handles disconnects gracefully

WebSocket Providers

Recommended BSC WebSocket providers:

  • NodeReal: wss://bsc-mainnet.nodereal.io/ws/v1/YOUR_KEY
  • Ankr: wss://rpc.ankr.com/bsc/ws/YOUR_KEY
  • QuickNode: Custom endpoint

Environment Variables

# Required for WebSocket
export BSC_WSS_URL=wss://bsc-mainnet.nodereal.io/ws/v1/YOUR_API_KEY

# Optional: Custom RPC
export BSC_RPC_URL=https://bsc-dataseed.binance.org/

Architecture

Math Libraries

All core math ported from Solidity with BigInt:

  • FullMath: 512-bit precision multiplication and division
  • TickMath: Tick ↔ sqrt price conversions
  • SqrtPriceMath: Price calculations and amount deltas
  • SwapMath: Swap step computations
  • TickBitmap: Initialized tick lookups
  • LiquidityMath: Liquidity delta calculations

Types

interface PoolState {
  address: string;
  token0: string;
  token1: string;
  fee: number;
  tickSpacing: number;
  sqrtPriceX96: bigint;
  tick: number;
  liquidity: bigint;
  ticks: Map<number, TickInfo>;
  tickBitmap: Map<number, bigint>;
}

interface TickInfo {
  liquidityGross: bigint;
  liquidityNet: bigint;
  initialized: boolean;
  // ... other fields
}

API Reference

QuoterV3

Main quoter class for calculating swap amounts.

quoteExactInputSingle()

Quote exact input for a single pool swap.

quoteExactInputSingle(
  poolState: PoolState,
  zeroForOne: boolean,
  amountIn: bigint,
  sqrtPriceLimitX96?: bigint
): bigint

Parameters:

  • poolState: Pool state containing all necessary data
  • zeroForOne: true for token0→token1, false for token1→token0
  • amountIn: Amount of input token
  • sqrtPriceLimitX96: Optional price limit

Returns: Expected output amount

Helper Functions

createPoolState()

Create a PoolState object with default values.

const poolState = createPoolState({
  address: '0x...',
  token0: '0x...',
  token1: '0x...',
  fee: 3000,
  tickSpacing: 60,
});

createTickInfo()

Create a TickInfo object with default values.

const tickInfo = createTickInfo({
  liquidityGross: 1000000n,
  liquidityNet: 1000000n,
  initialized: true,
});

Testing

Run the test suite:

npm test

Run tests in watch mode:

npm run test:watch

Performance

  • Quote calculation: < 1ms (after pool state is loaded)
  • No RPC calls: All calculations done locally
  • Memory efficient: Only stores initialized ticks

Limitations

Phase 2 Current Status

Implemented:

  • State fetching: Fetch from BSC blockchain
  • Multicall integration: Efficient batched calls
  • State caching: Cache for performance
  • Single pool quotes: Exact input swaps

Not yet implemented (Future - Phase 4):

  • No multi-hop swaps: Only single pool swaps
  • No exact output quotes: Only exact input implemented
  • No browser support: Node.js only
  • No gas estimation: Gas costs not estimated
  • No multi-chain: BSC only currently

Roadmap

✅ Phase 1 - Math & Quote Logic (Complete)

  • ✅ Port all math libraries from Solidity
  • ✅ Implement quote calculation logic
  • ✅ Comprehensive tests
  • ✅ Documentation

✅ Phase 2 - State Fetching (Complete)

  • ✅ Add ethers.js integration
  • ✅ Implement Multicall3 state fetching
  • ✅ Pool state caching
  • ✅ Integration tests

✅ Phase 3 - WebSocket Real-time (Complete)

  • ✅ WebSocket subscriber for Swap events
  • ✅ Auto-reconnect with exponential backoff
  • ✅ Event-driven state updates (<10ms)
  • ✅ Integration with StateFetcher

Phase 4 - Production Features (Future)

  • [ ] WebSocket real-time updates
  • [ ] Multi-hop swap quotes
  • [ ] Exact output quotes
  • [ ] Browser support (ESM build)

Phase 4 - Production Ready

  • [ ] npm package publication
  • [ ] Comprehensive documentation
  • [ ] Performance benchmarks
  • [ ] Gas estimation

Technical Notes

BigInt Precision

JavaScript BigInt provides arbitrary precision, perfect for Solidity uint256/int256:

// Python
x = (a * b) & ((1 << 256) - 1)

// TypeScript
const x = (a * b) & ((1n << 256n) - 1n);

Tick Spacing

Different fee tiers have different tick spacings:

  • 0.01% fee: tickSpacing = 1
  • 0.05% fee: tickSpacing = 10
  • 0.3% fee: tickSpacing = 60
  • 1% fee: tickSpacing = 200

Price Limits

Price limits prevent excessive slippage:

  • zeroForOne = true: limit must be < current price
  • zeroForOne = false: limit must be > current price

Examples

See test/ directory for comprehensive examples:

  • test/math.test.ts: Math library usage
  • test/quoter.test.ts: Quote calculation examples
  • test/mockState.ts: Creating pool states

Contributing

Contributions welcome! Please ensure:

  • All tests pass
  • Code is formatted with Prettier
  • TypeScript compiles without errors
  • Follow existing code style

License

MIT License - same as Uniswap V3

Credits

  • Uniswap V3 Core: https://github.com/Uniswap/v3-core
  • Original Python implementation: v3-python-quoter

Comparison with Python Version

| Feature | Python | TypeScript | |---------|--------|------------| | Math libraries | ✅ | ✅ | | Quote logic | ✅ | ✅ | | State fetching | ✅ | ❌ (planned) | | WebSocket | ✅ | ❌ (planned) | | Multicall | ✅ | ❌ (planned) | | Browser support | ❌ | ❌ (planned) | | Runtime | Python 3.8+ | Node.js 18+ |

FAQ

Why BigInt instead of libraries like bn.js?

Native BigInt is faster, simpler, and has better TypeScript support. It's perfect for uint256 arithmetic.

Can I use this in production?

This minimal version is suitable for testing and development. For production, you'll need to implement state fetching and real-time updates.

How accurate are the quotes?

100% accurate - the math is ported directly from Solidity with identical logic and precision.

Why not use Uniswap SDK?

The official SDK still requires RPC calls to QuoterV2 contract. This implementation calculates quotes locally for much better performance.

Support

For issues and questions:

  • GitHub Issues: [Create an issue]
  • Documentation: See this README and inline code comments

Status: Minimal implementation complete ✅
Version: 0.1.0
Last Updated: 2024