Why
Web2 rails call you back — Stripe webhooks, push services, delivery receipts. A chain just is: state advances, logs are emitted, and nobody tells your user their money arrived. So the notification layer everyone takes for granted is, on-chain, an application you must build: watch events, queue them, deliver through push or email, deduplicate across retries and websocket reconnects.
The part that separates the toy from the product is reorg handling. Notify instantly at inclusion and a reorg makes you a liar; notify only at finality and every payment feels slow. The honest design is tiered, mirroring receipt-is-not-settlement on the outbound side: a tentative payment detected at inclusion, a final payment confirmed at finality, and — the branch nobody builds until it burns them — a retraction path when the tentative event vanishes from the canonical chain. Notification state becomes a small state machine, not a fire-and-forget send.
How it works
Watcher, queue, tiered delivery, and a reorg drill.
PoC
On anvil: a watcher (viem watchEvent or the Ponder pipeline) feeding a queue table { event, blockHash, tier, notifyState }. Delivery worker sends payment detected on inclusion and upgrades to confirmed after N blocks or finality; every message carries an id so a later retraction can reference it. Then the drill: anvil snapshot, include the payment, notify; revert and re-mine without it; the watcher sees the canonical chain no longer contains the event and the pipeline sends the retraction (or edits the in-app notification state). Tests: no duplicate sends across watcher restarts, retraction fires only for tentative-tier messages, finalized notifications are never retracted.
What it proves
Outbound truthfulness is a state machine, and inclusion-tier messages are conditional statements — the product face of probabilistic settlement. Pairs with the-app-reads-a-projection (inbound honesty) to complete the loop: what the user is told, in both directions, is an application-layer contract about chain state.
Where it lands in Jayverse
- Wallet: tier payment notifications at inclusion and finality, with a retraction path. Any incoming-transfer alert in Wallet should send tentative at inclusion, upgrade to confirmed at finality, and carry a message id so a reorg drill on Devnet can prove the retraction actually fires.
- Rabbit: build the same event-queue-notify pipeline for session-key actions. Agentic executions (a mandate firing, a session key spending) need dedup across watcher restarts and websocket reconnects, not a fire-and-forget send.
- Verex: match settlement notifications to the dispute window. A trader should be told "detected" at inclusion and "settled" only after the dispute window closes, and a market that gets disputed must retract any tentative "you won" message it already sent.
Key expressions
| Expression | 뜻 · 쓰이는 자리 |
|---|---|
| call (someone) back | (누군가에게) 다시 연락하다·알려주다 · 체인이 알아서 알림을 주지 않는다는 비유. "The chain never calls you back" |
| take for granted | 당연하게 여기다 · 웹2에서는 당연했던 기능이 온체인엔 없을 때. "the notification layer everyone takes for granted" |
| fire-and-forget | 보내고 끝(응답 확인 없이 던지기만 하는 방식) · 상태 관리 없이 그냥 발송만 하는 방식. "not a fire-and-forget send" |
| until it burns them | 나중에 크게 당할 때까지(문제가 터지기 전까지) · 아무도 미리 대비하지 않는 취약점. "the branch nobody builds until it burns them" |
| force a reorg | 일부러 리오그(재구성)를 발생시키다 · 테스트 환경에서 체인 되돌림을 강제로 일으킬 때. "then force a reorg on anvil and watch" |
| makes you a liar | 거짓말한 꼴이 되게 만들다 · 성급한 확정 알림이 나중에 틀린 정보가 될 때. "a reorg makes you a liar" |
| revert and re-mine | 되돌리고 다시 채굴하다(체인 상태를 재구성) · 리오그 테스트 절차를 설명할 때. "revert and re-mine without it" |
| dedupe | 중복을 제거하다 · 같은 이벤트를 두 번 처리하지 않도록 걸러낼 때. "deduplicate across retries and websocket reconnects" |
| outbound truthfulness | 밖으로 내보내는 정보의 정직성(사용자에게 알리는 내용의 진실성) · 알림 시스템 설계의 핵심 원칙. "Outbound truthfulness is a state machine" |
| Ponder | 이더리움 이벤트 인덱싱 프레임워크(온체인 이벤트를 감시·저장) · 이 카드가 예로 드는 워처 구현 도구. "the Ponder pipeline" |