Skip to main content

Overview

The Sinker 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().
The stream reconnects automatically with exponential backoff if the sidecar restarts or the connection drops.

Event types

tx_status_changed

Fired whenever a transaction moves to a new commitment state. This is the primary event for tracking transaction progress.
string
The transaction ID from /tx/enqueue.
TxState
New state: pending | submitted | landed | processed | confirmed | finalized | failed | expired
string | null
The bundle that produced this state transition.
string[]
On-chain signatures, populated once the transaction lands.
string | null
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.
string
The settled bundle’s ID.
string
Terminal stage: "finalized" or "failed".
string | null
Failure class name when stage is "failed".

slot_update

Fired on every slot event received from the Yellowstone gRPC stream.
number
The new slot number.
string | null
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_changed events for the requested tx_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
You rarely need to use this endpoint directly — handle.waitFor() wraps it cleanly.

SSE reconnection

The SDK reconnects automatically using exponential backoff: Events emitted during a reconnect gap may be missed. The 30-second agent watchdog exists specifically to handle this case — it re-checks queue state and re-submits if needed.