Skip to content

sultanpeyek/chainbard

Repository files navigation

chainbard

chainbard

An autonomous on-chain storyteller. Every address holds a story. Render it. The ledger remembers; chainbard retells it. Paste a Solana identifier — a wallet, a transaction signature, an NFT, or a token mint — and chainbard discovers tools on the Synapse Agent Protocol (SAP), pulls live context from Ace Data Cloud + Synapse RPC, and renders a permanent, shareable story page. It runs two ways with no manual step in between: a reactive flow (a buyer pays 0.30 USDC over x402 for a story) and an autonomous daily curator tick (a cron agent picks a subject, researches it, and publishes — funded from its own treasury). Every Ace Data call is paid through the Ace Data Cloud x402 facilitator.

Live: https://chainbard.vercel.app · Tick log: https://chainbard.vercel.app/activity

Submission for the Superteam Earn bounty Autonomous Agent Bounty: OOBE × Ace Data Cloud.


Category

Competing in Category 2 — Ace Data Cloud Usage (x402 Facilitator). The project targets AceData x402 USDC volume only; there is no Cat-1 escrow path. All buy-side Ace Data spend settles through the agent's own x402 self-broadcast rail on Synapse RPC (ADR 0016).


Proof on mainnet

The agent identity rows below are fixed. The on-chain settlement and memo proofs are live-truth — they render fresh on /judge for reviewers to verify, so the standing proof surface is the page, not a static signature pinned here.

What Where
Deployed app https://chainbard.vercel.app
On-chain proof surface (settlement sigs, memo trail, service provenance) https://chainbard.vercel.app/judge
Public tick log (neutral story feed) https://chainbard.vercel.app/activity
Registered agent (Synapse Explorer) https://explorer.oobeprotocol.ai/agent/9cssRtj1tpo8juYMKVw4BLonEXnSH2e6bfc9Qp88fN48
Agent PDA (SAP AgentAccount) 7WES6mSvsw3YnMBBvFQotK2GczLMgUCCiKxJFgRXUbYh
Settled x402 payment (agent → AceData) live on /judge
SAP Memo v2 audit entry live on /judge

The /judge page is the on-chain proof surface — memo trail, settlement sigs, and service provenance, all verifiable on Solscan. /activity is a neutral story feed for discovery (timestamp, kind, story link only); spend posture and receipt internals never leak on it (ADR 0016 §F).


End-to-end flow

Two paths, one public output (a story page at a permanent URL). Neither path has a manual step between trigger and published story. The whole system, top-level:

