CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-uniswap--router-sdk

SDK for routing swaps across Uniswap V2, V3, and V4 protocols with automatic route optimization and gas-efficient execution.

Pending
Overview
Eval results
Files

mixed-routes.mddocs/

Mixed Route System

Advanced routing system for trades that span multiple Uniswap protocols. The mixed route system optimizes paths across V2, V3, and V4 pools for maximum efficiency and enables complex multi-protocol arbitrage strategies.

Capabilities

MixedRouteSDK Class

Core class representing a route that can span multiple Uniswap protocols within a single swap path.

/**
 * Represents a list of pools or pairs through which a swap can occur across multiple protocols
 */
class MixedRouteSDK<TInput extends Currency, TOutput extends Currency> {
  /** Array of pools/pairs from different protocols */
  readonly pools: TPool[];
  
  /** Array of currencies in the swap path */
  readonly path: Currency[];
  
  /** Input currency for the route */
  readonly input: TInput;
  
  /** Output currency for the route */
  readonly output: TOutput;
  
  /** Input currency as it appears in the path (may be wrapped for compatibility) */
  readonly pathInput: Currency;
  
  /** Output currency as it appears in the path (may be wrapped for compatibility) */
  readonly pathOutput: Currency;
  
  /**
   * Creates a mixed route instance
   * @param pools - Array of TPool objects (pools or pairs), ordered by the route the swap will take
   * @param input - Input currency
   * @param output - Output currency  
   * @param retainFakePools - Set to true to retain pools that have fake eth-weth pools (default: false)
   */
  constructor(pools: TPool[], input: TInput, output: TOutput, retainFakePools?: boolean);
  
  /** Chain ID of the route (all pools must be on same chain) */
  get chainId(): number;
  
  /** Mid price of the route calculated across all pools */
  get midPrice(): Price<TInput, TOutput>;
}

MixedRouteTrade Class

Trade class specifically for mixed route swaps with advanced routing capabilities.

/**
 * Represents a trade executed against mixed routes where some percentage of input 
 * is split across routes spanning multiple protocols
 */
class MixedRouteTrade<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType> {
  /** Individual swap details for each mixed route */
  readonly swaps: {
    route: MixedRouteSDK<TInput, TOutput>;
    inputAmount: CurrencyAmount<TInput>;
    outputAmount: CurrencyAmount<TOutput>;
  }[];
  
  /** Type of trade (currently only EXACT_INPUT supported) */
  readonly tradeType: TTradeType;
  
  /** 
   * @deprecated Use swaps property instead. Returns route if trade has single route, throws if multiple routes
   */
  get route(): MixedRouteSDK<TInput, TOutput>;
  
  /** Total input amount for the trade */
  get inputAmount(): CurrencyAmount<TInput>;
  
  /** Total output amount for the trade */
  get outputAmount(): CurrencyAmount<TOutput>;
  
  /** Execution price of the trade */
  get executionPrice(): Price<TInput, TOutput>;
  
  /** Price impact of the trade */
  get priceImpact(): Percent;
  
  /**
   * Get minimum amount out with slippage protection
   * @param slippageTolerance - Tolerance for unfavorable slippage
   * @param amountOut - Optional specific amount out
   * @returns Minimum amount out accounting for slippage
   */
  minimumAmountOut(slippageTolerance: Percent, amountOut?: CurrencyAmount<TOutput>): CurrencyAmount<TOutput>;
  
  /**
   * Get maximum amount in with slippage protection  
   * @param slippageTolerance - Tolerance for unfavorable slippage
   * @param amountIn - Optional specific amount in
   * @returns Maximum amount in (same as input for exact input trades)
   */
  maximumAmountIn(slippageTolerance: Percent, amountIn?: CurrencyAmount<TInput>): CurrencyAmount<TInput>;
  
  /**
   * Get worst-case execution price with slippage
   * @param slippageTolerance - Allowed slippage tolerance
   * @returns Worst-case execution price
   */
  worstExecutionPrice(slippageTolerance: Percent): Price<TInput, TOutput>;
}

Factory Methods

