Queries

Sample Subgraph Queries

Querying

Below are some sample queries you can use to gather information from the Hop contracts.

You can build your own queries using a GraphQL Explorer and enter your endpoint to limit the data to exactly what you need.

Transfers

  • Get transfer root info

{
  transfersCommitteds(
    where: {
      rootHash: "0xdda1a36c3cd03b88089659e3c949de2f7bc9e855cb1bdb08b754af765914b4f6"
    }
  ) {
    totalAmount
    transactionHash
    token
    timestamp
  }
}
  • Get list of transfer roots

{
  transfersCommitteds(orderBy: timestamp, orderDirection: desc) {
    totalAmount
    transactionHash
    token
    timestamp
  }
}
  • Get source transfer info

    • L2>L1 or L2>L2

{
  transferSents(
    where: {
      transferId: "0x696c75a27f70ae5210192164a0006a105e71a5b09c117340756bb09d85ddd9a5"
    }
  ) {
    timestamp
    amount
    bonderFee
    transactionHash
    token
    from
    recipient
  }
}
  • Getting transferId by transaction hash

{
  poolSnapshots(
    first: 1000
    orderBy: timestamp
    orderDirection: asc
    where: {
      pool: "0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014"
    }
  ) {
    amounts
    totalShares
    swapVolume
    swapFees
    liquidity
    pool {
      id
    }
  }
}
  • Get list of transfers

    • L2>L2 or L2>L1

      • Use L2 subgraphs for these queries (the subgraph used is the origin chain)

{
  transferSents(
    where: {
      timestamp_gt: 1650331530
      timestamp_lt: 1652898343
      destinationChainId: 42161
    }
  ) {
    transferId
    amount
    bonderFee
    transactionHash
    token
    timestamp
    from
    recipient
  }
}
  • L1->L2

    • Use L1 mainnet subgraph for these queries (the L1 subgraph is the origin chain)

      • Note: there is no transferId for L1->L2 transfers. The id is not the same as a transferId.

{
  transferSentToL2S(
    where: {
      timestamp_gt: 1650331530
      timestamp_lt: 1652898343
      destinationChainId: 42161
    }
  ) {
    amount
    relayerFee
    transactionHash
    token
    timestamp
    from
    recipient
  }
}
  • Get list of transfers that were bonded at destination chain

  • Use the destination chain subgraph for these queries

{
  withdrawalBondeds {
    amount
    transferId
    timestamp
    transactionHash
  }
}

Note: The WithdrawalBonded event does not contain the recipient or the original sender, so a lookup using the transferId will need to be used on TransferSent (origin from L2) or TransferSentToL2 (origin from L1) to retrieve those values.

Volume

  • Cumulative volume

{
  volumes {
    amount
    token
  }
}
  • Manual calculation

    • The amount on transferSents (xdai, polygon, arbitrum, optimism) and transferSentToL2S (mainnet) entities can be added up to get overall tx volume on each chain.

{
  transferSents {
    destinationChainId
    amount
    token
  }
}
{
  transferSentToL2S {
    destinationChainId
    amount
    token
  }
}
  • Daily Volume

{
  dailyVolumes(
    where: { token: "ETH", date_gt: 1636416000, date_lte: 1636583276 }
    orderBy: date
    orderDirection: desc
    first: 1
  ) {
    id
    amount
    token
    date
  }
}

The date range is calculated as such:

const now = Math.floor(Date.now() / 1000)
const dayId = Math.floor(now / 86400)
const startDate = (dayId - 1) * 86400
const endDate = now

TVL

⚠️ currently the TVL entities don't report fully accurate data because it's only using add/remove liquidity events instead of tracking transfer events. Use defillama to view accurate TVL.

  • Cumutative TVL

{
  tvls {
    amount
    token
  }
}
  • Cumulative AMM TVL

{
  ammTvls {
    amount
    token
  }
}

Fees

  • Cumulative AMM Fees

{
  ammFees {
    amount
    token
  }
}
  • Cumulative Bonder Fees

{
  bonderFees {
    amount
    token
  }
}

Manual calculation The bonder fee can be calculated by adding the bonderFee value from transferSents entities

{
  transferSents {
    bonderFee
    destinationChainId
    token
  }
}
  • LP fees

    • The LP fees can be calculated by adding up tokensSold0.0004* from *tokenSwaps* entities

{
  tokenSwaps {
    tokensSold
    token
  }
}

Pagination

JavaScript fetch example

  async function queryFetch(url, query, variables) {
    const res = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json'
      },
      body: JSON.stringify({
        query,
        variables: variables || {}
      })
    })
    const jsonRes = await res.json()
    if (jsonRes.errors && json.errors.length) {
      throw new Error(jsonRes.errors[0].message)
    }
    return jsonRes.data
  }

  async function main() {
    const url = 'https://api.thegraph.com/subgraphs/name/hop-protocol/hop-mainnet'
    const query = `
      query TransferSentToL2($destinationChainId: Int) {
        events: transferSentToL2S(
          where: {
            destinationChainId: $destinationChainId
          },
          orderBy: timestamp,
          orderDirection: desc
        ) {
          id
          destinationChainId
          amount
          amountOutMin
          relayerFee
          recipient
          deadline
          transactionHash
          timestamp
          token
          from
        }
      }
    `
    const variables = {
      destinationChainId: 137
    }
    const result = await queryFetch(url, query, variables)
    console.log(result)
  }

  main().catch(console.error)

FAQ

Why are there multiple subgraphs? At the moment a subgraph with TheGraph can only be tied to one chain meaning it doesn't have the context or events from the other chains, hence the chain specific subgraph urls. Maybe in the future TheGraph will support multi-chain subgraphs.

Last updated