Query Guide

Introduction

This guide covers common query patterns, optimization techniques, and best practices for retrieving data from the Panda Protocol subgraph.

Basic Queries

Pool Data

# Get basic pool information
{
  pandaPool(id: "0x123...") {
    id
    price
    volumeUSD
    swapsCount
    graduated
  }
}

# List active pools with high volume
{
  pandaPools(
    where: {
      volumeUSD_gt: "100000",
      graduated: false
    }
    orderBy: volumeUSD
    orderDirection: desc
    first: 10
  ) {
    id
    price
    volumeUSD
  }
}

Trading Activity

# Recent swaps for a pool
{
  pandaPoolSwaps(
    where: { pool: "0x123..." }
    orderBy: timestamp
    orderDirection: desc
    first: 100
  ) {
    timestamp
    amountPandaIn
    amountPandaOut
    volumeUSD
    averagePrice
  }
}

Advanced Queries

Time-Based Queries

# Get pools with recent activity
{
  pandaPools(
    where: {
      lastSwapTimestamp_gt: "1634567890"
    }
  ) {
    id
    price
    lastSwapTimestamp
  }
}

# Get hourly price data
{
  priceSnapshots(
    where: {
      pool: "0x123...",
      timeframe: HOUR,
      timestamp_gt: "1634567890"
    }
    orderBy: timestamp
    orderDirection: asc
  ) {
    timestamp
    open
    high
    low
    close
  }
}

Market Analysis

# Top pools by volume
{
  pandaPools(
    orderBy: volumeUSD
    orderDirection: desc
    first: 5
  ) {
    id
    volumeUSD
    marketCapUSD
    swapsCount
  }
}

# Token holder distribution
{
  token(id: "0x123...") {
    symbol
    holdersCount
    holders(
      orderBy: balance
      orderDirection: desc
      first: 10
    ) {
      address
      balance
      sharePercentage
    }
  }
}

Query Optimization

Pagination

# Using skip/first for pagination
{
  pandaPoolSwaps(
    skip: 100    # Skip first 100 results
    first: 50    # Get next 50 results
    orderBy: timestamp
    orderDirection: desc
  ) {
    id
    timestamp
  }
}

Field Selection

# Good: Specific fields
{
  pandaPools {
    id
    price
    volumeUSD
  }
}

# Bad: Overfetching
{
  pandaPools {
    id
    price
    volumeUSD
    swapsCount
    lastSwapTimestamp
    graduated
    raised
    # ... unnecessary fields
  }
}

Using Fragments

# Define reusable fragments
fragment PoolBasics on PandaPool {
  id
  price
  volumeUSD
  swapsCount
}

# Use in queries
{
  activePools: pandaPools(
    where: { graduated: false }
  ) {
    ...PoolBasics
  }
  
  graduatedPools: pandaPools(
    where: { graduated: true }
  ) {
    ...PoolBasics
  }
}

Common Use Cases

Trading Interface Data

# Get pool trading data
{
  pandaPool(id: "0x123...") {
    price
    pandaReserve
    baseReserve
    swapsCount
    lastSwapTimestamp
    recentSwaps: swaps(
      first: 50
      orderBy: timestamp
      orderDirection: desc
    ) {
      timestamp
      amountPandaIn
      amountPandaOut
      averagePrice
    }
  }
}

Analytics Dashboard

# Get market overview
{
  statistics(id: "global") {
    totalVolumeUSD
    totalMarketCapUSD
    totalPandaPoolsCount
    totalGraduatedPandaPoolsCount
  }
  
  topPools: pandaPools(
    first: 5
    orderBy: volumeUSD
    orderDirection: desc
  ) {
    id
    volumeUSD
    marketCapUSD
    swapsCount
  }
}

Real-time Data Updates

Polling Strategy

# Efficient polling query
{
  pandaPool(id: "0x123...") {
    price
    lastSwapTimestamp
    pandaReserve
    baseReserve
  }
}

Using Block Numbers

# Query at specific block
{
  pandaPool(id: "0x123...", block: { number: 15000000 }) {
    price
    volumeUSD
  }
}

Error Handling

Null Checks

# Handle potential null values
{
  pandaPool(id: "0x123...") {
    id # Will be null if pool doesn't exist
    price
    # Always check optional relationships
    swaps(first: 1) {
      id
    }
  }
}

Block Timestamps

# Use block timestamps for time ranges
{
  pandaPoolSwaps(
    where: {
      timestamp_gt: "1634567890",
      timestamp_lt: "1634567990"
    }
  ) {
    timestamp
    averagePrice
  }
}

Best Practices

  1. Query Performance

    • Use pagination for large datasets

    • Select only needed fields

    • Optimize sorting and filtering

  2. Data Freshness

    • Consider indexing delays

    • Implement proper polling intervals

    • Use block numbers for consistency

  3. Error Recovery

    • Handle null entities gracefully

    • Validate data ranges

    • Implement retry logic

Next Steps

Continue to Advanced Usage for:

  • Complex query patterns

  • Performance optimization

  • Edge case handling

Support

Need help with queries?

Last updated