Static methods for creating mixed route trades with automatic quote simulation.

class MixedRouteTrade<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType> {
  /**
   * Create trade from a single mixed route with automatic simulation
   * @param route - Mixed route to trade through
   * @param amount - Amount to trade (must be exact input)
   * @param tradeType - Trade type (must be EXACT_INPUT)
   * @returns Promise resolving to MixedRouteTrade
   */
  static async fromRoute<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType>(
    route: MixedRouteSDK<TInput, TOutput>,
    amount: TTradeType extends TradeType.EXACT_INPUT ? CurrencyAmount<TInput> : CurrencyAmount<TOutput>,
    tradeType: TTradeType
  ): Promise<MixedRouteTrade<TInput, TOutput, TTradeType>>;
  
  /**
   * Create trade from multiple mixed routes with automatic simulation
   * @param routes - Array of routes with amounts
   * @param tradeType - Trade type (must be EXACT_INPUT)
   * @returns Promise resolving to MixedRouteTrade
   */
  static async fromRoutes<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType>(
    routes: {
      amount: TTradeType extends TradeType.EXACT_INPUT ? CurrencyAmount<TInput> : CurrencyAmount<TOutput>;
      route: MixedRouteSDK<TInput, TOutput>;
    }[],
    tradeType: TTradeType
  ): Promise<MixedRouteTrade<TInput, TOutput, TTradeType>>;
  
  /**
   * Create unchecked trade without simulation (when you have pre-computed amounts)
   * @param constructorArguments - Trade construction arguments
   * @returns MixedRouteTrade instance
   */
  static createUncheckedTrade<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType>(
    constructorArguments: {
      route: MixedRouteSDK<TInput, TOutput>;
      inputAmount: CurrencyAmount<TInput>;
      outputAmount: CurrencyAmount<TOutput>;
      tradeType: TTradeType;
    }
  ): MixedRouteTrade<TInput, TOutput, TTradeType>;
  
  /**
   * Create unchecked trade with multiple routes
   * @param constructorArguments - Multi-route trade construction arguments
   * @returns MixedRouteTrade instance
   */
  static createUncheckedTradeWithMultipleRoutes<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType>(
    constructorArguments: {
      routes: {
        route: MixedRouteSDK<TInput, TOutput>;
        inputAmount: CurrencyAmount<TInput>;
        outputAmount: CurrencyAmount<TOutput>;
      }[];
      tradeType: TTradeType;
    }
  ): MixedRouteTrade<TInput, TOutput, TTradeType>;
}

Best Trade Discovery

Algorithm for finding optimal trades across mixed routes.

class MixedRouteTrade<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType> {
  /**
   * Find the best exact input trades using mixed routes
   * @param pools - Available pools to consider
   * @param currencyAmountIn - Exact input amount
   * @param currencyOut - Desired output currency
   * @param options - Search options (maxNumResults, maxHops)
   * @param currentPools - Used in recursion; current list of pools  
   * @param nextAmountIn - Used in recursion; current amount being routed
   * @param bestTrades - Used in recursion; current best trades found
   * @returns Promise resolving to array of best trades sorted by output amount
   */
  static async bestTradeExactIn<TInput extends Currency, TOutput extends Currency>(
    pools: TPool[],
    currencyAmountIn: CurrencyAmount<TInput>,
    currencyOut: TOutput,
    options?: { maxNumResults?: number; maxHops?: number },
    currentPools?: TPool[],
    nextAmountIn?: CurrencyAmount<Currency>,
    bestTrades?: MixedRouteTrade<TInput, TOutput, TradeType.EXACT_INPUT>[]
  ): Promise<MixedRouteTrade<TInput, TOutput, TradeType.EXACT_INPUT>[]>;
}

Trade Comparison

Utility function for comparing and ranking mixed route trades.

/**
 * Compare two mixed route trades for sorting
 * @param a - First trade to compare
 * @param b - Second trade to compare  
 * @returns Negative if a is better, positive if b is better, zero if equal
 */
function tradeComparator<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType>(
  a: MixedRouteTrade<TInput, TOutput, TTradeType>,
  b: MixedRouteTrade<TInput, TOutput, TTradeType>
): number;

