Workspace IndexDev Notes › The chain never calls you back — notifications are your job

#65PoC

The chain never calls you back — notifications are your job

Users expect a push when their payment arrives; chains have no callbacks, so the app builds event → queue → notify itself — and reorg-safety means the pipeline must also know how to take a notification back.

Build an event-to-notification pipeline that notifies tentatively at inclusion and confirms at finality, then force a reorg on anvil and watch the pipeline retract instead of lying.

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.

← All Dev Notes · Workspace Index · Top ↑

체인은 회신 전화를 하지 않는다 — 알림은 앱의 몫

사용자는 결제가 도착하면 푸시를 기대하지만 체인에는 콜백이 없습니다. 그래서 앱이 이벤트 → 큐 → 알림을 직접 만듭니다 — 그리고 리오그 안전이란 파이프라인이 보낸 알림을 되가져오는 법도 알아야 한다는 뜻입니다.

포함 시 잠정 알림을 보내고 파이널리티에서 확정하는 이벤트-알림 파이프라인을 만든 뒤, anvil 에서 리오그를 강제해 파이프라인이 거짓말하는 대신 철회하는 것을 봅니다.

웹2 레일은 회신 전화를 합니다 — Stripe 웹훅, 푸시 서비스, 전달 영수증. 체인은 그냥 존재할 뿐입니다: 상태가 전진하고 로그가 방출되고, 누구도 당신 사용자에게 돈이 도착했다고 말해 주지 않습니다. 모두가 당연시하는 알림 계층은 온체인에서는 직접 만들어야 하는 애플리케이션입니다: 이벤트를 감시하고, 큐에 넣고, 푸시나 이메일로 전달하고, 재시도와 웹소켓 재접속 사이에서 중복 제거하고.

장난감과 제품을 가르는 부분은 리오그 처리입니다. 포함 즉시 알리면 리오그가 당신을 거짓말쟁이로 만들고, 파이널리티에서만 알리면 모든 결제가 느려 보입니다. 정직한 설계는 계층적이고, receipt-is-not-settlement 를 발신 쪽에서 반사합니다: 포함 시 “결제 감지(잠정)”, 파이널리티에서 “결제 확정”, 그리고 — 데기 전엔 아무도 안 만드는 분기 — 잠정 이벤트가 정본 체인에서 사라졌을 때의 철회 경로. 알림 상태는 발사 후 망각 전송이 아니라 작은 상태 머신이 됩니다.

동작 방식

워처, 큐, 계층 전달, 그리고 리오그 훈련.

PoC

anvil 위에서: 워처(viem watchEvent 또는 Ponder 파이프라인)가 큐 테이블 { event, blockHash, tier, notifyState } 를 채웁니다. 전달 워커는 포함 시 “결제 감지”를 보내고 N 블록 또는 파이널리티 후 “확정”으로 승급합니다; 모든 메시지는 id 를 싣어 나중의 철회가 참조할 수 있게 합니다. 그다음 훈련: anvil 스냅샷 → 결제 포함 → 알림; 되돌리고 그것 없이 재채굴; 워처가 정본 체인에 이벤트가 더는 없음을 보고 파이프라인이 철회를 보냅니다(또는 인앱 알림 상태를 수정). 테스트: 워처 재시작에도 중복 발송 없음, 철회는 잠정 계층 메시지에만 발동, 확정 알림은 절대 철회되지 않음.

무엇을 증명하나

발신의 진실성은 상태 머신이고, 포함 계층 메시지는 조건부 진술입니다 — 확률적 정산의 제품 면. the-app-reads-a-projection(수신의 정직)과 짝지어 고리를 완성합니다: 사용자에게 말해지는 것은, 양방향 모두, 체인 상태에 대한 애플리케이션 계층의 계약입니다.

← 전체 개발 노트 · 워크스페이스 인덱스 · 맨 위 ↑