You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: track state-change block and canceler on IndexingAgreement
Consumers that reconcile agreement state against the on-chain truth
(dipper's chain_listener, primarily) need two things the aggregated
IndexingAgreement entity does not currently expose:
1. A block-indexed marker of the most recent state change, so a poll
can fetch only agreements that moved since the last seen block.
Adds `lastStateChangeBlock: BigInt!` to the entity and stamps it
with `event.block.number` on every handler that transitions state:
AgreementAccepted / Canceled / Updated / RCACollected in
recurringCollector.ts, and IndexingAgreementAccepted / Canceled /
Updated in subgraphService.ts. Distinct from the existing
`lastUpdatedAt` timestamp which is only written on AgreementUpdated.
2. The address that initiated a cancel, preserved as data rather than
derived from the enum. Adds `canceledBy: Bytes!` to the entity and
a new `handleIndexingAgreementCanceled` on the SubgraphService data
source that reads `canceledOnBehalfOf` from the event. That captures
operator-initiated cancels correctly -- the RecurringCollector's
AgreementCanceled event only carries an enum (ServiceProvider or
Payer) and the real signer is lost.
Matchstick tests cover the new field stamping and the new cancel
handler; existing tests gain `lastStateChangeBlock` assertions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: schema.graphql
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -42,8 +42,12 @@ type IndexingAgreement @entity(immutable: false) {
42
42
lastUpdatedAt: BigInt!
43
43
"Timestamp when agreement was canceled (0 if not canceled)"
44
44
canceledAt: BigInt!
45
+
"Address that initiated the cancel (zero address if not canceled). Taken from SubgraphService.IndexingAgreementCanceled.canceledOnBehalfOf so operator-initiated cancels are captured correctly."
46
+
canceledBy: Bytes!
45
47
"Total tokens collected over lifetime"
46
48
tokensCollected: BigInt!
49
+
"Block number of the latest state change on this agreement (Accepted / Updated / Canceled / RCACollected). Consumers that reconcile state diffs poll with `lastStateChangeBlock_gt` since last seen block."
0 commit comments