Overview
TheSinker class maintains a single persistent SSE connection to GET /internal/events. All event types are multiplexed over this one connection and dispatched to the appropriate handlers via sinker.on().
Event types
tx_status_changed
Fired whenever a transaction moves to a new commitment state. This is the primary event for tracking transaction progress.
The transaction ID from
/tx/enqueue.New state:
pending | submitted | landed | processed | confirmed | finalized | failed | expiredThe bundle that produced this state transition.
On-chain signatures, populated once the transaction lands.
Failure class name when
state is "failed".bundle_settled
Fired when a bundle reaches a terminal state (finalized or failed). The AI agent listens to this event to decide whether to retry.
The settled bundle’s ID.
Terminal stage:
"finalized" or "failed".Failure class name when
stage is "failed".slot_update
Fired on every slot event received from the Yellowstone gRPC stream.
The new slot number.
The validator identity pubkey scheduled for this slot, or
null if not in the leader buffer.tx_enqueued
Fired immediately when POST /tx/enqueue succeeds. The AI agent uses this as the primary trigger to start a decision cycle.
submit_requested
Fired when POST /internal/submit is called — either by the AI agent or by a manual call to sinker.submit(). Useful for observability dashboards.
Per-transaction streams
For a filtered stream scoped to a single transaction,handle.waitFor() uses the
GET /tx/events/:tx_id endpoint internally. This stream:
- Sends only
tx_status_changedevents for the requestedtx_id - Closes automatically after the first terminal state (
finalized,failed,expired) - Sends the current state immediately if the tx is already terminal when the client connects
handle.waitFor() wraps it cleanly.
SSE reconnection
The SDK reconnects automatically using exponential backoff:| Attempt | Wait before retry |
|---|---|
| 1 | 500ms |
| 2 | 1,000ms |
| 3 | 2,000ms |
| 4 | 4,000ms |
| … | doubles each time, cap 30s |