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.

5
Verified Contracts
770
Chain ID
100%
Verification Rate
ContractAddressCategoryPurpose
PoolManager
0x11c23891d9f723c4f1c6560f892e4581d87b6d8a
CoreManages all pools
PositionManager
0x1809116b4230794c823b1b17d46c74076e90d035
PeripheryLiquidity positions as NFTs
Permit2
0x403cf2852cf448b5de36e865c5736a7fb7b25ea2
CoreGasless approvals
WQELT
0xfebc6f9f0149036006c4f5ac124685e0ef48e8a2
UtilityWrapped QELT token
PositionDescriptor
0x9bb9a0bac572ac1740eeadbedb97cddb497c57f0
PeripheryNFT 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.