Uniswap v4 Developer Guide
Complete integration guide for the fully verified Uniswap v4 deployment on QELT Mainnet. All contracts are deployed, verified, and ready for production use.
Contract Addresses
All Uniswap v4 contracts are fully verified on QELTScan with complete source code and ABIs available.
| Contract | Address | Category | Purpose |
|---|---|---|---|
| PoolManager | 0x11c23891d9f723c4f1c6560f892e4581d87b6d8a | Core | Manages all pools |
| PositionManager | 0x1809116b4230794c823b1b17d46c74076e90d035 | Periphery | Liquidity positions as NFTs |
| Permit2 | 0x403cf2852cf448b5de36e865c5736a7fb7b25ea2 | Core | Gasless approvals |
| WQELT | 0xfebc6f9f0149036006c4f5ac124685e0ef48e8a2 | Utility | Wrapped QELT token |
| PositionDescriptor | 0x9bb9a0bac572ac1740eeadbedb97cddb497c57f0 | Periphery | NFT metadata |
Quick Start
Get started with Uniswap v4 on QELT Mainnet in minutes. All contracts are verified and ready for integration.
Network Configuration
const QELT_MAINNET = {
name: 'QELT Mainnet',
chainId: 770,
rpcUrl: 'https://mainnet.qelt.ai',
explorerUrl: 'https://qeltscan.ai',
nativeCurrency: {
name: 'QELT',
symbol: 'QELT',
decimals: 18
}
};Initialize Contracts
import { ethers } from 'ethers';
// Connect to QELT Mainnet
const provider = new ethers.JsonRpcProvider('https://mainnet.qelt.ai');
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Contract instances
const poolManager = new ethers.Contract(
'0x11c23891d9f723c4f1c6560f892e4581d87b6d8a',
POOL_MANAGER_ABI,
signer
);
const positionManager = new ethers.Contract(
'0x1809116b4230794c823b1b17d46c74076e90d035',
POSITION_MANAGER_ABI,
signer
);Key Features
Concentrated Liquidity
Provide liquidity in specific price ranges for maximum capital efficiency
NFT Positions
Each liquidity position is represented as a unique, transferable NFT
Custom Hooks
Extend pool functionality with programmable hooks for advanced features
Gasless Approvals
Permit2 integration enables gasless token approvals and better UX
Liquidity Management
Manage liquidity positions with concentrated liquidity ranges for optimal capital efficiency.
Create a New Pool
async function createPool(token0, token1, fee, initialPrice) {
// Ensure tokens are sorted
const [currency0, currency1] = token0 < token1
? [token0, token1]
: [token1, token0];
const poolKey = {
currency0,
currency1,
fee: fee, // 3000 = 0.3%, 500 = 0.05%
tickSpacing: getTickSpacing(fee),
hooks: ethers.ZeroAddress // No hooks
};
// Calculate sqrtPriceX96 from price
const sqrtPriceX96 = calculateSqrtPriceX96(initialPrice);
// Initialize pool
const tx = await poolManager.initialize(poolKey, sqrtPriceX96);
await tx.wait();
return poolKey;
}Add Liquidity (Mint Position)
async function addLiquidity(poolKey, tickLower, tickUpper, amount0, amount1) {
// 1. Approve tokens to Permit2
await token0.approve(permit2.target, amount0);
await token1.approve(permit2.target, amount1);
// 2. Approve Permit2 to PositionManager
await permit2.approve(
poolKey.currency0,
positionManager.target,
amount0,
Math.floor(Date.now() / 1000) + 3600
);
// 3. Calculate liquidity from amounts
const liquidity = calculateLiquidity(
poolKey, tickLower, tickUpper, amount0, amount1
);
// 4. Mint position
const mintParams = {
poolKey,
tickLower,
tickUpper,
liquidity,
amount0Max: amount0,
amount1Max: amount1,
amount0Min: amount0.mul(95).div(100), // 5% slippage
amount1Min: amount1.mul(95).div(100),
recipient: await signer.getAddress(),
deadline: Math.floor(Date.now() / 1000) + 1800
};
const tx = await positionManager.mint(mintParams);
const receipt = await tx.wait();
return tokenId; // Position NFT ID
}Remove Liquidity (Burn Position)
async function removeLiquidity(tokenId, liquidityAmount) {
// Decrease liquidity
const decreaseLiquidityParams = {
tokenId,
liquidity: liquidityAmount,
amount0Min: 0,
amount1Min: 0,
deadline: Math.floor(Date.now() / 1000) + 1800
};
const tx1 = await positionManager.decreaseLiquidity(decreaseLiquidityParams);
await tx1.wait();
// Collect fees and tokens
const collectParams = {
tokenId,
recipient: await signer.getAddress(),
amount0Max: ethers.MaxUint128,
amount1Max: ethers.MaxUint128
};
const tx2 = await positionManager.collect(collectParams);
await tx2.wait();
}Working with Position NFTs
Each liquidity position in Uniswap v4 is represented as an ERC721 NFT, allowing positions to be transferred, traded, or used as collateral.
Query Position Details
async function getPositionInfo(tokenId) {
const position = await positionManager.positions(tokenId);
return {
tokenId,
poolKey: position.poolKey,
tickLower: position.tickLower,
tickUpper: position.tickUpper,
liquidity: position.liquidity,
tokensOwed0: position.tokensOwed0,
tokensOwed1: position.tokensOwed1
};
}Collect Fees
async function collectFees(tokenId) {
const collectParams = {
tokenId,
recipient: await signer.getAddress(),
amount0Max: ethers.MaxUint128,
amount1Max: ethers.MaxUint128
};
const tx = await positionManager.collect(collectParams);
await tx.wait();
console.log('Fees collected');
}Working with WQELT
WQELT (Wrapped QELT) is the ERC20 version of native QELT, required for trading on Uniswap v4. Contract: 0xfebc6f9f0149036006c4f5ac124685e0ef48e8a2
Wrap QELT → WQELT
async function wrapQELT(amount) {
const tx = await wqelt.deposit({
value: amount
});
await tx.wait();
console.log('QELT → WQELT');
}Unwrap WQELT → QELT
async function unwrapQELT(amount) {
const tx = await wqelt.withdraw(
amount
);
await tx.wait();
console.log('WQELT → QELT');
}Pool Information & Analytics
Query real-time pool state and liquidity information directly from the PoolManager contract.
Get Pool State
async function getPoolState(poolKey) {
// Get pool ID
const poolId = await poolManager.getPoolId(poolKey);
// Get pool state
const slot0 = await poolManager.getSlot0(poolId);
const liquidity = await poolManager.getLiquidity(poolId);
return {
poolId,
sqrtPriceX96: slot0.sqrtPriceX96,
tick: slot0.tick,
protocolFee: slot0.protocolFee,
lpFee: slot0.lpFee,
liquidity
};
}Best Practices & Security
Slippage Protection
Always set appropriate minimum amounts to protect against price movements during transaction execution.
// Calculate 1% slippage tolerance const amount0Min = amount0.mul(99).div(100); const amount1Min = amount1.mul(99).div(100);
Gas Estimation
Estimate gas before complex transactions to prevent failures.
const gasEstimate = await positionManager.estimateGas.mint(params); const gasPrice = await provider.getGasPrice(); const estimatedCost = gasEstimate.mul(gasPrice);
Error Handling
Implement robust error handling with retry logic for critical operations.
try {
const tx = await positionManager.mint(params);
await tx.wait();
} catch (error) {
console.error('Transaction failed:', error.message);
// Handle error appropriately
}Resources & Support
Ready to Build?
All Uniswap v4 contracts are deployed, verified, and ready for integration on QELT Mainnet. Start building decentralized trading applications today.
