Events and Indexing
Every state change in ClaimRush emits a Solidity event. These events are the primary data source for subgraphs, analytics dashboards (Dune), push notifications, and achievement systems. This page lists the canonical event tables by contract and the tooling you need to index them.
Canonical sources
| What | Where |
|---|---|
| Event signatures | src/lib/Events.sol (plus contract-local events like DelegationHub.SessionSet) |
| Decoding rules | docs/analytics/dune-integration-pack-v1.0.0.md |
| ABIs | abis/<network>/*.abi.json |
| Addresses | deployments/<network>.json |
| Runtime watcher set | services/event-watcher/src/abi.ts (canonical set of events actually watched in production; see docs/spec/real-time-layer-spec-v1.0.0.md) |
Rule: Filter logs by evt_block_number >= startBlock.
Event codebooks (immutable)
| Enum | Values |
|---|---|
ShareholderClaim.mode | 0=ETH, 1=LOCK_FURNACE |
AutoCompoundPaused.reasonCode | 1=NOT_OWNER, 2=LISTED, 3=EXPIRED, 4=INVALID_TOKEN_ID, 5=FURNACE_REVERT, 6=QUOTE_FAILED, 7=CHECKPOINT_FAILED (also used by ShareholderAutoCompoundPaused and KingAutoLockSkipped) |
FurnaceEnter.mode | 0=ENTER_WITH_ETH, 1=ENTER_WITH_CLAIM, 2=LOCK_FURNACE, 3=ENTER_WITH_TOKEN, 4=EXTEND_WITH_BONUS |
LockDelisted.reason | 0=NORMAL, 1=EMERGENCY, 2=SOLD_INTO_OFFER (reserved; not emitted), 3=SOLD_TO_FURNACE, 4=EXPIRED, 5=APPROVAL_REVOKED (reserved; not emitted) |
DelegationSessionUsed.actionTypeId | 1=TAKEOVER_FOR; 2=MINECORE_SET_REIGN_RECIPIENTS (coarse actionType enum: REIGN_RECIPIENTS); 10-12=CLAIM; 20-22=FURNACE_ENTER; 30-32=VE_LOCK; 40-42=CONFIG (see docs/manuals/developer/delegationhub.md) |
Key event groups
This list is intentionally not exhaustive. It highlights the events most commonly consumed by UIs/indexers; treat src/lib/Events.sol as the source of truth.
MineCore: EntryTokenRegistrySet, FurnaceChanged, Takeover, ReignRecipientsSet, ReignFinalized, TakeoversPausedChanged, KingWithdrawal (+ KingWithdrawalTo), KingEthCredited, KingEthPaid, PendingClaimWithdrawn, Refund* (RefundCredited, RefundWithdrawn), ShareholderRoyaltiesTakeoverFailed, ShareholderRoyaltiesFlushFailed, FurnaceCreditReserveFailed, KingAutoLock*
DelegationHub / Delegation: SessionSet, DelegationSessionUsed
VeClaimNFT: FurnaceChanged, MineMarketChanged, LockCreated, LockExtended, LockAmountIncreased, LockMerged, LockUnlocked, AutoMaxSet, Transfer (burn/transfer tracking), DelegationSessionUsed, SlopeDriftClamped, ShareholderCheckpointFailed
ShareholderRoyalties: ShareholderWiringSet, ShareholderTakeoverAllocation, ShareholderFlush, ShareholderClaim (emitted on every ETH/lock claim), ShareholderAutoCompound*, RewardCheckpointCapReached, OverflowCheckpointCapReached
Furnace: MineCoreChanged, MineMarketChanged, ShareholderRoyaltiesChanged, FurnaceEnter, AutoMaxBonusClaimed, BonusPaid†, LpOverflowDripPaid†, LockSoldToFurnace†, LpStreamFunded, ReserveCredited, ReserveClamped, FurnaceQuoterSet, LpRewardsVaultSet, LpRewardsNotifyFailed, LockingPausedChanged
†
BonusPaid,LpOverflowDripPaid, andLockSoldToFurnaceare emitted from the Furnace address viadelegatecallintoFurnaceGuardHelper(EIP-170 bytecode relief). The events are declared inIFurnaceso they appear in Furnace’s compiled ABI and can be decoded by block explorers and indexers without merging a secondary ABI.
LpStakingVault7D: LpStaked, LpUnbondStarted, LpUnbondWithdrawn, LpRewardsNotified, LpRewardsClaimed, LpRewardsLocked, HarvestKeeperSet, AutoCompound*, LpFeesHarvestedToRewards, DelegationSessionUsed
MarketRouter: LockListed (limit sell / Market listing: minClaimOut + expiresAtTime), LockDelisted, ListingSettled, MarketSellToFurnace, SettlementKeeperSet, BonusTargetEscrowParamsChanged, TradingPausedChanged, BonusTargetEscrow* (limit buy / Buy intent: Created, Configured, Executed, AutoFurnaceExecuted, Expired, Cancelled, ExpiryExtended)
MaintenanceHub: Poked (includes checkpointOk and flushOk boolean flags indicating whether the ve checkpoint and shareholder flush succeeded individually), TokenRescued
Genesis: GenesisFinalized, SkimFailed (bounded revert data from failed pool skim), Locked, LockExtended, WithdrawLp (to is indexed), TokenRescued
Decoding notes
- Reign recipients:
ReignRecipientsSet(reignId, king, ethRecipient, claimRecipient)can be emitted mid-reign.kingis the active reign identity whose routing changed, not the transaction caller. Use it to track where the dethroned-King 75% ETH payout and the King-stream CLAIM are routed. - Auto-compound pause reasons: the
reasonCodecodebook is shared acrossAutoCompoundPaused,ShareholderAutoCompoundPaused, and MineCore’sKingAutoLockSkipped. - MineCore king withdrawals:
KingWithdrawal(user, amount)is always emitted.KingWithdrawalTo(user, to, amount)is emitted only when ETH was successfully delivered toto(not on fallback touser). Iftorejects ETH and differs fromuser, MineCore retries delivery touser; in that case onlyKingWithdrawalfires. - King ETH payout success:
KingEthPaid(recipient, amount)fires when the dethroned-King ETH payout push succeeds during a takeover. - King ETH payout fallback:
KingEthCredited(recipient, amount)fires when the best-effort dethroned-King payout push (bounded gas stipend) fails during a takeover. The ETH is credited tokingEthBalance[recipient]for pull withdrawal viawithdrawKingBalance(). - Pending CLAIM withdrawal:
PendingClaimWithdrawn(user, to, amount)fires when a user (or ClaimAllHelper on their behalf) withdraws pending CLAIM frompendingClaimBalance(credited when the auto-lock path skips or fails during a reign settlement). - Furnace reserve credit failure:
FurnaceCreditReserveFailed(furnace, amount, reason)fires whenFurnace.creditReserve(amount)reverts during a takeover. MineCore has already minted and transferred the CLAIM to the Furnace address, but the internal reserve accounting update failed. Thereasonfield contains bounded revert data. Treat this as an operational alert — the Furnace holds the CLAIM butfurnaceReserveis understated until a subsequent_syncFurnaceReserve()call corrects it. - LP Harvest & Lock:
LpRewardsLocked.tokenIdis the actual destination lock id returned byFurnace.enterWithClaimFor. If a new lock is minted, this is the minted token id (not the quote placeholder0). - LP auto-compound heuristic:
LpRewardsLockedEvent.autoCompoundedin the subgraph is derived from the top-leveltx.inputselector (matchingcompoundFor/compoundForMany). If the auto-compound is routed through an intermediary contract (e.g., MaintenanceHub or a future batching proxy), the heuristic returnsfalsebecause the subgraph cannot see internal calldata. Consumers that need reliable auto-compound attribution should cross-reference with the executor address or the upstreamAutoCompoundConfiguredstate. - Reserved delist reasons:
SOLD_INTO_OFFER(2) andAPPROVAL_REVOKED(5) exist in the analytics codebook but the strict-mode router does not emit them. Production indexers should expect liveLockDelisted.reasonvalues ofNORMAL,EMERGENCY,SOLD_TO_FURNACE, andEXPIRED. - Royalties hardening: If ShareholderRoyalties errors during takeover, MineCore emits:
ShareholderRoyaltiesTakeoverFailed(reignId, amountEth, reason)whenonTakeoverreverts (ETH is held in MineCore.shareholderEthPending for retry)- the same
ShareholderRoyaltiesTakeoverFailed(...)event is also emitted ifretryPushShareholderEth()later fails; in that retry pathreignId = 0andamountEthis the retried pending bucket ShareholderRoyaltiesFlushFailed(reason)whenflushPendingShareholderETHreverts (ETH remains in ShareholderRoyalties.pendingShareholderETH for later flush)reasoncontains bounded revert data (up to 128 bytes) via_boundedRevertData(). Indexers can decode standard revert selectors from this field.
- Baron auto-compound failures:
ShareholderAutoCompoundFailed(user, amountEth, tokenId)fires when the downstreamFurnace.lockEthReward(...)call reverts during auto-compound, or when the quote call fails incompoundForMany. The user’s ETH remains in ShareholderRoyalties (theirclaimableEthbalance is unchanged). For Furnace reverts,ShareholderAutoCompoundPausedis also emitted with a reason code indicating the failure type. For quote failures in the batch path (compoundForMany), the user is skipped (not paused), so retry is automatic on the next cadence. Keepers should surfaceShareholderAutoCompoundFailedevents for operator alerting. - King auto-lock failures:
KingAutoLockFailed.revertDatais not generic downstream revert data. MineCore emits selector-encodedErrors.ZeroAddress/Errors.WiringMismatchfor pre-call fail-closed cases. If the downstream Furnace call itself reverts,revertDatacontains bounded revert data (up to 128 bytes) via_boundedRevertData(). - Furnace LP stream:
BonusPaid.lpTopupClaim,LpOverflowDripPaid.dripAmount, and sellbacklpRewardall re-fund the stream schedule. Each re-fund emitsLpStreamFunded(amountFunded, newRatePerSec, newPeriodFinish). Stream accrual later transfers CLAIM to the LP vault and attemptsnotifyRewards(...); successful notifies emitLpRewardsNotified, while failed notifies emitLpRewardsNotifyFailed(vault, amountClaim, revertData). In v1.0.0 thatrevertDatafield is emitted as empty bytes for hardening, and the vault can later reconcile the same CLAIM via balance-delta on a successful notify or fee harvest. The subgraph persists immutableLpStreamFundedEventrows and mirrors the latest schedule ontoFurnaceState.lpStreamRatePerSec/FurnaceState.lpStreamPeriodFinish. - enterWithToken: FurnaceEnter doesn’t include tokenIn/amountIn; recover from calldata or ERC20 Transfer logs.
- EntryTokenRegistry: MineCore and Furnace emit
EntryTokenRegistrySetindependently. - Planned events (not yet declared):
MarketLockRetargetedandMarketLockAbsorbedare reserved names for future MineMarket lock retargeting/absorption functionality. They are not currently declared insrc/lib/Events.sol, not emitted by any contract, not present in shipped ABIs, and not indexed by the subgraph. No indexer or frontend action is needed until the corresponding contract logic ships. When these events do ship, they must be added toEvents.sol, exported in the ABI, and wired into subgraph handlers; track in the MineMarket implementation checklist. - Protocol wiring singleton:
Protocol.mineCore,Protocol.marketRouter,Protocol.furnace, andProtocol.shareholderRoyaltiesrepresent the latest observed current wiring inside the indexed event surface, not one-time seeds. Canonical update receipts areMineCore.FurnaceChanged,VeClaimNFT.FurnaceChanged,VeClaimNFT.MineMarketChanged,Furnace.MineCoreChanged,Furnace.MineMarketChanged,Furnace.ShareholderRoyaltiesChanged, andShareholderRoyalties.ShareholderWiringSet. Note:DelegationHub,ClaimAllHelper,DexAdapter,ClaimToken,AgentLens,FurnaceQuoter, andMineCoreQuoterhave no wiring-update events indexed (DexAdapter, ClaimToken, FurnaceQuoter, MineCoreQuoter, and AgentLens are not subgraph datasources at all). - ve snapshot semantics:
User.veBalanceWeiandVeLock.currentVeWeiin the shipped subgraph are event-driven snapshots. They do not continuously decay between unrelated events. Frontend/API consumers that need “ve now” MUST recompute fromamountWei,lockEnd, andautoMaxagainst the same payload’s_meta.block.timestampwhen available, or use the derived leaderboard/snapshot job. For per-user surfaces, that lock list MUST be the full owner snapshot, fetched via paginatedtokenIdcursor reads at one pinned head, not a cappedfirst: Nowner query. Wall-clock fallback is acceptable only when_metais unavailable. - Delegation sessions:
DelegationSessionUsed.actionTypeIdis a numeric code (not an enum).refIdmeaning depends on the action. Seedocs/manuals/developer/delegationhub.md. RawactionTypeIdis canonical; the shipped coarse subgraph enum insubgraph/src/utils/delegation.tsmapsactionTypeId = 2(MINECORE_SET_REIGN_RECIPIENTS) toREIGN_RECIPIENTS. Security-session UIs MUST derive active vs expired from the same payload’s_meta.block.timestamp, not wall clock. A session is active iffperms > 0andexpiry >= _meta.block.timestamp;expiry = 0is immediately expired, not active. Radar-style delegation/reign-recipient alert polling MUST page forward from a pinned(blockNumber,id)cursor at one_metahead or fail closed; a cappedfirst: Nrecent-events query plus local seen-ID diff is a correctness bug because it can silently miss alerts. - Listing state: veNFTs do not emit dedicated “listed/frozen” events. Use MarketRouter events (
LockListed,LockDelisted,ListingSettled) to index listing lifecycle. - Auto-furnace execution receipts:
executeAutoFurnaceemits bothBonusTargetEscrowExecutedandBonusTargetEscrowAutoFurnaceExecutedin the same tx. Treat the genericBonusTargetEscrowExecutedreceipt as canonical execution accounting; the auto-furnace-specific receipt is a detail companion. The shipped subgraph intentionally emits theActivityItemonly from theBonusTargetEscrowAutoFurnaceExecutedhandler to avoid duplicate activity rows. If a future execution path emits only the generic receipt (without the companion), activity feed consumers would silently miss the event. - Offer history rows: the subgraph writes
BonusTargetEscrowEvent.kind = FILLEDfrom the generic execution receipt.AUTO_FURNACE_EXECUTEDis retained as the same-tx companion row for detail consumers, so history UIs SHOULD filter or dedupe companion rows to avoid showing one fill twice. - Destination lock fallback:
DestinationLockIneligible(offerId, destinationLockId)fires duringexecuteAutoFurnacewhen the buyer’s requested destination lock is no longer eligible (expired, transferred, or delisted) and execution falls back to creating a new lock. Indexers should surface this for keeper/buyer alerting.
Indexing strategy
- Use shipped ABIs as single decoding input; subgraph manifests MUST reference the exported
abis/<network>/*.abi.jsonfiles directly rather than maintaining event-only copies undersubgraph/abis/. - Prefer event-driven state (e.g., LockCreated/Extended/Unlocked for lifecycle)
- Storage reads only for spot dashboard values
- Follow
docs/analytics/metrics-canon-v1.0.0.mdfor metrics - Leaderboards:
docs/analytics/indexer-and-dune-implementation-guide-v1.0.0.md - Manifest drift checks:
make subgraph-manifest-sync-check(orpython3 scripts/sync_subgraph_manifest_from_deployments.py --check ...) - Runtime readiness checks:
make subgraph-live-runtime-readiness-check(orpython3 scripts/check_subgraph_manifest_runtime_readiness.py subgraph/subgraph.prod.yaml ...) - Frontend/API head-consistency checks:
python3 scripts/check_frontend_subgraph_head_consistency.py - Owner-lock snapshot pagination checks:
python3 scripts/check_owner_lock_snapshot_pagination.py - Delegation security polling/status checks:
python3 scripts/check_delegation_security_polling.py - ABI coverage checks:
python3 scripts/check_subgraph_events_vs_abi.py subgraph/subgraph.yaml ... - Mutable wiring semantic checks:
python3 scripts/check_subgraph_protocol_wiring_semantics.py - Docs event-checklist parity checks:
python3 scripts/check_subgraph_doc_event_checklist.py - Codegen/build layout checks:
python3 scripts/check_subgraph_codegen_layout.py - Manifest entity completeness checks:
python3 scripts/check_subgraph_manifest_entities.py subgraph/subgraph.yaml ... - Derived event-kind parity checks:
python3 scripts/check_subgraph_derived_event_kinds.py - Subgraph query allowlist sync/check:
make subgraph-query-allowlist-check(validation) andmake subgraph-query-allowlist-sync(updatesworkers/chat/.subgraph-query-allowlist.envplusworkers/chat/wrangler.jobs.tomlprod/staging values); interpolated templates still need manual review - Local subgraph caveat: the local/default manifests (
subgraph/subgraph.local.yamlandsubgraph/subgraph.yamlwhen pointed atdeployments/local.json) intentionally omit the Furnace block handler. On local graph-node setups, bonus quote snapshots only advance on Furnace bonus/reserve-affecting events, so idle-period quote history can look stale until the next relevant event.
Intentionally unindexed ABI events
The following ABI events are intentionally NOT handled by the subgraph because they are admin/ownership/approval lifecycle events that do not affect the product UI or analytics. Additionally, five ABI-exported contracts (AgentLens, ClaimToken, DexAdapter, FurnaceQuoter, MineCoreQuoter) are not subgraph datasources; their events are not indexed because those contracts either have zero events (AgentLens, FurnaceQuoter, MineCoreQuoter) or only emit admin/ownership events (DexAdapter) or wiring events already redundantly covered by other indexed contracts (ClaimToken.MineCoreChanged):
ConfigFrozen (ClaimToken, Furnace, MineCore, VeClaimNFT, ShareholderRoyalties), GuardianChanged (Furnace, MineCore, MarketRouter), OwnershipTransferStarted / OwnershipTransferred (7 contracts), Approval / ApprovalForAll (VeClaimNFT), EIP712DomainChanged (DelegationHub), ClaimAllHelperChanged (MineCore, ShareholderRoyalties), DelegationHubChanged (MineCore, Furnace), DustSwept (ShareholderRoyalties — owner-only sub-wei rounding dust recovery), RewardCheckpointCapReached / OverflowCheckpointCapReached (ShareholderRoyalties — operational monitoring for checkpoint array growth), EmergencyVaultRewireCancelled / EmergencyVaultRewireExecuted / EmergencyVaultRewireRequested (Furnace — guardian emergency LP vault rewire lifecycle; ops/audit trail only), DestinationLockIneligible (MarketRouter — swap routing rejects ineligible ve lock destination; no subgraph entity state), MetadataUpdate / BatchMetadataUpdate / BaseURISet / ContractURISet / ContractURIUpdated (VeClaimNFT — ERC-4906/ERC-7572 metadata signals for wallets and marketplaces; admin-only URI setters). These are documented in scripts/check_subgraph_events_vs_abi.py in the INTENTIONALLY_UNINDEXED_EVENTS allowlist and validated in CI. If any of these become product-relevant, add a manifest handler and remove from the allowlist.
Agent tooling
Repo tooling for offchain agents lives in agents/sdk/. It includes:
getGameStateSnapshot({ publicClient, manifest, ... })(AgentLens-first, multicall fallback)- JSONL event streamer (RPC logs, optional subgraph backfill)
- subgraph lag/core event-discoverable address parity checker
Run the streamer:
RPC_URL=...
npm -C agents/sdk run example:eventsBackfill recent history from the subgraph before live RPC logs:
RPC_URL=...
SUBGRAPH_URL=...
npm -C agents/sdk run example:events -- --backfill --backfill-limit 100Validate subgraph health + core/event-discoverable address parity:
RPC_URL=...
SUBGRAPH_URL=...
npm -C agents/sdk run example:subgraph-health -- --prettyDune integration
| Resource | Path |
|---|---|
| Event decoding + codebooks | docs/analytics/dune-integration-pack-v1.0.0.md |
| Metric meanings | docs/analytics/metrics-canon-v1.0.0.md |
| Leaderboards | docs/analytics/leaderboards-ui-and-dune-compatible-v1.0.0.md |
| SQL templates | analytics/dune/ |
Usage: Get addresses from manifests → decode with ABIs → filter by startBlock → build from templates.
Achievements engine
Cosmetic badges computed offchain in chat worker.
Endpoint: GET /api/achievements?address=0x...&chainId=8453
Config (workers/chat): SUBGRAPH_URL (required), SUBGRAPH_AUTH_TOKEN (optional), ACHIEVEMENTS_SYNC_ENABLED, ACHIEVEMENTS_SYNC_OVERLAP_BLOCKS, ACHIEVEMENTS_SYNC_BATCH_SIZE
Required subgraph entities: Takeover, ReignFinalizedEvent, VeLock*Event, ShareholderClaimEvent, FurnaceEnterEvent, FurnaceState, LpStreamFundedEvent, MarketLockListedEvent, MarketSellToFurnaceEvent, BonusTargetEscrowEvent, BonusTargetEscrowExecutedEvent, BonusTargetEscrowAutoFurnaceExecutedEvent, LpStakedEvent, etc. See subgraph/schema.graphql.
Hard rule (background consumers): any capped subgraph history/event window MUST either paginate or fail closed. The shipped chat-worker consumers reject saturated windows for recent-touch scans, badge-profile history, Furnace percentile lookbacks, and push dispatch (RECENT_TOUCH_WINDOW_OVERFLOW, PROFILE_FOR_BADGES_WINDOW_OVERFLOW, FURNACE_PERCENTILE_WINDOW_OVERFLOW, PUSH_EVENT_WINDOW_OVERFLOW) so cursors and achievements/notifications cannot silently drift from truncated results. Push dispatch also MUST capture _meta first, pin its event query to that indexed head, and advance both last_dispatch_ts and last_unlock_scan_ts to the indexed head timestamp, never to wall clock.
Hard rule (timestamp-sorted feeds): if a frontend/API activity feed is ordered by timestamp desc, the cursor MUST carry both the boundary timestamp and a stable tie-breaker id. A raw id_lt filter is invalid for ActivityItem because ids are txHash/logIndex-derived and not monotonic by timestamp. The shipped /api/activity-feed path is guarded in CI by scripts/check_activity_feed_pagination.py.
Hard rule (owner lock sets): any frontend/API surface that derives current ve, active lock count, or lock eligibility from an owner’s lock set MUST fetch the full owner lock set via paginated tokenId cursor reads pinned to one _meta head. This applies both to direct veLocks(where: { owner: ... }) queries and to relation shortcuts like user(id: ...) { locks(first: N) }. A capped first: N owner-lock query is a correctness bug because it silently undercounts power users. The shipped frontend is guarded in CI by scripts/check_owner_lock_snapshot_pagination.py.
Hard rule (security session sets): any frontend/API surface that shows active delegation-session counts, active delegate cards, or bulk revoke targets MUST fetch the full delegationSessions set via paginated id cursor reads pinned to one _meta head. A capped delegationSessions(first: N) query is a correctness bug because it can hide active delegates and make revoke/security surfaces incomplete. The shipped frontend is guarded in CI by scripts/check_delegation_security_polling.py.
Hard rule (client-derived crown decay): any frontend surface that derives Crown takeover price, cost tier, or decay zone from subgraph data MUST use the same payload’s _meta.block.timestamp as “now”, including SSR/prefetched variants. A wall-clock-only derivation can drift ahead of the indexed head under lag and misstate urgency. The shipped Overview and Radar consumers are guarded in CI by scripts/check_frontend_subgraph_head_consistency.py.
Hard rule (multi-query analytics/admin surfaces): any dashboard or API route that stitches multiple event/entity windows into one payload MUST capture _meta first, pin every follow-up read to that same block, and bound every window to that same indexed timestamp. If _meta is unavailable, the consumer MUST fail closed instead of mixing wall-clock time with subgraph data. The shipped admin system metrics route is guarded in CI by scripts/check_admin_system_metrics_snapshot_consistency.py.
Hard rule (public Furnace windows): any frontend/API surface that reports Furnace 7d bonus payouts, 24h entry counts, or similar event windows MUST capture _meta first, pin the window scan to that block, and paginate with a stable cursor. skip pagination on a moving head is invalid for these public metrics because it can silently miss or double-count rows while the indexer advances. The shipped Furnace/Home consumers are guarded in CI by scripts/check_frontend_subgraph_head_consistency.py.
Hard rule (active market order sets): any surface that shows a user’s active listings or active offers MUST page the full active-order set at one pinned head. A capped marketListings(... first: N) or bonusTargetEscrows(... first: N) query silently undercounts active orders and can hide cancellable positions. Any listing/offer expiry or “expiring soon” urgency derived from that snapshot MUST also use the same payload’s _meta.block.timestamp as “now”; wall-clock-only expiry math can hide still-active indexed orders while the indexer lags. The shipped frontend is guarded in CI by scripts/check_market_order_snapshot_pagination.py.
See also
- Security, Guardian, Pausing — pause events and guardian controls
- Core Mechanics — takeover and emission events
- Market (MarketRouter) — listing and escrow events
- Tutorial: Index takeovers and reigns
- Tutorial: Index Market listings
Public or shared API responses that derive live values from subgraph data must use the same payload’s _meta.block.timestamp, not wall clock fallback, for any time-sensitive calculations.
Range-cropped Crown APIs, reign recap/share payloads, and the live /crown/reign/[reignId] page must anchor their live nowSec and any since windows to a captured _meta head. For live mode, nowSec in /api/crown-reigns, /api/reign-recap, and the reign detail page must represent indexed time, not request wall clock time.