Modern TypeScript SDK for integrating Uniswap V4 into your dapp.
Early version: API may change rapidly.
A developer-friendly library for interacting with Uniswap V4 contracts. This library provides a simple and flexible interface for common operations like adding liquidity, swapping tokens, and managing positions.
- 🚀 Simple and intuitive API
- 🔄 Support for all major Uniswap V4 operations
- 💰 Native token support
- 🔒 Permit2 integration for gasless approvals
- 📊 Flexible liquidity management
- 🔍 Built-in quote simulation
- 🛠 TypeScript support
npm install uniswap-dev-kit
# or
yarn add uniswap-dev-kit
import { UniDevKitV4 } from 'uniswap-dev-kit';
const uniDevKit = new UniDevKitV4({
chainId: 1,
contracts: {
poolManager: "0x...",
positionManager: "0x...",
positionDescriptor: "0x...",
quoter: "0x...",
stateView: "0x...",
universalRouter: "0x..."
}
});
const pool = await uniDevKit.getPool({
tokens: ["0xTokenA", "0xTokenB"],
fee: 3000
});
const quote = await uniDevKit.getQuote({
pool,
amountIn: "1000000000000000000"
});
Full API documentation with TypeDoc: https://bootnodedev.github.io/uni-dev-kit
Retrieve a pool object from two tokens and a fee tier.
const pool = await uniDevKit.getPool({
tokens: [tokenA, tokenB],
fee: 3000
});
Simulate a swap to get amountOut
and sqrtPriceLimitX96
.
const quote = await uniDevKit.getQuote({
pool,
amountIn: "1000000000000000000"
});
Retrieve token metadata.
const tokens = await uniDevKit.getTokens({
addresses: ["0x...", "0x..."]
});
Get details about a Uniswap V4 LP position.
const position = await uniDevKit.getPosition({
tokenId: 123
});
Retrieve the PoolKey
object for a given pool ID.
const poolKey = await uniDevKit.getPoolKeyFromPoolId({
poolId: "0x..."
});
Construct calldata for a Universal Router swap.
// Basic swap
const { calldata, value } = await uniDevKit.buildSwapCallData({
tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
amountIn: parseUnits("100", 6), // 100 USDC
pool: pool,
slippageTolerance: 50, // 0.5%
recipient: "0x..."
});
// Swap with permit2
const permitData = await uniDevKit.preparePermit2Data({
token: tokenIn,
spender: uniDevKit.getContractAddress('universalRouter'),
owner: userAddress
});
const signature = await signer._signTypedData(permitData.toSign);
const permitWithSignature = permitData.buildPermit2DataWithSignature(signature);
const { calldata: calldataWithPermit, value: valueWithPermit } = await uniDevKit.buildSwapCallData({
tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
amountIn: parseUnits("100", 6),
pool: pool,
slippageTolerance: 50,
recipient: "0x...",
permit2Signature: permitWithSignature
});
const tx = await sendTransaction({
to: uniDevKit.getContractAddress('universalRouter'),
data: calldata,
value
});
Build calldata to add liquidity to a pool.
// Without permit
const { calldata, value } = await uniDevKit.buildAddLiquidityCallData({
pool,
amount0: "100000000",
amount1: "50000000000000000",
recipient: "0x...",
slippageTolerance: 50
});
// With Permit2 batch approval
const permitData = await uniDevKit.preparePermit2BatchData({
tokens: [pool.token0.address, pool.token1.address],
spender: uniDevKit.getContractAddress('positionManager'),
owner: userAddress
});
const signature = await signer.signTypedData(
permitData.toSign.domain,
permitData.toSign.types,
permitData.toSign.values
);
const permitWithSignature = permitData.buildPermit2BatchDataWithSignature(signature);
const { calldata, value } = await uniDevKit.buildAddLiquidityCallData({
pool,
amount0: parseUnits("100", 6),
recipient: "0x...",
permit2BatchSignature: permitWithSignature
});
const tx = await sendTransaction({
to: uniDevKit.getContractAddress('positionManager'),
data: calldata,
value
});
Construct a Permit2 batch approval for gasless interactions.
const permitData = await uniDevKit.preparePermit2BatchCallData({
tokens: [tokenA.address, tokenB.address],
spender: uniDevKit.getContractAddress('positionManager'),
owner: userAddress
});
pnpm build
— Build the librarypnpm test
— Run all testspnpm lint
— Lint code with Biomepnpm format
— Format code with Biomepnpm docs
— Generate API docs with TypeDoc
See CONTRIBUTING.md for guidelines.
- Releases are automated with semantic-release.
MIT