DRAFT - not published. Working whitepaper, open to iteration.

Propose an edit (GitHub)

Zaalcaster @ The ZAO - Whitepaper (draft v0.1)

Zaalcaster

Zaal's personal Farcaster client. Preview-first posting, a keyboard-driven engage inbox, a gamified daily loop, and deep integrations with Empire Builder, POIDH, and Zora - all in a single deployable Node.js app with a web cockpit and a Farcaster Mini App.

v0.1 draft 2026-07-17 Deployed: z.thezao.xyz bettercallzaal/zaalcaster
01

What it is

Zaalcaster is a personal Farcaster client built specifically for Zaal (@zaal, FID 19640). It is not a social network or a general-purpose product - it is Zaal's owned interface to Farcaster, running as both a local CLI tool and a Vercel-hosted web cockpit at z.thezao.xyz. As of July 2026 it also runs as a Farcaster Mini App, discoverable and launchable in-feed from any cast that embeds it[1].

Everything in zaalcaster follows a single principle: Zaal approves every cast. No content is ever published without an explicit confirmation - either the --yes flag in the CLI or a confirm button in the web UI. The client surfaces information and drafts; Zaal is the send button.

Other Farcaster clients (herocast, Supercast, the official Warpcast app) are built for general audiences and optimized for discovery and engagement. Zaalcaster is different: it is built around Zaal's specific daily workflow - reading inbound replies, engaging with the community, tracking WaveWarZ and ZABAL Gamez activity, posting to the /zao and /wavewarz channels, and managing the ecosystem integrations (Empire Builder boosters, POIDH bounties, Zora Creator Coin) from a single interface.

02

Architecture

Three layers in one repo