trigger                 SAP discovery                execution                  x402                         persist
{ reactive buyer    ─▶  { AgentAccount PDAs     ─▶  { Synapse RPC reads    ─▶  { AceData x402          ─▶  permanent story page
| autonomous cron }       via getProgramAccounts     + Ace SERP/Chat/Image       settlement;                  + /activity feed
                                                      + Video/Audio }             agent buys }                 + SAP Memo v2

Reactive flow (buyer-funded story, agent-subsidised media)

buyer pastes input ──▶ POST /api/mint/story
   │
   ├─ detectKind(input)            wallet | tx | nft | token
   ├─ 402 + accepts[]              server demands 0.30 USDC
   ├─ buyer signs X-Payment        Ace Data x402 facilitator settles the sell-side on-chain
   ├─ x402-verifier                amount + dest ATA + mint + slot freshness + sig dedupe
   ├─ spotlight-fetcher            Synapse RPC + Ace SERP enrich
   ├─ story-renderer               Ace Chat (structured) + multi-SERP + Ace Image (inline)
   ├─ persist ──▶                  permanent story page at /[input], published immediately
   └─ enqueue media-attach         durable QStash job: video + audio generated out-of-band,
                                   patched onto the story; the share page late-hydrates them

The story (chat + multi-SERP + image) publishes synchronously. Video and audio are generated by a durable QStash media-attach job (/api/workflow/media-attach) on the agent's own x402 rail and patched in afterward — the page is eventually-consistent for media (ADR 0016 §D).

Autonomous daily curator tick (agent-funded)

The primary autonomous trigger is an hourly Upstash QStash schedule that POSTs the durable Workflow route (/api/workflow/autonomous-tick, resumable, gated by QStash signing keys). An alternate synchronous trigger is available at GET /api/cron/autonomous-tick (Vercel Cron endpoint, Bearer auth). Both execute the same 5-step brain — no human, no buyer:

1. Ace SERP/news            gather the day's on-chain signals
2. Ace Chat (structured)    decide { kind, identifier, rationale }
3. Ace SERP                 enrich the chosen subject (multi-SERP)
4. Synapse RPC              enrich on-chain (balances, asset data, history)
5. story-renderer           Ace Chat + Ace Image + Video + Audio → publish + post URL to operator webhook

Each tick writes one SAP Memo v2 audit entry — a trimmed on-chain trail of the render (render id, kind, public identifier, and service-provenance receipt; rationale and source headline are deliberately dropped). The agent pays Ace Data from its own treasury and consumes only third-party services — no self-dealing (see CONTEXT.md).


Agent discovery via SAP

  • Agent network — chainbard enumerates every AgentAccount PDA on the SAP program (getProgramAccounts against the on-chain IDL) at GET /api/agents/discover. This is the live capability network: who's registered, their capabilities, pricing, and x402 endpoints. The endpoint is read-only and public; it powers operator inspection and future UI surfaces.

How payment works

  • Always x402, never bypassed. Every Ace Data call — the reactive buy-side (chat / multi-SERP / image) and the autonomous tick's full pipeline — routes through the agent's x402 self-broadcast rail on the Ace Data Cloud x402 facilitator. There is no bearer/API-token fallback; the facilitator plane is the only path (ADR 0016 §A, ADR 0001).
  • Synapse-first settlement. Each paid call settles through Synapse RPC for Cat-2 compliance; if Synapse hasn't confirmed within ~15s, the same signed tx is re-broadcast through solana_send (a generic RPC) so an unreliable Synapse doesn't block settlement. Identical signature ⇒ the network executes it at most once — never a double-spend (ADR 0016, ADR 0012). On-chain reads (balances, asset data, history) also route through Synapse RPC.
  • Real sell-side verification. When a buyer pays the reactive flow, the x402-verifier module checks payment amount, destination ATA, mint, slot freshness, and signature dedupe before serving — not just "is the signature confirmed."
  • Spend guard. The cost-guard is always-on with a hardcoded daily cap (ADR 0016 §G, ADR 0004) — a cheap runaway breaker, not an opt-in toggle. The agent wallet's USDC balance is the real ceiling; the in-memory daily cap is a safety secondary. Its breach is logged without dollar amounts on any public surface.
  • Buyer-funded, agent-subsidised. The buyer's 0.30 USDC pays for the synchronous story render (chat + multi-SERP + image). Video and audio are enqueued asynchronously (the QStash media-attach job) on the agent's own x402 budget, subsidising media enrichment beyond the sell-side price — by design, because buy-side volume is the Cat-2 metric (ADR 0016 §B). Demo runs (provenance='demo') are excluded from volume accounting (ADR 0005).

Provenance & honest volume

Every story carries a provenance tag — one of four values — so judge-relevant volume can be read honestly, never inflated by self-dealing or demos:

provenance Wax-seal label What it is
seed curator seed hand-seeded starter content
buyer buyer render someone paid 0.30 USDC over x402 through the reactive flow — including the smoke/test-loop wallet below, so buyer alone isn't proof of an external buyer
curator curator pick the autonomous tick paid Ace Data services via the agent's own x402 self-broadcast from treasury — legit Cat 2 consumption, counts
demo demo run the operator self-funds a demo-buyer that pays the agent's own ATA (self-dealing) — excluded

listRecent filters with WHERE provenance <> 'demo', so demo and seeded content never enter the real volume read (ADR 0005). The labels above are the wax-seal text rendered on each story page.

A second exclusion lives at the wallet level, and it takes precedence over the provenance tag: a continuous smoke / test-loop wallet (4HtB4QCubGYpqUnY6DDiZY8WvtyAXbNveRagVSVNuYUf) runs synthetic transactions to keep the pipeline warm. Because that wallet has also been driven through the homepage reactive flow, some of its stories carry the buyer tag — so reading honest external volume means excluding this wallet regardless of provenance, not trusting the tag alone. As noted on /judge, its transactions are synthetic — exclude it from the memo trail to read the actual judge-relevant volume.


What makes it autonomous

The daily curator tick runs on a schedule with no human and no buyer: it decides its own subject, researches it, pays for the AI services it needs, publishes the story, posts the URL to an operator webhook, and writes a trimmed on-chain audit entry (service provenance only, no spend/rationale details). Trigger → agent discovery → execution → payment → publish, end to end. The /judge page is the on-chain proof surface (memo trail, settlement sigs, service provenance); /activity is a neutral story feed for discovery.


Autonomous x402 settlement (Cat 2 maximised)

The autonomous tick is always x402 — every call settles USDC through the agent's own x402 self-broadcast client (the agent is the SPL fee-payer/broadcaster, so it funds tx fees with a dust amount of SOL). Both the autonomous tick and the reactive mint use the same rich pipeline. The agent pays for all buy-side Ace Data consumption from its own treasury; there is no bearer-token fallback (ADR 0016 §A/§B). Per run, the tick books six-plus distinct Cat-2 services:

Service Ace surface Role on the tick
SERP (Google) ace.search.google The agent's eyes — multi-layer subject research (events, origin, price, sentiment, listing).
Chat (heavy) ace.openai.chat.completions.create The brain — daily subject decision + narrative write, on ACE_CHAT_MODEL_HEAVY.
Image ace.openai.images.generate Hero infographic (nano-bananaseedream), under CONTENT_POLICY (ADR 0002).
Video (primary) ace.video.generate (veo / veo3) Abstract data-motion clip — kinetic typography / animated data card, no beings.
Video (fallback) ace.video.generate (kling) Provider-chain fallback when the primary video provider fails.
Audio ace.audio.generate (fish) Spoken-word narration of the story subtitle + lede.

Call count per tick: Chat ≈ 1 (Director + write), multi-SERP up to 5 deterministic queries (events / origin / price-analysis / sentiment / listing), Image 1, Video primary 1 async task, Video fallback 1 (only if primary fails), Audio 1 async task — up to 9+ paid calls. Video and audio are async (wait: false → a task id, polled via the free ace.tasks.get), so the tick stays short while still booking real Ace Data volume. Each is optional enrichment — a media failure never fails the tick.

On the reactive mint, media is enriched post-publish via a durable QStash job (/api/workflow/media-attach) that patches story.videoUrl/story.audioUrl out-of-band, keeping the mint fast and the page eventually-consistent.

Cadence. The durable trigger runs hourly via Upstash QStash (CRON_CADENCE_CRON defaults to 0 * * * *), which POSTs the Workflow route (/api/workflow/autonomous-tick); QStash signing keys gate the endpoint.

Drain-to-zero by design. The agent is autonomous and unmaintained — it burns until its treasury USDC is exhausted, then goes dormant by design. There is no pre-flight balance gate: dormancy is triggered only when a paid call fails at runtime due to insufficient USDC or SOL (on-chain 0x1 / SPL InsufficientFunds). isFundsExhausted() classifies the error, setDormant() persists an opaque reason code (no balance/floor numbers leaked), and the tick short-circuits silently — no tick_log row, no webhook. While dormant the tick stays quiet until the operator re-funds and clears the flag. There is no auto-top-up: the burn is the point.

Operator runbook

  1. Fund the agent — send USDC (the spend) and SOL (the agent is the x402 fee-payer/broadcaster, so it needs lamports for fees) to the agent wallet.
  2. Probe the rail — use the unified debug CLI to walk every stage: bun run ace:debug <input> --live runs detect → spotlights → director → multi-SERP → render → image → video → audio → persist → memo and prints, per stage, the provider + model in use, the output/link, and on failure the error
    • root cause. In --live it also prints the on-chain USDC settlement tx (Solscan link) for every successful paid call. For a fast service sanity-check, bun run scripts/spikes/x402-probe.ts still fires one minimal paid call per service (chat, search, image, video veo, video kling, audio fish) plus a free tasks.get retrieval, printing per-service OK / FAILED and the settle txs.
  3. Set env — the pipeline is always-on with sensible defaults; no toggle gates. Mandatory: QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY, QSTASH_NEXT_SIGNING_KEY, WORKFLOW_URL, CRON_CADENCE_CRON (default 0 * * * *), AGENT_SECRET_KEY_BASE58 (required — the rail fails without it), SYNAPSE_RPC_URL (settlement compliance; falls back to SOLANA_RPC_URL if unset, losing the Synapse-in-execution benefit). Optional enrichment + config: ACE_CHAT_MODEL_HEAVY (heavy write/decision model; defaults to ACE_CHAT_MODEL), VIDEO_PROVIDER/VIDEO_MODEL, VIDEO_FALLBACK_PROVIDER/VIDEO_FALLBACK_MODEL, AUDIO_PROVIDER/AUDIO_MODEL, IMAGE_PROVIDER/IMAGE_FALLBACK_PROVIDER, MEDIA_COLLECT_TIMEOUT_MS, SOLANA_SEND_RPC_URL, BLOB_READ_WRITE_TOKEN (Vercel Blob mirror for media).
  4. Schedule itbun run scripts/setup-qstash-schedule.ts registers the hourly QStash schedule (QSTASH_TOKEN, WORKFLOW_URL, CRON_CADENCE_CRON) that POSTs the Workflow route. From here the agent runs itself until the treasury runs dry.

Cat 2 requirements — mapped

Requirement Status
Registered on SAP mainnet ✅ agent live on Synapse Explorer (see Proof)
Complete automated workflow ✅ daily curator tick (QStash) + reactive flow
Ace Data Cloud account
x402 with AceData facilitator + Synapse RPC in execution ✅ always-x402 plane (ADR 0016) + Synapse-first settlement
≥3 distinct Ace Data services ✅ SERP (×5) + Chat (heavy) + Image + Video (primary + fallback) + Audio — 6+ total

How to test (for judges)

Two lanes — verify everything from the browser, or go deeper from the CLI.

Frontend (no wallet needed)

  • /judge — the on-chain proof surface: a live 402 probe against the reactive flow (see the real 402 and its accepts[] payment requirements, settled live), agent discovery, the SAP memo trail, and the curator history.
  • /activity — a neutral story feed of autonomous picks (timestamp, kind, story link). On-chain proof lives on /judge.
  • Home — paste any Solana identifier (wallet, tx, NFT, token mint) for a free read-only preview, no payment.

CLI

bun run demo                 # simulate the full flow, spends nothing
bun run demo -- --send       # real mainnet writes: fund → pay → mint → publish → recover
bun run ace:debug <input>    # debug the ACE flow (simulate by default, --live for real x402 spend)
bun run test-x402            # exercise the AceData x402 facilitator settlement
bun run check-agent          # confirm the registered SAP AgentAccount on mainnet

Stack

  • Next.js 16.2.6 (App Router, Turbopack, src/), React 19.2.4, Tailwind ^4.3.0, Bun, Biome (not ESLint)
  • Neon Postgres + Drizzle — story + activity repos
  • @oobe-protocol-labs/synapse-sap-sdk 0.19.8 — SAP register / discovery / memo
  • @oobe-protocol-labs/synapse-client-sdk ^2.0.6 — Synapse RPC + x402
  • @acedatacloud/sdk ^2026.504.2 + @acedatacloud/x402-client ^2026.507.2 — Ace Data APIs + x402 payment
  • @solana/web3.js ^1.98.4, @solana/spl-token, @coral-xyz/anchor, bs58, bn.js

SAP SDK note. The published synapse-sap-sdk 0.19.8 bundled IDL drifts from the deployed v0.18 program. chainbard uses the on-chain IDL (Program.fetchIdl + Anchor coder) as the source of truth for account layouts and raw instruction discriminators. See ADR 0001.


Run it locally

bun install
cp .env.example .env.local   # fill in keys (see comments in .env.example)
bun run check                # biome + tsc
bun dev                      # http://localhost:3000

Watch the full flow end-to-end without juggling a funded wallet:

bun run demo                 # simulate: read-only preview + real 402 probe, spends nothing
bun run demo -- --send       # real mainnet writes: fund → pay → mint → publish → recover
bun run ace:debug <input>    # walk every ACE stage with provider/model + error causes

Other operator scripts: register-agent, check-agent, test-x402, close-agent, fund-buyer, seed-mint, seed-featured, ace:debug. See package.json.


Brand

The mark is a bard's plumed cap with a gold feather/quill (PlumeMark) on warm near-black ground — "the bard sets a quill to your chain." Palette, typography, asset files, and usage rules live in docs/brand.md.


Architecture & decisions

  • GlossaryCONTEXT.md (every term used precisely)
  • ADRsdocs/adr/ (0001–0016): payment plane (0001), content policy (0002), virality-first / autonomous deprioritization (0003), cost guard (0004), demo self-funding exception (0005), payment-gated live render (0006), t3-env strict typed config (0007), two-tier brand mark (0008), streaming verbose mint console (0009), brief director no orchestration SDK (0010), token narrative-first (0011), synapse-primary x402 paid legs (0012), durable payment-intent idempotency (0013), token two-tier truth and infographic (0014), x402-cron conversion (0015), always-on pipeline Cat-2-only redacted surfaces (0016)
  • Integration notesdocs/sap.md, docs/acedata.md, docs/synapse.md
  • Branddocs/brand.md (palette, typography, assets)

License

MIT — see LICENSE.

About

Solana storyteller — reactive x402 mint + autonomous daily tick

Resources

License

Stars

Watchers

Forks

Contributors

Languages