# Shared To-Do Board > ⚠️ **Experimental — generated with no human supervision.** This realm was > produced automatically by an MCP-driven agent to exercise the gno MCP server > and tooling, and to generate test content for gno compilers, linters and > formatters. **Not audited. Not for production.** Full context & folder README: > [r/moul/x/daily](https://github.com/moul/gno-contracts/blob/main/r/moul/x/daily/README.md) --- An on-chain, shared to-do list realm for the gno.land **sapphire** testnet (gno 0.9). Anyone can add an item to the board; each item records the caller's address as its author, and can be toggled open/done or removed. `Render` shows the board as Markdown checkboxes with live open/done counts, newest item first. - **Realm path:** `gno.land/r/REPLACE_ADDR/todos` (replace `REPLACE_ADDR` with your deploy address) ## Exported transactions | Function | Effect | |---|---| | `Add(text string) int` | Adds an item authored by the caller, returns its id | | `Toggle(id int)` | Flips an item between open and done | | `Remove(id int)` | Deletes an item | All three are gno 0.9 crossing functions (`cur realm` first parameter) and must be invoked with `cross(cur)` from another realm, or directly via `MsgCall`. ## Example calls ```sh # Add an item (returns the new id) gnokey maketx call -pkgpath "gno.land/r/REPLACE_ADDR/todos" \ -func Add -args "buy milk" -gas-fee 1000000ugnot -gas-wanted 2000000 \ -broadcast -chainid sapphire-1 -remote mykey # Mark item #3 done (toggle) gnokey maketx call -pkgpath "gno.land/r/REPLACE_ADDR/todos" \ -func Toggle -args 3 -gas-fee 1000000ugnot -gas-wanted 2000000 \ -broadcast -chainid sapphire-1 -remote mykey # Remove item #3 gnokey maketx call -pkgpath "gno.land/r/REPLACE_ADDR/todos" \ -func Remove -args 3 -gas-fee 1000000ugnot -gas-wanted 2000000 \ -broadcast -chainid sapphire-1 -remote mykey ``` ## Example render output ```markdown # Shared To-Do Board 2 open · 1 done · 3 total - [ ] #3 walk dog (g1abc…) - [x] #2 buy milk (g1abc…) - [ ] #1 write realm (g1def…) ``` ## What changed in v1 Two ports against [`v0`](https://github.com/moul/gno-contracts/tree/4f2df83869b80470eb81c48a82fdbe82256b8113/r/moul/x/daily/todos), which stays live and untouched. ### Rendering Identical behaviour to [`v0`](https://github.com/moul/gno-contracts/tree/4f2df83869b80470eb81c48a82fdbe82256b8113/r/moul/x/daily/todos) apart from rendering, which now goes through [`p/moul/kit/ui`](/p/moul/kit/ui/v0) instead of the local `shortAddr` helper. **One address format.** Eleven realms carried their own `shortAddr` with four different truncation rules, so the same account rendered differently depending on which realm you opened. `ui.Addr` is that decision made once: 8 leading characters, an ellipsis, 4 trailing, in backticks. Visible change: addresses now render in monospace. ### Storage State moved from a hand-rolled `avl.Tree` + `nextID` + zero-padding helper to [`p/moul/kit/store`](/p/moul/kit/store/v0), which keys entries by [`seqid`](/p/nt/seqid/v0) instead of a fixed-width decimal string. `v0` padded ids to width 12. Past that width the padding stops and the tree orders `"1000000000000"` before `"999999999999"`, so every list this realm renders would be wrong from that entry on. `store` keys are 8 big-endian bytes whose order is numeric for every `uint64`, so there is no width left to outgrow. `item` loses its `id` field, which the store now owns. `Render`'s newest-first list also gets shorter: `v0` collected every line into a slice in ascending order and then walked it backwards, where the store iterates descending directly. `Toggle`'s not-found path becomes one line, and `Remove`'s message gains the id in the same wording. Ids stay plain integers and the rendered output of the storage port is unchanged. Each port changes something `v0` promised, one the rendered output and one the storage layout, so under this repo's versioning rule each is a compatibility change and neither could be an edit to `v0` in place. They land in the **same** new version because `v1` was never published. A version number is a tag on something that exists on a chain, and until it does there is nothing for a second number to avoid disturbing, so the right move is to keep editing the version you have. `gnopm unbump` is what folded the second port back down into this one. --- Part of **[moul/gno-contracts](https://github.com/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/todos/v1 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/r/moul/x/daily/todos/v1/deps.png) > 🧪 **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](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).