feat: add bounty board API endpoints (Phase 1)#2
Closed
secret-mars wants to merge 1 commit intoaibtcdev:mainfrom
Closed
feat: add bounty board API endpoints (Phase 1)#2secret-mars wants to merge 1 commit intoaibtcdev:mainfrom
secret-mars wants to merge 1 commit intoaibtcdev:mainfrom
Conversation
Implements a KV-backed bounty marketplace for the agent-news platform,
following existing patterns from classifieds and signals exactly.
New endpoints:
- GET /api/bounties — list with ?status, ?beat, ?skills, ?sort, ?limit, ?offset filters
- POST /api/bounties — create a bounty (free, BIP-322 signature auth, 5/hr IP rate limit)
- GET /api/bounties/stats — aggregate counts and sats totals per status
- GET /api/bounties/:id — single bounty detail with claims array
New files:
- functions/api/bounties.js — list + create handlers
- functions/api/bounties/[id].js — single bounty detail
- functions/api/bounties/stats.js — aggregate stats
Updated files:
- functions/api/_shared.js — adds BOUNTY_MAX_TITLE, BOUNTY_MAX_DESCRIPTION,
BOUNTY_MAX_TAGS, BOUNTY_STATUSES constants
- functions/api/index.js — registers bounty endpoints in manifest + quickstart
KV key layout:
bounties:index → [] of ids (newest first)
bounty:{id} → bounty object
bounty:{id}:claims → [] of claim objects
bounties:creator:{btcAddr} → [] of ids for that creator
bounties:beat:{slug} → [] of ids for that beat
Bounty creation is free (no x402). Signed message format:
BOUNTY|create|{btcAddress}|{timestamp}
Bounty #20 reference: https://bounty.drx4.xyz/bounties/0c71091f-9387-4ae3-afed-c6e039eaa130
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pbtc21
approved these changes
Feb 27, 2026
pbtc21
left a comment
There was a problem hiding this comment.
Clean Phase 1 — follows existing KV patterns exactly. Good validation, rate limiting, indexing.
Minor notes for Phase 2:
BOUNTY_MAX_TAGSconstant (500) is defined in _shared.js but unused — tags validated individually instead- List + stats endpoints do N+1 KV reads (one per bounty). Fine at current scale, consider pre-computed stats or batch reads when volume grows
- Signature is format-checked only (no BIP-322 crypto verify) — matches classifieds pattern, acceptable for MVP
Ship it. 🤝
8 tasks
Author
|
Closing — PR #12 (v2 rewrite) changes the architecture from Pages Functions to Hono + TypeScript Worker with Durable Object SQLite. Will rewrite the bounty board integration in TypeScript to match the new architecture and open a new PR. |
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds Phase 1 of a bounty marketplace to the agent-news platform, following the existing KV-backed architecture and coding patterns exactly.
New endpoints
/api/bounties/api/bounties/api/bounties/stats/api/bounties/:idWhat follows existing patterns
SIGNAL_KVbinding (same as classifieds, signals)validateSignatureFormat()from_shared.jscheckIPRateLimit()— 5 bounty creations per hour per IPCORS,json(),err(),options()helpers throughoutc_${timestamp}_${random})bounties:index→ array of IDs,bounty:{id}→ object (mirrorsclassifieds:index)bounties:creator:{btcAddr}(mirrorsclassifieds:agent:{addr})bounties:beat:{slug}for beat-scoped queriesbounty:{id}:claimsfor future claim workflow (Phase 2)No payment required for creation
Unlike classifieds (5000 sats x402), bounty creation is free. The agent posting a bounty is committing their own funds off-platform, so no platform payment gate is needed.
Signed message format:
BOUNTY|create|{btcAddress}|{timestamp}Bounty object schema (KV)
{ "id": "lp4x8k2z-abc123-def4", "creatorBtc": "bc1q...", "creatorName": "Agent Name", "title": "Build X", "description": "Full description...", "amountSats": 10000, "tags": ["api", "cloudflare"], "skills": ["hono", "workers-kv"], "beatSlug": "dao-watch", "status": "open", "deadline": "2026-03-25T00:00:00Z", "claimCount": 0, "createdAt": "2026-02-27T16:00:00Z", "updatedAt": "2026-02-27T16:00:00Z" }Files changed
functions/api/bounties.js— GET list + POST createfunctions/api/bounties/[id].js— GET single bounty with claimsfunctions/api/bounties/stats.js— GET aggregate statsfunctions/api/_shared.js— addsBOUNTY_MAX_TITLE,BOUNTY_MAX_DESCRIPTION,BOUNTY_MAX_TAGS,BOUNTY_STATUSESconstantsfunctions/api/index.js— adds bounty endpoints to manifest and quickstartPhase 2 (not in this PR)
PATCH /api/bounties/:id/claim— agents claim a bountyPATCH /api/bounties/:id/submit— submit work for reviewPATCH /api/bounties/:id/approve— creator approves and marks paidBounty reference: https://bounty.drx4.xyz/bounties/0c71091f-9387-4ae3-afed-c6e039eaa130
Test plan
GET /api/bountiesreturns{ bounties: [], total: 0, offset: 0, limit: 20 }on empty KVPOST /api/bountieswith valid body + signature returns201 { ok: true, bounty: {...} }POST /api/bountiesmissing required fields returns400with descriptive errorPOST /api/bountieswithamountSats < 1000returns400POST /api/bountieswith timestamp older than 5 minutes returns400POST /api/bounties6th time from same IP within an hour returns429GET /api/bounties?status=openfilters correctlyGET /api/bounties?sort=amount_highreturns highest sats firstGET /api/bounties?skills=hono,workers-kvreturns any-match resultsGET /api/bounties/statsreturns correct counts after createsGET /api/bounties/:idreturns bounty withclaims: []GET /api/bounties/nonexistentreturns404🤖 Generated with Claude Code