Pool Type Definition

Type definition for pools that can be used in mixed routes.

/**
 * Union type representing pools from different Uniswap protocols
 */
type TPool = Pair | V3Pool | V4Pool;

Usage Examples:

import { MixedRouteSDK, MixedRouteTrade, TPool } from "@uniswap/router-sdk";
import { CurrencyAmount, TradeType } from "@uniswap/sdk-core";
import { Pair } from "@uniswap/v2-sdk";
import { Pool as V3Pool } from "@uniswap/v3-sdk";

// Create a mixed route spanning V2 and V3
const pools: TPool[] = [
  v2Pair,    // V2 USDC-WETH pair
  v3Pool     // V3 WETH-DAI pool
];

const mixedRoute = new MixedRouteSDK(pools, USDC, DAI);
console.log("Route spans protocols:", mixedRoute.pools.length);
console.log("Path:", mixedRoute.path.map(token => token.symbol));
console.log("Mid price:", mixedRoute.midPrice.toSignificant(6));
// Create trade from mixed route
const inputAmount = CurrencyAmount.fromRawAmount(USDC, "1000000000"); // 1000 USDC

const mixedTrade = await MixedRouteTrade.fromRoute(
  mixedRoute,
  inputAmount,
  TradeType.EXACT_INPUT
);

console.log("Input:", mixedTrade.inputAmount.toExact());
console.log("Output:", mixedTrade.outputAmount.toExact());
console.log("Price impact:", mixedTrade.priceImpact.toFixed(2) + "%");
// Find best trades across multiple mixed routes
const allPools: TPool[] = [
  ...v2Pairs,
  ...v3Pools,
  ...v4Pools
];

const bestTrades = await MixedRouteTrade.bestTradeExactIn(
  allPools,
  inputAmount,
  DAI,
  {
    maxNumResults: 3,  // Return top 3 trades
    maxHops: 3        // Allow up to 3 hops
  }
);

bestTrades.forEach((trade, index) => {
  console.log(`Trade ${index + 1}:`);
  console.log(`  Output: ${trade.outputAmount.toExact()}`);
  console.log(`  Route length: ${trade.swaps[0].route.pools.length}`);
  console.log(`  Price impact: ${trade.priceImpact.toFixed(2)}%`);
});
// Create trade with multiple mixed routes for splitting
const routes = [
  {
    route: mixedRoute1,
    amount: CurrencyAmount.fromRawAmount(USDC, "500000000") // 500 USDC
  },
  {
    route: mixedRoute2, 
    amount: CurrencyAmount.fromRawAmount(USDC, "500000000") // 500 USDC
  }
];

const splitTrade = await MixedRouteTrade.fromRoutes(routes, TradeType.EXACT_INPUT);
console.log("Total input:", splitTrade.inputAmount.toExact());
console.log("Total output:", splitTrade.outputAmount.toExact());
console.log("Number of routes:", splitTrade.swaps.length);
// Compare trades for optimization
import { tradeComparator } from "@uniswap/router-sdk";

const comparison = tradeComparator(trade1, trade2);
if (comparison < 0) {
  console.log("Trade 1 is better");
} else if (comparison > 0) {
  console.log("Trade 2 is better");
} else {
  console.log("Trades are equivalent");
}

// Sort trades by quality
const sortedTrades = trades.sort(tradeComparator);
const bestTrade = sortedTrades[0];
// Handle slippage for mixed routes
const slippageTolerance = new Percent(50, 10000); // 0.5%
const minOut = mixedTrade.minimumAmountOut(slippageTolerance);
const worstPrice = mixedTrade.worstExecutionPrice(slippageTolerance);

console.log("Minimum output with slippage:", minOut.toExact());
console.log("Worst execution price:", worstPrice.toSignificant(6));

Install with Tessl CLI

npx tessl i tessl/npm-uniswap--router-sdk

docs

approval-liquidity.md

index.md

mixed-routes.md

route-handling.md

swap-routing.md

trade-management.md

utilities.md

tile.json