GraphQL Cursor Pagination for Blockchain Records
Design GraphQL connections with stable cursors, deterministic event ordering and explicit range context so clients can resume a blockchain scan.

Overview
When translating these concepts into an integration, keep the scope described by the wallet history api with the result. The examples in wallet transaction history and smart contract event logs show how the same distinction affects neighbouring data questions.
A GraphQL connection can expose edges, cursors and page information. Those fields still need stable semantics underneath; wrapping an unstable offset in a cursor string does not make traversal reliable.
Define what the cursor resumes
Bind the cursor to the query’s network, filters, ordering and range context. Use a stable event boundary where the dataset permits it. Treat cursors as opaque to clients. If the server cannot preserve a traversal after a dataset revision, return a defined invalidation or restart condition instead of silently skipping records.
Worked example: resuming a fixed range
A client scans accepted blocks 100 through 200 and commits the first page ending at event E. Its next request uses E’s cursor with the same filters. Newly arriving blocks above 200 do not move that historical boundary. Reusing the cursor with a different asset filter should be rejected or handled under an explicit contract.
Test page information
Include no results, equal timestamps, repeated cursors and an interrupted page write. Advance client checkpoints only after durable processing. Verify hasNextPage and endCursor together according to the schema. A client should not infer completion solely from receiving fewer rows than requested unless that guarantee is documented.
A practical acceptance test
Resume a pinned range using the returned cursor, then reuse that cursor with a changed asset filter. Verify the documented rejection or restart behaviour. Test an empty final page and repeated delivery of the previous page. The client should use page information and durable processing state rather than decode the opaque cursor or guess completion from row count.
Questions about the topic
Frequently asked questions
Is every encoded offset a stable cursor?
No. Stability depends on the underlying traversal contract.
Can a cursor be reused with different filters?
Only if the API explicitly defines that behaviour.
Standards & technical documentation
