Chainhooks
Chainhooks are how the protocol observes confirmed on-chain transactions on your behalf, and the event types your app sees the results of.
A chainhook is a blockchain event listener the protocol runs for you. When a transaction your app broadcast confirms on chain, the protocol observes it and updates the state you read back through the SDK.
You never register, configure, or receive a chainhook yourself. It is named here because it is the reason a write shows up in a read a few seconds after you broadcast it, and because the table below is what you will see change.
What the protocol observes
| A transaction that confirms | What you see afterwards |
|---|---|
| A contract deploy | SmartProduct status -> PUBLISHED, contractAddress populated |
| A mint | A new ProductInstance with its instanceNumber |
| A burn | burnedAt / burnTxId set, currentInstances decremented |
| A transfer | ProductInstance.ownerAddress updated |
| A capability or info change (supply, location, product info, max uses, detach) | The product's stored state follows the contract |
| A tournament lock, unlock, result, score or prize claim (PREDICTION) | Status LOCKED / PUBLISHED / SETTLED and the entry scores follow the contract |
| A lobby join, leave, start, move, win, draw or claim (GAME) | The seats, the match board and its status follow the contract |
The mapping from a transaction to these effects is the protocol's to maintain; you read the results through the SDK.
Confirmation timing
Post-Nakamoto, Stacks blocks settle every few seconds. Bitcoin-level finality arrives when Stacks anchors to a Bitcoin block, roughly every ten minutes. currentInstances on a SmartProduct reflects confirmed mints only - a broadcast that has not confirmed is not counted.
What the protocol guarantees
- Delivery is not the only route in. Event observation does not depend on a single push channel, so an outage delays events rather than losing them. Your app does not need a fallback path of its own.
- Nothing is applied twice. Every event is idempotent on its transaction id. A redelivered or replayed event converges on the same state instead of double-counting.
- Reorgs resolve themselves. A transaction reorganized out of the chain and re-mined lands the same final state. One that is never re-mined is walked back, so a read never keeps an edition that no longer exists.
Following one transaction
If you need the fate of a specific broadcast rather than the eventual read, register it and poll the protocol - never the chain:
await rtClient.pendingTransactions.register({ txId });
const status = await rtClient.pendingTransactions.getStatus(txId);Privy publish and collect flows self-register server-side and only need getStatus. Bring-your-own-wallet flows register at broadcast time.
See How State Syncs for the full picture between broadcast and confirmation, and rtClient.pendingTransactions for the client surface.
Game Lobbies
The GAME domain: a lobby is a smart product that hosts a series of two-player matches for a pot. What it is made of, and what it guarantees a caller.
How State Syncs
Writes land on chain first and reach the API on confirmation. What your app can observe at each step, and the guarantees you can build on.