Core TypeScript utilities and abstractions for building applications on top of Uniswap V3
—
Type-safe currency abstractions for native currencies and ERC20 tokens with comprehensive equality checking and wrapping functionality.
Abstract base class providing the foundation for all currency types.
/**
* A currency is any fungible financial instrument, including Ether, all ERC20 tokens, and other chain-native currencies
*/
abstract class BaseCurrency {
/** Returns whether the currency is native to the chain and must be wrapped (e.g. Ether) */
abstract readonly isNative: boolean;
/** Returns whether the currency is a token that is usable in Uniswap without wrapping */
abstract readonly isToken: boolean;
/** The chain ID on which this currency resides */
readonly chainId: number;
/** The decimals used in representing currency amounts */
readonly decimals: number;
/** The symbol of the currency, i.e. a short textual non-unique identifier */
readonly symbol?: string;
/** The name of the currency, i.e. a descriptive textual non-unique identifier */
readonly name?: string;
/**
* Constructs an instance of the base class `BaseCurrency`
* @param chainId - The chain ID on which this currency resides
* @param decimals - Decimals of the currency
* @param symbol - Symbol of the currency
* @param name - Name of the currency
*/
protected constructor(chainId: number, decimals: number, symbol?: string, name?: string);
/**
* Returns whether this currency is functionally equivalent to the other currency
* @param other - The other currency to compare
*/
abstract equals(other: Currency): boolean;
/**
* Return the wrapped version of this currency that can be used with the Uniswap contracts
*/
abstract get wrapped(): Token;
}Abstract class for native currencies like Ether, MATIC, etc.
/**
* Represents the native currency of the chain on which it resides
*/
abstract class NativeCurrency extends BaseCurrency {
readonly isNative: true;
readonly isToken: false;
}Concrete implementation for Ethereum's native currency.
/**
* Ether is the main usage of a 'native' currency, i.e. for Ethereum mainnet and all testnets
*/
class Ether extends NativeCurrency {
/**
* Get or create an Ether instance for the specified chain
* @param chainId - The chain ID to get Ether for
* @returns Ether instance for the chain
*/
static onChain(chainId: number): Ether;
/**
* Get the wrapped version of Ether (WETH9) for this chain
*/
get wrapped(): Token;
/**
* Check if this Ether instance equals another currency
* @param other - Currency to compare against
*/
equals(other: Currency): boolean;
}Represents ERC20 tokens with full address and metadata support.
/**
* Represents an ERC20 token with a unique address and some metadata
*/
class Token extends BaseCurrency {
readonly isNative: false;
readonly isToken: true;
/** The contract address on the chain on which this token lives */
readonly address: string;
/** Buy fee tax for FOT tokens, in basis points */
readonly buyFeeBps?: BigNumber;
/** Sell fee tax for FOT tokens, in basis points */
readonly sellFeeBps?: BigNumber;
/**
* @param chainId - Chain ID for this token
* @param address - The contract address on the chain on which this token lives
* @param decimals - Decimals for this token
* @param symbol - Symbol for this token
* @param name - Name for this token
* @param bypassChecksum - If true it only checks for length === 42, startsWith 0x and contains only hex characters
* @param buyFeeBps - Buy fee tax for FOT tokens, in basis points
* @param sellFeeBps - Sell fee tax for FOT tokens, in basis points
*/
constructor(
chainId: number,
address: string,
decimals: number,
symbol?: string,
name?: string,
bypassChecksum?: boolean,
buyFeeBps?: BigNumber,
sellFeeBps?: BigNumber
);
/**
* Returns true if the two tokens are equivalent, i.e. have the same chainId and address
* @param other - Other currency to compare
*/
equals(other: Currency): boolean;
/**
* Returns true if the address of this token sorts before the address of the other token
* @param other - Other token to compare
* @throws if the tokens have the same address
* @throws if the tokens are on different chains
*/
sortsBefore(other: Token): boolean;
/**
* Return this token, which does not need to be wrapped
*/
get wrapped(): Token;
}Pre-configured WETH9 token instances for supported chains.
/**
* Known WETH9 implementation addresses, used in Ether#wrapped
*/
const WETH9: { [chainId: number]: Token };Usage Examples:
import { ChainId, Token, Ether, WETH9 } from "@uniswap/sdk-core";
// Create a custom ERC20 token
const USDC = new Token(
ChainId.MAINNET,
"0xA0b86a33E6424b73E63872f681e2230aDC3D3dC",
6,
"USDC",
"USD Coin"
);
// Create native Ether currency
const ether = Ether.onChain(ChainId.MAINNET);
// Get wrapped version of native currency
const weth = ether.wrapped;
console.log(weth.address); // WETH9 address for mainnet
// Access pre-configured WETH9 instances
const wethMainnet = WETH9[ChainId.MAINNET];
console.log(wethMainnet.symbol); // "WETH"
// Compare currencies
const usdc2 = new Token(
ChainId.MAINNET,
"0xA0b86a33E6424b73E63872f681e2230aDC3D3dC",
6,
"USDC",
"USD Coin"
);
console.log(USDC.equals(usdc2)); // true - same chain and address
console.log(USDC.equals(ether)); // false - different currency types
// Token sorting (useful for pair ordering)
const tokenA = new Token(ChainId.MAINNET, "0x1111111111111111111111111111111111111111", 18);
const tokenB = new Token(ChainId.MAINNET, "0x2222222222222222222222222222222222222222", 18);
console.log(tokenA.sortsBefore(tokenB)); // true - address A < address B
// Fee-on-transfer token support
import { BigNumber } from "@ethersproject/bignumber";
const fotToken = new Token(
ChainId.MAINNET,
"0x3333333333333333333333333333333333333333",
18,
"FOT",
"Fee on Transfer Token",
false,
BigNumber.from(100), // 1% buy fee
BigNumber.from(200) // 2% sell fee
);
console.log(fotToken.buyFeeBps?.toString()); // "100"
console.log(fotToken.sellFeeBps?.toString()); // "200"/**
* Union type representing any currency (native or token)
*/
type Currency = NativeCurrency | Token;Install with Tessl CLI
npx tessl i tessl/npm-uniswap--sdk-core