Indexer (GraphQL)
The protocol runs a Ponder indexer that follows every protocol contract from the deploy block and maintains the tables below. It is the right data source for anything historical or aggregate: acquisition history, auction bid logs, burn totals, referral ledgers. Current single values (the live bid, an auction's high bid) are better read from the chain directly, which the indexer necessarily lags by a block or so.
The indexer's full source lives in the public repo under
indexer/:
ponder.schema.ts defines the tables, src/index.ts the event handlers.
Endpoint
The GraphQL endpoint is deployment-configured, not a fixed public URL. The
site's server reads it from the INDEXER_URL environment variable and
queries it server-side only; the browser never talks to the indexer
directly. To run your own instance, point the Ponder app at a mainnet RPC
and it serves the standard Ponder GraphQL API at both / and /graphql
(plus /health and /ready).
Ponder's GraphQL exposes each table twice: a singular field that takes the
primary key (returnAuction(id: 5822), protocolCounter(id: "global"))
and a pluralized connection with where / orderBy / orderDirection /
limit arguments whose rows sit under items
(returnAuctions(...) { items { ... } }).
Tables
Acquisitions and the live bid
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
acquisition |
Per-Punk latest acquisition, keyed by punkId and overwritten on re-acquisition of a returned Punk (mirrors the on-chain per-Punk readers) |
punkId, targetTraitId, mask, acquirer, originalSeller, priceWei, custody (InReturnAuction / ReturnedToMarket / Vaulted), acquisitionCount, latestHistoryId |
PermanentCollection.AcquisitionRecorded; custody patched by CustodyUpdated |
acquisitionHistory |
Append-only log, one row per acquisition ever recorded (never overwritten) | punkId, seq (0-based per-Punk index), targetTraitId, priceWei, custody (this acquisition's terminal outcome), timestamp, txHash |
PermanentCollection.AcquisitionRecorded; custody patched by CustodyUpdated |
traitTrial |
Per-trait count of acquisitions that have targeted it (the input to the return-auction reserve escalation) | traitId, count, lastPunkId |
PermanentCollection.AcquisitionRecorded |
traitTransition |
Trait state transitions | kind (Pending / Collected), punkId, bits (the trait bitmask) |
PermanentCollection.TraitsPending / TraitsCollected |
bidEvent |
Every live-bid flow event: acceptances and inflows | kind (Accepted / ListingAccepted / BareTopUp / Contribution / PoolReplenished), punkId, seller, caller, amount, finderFee, referrer, tag, referrerShare |
Patron.BidAccepted / ListingAccepted; LiveBidAdapter.BareTopUp / Contribution / PoolReplenished |
allowlistEntry |
Patron's seller allowlist, keyed by seller address | seller, active, addedAt, removedAt |
Patron.AllowedSellerAdded / AllowedSellerRemoved |
Return auctions
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
returnAuction |
Per-Punk auction state, keyed by punkId; reset when a returned Punk is re-auctioned |
punkId, targetTraitId, acquisitionCost, reserveWei, startedAt, endsAt, highBidWei, highBidder, extensions, settled, outcome (Cleared / Vaulted), bountyShareWei, burnShareWei |
ReturnAuctionModule.ReturnAuctionStarted / BidPlaced / ReturnAuctionExtended / ReturnAuctionCleared / PunkVaulted |
bid |
Append-only return-auction bid log | punkId, bidder, amount, endsAt, extended (whether this bid triggered an anti-snipe extension) |
ReturnAuctionModule.BidPlaced |
refund |
Outbid-refund pull-queue activity | kind (Queued / Withdrawn), bidder, amount |
ReturnAuctionModule.RefundQueued / RefundWithdrawn |
Vault and Proofs
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
vaultedPunk |
One row per Punk permanently vaulted | punkId, collectedTraitId, vaultedAtBlock, txHash |
ReturnAuctionModule.PunkVaulted |
proof |
One row per Proof NFT (token ids 0..110, tokenId == traitId), minted on the first vaulting of a trait; the mint record is immutable, currentOwner follows transfers |
tokenId, traitId, punkId, recipient (originalSeller at mint), currentOwner, sequence (1-based collection order), mintedAt |
PunkVault.ProofMinted; owner patched by PunkVault.Transfer |
punkVaultTransfer |
Append-only ERC721 transfer log for PunkVault tokens (the 111 Proofs plus the Vault Title, token id 111) | tokenId, from, to, txHash |
PunkVault.Transfer |
Fees and burns
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
adapterSweep |
LiveBidAdapter forwards into Patron; keeper rewards land as sibling rows (-reward id suffix) joinable by txHash |
ethSwept, ethForwarded, ethBuffered, keeper, keeperReward |
LiveBidAdapter.Swept / KeeperReward |
vaultBurnSweep |
VaultBurnPool releases to BuybackBurner on vault-path settles | amount, txHash |
VaultBurnPool.Swept |
burnerDeposit |
ETH arriving at BuybackBurner | source, amount, remainingEth |
BuybackBurner.BurnEthDeposited |
burnStep |
Each ETH → $111 → 0xdead burn step; execution rewards land as sibling -reward rows |
ethSpent, tokensBurned, remainingEth, executionReward, caller |
BuybackBurner.TokensBurned / ExecutionRewardPaid |
parameterChange |
Admin parameter retunes on the two contracts that still have setters | contract (LiveBidAdapter / BuybackBurner), key, oldValue, newValue |
LiveBidAdapter.ParameterChanged / BuybackBurner.ParameterChanged |
Title auction
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
titleAuctionState |
Singleton row (id: "global") tracking the Vault Title auction lifecycle |
kickedOff, settled, endsAt, highBidWei, highBidder, winner, finalHighBidWei, restartCount, extensionsThisRound |
PunkVaultTitleAuction.Kickoff / Bid / Extended / Settled / SettledNoBidder |
titleAuctionBid |
Append-only Title bid log | bidder, amount, endsAt, extended |
PunkVaultTitleAuction.Bid |
titleAuctionRefund |
Refund pull-queue activity | kind (Queued / Withdrawn), bidder, amount |
PunkVaultTitleAuction.RefundQueued / RefundWithdrawn |
titleAuctionProceeds |
Proceeds pull-queue activity | kind (Queued / Withdrawn), recipient, amount |
PunkVaultTitleAuction.ProceedsQueued / ProceedsWithdrawn |
Referrals
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
referrer |
Per-referrer aggregate, keyed by address; balance mirrors ReferralPayout.balances(referrer) on chain |
balance (= totalCredited - totalClaimed), totalCredited, totalClaimed, lastCreditedAt, lastClaimedAt |
ReferralPayout.ReferralCredited / ReferralClaimed |
referralCredit |
Append-only credit log (one row per attributed-swap payout) | referrer, amount, txHash |
ReferralPayout.ReferralCredited |
referralClaim |
Append-only claim log | referrer, amount, txHash |
ReferralPayout.ReferralClaimed |
Counters
| Table | What it records | Key fields | Fed by |
|---|---|---|---|
protocolCounter |
Singleton row (id: "global") of protocol-wide headline numbers, cheaper than aggregating the event tables |
collectedCount, acquisitionCount, vaultedCount, clearedCount, proofsMinted, totalEthBurned, totalTokensBurned, totalBountyInflowsWei, totalVaultBurnSweptWei, totalContributionVolumeWei, totalSwapVolumeWei, swapCount |
bumped by many handlers; the swap volume and count come from the skim hook's per-swap SkimSplit events, filtered to the official pool |
Rows in the event-log tables are keyed <txHash>-<logIndex> unless noted;
per-entity tables key on the natural id (punkId, traitId, tokenId, an
address). Timestamps are unix seconds, amounts are wei, both serialized as
strings in GraphQL responses.
Example queries
Headline protocol stats:
{
protocolCounter(id: "global") {
collectedCount
vaultedCount
clearedCount
proofsMinted
totalEthBurned
totalTokensBurned
totalSwapVolumeWei
swapCount
}
}Open return auctions, soonest-ending first:
{
returnAuctions(
where: {settled: false}
orderBy: "endsAt"
orderDirection: "asc"
) {
items {
punkId
targetTraitId
reserveWei
highBidWei
highBidder
endsAt
extensions
}
}
}Every Proof minted so far, in collection order, with current holders:
{
proofs(orderBy: "sequence", orderDirection: "asc", limit: 111) {
items {
tokenId
traitId
punkId
recipient
currentOwner
sequence
mintedAt
}
}
}