Skip to content

feat(sdk): queryEvents cursor iterator — auto-chain next_cursor until results exhausted #132

Description

@Depo-dev

Summary

queryEvents is a single-page call. If a developer wants all events for a contract they have to write a while loop, check has_more, store the next_cursor, and call again. This is boilerplate every single consumer has to write. A higher-level async iterator bakes that pattern into the SDK so callers can just write for await (const event of client.iterEvents(params)) and get every event without thinking about pages.

Context

The cursor system is already in place on the server side — the API returns an opaque next_cursor and a has_more boolean. The SDK just needs a thin wrapper that follows those cursors automatically. This is a pure client-side feature with no server changes required.

What needs to be built

A new function iterEvents(params: QueryEventsParams, options?: IterOptions): AsyncIterable<SorobanEvent> that:

  • Calls queryEvents with the provided params
  • Yields each event from the page as it arrives
  • When the page is exhausted, checks has_more; if true, calls queryEvents again with the next_cursor from the previous response
  • Continues until has_more === false or the optional maxPages limit is hit (default: 100 — a safety valve to prevent infinite loops on runaway contracts)
  • Propagates any TridentApiError thrown by queryEvents transparently so the caller's try/catch still works

The function should work with for await...of in Node 18+, modern browsers, and Deno without any polyfills since it uses the standard AsyncIterable protocol.

Acceptance Criteria

  • client.iterEvents(params) returns an AsyncIterable<SorobanEvent>
  • Works with for await...of in Node 18+
  • Stops automatically when has_more === false
  • Respects maxPages option (default 100); throws TridentApiError with code ITERATION_LIMIT if exceeded
  • Unit tests with a mocked queryEvents that returns 3 pages of 5 events each — assert 15 events yielded in order
  • Unit test: error thrown on page 2 propagates out of the iterator correctly
  • Exported from the top-level index alongside queryEvents
  • README example showing for await usage

Files

sdk/typescript/src/iterator.ts (new)

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave program

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions