func CooldownBlocks
ActionCooldownBlocks lets a front end say how long the wait is instead of surprising someone with a panic.
Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.
Package chat is the SPLASH arcade's room: a bounded, append-only ring of public messages, posted by anyone with a wal...
Package chat is the SPLASH arcade's room: a bounded, append-only ring of public messages, posted by anyone with a wallet and readable by anyone at all.
IT EXISTS BECAUSE SETTLEMENT IS A SHARED MOMENT. Duels pin a future drand round and many of them land on the SAME round — the bucketing in arcade/duel is deliberate about that. A dozen people watching one number arrive is the thing worth being in a room for. Without somewhere to say so it is a dozen people each alone with a spinner.
WHAT THIS REALM DELIBERATELY DOES NOT HAVE, and why each absence is a decision rather than an omission:
NO ADMIN, NO OWNER, NO DELETE, NO EDIT. Not "not yet" — there is no address anywhere in this file with a power no other address has. The rules page promises "no admin over your money" and "nobody can pause, delay or refuse"; a moderator key over other people's words is the same promise broken in a different column. Ruled by the owner 2026-10-08 after being shown the trade explicitly: the alternative was a key that could remove messages, and he chose not to have one.
NO MONEY. This realm holds no coin, has no allowance, makes no transfer and imports no token. It cannot lose funds because it never has any. That is most of its security argument and it is why the whole file is this short.
THAT INVARIANT NEEDS AN ACTIVE GUARD, NOT JUST THE ABSENCE OF CODE, and the first draft of this file got that wrong. A realm receives native coin whether or not it has any code to do so: `maketx call --send 1000000ugnot -func Post` credits this realm's address at the chain root, and Post would have succeeded and kept it. With no banker, no owner and no withdraw — all deliberate, all permanent, because a realm cannot be upgraded — that coin would be destroyed rather than merely stuck. Hence rejectAttachedCoin below, which is the same guard the other four SPLASH realms have carried since 2026-10-07. Caught by audit before deployment, 2026-10-08.
THE GUARD COVERS Post AND NOTHING ELSE, and cannot be made to cover more. Gno gives a realm no receive hook, so a plain `maketx send` to this address, a wugnot transfer, or any other realm's banker can put value here and no code anywhere could refuse it. The eight read functions are non-crossing and so have no `cur` to check at all. What the guard buys is the one case a normal user could hit by accident — attaching coin to the call they actually meant to make. Everything else burns the sender's own coin and harms nobody: this realm has no accounting, reads no balance and pays nothing out, so stray value cannot change any behaviour. Said plainly here so the next reader does not mistake "guarded" for "impossible".
NO REPLIES, NO THREADS, NO MENTIONS, NO REACTIONS. A flat room. Every one of those is a second index, and a second index is a second thing that can grow without bound.
WHAT IT DOES HAVE, and the reasoning that is NOT obvious from the code:
A FIXED-SIZE RING. Storage on a chain is paid for once and kept forever. An unbounded log would make every future Post more expensive than the last and eventually price the room shut. The ring overwrites; Seen() reports the true total so nobody mistakes "the ring holds 64" for "64 messages have ever been sent". The event log is the durable record — see the chain.Emit in Post.
A PER-ADDRESS COOLDOWN. THIS IS NOT MODERATION and the distinction matters enough to state: it is a rule of arithmetic applied identically to every address including ours, enforced by the contract, with no human in the loop and no exceptions possible. It stops ONE WALLET bursting and evicting the room in a single block, and that is all it stops — 64 funded addresses still wipe the ring in a block or two, and that is accepted. The exact arithmetic lives on cooldownBlocks and is deliberately NOT repeated here: an earlier version stated it in both places, the correction landed on one, and the false figure sat at the top of the file where most readers meet it first. One claim, one home. It cannot silence anybody — it only makes everyone wait the same amount.
CooldownBlocks lets a front end say how long the wait is instead of surprising someone with a panic.
Count is how many messages the ring currently holds, at most RingSize.
MaxTextLen lets a front end enforce the same cap the contract will, so a too-long message is refused in the browser instead of costing gas to fail.
NextAllowedHeight is the first block at which addr may post again, or 0 if addr has never posted. A front end can disable its button until then rather than letting someone pay gas to be refused.
Post appends one message and returns its ID.
It is a crossing function because it reads the caller's identity, and it requires an EOA: cur.Previous().IsUserCall(). A realm posting on a user's behalf would make Author meaningless — the room would show the realm's address for every line and there would be no way to tell who said what. There is no reason for a contract to speak here.
RingSize is the bound, exported so a front end can say "last 64" without hardcoding a number that might change.
Seen is every message ever posted, including those the ring has overwritten. The gap between this and Count is exactly what a reader must go to the event log for.
Recent returns up to `limit` messages, MOST RECENT FIRST. limit is clamped to what the ring holds, so no caller can ask for an unbounded amount of work.
1type Message struct {
2 ID int64 // monotonic, never reused, survives ring eviction
3 Author address // the EOA that signed; set by the contract, not the caller
4 Text string // the ONLY caller-controlled field in this struct
5 Height int64 // block it landed in
6 Time int64 // block timestamp, unix seconds
7}Message is one line in the room. Every field is set by the contract from the transaction itself EXCEPT Text, which is the only caller-supplied value in this realm — so Text is the only thing any reader has to treat as hostile. Author cannot be forged: it is read from the call, never from an argument.