Hop
Search…
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.
Copy link
On this page
Querying
Transfers
Volume
TVL
Fees
Pagination
JavaScript fetch example
FAQ