Description
Soroban smart contracts emit structured events that the SDK consumes but only processes synchronously during transaction result parsing. Long-running processes need to subscribe to a contract's event stream and react to new events (e.g. split_registered, payment_released) as they are emitted on-chain, without polling for each transaction individually. A contract event log subscriber should abstract the getEvents RPC call into a reactive subscription.
Technical Context
Add src/contractEventSubscriber.ts. Uses @stellar/stellar-sdk SorobanRpc.Server.getEvents() with filters: [{ type: 'contract', contractIds: [...] }]. Polls at a configurable interval (default 5 s) and yields only new events since the last startLedger. Adds ContractEventFilter and ParsedContractEvent to src/types.ts. Integrates with src/events.ts and src/cursorTracker.ts for ledger position persistence.
Acceptance Criteria
Description
Soroban smart contracts emit structured events that the SDK consumes but only processes synchronously during transaction result parsing. Long-running processes need to subscribe to a contract's event stream and react to new events (e.g.
split_registered,payment_released) as they are emitted on-chain, without polling for each transaction individually. A contract event log subscriber should abstract thegetEventsRPC call into a reactive subscription.Technical Context
Add
src/contractEventSubscriber.ts. Uses@stellar/stellar-sdkSorobanRpc.Server.getEvents()withfilters: [{ type: 'contract', contractIds: [...] }]. Polls at a configurable interval (default 5 s) and yields only new events since the laststartLedger. AddsContractEventFilterandParsedContractEventtosrc/types.ts. Integrates withsrc/events.tsandsrc/cursorTracker.tsfor ledger position persistence.Acceptance Criteria
ContractEventSubscriber.subscribe(contractId, filter): AsyncIterableIterator<ParsedContractEvent>yields new contract events as they appear on-chain@stellar/stellar-sdkxdr.ScValdecode utilitiesledgerSequenceviasrc/cursorTracker.tsso the subscription resumes correctly after a restartunsubscribe()stops the polling loop and releases resourcesSorobanRpc.getEvents()responses across three poll cycles and assert that only new events (not duplicates) are yielded