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

@lendliq/router

v1.0.0

Published

DEX routing and path finding for LendLiq protocol

Readme

@lendliq/router

DEX routing and path finding for LendLiq protocol. Works with @lendliq/sdk for core entities.

Installation

npm install @lendliq/router @lendliq/sdk viem
# or
yarn add @lendliq/router @lendliq/sdk viem
# or
pnpm add @lendliq/router @lendliq/sdk viem

Quick Start

import { PathFinder } from "@lendliq/router";
import { Token, Trade, Route } from "@lendliq/sdk";
import { createPublicClient, http } from "viem";
import { bsc } from "viem/chains";
import { BigNumber } from "bignumber.js";

// 1. Define your tokens
const WBNB = new Token(56, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", 18, "WBNB");
const USDT = new Token(56, "0x55d398326f99059fF775485246999027B3197955", 18, "USDT");
const ETH = new Token(56, "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", 18, "ETH");

// 2. Create viem client
const client = createPublicClient({
  chain: bsc,
  transport: http()
});

// 3. Initialize PathFinder (once at app startup)
const pathFinder = await PathFinder.create({
  chainId: 56,
  client,
  v3Factory: "0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7",
  tokens: [WBNB, USDT, ETH],
  feeTiers: [500, 2500, 10000],
});

// 4. Find best route (no need to pass config again!)
const result = await pathFinder.findBestRoute(
  USDT.address,
  ETH.address,
  new BigNumber("100000000000000000000") // 100 USDT
);

if (result) {
  console.log(`Output: ${result.amountOut.toString()}`);
  console.log(`Price Impact: ${result.priceImpact}%`);
  console.log(`Routes: ${result.routes.length}`);

  // Create Trade object for execution
  const routes = result.routes.map(r =>
    new Route(r.steps, r.expectedOutput, r.priceImpact, r.percentage)
  );
  const trade = new Trade(USDT, ETH, amountIn, result.amountOut, routes, result.priceImpact);

  // Get params for smart contract
  const params = trade.toAggregatorParams(userAddress, 50); // 0.5% slippage
}

Setup Configuration

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | chainId | number | Yes | - | Chain ID (e.g., 56 for BSC) | | client | PublicClient | Yes | - | Viem public client | | v3Factory | string | Yes | - | V3 factory contract address | | tokens | Token[] | Yes | - | Token list for pool discovery | | quoter | string | No | - | Optional Quoter contract address | | feeTiers | number[] | No | [500, 2500, 10000] | Fee tiers to search (basis points) | | maxHops | number | No | 3 | Maximum hops in a route | | maxRoutes | number | No | 5 | Maximum routes to consider | | enableSplitRouting | boolean | No | true | Enable split routing | | maxSplitRoutes | number | No | 3 | Maximum routes to split across | | minSplitPercentage | number | No | 500 | Minimum percentage per split (5%) | | multicallBatchSize | number | No | 100 | Batch size for multicall requests |

API

PathFinder.create(config)

Create and initialize a new PathFinder instance. Discovers all pools between provided tokens.

const pathFinder = await PathFinder.create({
  chainId: 56,
  client,
  v3Factory: "0x...",
  tokens: [WBNB, USDT, ETH, BUSD],
  feeTiers: [500, 2500, 10000],
});

pathFinder.findBestRoute(tokenIn, tokenOut, amountIn, options?)

Find the best route for a swap. Configuration from setup is used automatically.

const result = await pathFinder.findBestRoute(
  USDT.address,
  ETH.address,
  new BigNumber("100000000000000000000"),
  {
    // Optional overrides for this query
    maxHops: 2,
    disableSplitRouting: true,
  }
);

pathFinder.addTokens(tokens)

Add new tokens and discover their pools with existing tokens.

const CAKE = new Token(56, "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", 18, "CAKE");
await pathFinder.addTokens([CAKE]);

pathFinder.refreshPools()

Refresh all pool data (prices, liquidity).

await pathFinder.refreshPools();

pathFinder.setFeeTiers(feeTiers)

Update fee tiers and clear pool cache.

pathFinder.setFeeTiers([100, 500, 3000, 10000]);

pathFinder.getDiscoveredPools()

Get all discovered pools.

const pools = pathFinder.getDiscoveredPools();
console.log(`Found ${pools.length} pools`);

pathFinder.getCacheStats()

Get cache statistics.

const stats = pathFinder.getCacheStats();
console.log(`Pools: ${stats.pools}, Tokens: ${stats.tokens}`);

Performance (Multicall)

PathFinder uses multicall for efficient batch RPC requests, significantly reducing initialization time:

// Without multicall: 10 tokens × 3 fee tiers = 135 pool queries = 135+ RPC calls
// With multicall: Same queries batched into ~3-4 RPC calls

// Example: 10 tokens with 3 fee tiers
// - Pool address queries: 1 multicall (45 calls batched)
// - Pool data queries: 1-2 multicalls (225 calls batched)
// - Token decimals: 1 multicall (if needed)

Configure batch size based on your RPC provider limits:

const pathFinder = await PathFinder.create({
  // ... other config
  multicallBatchSize: 100, // Default: 100, adjust based on RPC limits
});

Split Routing

For large trades, PathFinder automatically splits the trade across multiple routes to minimize price impact:

const result = await pathFinder.findBestRoute(tokenIn, tokenOut, largeAmount);

// result.routes might contain multiple routes:
// [
//   { percentage: 6000, expectedOutput: "...", steps: [...] },  // 60%
//   { percentage: 4000, expectedOutput: "...", steps: [...] },  // 40%
// ]

Multi-Chain Support

Use the same API for different chains:

// BSC Mainnet
const bscPathFinder = await PathFinder.create({
  chainId: 56,
  client: bscClient,
  v3Factory: "0x...",
  tokens: bscTokens,
});

// BSC Testnet
const testnetPathFinder = await PathFinder.create({
  chainId: 97,
  client: testnetClient,
  v3Factory: "0x...",
  tokens: testnetTokens,
});

// Ethereum
const ethPathFinder = await PathFinder.create({
  chainId: 1,
  client: ethClient,
  v3Factory: "0x1F98431c8aD98523631AE4a59f267346ea31F984", // Uniswap V3
  tokens: ethTokens,
  feeTiers: [100, 500, 3000, 10000], // Uniswap fee tiers
});

License

MIT