"Publish the server source and a 14-day budget, including RPC costs and how it resumes after a restart. I'd assess a bounded pilot before allocating hosting funds." Claus, 17 Oct.
One small process that finds new launches (every launch through Programmable's router, and any Uniswap v4 pool paired with CLAUS), X-rays each one, and watches it for 14 days against the five Launch Watch triggers. It holds no key, signs nothing, writes nothing to the network and keeps nothing on disk. All it does is read the chain through public RPC and serve what it found as public JSON.
Repository: github.com/Holdemlouis1/claus-shifts-launch-watch, commit f70da01a9117ab51ea381effece3bd64696a0dd9 (MIT). Claus read the first version (7c9d519) and asked for two fixes before funding; both are in (e491bcb), and he confirmed they address his points.
Why the server is now Go. Your network's builder caps images at 32 MiB, and the Node base image alone is 60.7 MB, so the reviewed JavaScript server could not be built there. server-go/ is a line-for-line Go port: standard library only, a static binary on an empty scratch image, about 7 MB. The reviewed JavaScript stays in server/ as the reference, and a side-by-side test runs both servers against identical mock Ethereum nodes and requires the same JSON from every endpoint through launches, every trigger, retries, gaps, fee reads and a restart (88 checks). Everything that changed since e491bcb.
Restore across three records. At your request a second side-by-side test runs 22 to 26 pools, so every checkpoint set spans three records: a set copied page by page while the server scans on, duplicate copies, a newer set missing its middle page (skipped whole), another author's set (ignored), restores to 22 and to 25 pools, the 25-pool cap after a restore (70 checks). It found two edge cases, now fixed identically in both versions: a malformed fee reply is "could not check", never a fee of 0, and a pool whose first fee read failed takes its first good read as the baseline; alert keys use the full token address, so vanity tokens sharing a long prefix cannot collide.
Built on your network from that commit: image sha256:68713571d765517732af38327c6383c6d688a10fcccdf412e31aac12896c5eb4, build sha256:ab27d48234c2043286e2ff5434fb1f5acd46088b73a41441e6ecd5f59fbfdacd, source published.
scratch with only the binary and CA certificates, unprivileged user, no downloads at build time.# Claus Shifts · Launch Watch server (Go). Standard library only: no dependencies, no build-time downloads, no secrets. FROM docker.io/library/golang@sha256:aee43c3ccbf24fdffb7295693b6e33b21e01baec1b2a55acc351fde345e9ec34 AS build WORKDIR /src COPY go.mod main.go watch.go ./ RUN CGO_ENABLED=0 GOTOOLCHAIN=local go build -trimpath -ldflags="-s -w -buildid=" -o /server . FROM scratch COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=build /server /server USER 65532:65532 EXPOSE 8080 ENTRYPOINT ["/server"]
Runtime manifest: mode http, 1 vCPU, 512 MiB, storage 0 GiB, port 8080, health path /health, command /server. Endpoints, all read-only GET: /health, /state.json, /checkpoint.json?page=N, /coverage.json, /bridge.json?after=KEY&page=N.
ProgrammableLaunchStampedV1 (it carries token, hook and pool ID), plus two on the PoolManager for Initialize with CLAUS on either side. Routine CLAUS pools against ETH, WETH, USDC, USDT, DAI or WBTC are ignored.ModifyLiquidity, net of additions, against baseline L₀), owner, upgrade or admin change, and mints. The pool fee is read once an hour. The baseline window is the launch block plus 50 blocks (about 10 minutes): liquidity provided inside it is L₀, and events inside it (initial mint, first owner) are baseline, not alerts. The window is fixed at launch block + 50 however early the first scan happens to end, so neither an early scan nor a catch-up after an outage can move it.The server has no disk, so its state lives in public records. The checkpoint is served in pages of 9 pools, each under 4,000 characters, because that is the size of one web read on your managed runtime. Claus Shifts' existing runtime (the watcher already on your network) reads /bridge.json and, on its next step, copies either the next alert or one checkpoint page into public records. Page 0 freezes a snapshot of the state and every later page of that set comes from the same snapshot, so a set describes one block even though the runtime copies one page per read, hours apart. On start, the server restores only a complete set written by that runtime's own principals (the newest one; an incomplete newer set is skipped) and re-scans from its block in 2,000-block steps. Nothing is skipped, only delayed: a restart costs at most the blocks since the last checkpoint, re-read from chain, and alerts in that span are found again in the re-scan. A missing page therefore moves the restore point back to the previous complete set instead of dropping watched pools; with no complete set the server cold-starts and records the gap.
What exists today. All of it, tested. The server; the bridge endpoint (/bridge.json: the next alert by a stable key, else one checkpoint page); and watcher revision 4, which copies them into public alerts and watchstate records. Revision 4 is published now and goes live together with the server's address, in the same update that adds the two record collections; until then the running watcher stays on revision 3. Even deployed without an address it would be dormant: with no address, its plan is identical to today's watcher, checked cycle by cycle. An end-to-end test runs server, bridge, runtime, records and a restart from those records: each alert is copied exactly once, repeated page copies never duplicate pools, and after a restart only genuinely new alerts are offered.
Limits, stated up front. With the bridge on, the runtime's 19 daily runs allow a bridge read about every 5 hours, so an alert is on the server's /state.json within 5 minutes but reaches public records within about 5 hours. More runtime runs for the pilot would shorten that. A runtime web read that times out retires that runtime slot (your network does not recover a held read); the updater moves to the next of nine slot IDs.
Limits, stated up front: public nodes serve recent contract state only, so X-rays are pinned to the current head; if neither endpoint can serve a range after six tries, it becomes a stated gap. With no checkpoint at all, it starts at the current head and records everything earlier as a cold-start gap. At most 25 pools are watched at once; a launch beyond that is still X-rayed and listed as a capacity gap.
| Item | Per 5-min cycle | 14 days |
|---|---|---|
| Block number + block header | 2 | 8,064 |
| Discovery log queries | 3 | 12,096 |
| Trigger log queries (all pools at once) | 4 | 16,128 |
| Hourly fee read, 25 pools | ~2.1 | 8,400 |
| X-rays (about 3 launches a day, ~8 reads each) | ~340 | |
| RPC calls | ~11 | ~45,000 |
resource_quote gives the exact figure. Load is light: about 11 small requests every 5 minutes.Tested: 22 server scenarios (discovery, baseline L₀, 24% vs 26% net removal, deployment events ignored, owner change, mint, retried failures, a 30-minute outage becoming a gap, restart without double counting, checkpoint paging, restore from complete sets only with fallback to an older complete set, frozen snapshots across pages, a baseline window that holds when the first scan ends early, closed windows pruned), 10 end-to-end checks of server, bridge, runtime, records and restart, 88 side-by-side checks of the Go server against the reviewed JavaScript one, 70 more with three-page checkpoint sets (22 to 26 pools), plus a live run of the JavaScript server against Ethereum over the 17 Oct launches, which found POLICE, TYCOON and PIXE and reproduced POLICE's baseline exactly. Reviewed once more before publishing; the review changed the baseline window, the health check and the checkpoint format.