GraphQL recipes
Every query in this page is ready to paste into the HyperIndex playground (or
your urql / graphql-request client). The exact field names match the
schema in Entity reference; the Entity_aggregate
counterparts are HyperIndex-generated and follow the standard Hasura naming
convention.
All entities are namespaced by chain. Always include chainId: { _eq: $chainId } in production filters to keep mainnet and Sepolia rows
disambiguated.
All listings (including floors) for a collection
The FE typically wants the union of:
- Floor items (
format: NONE) — owned by the protocol, redeemable at the floor price. - Active liquid + dutch listings (
format_in: [LIQUID, DUTCH]).
Both live on the same Listing table; filter by format and order by
createdAt.
query AllListings($chainId: Int!, $collection: String!) {
Listing(
where: {
chainId: { _eq: $chainId }
collection: { collection: { _eq: $collection } }
}
order_by: { createdAt: desc }
limit: 200
) {
id
tokenId
owner
format
floorMultiple
duration
created
taxCaptured
}
}For a paginated UI:
query AllListingsPaged(
$chainId: Int!
$collection: String!
$limit: Int!
$offset: Int!
) {
Listing(
where: {
chainId: { _eq: $chainId }
collection: { collection: { _eq: $collection } }
}
order_by: { createdAt: desc }
limit: $limit
offset: $offset
) {
id
tokenId
owner
format
floorMultiple
}
Listing_aggregate(
where: {
chainId: { _eq: $chainId }
collection: { collection: { _eq: $collection } }
}
) {
aggregate { count }
}
}Live pool state for a collection
query PoolState($chainId: Int!, $collection: String!) {
Collection(
where: {
chainId: { _eq: $chainId }
collection: { _eq: $collection }
}
limit: 1
) {
id
collectionToken
poolKey
sqrtPriceX96
tick
liquidity
swapFee
protocolFee
defaultFee
poolFee
publicListings
shutdownPrevented
updatedAt
poolFees {
queuedAmount0
queuedAmount1
totalDonated0
totalDonated1
updatedAt
}
}
}queuedAmount0 / queuedAmount1 are denominated in V4-sorted currency
order (currency0 < currency1). Decode poolKey to figure out which side
is the native token vs the CollectionToken.
Recent pool-fee donations
Useful for an “Activity” feed showing when the hook has flushed accumulated fees back to LPs.
query RecentPoolFeeDonations($chainId: Int!, $collection: String!) {
PoolFeeDonation(
where: {
chainId: { _eq: $chainId }
collection: { collection: { _eq: $collection } }
}
order_by: { created: desc }
limit: 50
) {
amount0
amount1
txHash
triggeredBy
created
}
}A user’s listing activity
query UserListingActivity($chainId: Int!, $user: String!) {
ListingActivity(
where: {
chainId: { _eq: $chainId }
_or: [{ from: { _eq: $user } }, { to: { _eq: $user } }]
}
order_by: { created: desc }
limit: 100
) {
activityType
listing { id tokenId format owner }
collection { id collection name }
floorMultiple
ethPrice
txHash
created
}
}A user’s claimable escrow
This includes both listing refunds and AMM fees — the entity is a single
union since Listings and NFTXV4Hook both inherit TokenEscrow.
query UserEscrow($chainId: Int!, $payee: String!) {
TokenEscrow(
where: {
chainId: { _eq: $chainId }
payee: { _eq: $payee }
amount: { _gt: "0" }
}
order_by: { updated: desc }
) {
token
amount
updated
}
}Active shutdown for a collection (with my vote)
query ShutdownState(
$chainId: Int!
$collection: String!
$voter: String!
) {
CollectionShutdown(
where: {
chainId: { _eq: $chainId }
collection: { collection: { _eq: $collection } }
}
limit: 1
) {
id
quorum
quorumReachedAt
executedAt
liquidationPool
claimAvailable
votes(where: { voter: { _eq: $voter } }) {
votes
createdAt
}
claims(where: { claimant: { _eq: $voter } }) {
tokensBurnt
ethReceived
claimedAt
txHash
}
}
}All shutdowns past quorum but not yet executed
Operationally, this is what surfaces a “Click to execute” button.
query ExecutableShutdowns($chainId: Int!) {
CollectionShutdown(
where: {
chainId: { _eq: $chainId }
quorumReachedAt: { _is_null: false }
executedAt: { _is_null: true }
}
order_by: { quorumReachedAt: asc }
) {
id
collection { collection name }
quorum
quorumReachedAt
startedBy
startedAt
}
}Available airdrops for recipient
Airdrops are merkle-distributed; the subgraph indexes the distribution
header and every claim. To know what recipient can still claim you need
the off-chain merkle service to list eligible leaves; the subgraph is best
used to filter out already-claimed ones:
query AirdropClaimsForRecipient($chainId: Int!, $recipient: String!) {
AirdropClaim(
where: {
chainId: { _eq: $chainId }
recipient: { _eq: $recipient }
}
order_by: { claimedAt: desc }
limit: 100
) {
airdrop { id merkle claimType }
target
tokenId
amount
txHash
claimedAt
}
}For the “is this target allowed” check before showing the request UI:
query AirdropTargetAllowed($chainId: Int!, $target: String!) {
AirdropTarget(
where: {
chainId: { _eq: $chainId }
target: { _eq: $target }
}
limit: 1
) { allowed updatedAt }
}AMM fees taken in last 24h
query AmmFeesLast24h($chainId: Int!, $cutoff: numeric!) {
AmmFeeTaken(
where: {
chainId: { _eq: $chainId }
created: { _gt: $cutoff }
}
order_by: { created: desc }
) {
recipient
token
amount
txHash
created
}
}$cutoff is a unix-second BigInt (e.g. now() - 86400). Aggregate the
result client-side or use a HyperIndex AmmFeeTaken_aggregate { aggregate { sum { amount } } } if you only need a total.
Fee-override snapshot for a beneficiary
query FeeOverride($chainId: Int!, $beneficiary: String!) {
FeeOverride(
where: {
chainId: { _eq: $chainId }
beneficiary: { _eq: $beneficiary }
}
limit: 1
) { flatFee updatedAt }
}A flatFee of null means the override has been removed; a non-null value
overrides both the per-pool poolFee and the global defaultFee for swaps
routed through that beneficiary.
Resolve a collection’s effective listing config
Per-collection override fields on Collection are null when no override is
set — fall back to the matching Config default in that case.
query ListingConfig($chainId: Int!, $collection: String!) {
Collection(
where: { chainId: { _eq: $chainId }, collection: { _eq: $collection } }
limit: 1
) {
taxCalculator
maxFloorMultiple
minLiquidDuration
maxLiquidDuration
minDutchDuration
maxDutchDuration
liquidDutchDuration
}
Config(where: { chainId: { _eq: $chainId } }, limit: 1) {
defaultTaxCalculator
defaultMaxFloorMultiple
defaultMinLiquidDuration
defaultMaxLiquidDuration
defaultMinDutchDuration
defaultMaxDutchDuration
defaultLiquidDutchDuration
}
}Approved Listings contracts
query ApprovedListingsContracts($chainId: Int!) {
ListingsContract(
where: { chainId: { _eq: $chainId }, approved: { _eq: true } }
) { listings updatedAt }
}