1func CreatePost(cur realm, body string, replyTo uint64) uint64
CreatePost publishes a post (replyTo == 0) or a reply (replyTo == parent id). Open write: any wallet, subject to the block cooldown and body caps. Returns the new post id.
1func DeletePost(cur realm, id uint64)
DeletePost soft-deletes the author's own post: content cleared, dropped from every live index (frees render slots immediately — B1), queued for hard-GC (B2). Replies stay: they render as replies to an unavailable post.
1func EditPost(cur realm, id uint64, newBody string)
EditPost lets the author replace the body of a visible post.
1func FlagPost(cur realm, id uint64)
FlagPost files a community flag. Guards, in order:
- flag rights are EARNED BY PARTICIPATION: the caller must have a firstSeen record (anchored by their first successful CreatePost) at least MinAccountAgeForFlag blocks old. A failed flag cannot anchor age itself — an on-chain abort reverts every write in the tx, so recording firstSeen here and then panicking would revert the record and deadlock pure flaggers; requiring a prior post is the honest, implementable account-age gate (realms cannot query global account age);
- one flag per address per post;
- per-day flag budget per address (blunts coordinated flag-brigades).
At FlagThreshold unique flags the post auto-hides (reversible via UnhidePost).
1func GetPostJSON(id uint64) string
GetPostJSON returns one post (any state — the indexer needs tombstones too).
1func ListFeedJSON(cursor uint64, limit int) string
ListFeedJSON returns the newest live posts strictly older than cursor (cursor == 0 → from the top). Pass the last id of the previous window as the next cursor.
ReverseIterate treats BOTH bounds as inclusive (avl/v0 TraverseInRange), so "strictly older than cursor" = end bound padID(cursor-1): ids are integers, keys are fixed-width, hence key < padID(cursor) ⟺ key ≤ padID(cursor-1).
1func ModRemovePost(cur realm, id uint64)
ModRemovePost permanently hides a post by moderation. Emits an audited ModAction. The node is tombstoned for hard-GC like an author delete.
1func SweepTombstones(cur realm, limit int) int
SweepTombstones hard-removes up to `limit` soft-deleted posts, reclaiming AVL storage so post+delete spam cannot accrete permanent state. Permissionless by design (state-shrink hygiene primitive, not a refund path). Bounded + idempotent: keep `limit` small (1-10); re-running drains the next batch and stops at 0. Returns the number of posts swept.
For a swept post that was a PARENT, its surviving replies' byParent links (`padID(parent):padID(child)`) would otherwise be orphaned under an id no longer in `posts` — a permanent leak plus a read inconsistency (replies still enumerable, getReplyCount() disagreeing). So the sweep range-deletes that byParent prefix; the reply posts themselves stay as standalone live content (their parent was removed by its own author). Bounded because the live reply set per post is capped at MaxRepliesPerPost — but a reply-heavy parent makes one sweep step do up to that many removes, so keep `limit` small (1) when draining known reply-heavy tombstones.
1func UnhidePost(cur realm, id uint64)
UnhidePost clears flags and restores a flag-hidden post to the live set.