Zaalcaster is a single Node.js ESM repository[2] that serves three surfaces:

  • CLI tools bin/*.js - one command per task: timeline, notifs, post, reply, search, channels, thread, user lookup, morning digest, cockpit inbox, empire lookups, POIDH queries. Run locally on Zaal's machine. Preview is always the default; nothing posts without an explicit flag.
  • Web cockpit + Mini App public/index.html + api/*.js - a Vercel-hosted serverless frontend. Single-page vanilla JS app with no framework dependency. Doubles as a Farcaster Mini App (fc:miniapp + fc:frame metadata, @farcaster/miniapp-sdk), so any cast that embeds z.thezao.xyz opens the full cockpit inside Warpcast.
  • Shared library lib.js - Neynar v2 API wrapper, env loading (Vercel env vars first, then ~/.zao/private/farcaster-zaal.env for local CLI), session/auth helpers, voice drafting relay. Both the CLI and the web serverless functions share lib.js - no divergence between surfaces.

External services

ServiceRoleAuth
Neynar v2[3]All Farcaster reads and writes - timeline, notifs, search, post, reply, follow, managed signerNEYNAR_API_KEY + ZAAL_SIGNER_UUID (write)
OpenRouterDraft generation in Zaal's voice (voice.js) - batched, never auto-postsOPENROUTER_API_KEY
Vercel KV[4]Gamification state (XP, streak, quests, badges), action ledger (every cast/like logged), system health cron freshness, spam listKV_REST_API_URL + KV_REST_API_TOKEN
Empire Builder[5]ZABAL and ZABAL GAMEZ empire reads - leaderboard, boosters, rank, stakingEMPIRE_BUILDER_API_KEY (partner)
POIDH[6]Bounty reads via poidh.xyz tRPC - BCZ rounds R1-R4 + manual lookupPublic (no auth)
Zora[7]Creator Coin card - market cap, price, holders via Zora public RESTPublic (no auth)
Juke AudioLive Farcaster audio spaces - create, info, embedJUKE_API_KEY (pending approval)

Auth model

Sign In With Farcaster (SIWF via Neynar SIWN[8]) gates the web cockpit. Any Farcaster user can sign in; the server independently verifies their signer via Neynar before issuing a session cookie (HMAC-SHA256 signed, 30-day expiry). Role 'zaal' (FID 19640) gets full read + write access. Role 'guest' (any other FID) gets read-only public surfaces: Feed, Channels, Search, Empire reads. Inbox, Post, Daily, and Grow are Zaal-only. The server-side guard is the real boundary; the frontend hides restricted tabs as a UX convenience only.

03

Feature set (as of July 2026)

Daily loop

The core daily workflow is the Cockpit[9]: a keyboard-driven single-screen inbox walk of all unanswered inbound mentions and replies. Keys: [a] send AI draft, [e] edit + confirm + send, [s] skip, [n] later, [q] quit. Every send shows the exact cast text before anything leaves the machine. The morning digest (npm run morning) chains engage + channels + timeline into a single morning read.

Gamification

The Daily tab[10] runs a gamified quest loop: 8 daily quests (GM post, reply, share, check channels, etc.) award +10 XP each. Quests auto-tick when Zaal's activity already matches. A consecutive-day streak tracks best-ever. 8 unlockable badges with toast notifications. Level, XP bar, and streak display at the top of the tab. The game state is stored in Vercel KV (zc:state.game) and syncs across CLI and web.

Ecosystem tabs

Three tabs cover the ZAO ecosystem integrations:

  • Empire tab (key 8, Zaal-only) Full Empire Builder surface: ZABAL and ZABAL GAMEZ empire card with rank and booster counts, top-25 leaderboard overlay, reward/burn/airdrop history, distribution lookup by tx hash, create-tokenless-empire flow (wallet-sign-to-POST, custom mode only), staking tools (activate staking + add staking booster with timestamp-replay protection), and a capabilities catalog showing every Empire Builder endpoint marked built vs. documented.
  • POIDH tab (key 9, guest-visible) Read-only bounty explorer via poidh.xyz tRPC. Quick chips for BCZ rounds R1-R4 + manual bounty-id lookup. Displays bounty details, claims, and claim counts. Read-only - on-chain claiming is a separate wallet action outside zaalcaster scope.
  • Zora Creator Coin card (Grow tab) Zaal's Zora Creator Coin (0x2275c5e507f1d01a0c043a4f888ec58f8215c285 on Base) - market cap, price, and holder count via Zora public REST. Inert until config.zoraCoinAddress is set; currently live with Zaal's real coin.

Booster engagement queue

The booster engagement queue[11] surfaces who liked Zaal's recent casts or posted the configured booster phrases ("zabal gamez" / "zabal games"). Each candidate is ranked (phrase-casters first) and shown as a full cast card with one-tap like or reply-with-confirm. Scanning is always a manual button - never automatic - because each scan costs ~15-20 Neynar API calls and the decision to engage is Zaal's.

Clanker launch prep

A dedicated chip in the Empire tab walks Zaal through the Clanker v4 token launch checklist: fee-recipient setup, the wallet-count-is-fixed / addresses-are-changeable rule, v5 audit status, and a pre-filled cast composer with live preview. The composer prefills the Post tab's own confirm flow - the Post tab's confirm button is the only send path. No token has been launched; this is build-only, Zaal's trigger.

Spaces (Juke Audio)

juke.js + bin/spaces.js provide create, info, and embed commands for Juke Audio live Farcaster rooms[12]. Creation is preview-first like post (requires --yes). A JUKE_API_KEY is required but pending Juke admin approval; local CLI and Vercel env both support it via the standard creds pattern.

Reliability infrastructure

Three reliability additions[13] make zaalcaster production-stable: (1) Rate-limit guard - fetchNeynar retries 429s with Retry-After/backoff (3 tries) so a busy day degrades gracefully. (2) Action ledger - logAction() appends every write (cast/reply/like/recast/delete) to KV list zc:actions; readable with node bin/actions.js [N]. (3) Self-monitor - cron/post-due writes zc:cron:last each run; getSystemHealth() checks signer health + cron freshness; node bin/health.js exits non-zero if unhealthy, catching the two historical silent failures (deploy-rate-limit killing cron, signer/key mismatch).

04

Design principles

Preview-first, always

Every post, reply, like, and create defaults to a no-op preview. The CLI requires --yes to actually execute a write. The web cockpit shows the full cast text in a confirm step. This is non-negotiable: zaalcaster has direct access to Zaal's managed signer, which can post to Farcaster on Zaal's behalf. Automatic posting would be a trust violation. The rule exists because every cast under @zaal reflects on Zaal personally - there is no undo on the Farcaster protocol.

No secrets in code

Credentials live at ~/.zao/private/farcaster-zaal.env locally (never committed) and in Vercel env vars for production. lib.js loads Vercel env first, then the local file - the same code runs in both contexts. The NEYNAR_API_KEY, ZAAL_SIGNER_UUID, and all other keys are never printed or logged. The session cookie stores an HMAC-signed FID, never the signer UUID itself (which is write-capable).

No emojis, no em dashes

Zaal's cast voice is short, plain, direct. "ppl", "u", "imho" are fine. No hype adjectives. No emojis. Plain hyphens, not em dashes. This voice constraint extends to code (commit messages, comments), generated drafts (voice.js), and the cockpit's suggest-reply flow. The goal is that a generated draft sounds like Zaal, not like a chatbot.

Single codebase, no framework lock-in

The web frontend is dependency-free vanilla JS. The backend is pure Node.js serverless functions. The only npm dependencies are what Neynar, KV, and the mini-app SDK require. This keeps the repo auditable, fast to clone, and deployable anywhere that runs Node.js - not just Vercel. The 12-function Vercel Hobby plan limit shaped the API file structure: writes are consolidated under react.js and stats.js rather than one file per action type.

05

Traction and status

Mini App - live on Vercel Deployed at z.thezao.xyz via the bettercallzaal/zaalcaster repository. Farcaster Mini App metadata present (fc:miniapp + fc:frame). The farcaster.json manifest is served via a vercel.json rewrite. Account association (the final discoverability step) requires Zaal to sign z.thezao.xyz with his Farcaster custody key via the dev.farcaster manifest tool and paste the result into public/farcaster.json - one manual step remaining for full in-feed discoverability. bettercallzaal/zaalcaster, public/farcaster.json, vercel.json
Empire Builder integration - two empires live ZABAL (tokenized) and ZABAL GAMEZ (tokenless) empires already exist and are readable via the Empire tab. empire.js live-verified against Zaal's real empires at build time. Known API drift: Empire Builder's real responses differ from May 2026 docs on field names (burned_rewards vs burned, user_address vs address) - lib catches both with fallback chains. bettercallzaal/zaalcaster, empire.js, CLAUDE.md (Empire Builder section, 2026-07-15)
POIDH read integration - BCZ rounds R1-R4 poidh.js reads poidh.xyz tRPC endpoints using the same pattern as bettercallzaal/zpoidh's refresh-poidh-leaderboard.py (pattern proven in production). PoidhV2 contract addresses recorded for mainnet, Arbitrum, Base, and Degen for future on-chain claim tooling. bettercallzaal/zaalcaster, poidh.js
Zora Creator Coin - live card Zora public REST (api-sdk.zora.engineering/coin) returns market cap, price, and holders for Zaal's coin (0x2275c5e507f1d01a0c043a4f888ec58f8215c285 on Base). Live-verified at $3,793 market cap at build time (2026-07-15). bettercallzaal/zaalcaster, zora.js, CLAUDE.md (Zora card section, 2026-07-15)
06

Ecosystem integration

Zaalcaster is both a personal tool and an integration surface for the ZAO ecosystem. The same cockpit that Zaal uses to manage his Farcaster presence also surfaces WaveWarZ battle results (via /wavewarz channel reads), ZABAL Gamez Empire Builder activity, POIDH bounties from BCZ rounds, and Zora creator coin data - all in one interface.

The Farcaster connection is foundational to the broader ZAO stack: COC Concertz show announcements go out via post.js, WaveWarZ battle results get amplified via the channels view, and daily community engagement (replies, follows, channel moderation) all flow through the cockpit. The action ledger captures every write, which feeds into future analytics on Zaal's reach and influence across Farcaster.

The Empire Builder tab connects zaalcaster to ZABAL's onchain leaderboard and booster ecosystem: Zaal can see where ZABAL ranks, who is boosting it, and queue up engagement with booster candidates without leaving the cockpit. The same tab will eventually support staking distributions and token creation (Clanker) once those flows are live-tested.

07

Roadmap

Built (live as of July 2026)

Full CLI suite, web cockpit + Mini App, SIWF guest access, gamified daily loop, Empire Builder read + staking + booster queue, POIDH tab, Zora coin card, Juke Spaces (pending JUKE_API_KEY), action ledger, health monitor, rate-limit guard, Clanker launch prep, Bluesky cross-post (bsky.js).

Pending (one manual step each)

Farcaster account association: Zaal signs z.thezao.xyz via dev.farcaster, pastes the result into public/farcaster.json. Unlocks full in-feed Mini App discoverability. JUKE_API_KEY: Pending Juke admin approval. Unlocks Spaces create from the CLI. Neynar Client ID: Register an app in the Neynar dev portal, set NEYNAR_CLIENT_ID + SESSION_SECRET in Vercel. Enables the SIWF sign-in button for guests in the hosted web cockpit.

On the roadmap (not yet spec'd)

Weekly engagement recap with Farcaster cast sharing (draft + confirm, never auto-post). Deeper ZABAL Gamez integration: leaderboard creation once non-tokenHolders type schemas are documented by Empire Builder. ZAO Papers link from Daily (surface relevant paper for the day's main project). Bluesky full posting parity (currently partial via bsky.js).

08

How to use it

Web cockpit (any device)

Navigate to z.thezao.xyz. Sign in with your Farcaster account via the SIWF button (guest read access). If you are Zaal (FID 19640), you get full access including the cockpit inbox, Post tab, Daily loop, Grow tab, and Empire tab. Guests see Feed, Channels, Search, and Empire reads.

Farcaster Mini App

Any cast that embeds z.thezao.xyz renders a mini app launch button in Warpcast. Tap it to open the cockpit inside the Farcaster client. Once the account association is set, the Mini App will also be discoverable in the Warpcast app directory.

Local CLI

Clone bettercallzaal/zaalcaster, run npm install, create ~/.zao/private/farcaster-zaal.env with NEYNAR_API_KEY + ZAAL_SIGNER_UUID + ZAAL_FID, then use npm run timeline, npm run cockpit, npm run morning. The CLI is the primary development surface; the web cockpit is for mobile and multi-device access.

For builders

The repo is a reference implementation for a personal Farcaster client. The patterns here - preview-first posting, shared lib.js across CLI and serverless, SIWF with role-based access, KV-backed game state - are reusable for any ZAO spoke that wants a Farcaster-native interface. Coordinate with Zaal before forking or adapting for a different ZAO project.