Quiver is a per-second x402 settlement rail on Arc. Archer and Scout are the agent demo of it; an Owncast sidecar is the creator-stack deployment of the same rail.
Quiver is a Lepton Agents Hackathon project built on the circlefin/arc-nanopayments starter. It bills for exactly the seconds consumed and stops the instant signing stops, composing a streaming rail from per-tick EIP-3009 authorizations that Circle Gateway batches on Arc testnet. Archer is the seller agent: it produces strategy signals, prices each request dynamically, protects them behind x402, and receives USDC through Circle Gateway. Scout is the buyer agent: it runs on a funder-level USDC budget, evaluates Archer's quoted price and confidence per call, and buys or declines with a logged reason.
Official domain: https://getquiver.xyz · Public demo: https://getquiver.xyz/try
Most x402 examples sell one discrete API response at a fixed price. Quiver makes the primitive the headline: pay-per-second streaming over x402 — composed from many small EIP-3009 authorizations that Circle Gateway batches for settlement on Arc. Archer and Scout prove the rail with autonomous pricing and buying decisions; the same per-second core now has a verified local Owncast sidecar where chat presence drives creator-stream ticks.
What's shipped today:
- Deployed Archer x402 endpoints with dynamic pricing (compute- and confidence-pegged) and logged reason strings.
- Scout with per-call buy/decline logic against quoted price, confidence, and remaining funder budget.
/try— an honestly-labeled, demo-funded human path (no wallet required) that triggers a real settlement.- Pay-per-second streaming — per-tick x402 loop (
GET /api/archer/stream),stream_eventstable, Scout CLI (npm run stream), dashboard live meter with tap-to-stop. - Dashboard metrics that separate demo buys, Scout payments, and stream ticks (
payment_events.raw.source). - Verifiable reasoning trace (SHA-256 hash) on every Archer response.
- Owncast sidecar — local Owncast
0.2.5replay verified the presence model:CHATstarts the stream,USER_PARTEDcloses it, andGET /api/integrations/clientsheartbeat is the fallback. Proof session25418b23-4f15-4146-aad8-3038320a011ewrote a verifiedstream_eventstick with Owncast metadata; heartbeat-only sessionbc3fa644-031f-4bfa-89d1-7c4849aad1fbstopped withoutUSER_PARTEDdelivered to the sidecar.
Obol independently tested Quiver as an external x402 buyer and bought GET /api/archer/signal, paying 0.00063 USDC for a confidence-priced signal. The paid response returned a clean sell signal plus Quiver's trace_hash, validating the paid signal and verifiable reasoning path outside Quiver's own Scout and demo flows.
Obol also scored Quiver on-chain with its agent. Proof transaction: 0x883706f4708c046cd5043c560ad55519ad75a09d63aa9ded9cf782007cd3f6cc.
flowchart LR
Visitor["Visitor at /try"] -->|"POST /api/demo/buy"| Demo["Demo buyer server-side"]
Demo -->|"funder → ephemeral → Gateway"| Archer["Archer x402 endpoints"]
Scout["Scout buyer agent"] -->|"402 quote + decision"| Archer
Archer -->|"HTTP 402 + dynamic price"| Scout
Funder["Funder wallet"] -->|"funds session wallet"| Ephemeral["Ephemeral payer wallet"]
Scout -->|"signs GatewayWalletBatched auth"| Ephemeral
Ephemeral -->|"paid retry"| Archer
Archer -->|"verify and settle"| Gateway["Circle Gateway"]
Gateway -->|"batched USDC settlement"| Arc["Arc testnet"]
Archer -->|"200 + signal + trace hash"| Scout
Archer -->|"insert payment_events"| Supabase["Cloud Supabase"]
Supabase -->|"realtime stream_events"| Dashboard["Quiver dashboard"]
Supabase -->|"realtime payments and balance"| Dashboard
- Frontend and API: Next.js App Router.
- Seller agent: Archer endpoints under
app/api/archer(lib/archer/strategy.ts,lib/archer/pricing.ts). - Buyer agent: Scout script in
agent.mts(lib/scout/decision.ts,lib/scout/quote.ts); streaming inlib/scout/stream.ts+stream.mts. - Demo path:
app/try/page.tsx+POST /api/demo/buy(lib/demo/gateway-buyer.ts); dashboard stream viaPOST /api/demo/stream/*. - Payment protocol: x402 (
402→PAYMENT-REQUIRED→ signed retry →200+PAYMENT-RESPONSE). - Settlement: Circle Gateway batched settlement on Arc testnet.
- Persistence: Cloud Supabase
payment_eventsandstream_events(source tagged inraw.source:demo|scout|stream). - Dashboard: payments + live stream meter (authorized/verified volume, tap-to-stop), source badges, Gateway balance, withdrawals.
- Grounding document:
docs/PRD.mdis the product source of truth;docs/ROADMAP.mdtracks what's shipped and what's next.
Circle Gateway requires a long enough authorization window for batched settlement. Quiver uses maxTimeoutSeconds = 604900 (7 days plus buffer) in lib/x402.ts.
All Archer endpoints are x402-protected and settle sub-cent USDC on Arc testnet. Prices are dynamic per request — base tiers below are floors/anchors, not fixed quotes.
| Endpoint | Base tier | Pricing axes |
|---|---|---|
GET /api/archer/signal |
~$0.001 | Confidence multiplier on base |
GET /api/archer/market-state |
~$0.0001 | Cheap lookup (minimal variation) |
GET /api/archer/stream |
~$0.0001/sec | Per-tick live decision feed slice (streaming) |
POST /api/archer/compute |
~$0.003 | +10% per KB of submitted context |
Each 402 includes extensions.quiver with price_usdc, price_reason, and confidence. Each 200 response includes:
decision:buy,sell, orholdconfidence: 0–1factors: human-readable signal inputsprice_reason: Archer's logged pricing decisionreasoning.trace_hash: SHA-256 over the canonicalized trace
Scout runs locally against the deployed seller:
BASE_URL=https://getquiver.xyz npm run agent -- --limit 0.01Decision rule (one sentence): Scout buys when confidence ≥ 0.45 and quoted price ≤ confidence × remaining funder budget; otherwise it declines and logs why.
The persistent BUYER_PRIVATE_KEY is a funder wallet. Each run creates a fresh ephemeral payer wallet, funds it, deposits into Gateway, and pays Archer from that session. Budget is tracked at the funder level via --limit.
Streaming is many discrete per-tick EIP-3009 authorizations (not a native rate primitive). One ephemeral wallet per session, funded once; each tick calls GatewayClient.pay() with long-validity auth (maxTimeoutSeconds = 604900).
Scout CLI (local, funder-funded):
BASE_URL=https://getquiver.xyz npm run stream -- --ticks 10
# Options: --limit 0.01 (USDC cap) --interval 1000 (ms between tick completions)Dashboard (operator sign-in at /dashboard): Live stream panel — Start/Stop, realtime meter on stream_events, exact-cost invariant on stop (ticks × $0.0001 = total).
Spike test (go/no-go gate — overlapping auths from one wallet at 1 Hz):
npm run spike:overlapping-authApply Supabase migrations before streaming (stream_events + realtime publication):
npx supabase db push
# Or paste supabase/migrations/20260318100000_create_stream_events.sql
# then 20260318100001_enable_stream_realtime.sql in the SQL editor.Verify realtime delivery:
node --experimental-transform-types --no-warnings --env-file=.env.local scripts/verify-stream-realtime.mtsThe Owncast sidecar runs as a local Node process next to an Owncast server. It receives POST /webhooks/incoming, starts Quiver's existing per-second stream on Owncast CHAT or USER_JOINED, stops on USER_PARTED, and uses GET /api/integrations/clients as the heartbeat fallback if a close event is missed.
Run the sidecar against local Owncast:
OWNCAST_URL=http://localhost:8080 \
OWNCAST_ACCESS_TOKEN=<token> \
BASE_URL=http://localhost:3000 \
npm run owncast:sidecarThe verified local model is intentionally precise: do not describe it as a pure USER_JOINED / USER_PARTED window for Owncast 0.2.5; USER_JOINED was not observed in the replay. CHAT is the verified start signal, USER_PARTED is the verified clean-close signal, heartbeat is the verified fallback, and stream_events remains the billing source of truth. See docs/OWNCAST_STAGE_1.md for the verdict table.
Public page: /try — no wallet, one click.
- Calls
POST /api/demo/buy(default:/api/archer/signal). - Server runs the same funder → ephemeral → Gateway → Archer flow as Scout.
- Settlements are real but tagged
demoinpayment_events.raw.source— not counted as distinct paying visitors. - Rate-limited per IP (
DEMO_RATE_LIMIT_SECONDS, default 30s) to protect the funder wallet. This is an in-memory, per-instance testnet guardrail; it is honest demo protection, not production abuse prevention.
Share https://getquiver.xyz/try for traction outreach.
npm install
cp .env.example .env.local
npm run generate-walletsFund the buyer/funder wallet from the Circle faucet.
npx supabase link --project-ref <your-project-ref>
npx supabase db push
npm run dev
npm run agent -- --limit 0.01Open http://localhost:3000/try for the local demo path.
Vercel (seller + demo):
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-publishable-or-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
ADMIN_EMAIL=your-dashboard-email
ADMIN_PASSWORD=your-dashboard-password
SELLER_ADDRESS=0xYourSellerWalletAddress
SELLER_PRIVATE_KEY=0xYourSellerPrivateKey
BASE_URL=https://getquiver.xyz
BUYER_PRIVATE_KEY=0xYourBuyerFunderPrivateKey
DEMO_RATE_LIMIT_SECONDS=30
DEMO_DEPOSIT_AMOUNT=0.01BUYER_PRIVATE_KEY is required in Vercel for the /try demo path (server-side funder). Scout still runs locally with the same key in .env.local.
Local only (Scout + demo dev):
BUYER_ADDRESS=0xYourBuyerFunderAddress
BUYER_PRIVATE_KEY=0xYourBuyerFunderPrivateKey
BASE_URL=http://localhost:3000Optional: OPENAI_API_KEY
Sign in at / → /dashboard (credentials from ADMIN_EMAIL / ADMIN_PASSWORD).
The dashboard shows:
- Headline proof row with Scout-only real payer metrics: distinct Scout payers, Scout settlements, and Scout-paid volume (demo excluded)
- Source-aware stream meter — labels agent streams vs Owncast creator streams from stream metadata, with neutral fallback when unknown
- Integration surfaces strip — agents shown as live Scout settlements; creators shown as verified local Owncast ticks / early access
- Demo buys vs Scout payments vs stream ticks (separate counts and volume below the headline)
- Per-row source badge (
demo|scout|stream) - Gateway balance, withdrawals, realtime payment feed
- Open https://getquiver.xyz/try and click Buy Archer signal (demo).
- Confirm the result shows the settled USDC amount, Archer's price reason, the trace hash, and an Arcscan transaction link when a transaction hash is available.
- Sign in to
/dashboardwith the provided operator credentials and confirm the headline row is Scout-only: distinct Scout payers, Scout settlements, and Scout volume. - Confirm the integration strip shows agents as live Scout settlements and creators as verified local Owncast ticks / early access.
- Start the Pay-per-second stream, let a few ticks land, then stop it. The meter should label the dashboard-started stream as an agent stream and the invariant should read
ticks × $0.0001 = totalusing verifiedstream_events. - Run Scout locally against production to show agentic buy/decline decisions:
BASE_URL=https://getquiver.xyz npm run agent -- --limit 0.01- Before recording or submitting, run
npm run verify:demo-readinesslocally. - Use the dashboard metrics for submission numbers: report demo buys, Scout payments, stream ticks, and distinct Scout payers separately.
Quiver deploys on Vercel with cloud Supabase. The official public domain is getquiver.xyz; the Vercel project remains the hosting target.
- Set all Vercel env vars above (use
BASE_URL=https://getquiver.xyz, not a preview URL). - Push to
main— Vercel redeploys automatically. - Verify live:
- https://getquiver.xyz/try loads and settles a demo buy
- Rapid repeat clicks return
429 - Scout run tags payments
scoutwith dynamic prices - Dashboard splits demo / Scout / stream metrics
- Stream meter ticks up on its own when Start stream is pressed (realtime on
stream_events) npm run verify:demo-readinesspasses lint and confirms stream tables / recent tick uniqueness
Keep the funder wallet topped up (~$1 minimum; refaucet from Circle if demo volume is high).
| Metric | Source |
|---|---|
| Demo buys | payment_events where raw.source = 'demo' |
| Scout payments | payment_events where raw.source = 'scout' |
| Stream ticks | payment_events or stream_events where raw.source = 'stream' (authorized volume) |
| Distinct paying clients | Unique Scout payer addresses only (exclude demo) |
| Volume / avg size | Report demo and Scout separately or combined with labels |
Testnet hackathon project only:
- Arc testnet USDC, throwaway wallets
.env/.env.localnever committed- Dashboard credentials private in Vercel
- Seller and buyer keys in Vercel for testnet demo purposes only
- Not investment advice; not a production trading system
- Dynamic Archer pricing (compute + confidence, logged reasons)
- Scout per-call buy/decline logic
- Human demo path (
/try, honestly tagged) - Pay-per-second x402 streaming (loop + dashboard meter)
- Partial stream adversarial hardening (timeouts, fail-closed UI, verified-count reconciliation)
- Stream hardening stretch: out-of-balance and abandoned-session cleanup
- Visitor pays with own wallet (stretch, post-streaming if time)