Quoting, monitoring, and metrics

Examples for getting swap quotes, monitoring auction progress, and fetching token details

Price quotes

/**
 * Example: Price Quoter
 * 
 * This example demonstrates:
 * - Getting price quotes across Uniswap V2, V3, and V4
 * - Comparing quotes to find best prices
 * - Handling different swap types (exact input/output)
 */

// UNCOMMENT IF RUNNING LOCALLY
// import { DopplerSDK } from '@whetstone-research/doppler-sdk';
import { DopplerSDK } from '../src';

import { createPublicClient, http, parseEther, formatEther, type Address } from 'viem'
import { base } from 'viem/chains'

const token = process.env.TOKEN as `0x${string}`;
const rpcUrl = process.env.RPC_URL || 'https://mainnet.base.org' as string;

if (!token) throw new Error('TOKEN is not set');

// Example token addresses (replace with actual addresses)
const weth = '0x4200000000000000000000000000000000000006' as Address // WETH on Base
const usdc = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as Address // USDC on Base

async function main() {
  // Initialize SDK
  const publicClient = createPublicClient({
    chain: base,
    transport: http(rpcUrl)
  })

  const sdk = new DopplerSDK({
    publicClient,
    chainId: base.id
  })

  const quoter = sdk.quoter

  console.log('💱 Price Quoter Example')
  console.log('=====================')

  // Example 1: Quote exact input on V3
  console.log('\n📊 Example 1: Swap 1 ETH for USDC on V3')
  try {
    const v3Quote = await quoter.quoteExactInputV3({
      tokenIn: weth,
      tokenOut: usdc,
      amountIn: parseEther('1'),
      fee: 3000 // 0.3% fee tier
    })
    
    console.log('- Amount out:', formatEther(v3Quote.amountOut), 'USDC')
    console.log('- Price impact (ticks crossed):', v3Quote.initializedTicksCrossed)
    console.log('- Gas estimate:', v3Quote.gasEstimate.toString())
    console.log('- Final sqrtPriceX96:', v3Quote.sqrtPriceX96After.toString())
  } catch (error) {
    console.error('V3 quote failed:', error.message)
  }

  // Example 2: Quote exact output on V3
  console.log('\n📊 Example 2: Get exactly 2000 USDC, pay in ETH on V3')
  try {
    const v3QuoteOut = await quoter.quoteExactOutputV3({
      tokenIn: weth,
      tokenOut: usdc,
      amountOut: parseEther('2000'), // Want exactly 2000 USDC
      fee: 3000
    })
    
    console.log('- Amount in required:', formatEther(v3QuoteOut.amountIn), 'ETH')
    console.log('- Price impact (ticks crossed):', v3QuoteOut.initializedTicksCrossed)
    console.log('- Gas estimate:', v3QuoteOut.gasEstimate.toString())
  } catch (error) {
    console.error('V3 exact output quote failed:', error.message)
  }

  // Example 3: Quote on V2 (if available)
  console.log('\n📊 Example 3: Swap 1 ETH for USDC on V2')
  try {
    const v2Quote = await quoter.quoteExactInputV2({
      amountIn: parseEther('1'),
      path: [weth, usdc]
    })
    
    console.log('- Amount out:', formatEther(v2Quote[1]), 'USDC')
    console.log('- Simple constant product AMM pricing')
  } catch (error) {
    console.error('V2 quote failed:', error.message)
  }

  // Example 4: Multi-hop V2 quote
  console.log('\n📊 Example 4: Multi-hop swap ETH -> USDC -> TOKEN on V2')
  try {
    const multiHopQuote = await quoter.quoteExactInputV2({
      amountIn: parseEther('1'),
      path: [weth, usdc, token] // ETH -> USDC -> TOKEN
    })
    
    console.log('Hop results:')
    console.log('- Start:', formatEther(multiHopQuote[0]), 'ETH')
    console.log('- After hop 1:', formatEther(multiHopQuote[1]), 'USDC')
    console.log('- Final:', formatEther(multiHopQuote[2]), 'TOKEN')
  } catch (error) {
    console.error('Multi-hop quote failed:', error.message)
  }

  // Example 5: V4 quote (for graduated dynamic auctions)
  console.log('\n📊 Example 5: Swap on V4 pool')
  try {
    const v4PoolKey = {
      currency0: weth,
      currency1: token,
      fee: 3000,
      tickSpacing: 60,
      hooks: '0x0000000000000000000000000000000000000000' as Address // No hook for graduated pool
    }
    
    const v4Quote = await quoter.quoteExactInputV4({
      poolKey: v4PoolKey,
      zeroForOne: true, // Swapping currency0 (WETH) for currency1 (TOKEN)
      exactAmount: parseEther('1')
    })
    
    console.log('- Amount out:', formatEther(v4Quote.amountOut), 'TOKEN')
    console.log('- Gas estimate:', v4Quote.gasEstimate.toString())
  } catch (error) {
    console.error('V4 quote failed:', error.message)
  }

  // Example 6: Compare quotes across versions
  console.log('\n🔄 Comparing quotes for 1 ETH -> USDC:')
  const results: { version: string; amountOut: bigint; gas: bigint }[] = []
  
  // Try V2
  try {
    const v2 = await quoter.quoteExactInputV2({
      amountIn: parseEther('1'),
      path: [weth, usdc]
    })
    results.push({ 
      version: 'V2', 
      amountOut: v2[1], 
      gas: BigInt(100000) // Approximate
    })
  } catch {}
  
  // Try V3
  try {
    const v3 = await quoter.quoteExactInputV3({
      tokenIn: weth,
      tokenOut: usdc,
      amountIn: parseEther('1'),
      fee: 3000
    })
    results.push({ 
      version: 'V3', 
      amountOut: v3.amountOut, 
      gas: v3.gasEstimate 
    })
  } catch {}
  
  // Sort by best output
  results.sort((a, b) => Number(b.amountOut - a.amountOut))
  
  console.log('\nBest quotes (sorted by output):')
  results.forEach((result, i) => {
    console.log(`${i + 1}. ${result.version}: ${formatEther(result.amountOut)} USDC (gas: ${result.gas})`)
  })
  
  if (results.length > 0) {
    console.log(`\n✅ Best option: ${results[0].version} with ${formatEther(results[0].amountOut)} USDC`)
  }

  console.log('\n✨ Example completed!')
}

main()

Auction monitoring

Token interactions

Last updated