SDK for routing swaps across Uniswap V2, V3, and V4 protocols with automatic route optimization and gas-efficient execution.
—
Extended multicall and payment utilities for transaction batching and native ETH handling. These utilities provide enhanced functionality beyond standard Uniswap SDK utilities, including advanced validation and fee handling.
Enhanced multicall functionality with deadline and previous block hash validation support.
/**
* Abstract class providing extended multicall functionality with validation
*/
abstract class MulticallExtended {
/** Contract interface for IMulticallExtended */
static INTERFACE: Interface;
/**
* Encode multicall with optional validation (deadline or previous block hash)
* @param calldatas - Single calldata string or array of calldata strings
* @param validation - Optional deadline (number) or previous block hash (0x-prefixed string)
* @returns Encoded multicall function data
*/
static encodeMulticall(calldatas: string | string[], validation?: Validation): string;
}Extended payment utilities with fee support for token sweeping and ETH wrapping/unwrapping.
/**
* Abstract class providing extended payment functionality with fee support
*/
abstract class PaymentsExtended {
/** Contract interface for IPeripheryPaymentsWithFeeExtended */
static INTERFACE: Interface;
/**
* Encode WETH9 unwrapping with optional fee
* @param amountMinimum - Minimum amount to unwrap
* @param recipient - Optional recipient address (uses msg.sender if not provided)
* @param feeOptions - Optional fee configuration
* @returns Encoded function data for WETH unwrap
*/
static encodeUnwrapWETH9(amountMinimum: JSBI, recipient?: string, feeOptions?: FeeOptions): string;
/**
* Encode token sweeping with optional fee
* @param token - Token to sweep
* @param amountMinimum - Minimum amount to sweep
* @param recipient - Optional recipient address (uses msg.sender if not provided)
* @param feeOptions - Optional fee configuration
* @returns Encoded function data for token sweep
*/
static encodeSweepToken(
token: Token,
amountMinimum: JSBI,
recipient?: string,
feeOptions?: FeeOptions
): string;
/**
* Encode token pull (transfer from user to contract)
* @param token - Token to pull
* @param amount - Amount to pull
* @returns Encoded function data for token pull
*/
static encodePull(token: Token, amount: JSBI): string;
/**
* Encode ETH wrapping to WETH
* @param amount - Amount of ETH to wrap
* @returns Encoded function data for ETH wrap
*/
static encodeWrapETH(amount: JSBI): string;
}Type definitions for validation parameters used in extended multicall.
/**
* Validation parameter - either deadline (timestamp) or previous block hash
*/
type Validation = BigintIsh | string;
/**
* Validate and parse a bytes32 string (for block hash validation)
* @param bytes32 - Hex string to validate (must be 64 hex characters with 0x prefix)
* @returns Lowercase hex string
* @throws Error if format is invalid
*/
function validateAndParseBytes32(bytes32: string): string;Internal utility functions for encoding fees in basis points.
/**
* Encode fee percentage as basis points
* @param fee - Fee as Percent object
* @returns Hex-encoded fee in basis points (fee * 10000)
*/
function encodeFeeBips(fee: Percent): string;Utilities for working with mixed routes and currency paths.
/**
* Utility function to return consecutive sections of Pools or Pairs in a MixedRoute partitioned by protocol
* @param route - Mixed route to partition
* @returns Nested array of pools grouped by protocol type
*/
function partitionMixedRouteByProtocol(route: MixedRouteSDK<Currency, Currency>): TPool[][];
/**
* Get the output token of an array of pools given the first input token
* @param pools - Array of pools to traverse
* @param firstInputToken - Starting input token
* @returns Final output token after traversing all pools
*/
function getOutputOfPools(pools: TPool[], firstInputToken: Currency): Currency;
/**
* Get the appropriate path currency for a given currency and pool
* @param currency - Currency to find path representation for
* @param pool - Pool to check currency against
* @returns Currency as it should appear in the path (may be wrapped version)
*/
function getPathCurrency(currency: Currency, pool: TPool): Currency;
/**
* Create currency amount with the appropriate path currency
* @param amount - Original currency amount
* @param pool - Pool to get path currency for
* @returns Currency amount with path-appropriate currency
*/
function amountWithPathCurrency(amount: CurrencyAmount<Currency>, pool: TPool): CurrencyAmount<Currency>;Utilities for encoding mixed routes into hex paths for on-chain execution.
/**
* Converts a mixed route to a hex encoded path for exactIn swaps
* @param route - Mixed route to encode
* @param useMixedRouterQuoteV2 - Whether to use Mixed Quoter V2 encoding for v4 pools
* @returns Hex-encoded path string
*/
function encodeMixedRouteToPath(
route: MixedRouteSDK<Currency, Currency>,
useMixedRouterQuoteV2?: boolean
): string;Usage Examples:
import {
MulticallExtended,
PaymentsExtended,
validateAndParseBytes32,
partitionMixedRouteByProtocol
} from "@uniswap/router-sdk";
// Basic multicall without validation
const calldatas = [
"0x...", // First call
"0x...", // Second call
"0x..." // Third call
];
const basicMulticall = MulticallExtended.encodeMulticall(calldatas);// Multicall with deadline validation
const deadline = Math.floor(Date.now() / 1000) + 1800; // 30 minutes
const multicallWithDeadline = MulticallExtended.encodeMulticall(calldatas, deadline);
// Multicall with previous block hash validation
const previousBlockHash = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
const validatedBlockHash = validateAndParseBytes32(previousBlockHash);
const multicallWithBlockHash = MulticallExtended.encodeMulticall(calldatas, validatedBlockHash);// ETH and token payment operations
import { Token, Percent } from "@uniswap/sdk-core";
import JSBI from "jsbi";
const token = new Token(1, "0x...", 18, "USDC", "USD Coin");
const amount = JSBI.BigInt("1000000000"); // 1000 tokens
// Unwrap WETH to ETH
const unwrapCalldata = PaymentsExtended.encodeUnwrapWETH9(amount);
// Unwrap WETH with fee
const feeOptions = {
fee: new Percent(30, 10000), // 0.3% fee
recipient: "0x742d35Cc6435C6329Eb54F0d86C05B1E11a02E6B"
};
const unwrapWithFeeCalldata = PaymentsExtended.encodeUnwrapWETH9(amount, undefined, feeOptions);// Token operations
const sweepCalldata = PaymentsExtended.encodeSweepToken(token, amount);
const pullCalldata = PaymentsExtended.encodePull(token, amount);
const wrapCalldata = PaymentsExtended.encodeWrapETH(amount);
// Sweep token with fee to specific recipient
const sweepWithFeeCalldata = PaymentsExtended.encodeSweepToken(
token,
amount,
"0x742d35Cc6435C6329Eb54F0d86C05B1E11a02E6B", // recipient
feeOptions
);// Mixed route utilities
import { MixedRouteSDK, encodeMixedRouteToPath } from "@uniswap/router-sdk";
const mixedRoute = new MixedRouteSDK([v2Pair, v3Pool], tokenA, tokenB);
// Partition route by protocol
const sections = partitionMixedRouteByProtocol(mixedRoute);
console.log(`Route has ${sections.length} protocol sections`);
sections.forEach((section, index) => {
const protocolType = section[0].constructor.name;
console.log(`Section ${index}: ${section.length} ${protocolType} pools`);
});
// Get final output
const finalOutput = getOutputOfPools(mixedRoute.pools, tokenA);
console.log("Final output token:", finalOutput.symbol);// Path encoding for on-chain execution
const encodedPath = encodeMixedRouteToPath(mixedRoute);
console.log("Encoded path:", encodedPath);
// Use V2 quoter encoding
const v2EncodedPath = encodeMixedRouteToPath(mixedRoute, true);
console.log("V2 quoter encoded path:", v2EncodedPath);// Path currency utilities
import { getPathCurrency, amountWithPathCurrency } from "@uniswap/router-sdk";
const pathCurrency = getPathCurrency(ETH, pool); // Might return WETH for wrapped pools
const pathAmount = amountWithPathCurrency(ethAmount, pool);
console.log("Original currency:", ETH.symbol);
console.log("Path currency:", pathCurrency.symbol);
console.log("Path amount currency:", pathAmount.currency.symbol);// Complete transaction construction example
const transactionCalldatas = [
// Pull tokens from user
PaymentsExtended.encodePull(tokenIn, inputAmount),
// Execute swap
swapCalldata,
// Unwrap WETH to ETH if needed
PaymentsExtended.encodeUnwrapWETH9(outputAmount, recipient),
// Sweep any remaining tokens
PaymentsExtended.encodeSweepToken(tokenOut, JSBI.BigInt(0))
];
// Batch all operations with deadline
const finalCalldata = MulticallExtended.encodeMulticall(
transactionCalldatas,
Math.floor(Date.now() / 1000) + 1800
);
// Execute transaction
const transaction = {
to: ROUTER_ADDRESS,
data: finalCalldata,
value: inputIsETH ? inputAmount.toString() : "0"
};Common validation and error scenarios:
// Validate block hash format
try {
const validated = validateAndParseBytes32("0x123"); // Too short
} catch (error) {
console.error("Invalid block hash format:", error.message);
}
// Check for valid path currencies
try {
const pathCurrency = getPathCurrency(currency, pool);
} catch (error) {
if (error.message.includes("Expected currency")) {
console.error("Currency not found in pool:", error.message);
}
}
// Validate pool compatibility in mixed routes
function validateMixedRoute(route: MixedRouteSDK<Currency, Currency>) {
try {
const sections = partitionMixedRouteByProtocol(route);
console.log(`Valid mixed route with ${sections.length} protocol sections`);
} catch (error) {
console.error("Invalid mixed route:", error.message);
}
}Install with Tessl CLI
npx tessl i tessl/npm-uniswap--router-sdk