Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source realm

Package streak is an on-chain check-in streak tracker: call CheckIn once per "day" to keep a streak alive, miss one a...

Readme View source

Check-in Streaks

⚠️ Experimental — generated with no human supervision by the daily MCP pipeline to exercise gno tooling. Not audited. See r/moul/x/daily.


Call CheckIn() once per "day" to keep a streak alive. Miss one and the current streak resets to 1 — but your best streak is never lowered, so a broken run costs the run, not the record.

There is no wall clock on-chain, so a "day" is a fixed window of BlocksPerDay (1000) blocks: day = ChainHeight() / BlocksPerDay. Every streak decision is therefore a pure function of block height — deterministic, replayable, and impossible to game by waiting for a favourable timestamp.

CheckIn()                        → extends or restarts your streak, returns it
Current(addr)                    → live streak (0 once the window has lapsed)
Best(addr)                       → record streak, never lowered
Day()                            → current day index

/r/moul/x/daily/streak/v0        → leaderboard, ranked by best streak
/r/moul/x/daily/streak/v0:g1...  → one address's standing

Current deliberately reports the live truth rather than the stored value: once a window lapses it returns 0 even though the record still holds the old number until the next check-in rewrites it.

Checking in twice in the same window is rejected — the streak only moves when the window does. Only an EOA can check in (IsUserCall), so another realm can't farm streaks on your behalf.

Built for gno 0.9. Live on both testnets (agent address):

  • sapphire — https://sapphire.testnets.gno.land/r/g12cs4cehujpffpjpywmkqj43m6u5ya53nj69sjz/streak
  • pearl — https://pearl.testnets.gno.land/r/g12cs4cehujpffpjpywmkqj43m6u5ya53nj69sjz/streak

Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

Dependency graph:

gno.land/r/moul/x/daily/streak/v0 dependency graph

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package streak is an on-chain check-in streak tracker: call CheckIn once per "day" to keep a streak alive, miss one and it resets to 1.

There is no wall clock on-chain, so a "day" here is a fixed window of BlocksPerDay blocks: day = ChainHeight() / BlocksPerDay. That makes every streak decision a pure function of block height — deterministic, replayable, and impossible to game by waiting for a favourable timestamp.

State is per-caller and append-only in spirit: an address's best streak is never lowered, so breaking a run costs the current streak but not the record.

This is a stateful app with nothing reusable to extract, so it ships as a lone realm rather than a p/ library + demo pair.

Constants 1

const BlocksPerDay

1const BlocksPerDay = 1000
source

BlocksPerDay is the length of a check-in window, in blocks. Chosen so a window is a meaningful stretch of chain activity while keeping tests and demos quick to reason about.

Functions 5

func Best

Action
1func Best(addr address) int
source

Best returns addr's record streak, which is never lowered.

func CheckIn

crossing Action
1func CheckIn(cur realm) int
source

CheckIn records a check-in for the caller and returns the resulting streak.

Checking in twice in the same window is rejected — the streak only moves when the window does. A gap of exactly one window continues the streak; any larger gap restarts it at 1.

func Current

Action
1func Current(addr address) int
source

Current returns addr's live streak — 0 once a window has been missed, even though the stored value only updates on the next check-in.

func Render

1func Render(path string) string
source

Render renders the streak board for gnoweb.

Example
1Render("")          / Render("/") -> leaderboard by best streak
2Render("/<address>")             -> that address's standing

Imports 6

Source Files 3