SDK for routing swaps across Uniswap V2, V3, and V4 protocols with automatic route optimization and gas-efficient execution.
—
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.
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>;
}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>;
}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>;
}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>[]>;
}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;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