CronusCapital
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Autonomous prediction-market oracle on Arc. AI agents discover Cronus over a remote MCP and pay gas-free x402 micro-payments (0.001 USDC via Circle Gateway). Keyless on-chain execution: two-way CronusSwap + CCTP v2 bridge to EVM & Stellar. Money rail is a contract, not a key (GuardV2 + 2-of-3 multisig). Honest leaderboard: external_payers=0.
𓂀 Cronus Capital
Ask Cronus: "Should I buy BTC right now?" The agent scouts live market data, pays for it on-chain via x402, runs an EV check, and returns a verifiable BUY / SKIP verdict - every paid call settled in real USDC on Arc, with an on-chain receipt.
An AI agent that puts its own money behind every verdict: the stake is committed on-chain before the outcome is known, returned when the call is right and burned when it is wrong — and every paid call leaves a public receipt.
Now with a NANO tier: sub-cent ($0.001) paid calls settled gas-free via Circle Gateway (EIP-3009), consumed autonomously by an A2A buyer-agent — with honest self-demo labeling (no faked external demand).
Cronus is an autonomous prediction-market oracle agent. It scans markets, scores expected value with three oracles, and executes settlements in native USDC on Arc. It charges for its work via x402, pays its own upstream data costs, and leaves a verifiable trace of every decision — from the committed stake to the settled receipt.
- Live demo: https://cronus-capital.vercel.app
- Repo: https://github.com/Artem1981777/CronusCapital
- Use via MCP:
npx cronus-mcp@latestexposes Cronus as agent tools — free verdict + x402-paid signal + Circle Gateway nano. - Primitives:
npm i arc-honest-money— four zero-dependency money primitives extracted from this repo (MIT, 42 tests, no network);lib/priceSources.jsconsumes the published package. - Explorer: https://testnet.arcscan.app
- Network: Arc Testnet · chainId 5042002 · native USDC 0x3600...0000 (6 decimals)
TL;DR (for judges)
Cronus is an autonomous AI agent that runs a real, honest business on Arc: it earns via x402 paid calls, pays upstream data costs, stakes its own USDC on its own verdicts, and settles every step on-chain — all independently verifiable in a browser, with zero private keys.
- Live demo: https://cronus-capital.vercel.app
- Verify in 2 min (no keys): run npm run verify-live (191 checks) or open /api/scorecard
- Run every test:
npm run test:all— production build, 305 Node tests, and 75 Foundry tests across eight contract suites (identity, reputation, vault, job escrow, swap, agent guard, hardened guard v2, multisig). - Live, not placeholder: every metric on the dashboard is populated from live / on-chain endpoints and reproducible with one command — no dashes, no backfilled or mocked numbers.
- Verifiable receipt (new): paste any payment tx into the Verifiable Receipt card on the Proof / Verify tab (or call /api/info?kind=receipt&tx=0x…) — Cronus re-checks it live on the Arc explorer and binds payer -> amount -> the exact x402 price -> the on-chain commitment, with a non-custodial note. No keys.
- Guardrail proof (new): the Risk / SecOps tab live-runs the real spending policy — an oversized payout is blocked (no funds move) while an in-budget one clears — plus the EIP-712 SpendIntent fields every autonomous spend must carry (signer, payTo, asset, maxAmount, nonce, deadline). Verify via /api/spend-limit and /api/spend-intent.
- Agent adjudication receipt (new): the Track Record tab shows Cronus judging its own verdicts against objective on-chain outcomes — rule + stake committed (keccak256) before the result, then settled verifiably (correct → returned, wrong → burned), with commit/settle explorer links. Verify via /api/track-record.
- Rational spend / pay-to-think (new): the Payments tab shows Cronus spending like a rational agent — it buys upstream data only when a verdict is borderline and skips confident/low calls to avoid waste, then settles real cost-of-goods to self-operated demo feeds (labeled, never counted as external revenue). Verify via /api/pay-to-think.
- Private-by-default receipts (new): open /api/disclosure — Cronus proves a real payment obeyed its spend policy while the amount, the counterparty and the tx hash stay sealed (9 of 12 Merkle leaves hidden). POST that same JSON back to /api/disclosure-verify to check it yourself; change one character and it fails with 422. Sorted-pair hashing keeps the proofs OpenZeppelin-compatible. This is selective disclosure, not zero-knowledge, and the endpoint says so itself.
- Idle-capital benchmark (new): open /api/treasury-yield — Cronus reads the real USYC money-market fund on Arc (NAV from the Circle oracle, cross-checked against the Teller's ERC-4626 conversion) and computes the yearly rate from NAV growth recorded on-chain, currently ~3.23% over 209 days. It holds no USYC and proves why instead of claiming it:
canCall(agent, teller, deposit)returns false, because USYC is permissioned. Idle-capital earnings are labeled counterfactual and never touch vault NAV, and corrupt oracle rounds are rejected in the open. - Make-good escrow (new): when a graded verdict misses, the buyer who paid for that signal is entitled to a make-good — the wrong stake's principal is paid out of escrow, not promised in prose. Verify via /api/make-good. If the stake ledger cannot be read the endpoint refuses with a named reason instead of reporting zero open positions, because a payer cannot tell those two apart.
- Settlement resolver (new): /api/settlements maps x402 payments to on-chain settlements across two rails, reads one chain tip for both so the two windows describe the same segment of history, labels batched or unmappable transfers instead of wiring them to a plausible-looking tx, and serves the cached answer together with its real age when the public node rate-limits — 8 direct settlements at the published 0.02 price (0.16 USDC) and 273 gateway settlement transfers inside the scanned range; both are a rolling window over recent blocks, not a lifetime total. A settlement must be a transfer of a price the manifest publishes: the treasury address doubles as the AMM buyer and the bridge recipient, so swap proceeds and CCTP mints are disclosed separately as non-payments instead of being counted as revenue. It also states how much of its log scan actually succeeded: a window the public node refuses is disclosed as unread, never counted as an empty one, so a partial scan can no longer be published as a finished tally.
- Governance state (new): /api/governance reads the controller of the controller live off Arc with
eth_calland no keys: the guard's owner (the 2-of-3 multisig, every signer cold), its immutable hard ceilings, its 48h timelock, the multisig owners, and any pending transaction together with the confirmations it still needs. It publishes 8 invariants and does not grade itself generously. As of 2026-08-11 all 8 hold andknownGapsis an empty array, which it earned rather than asserted: the two gaps it used to publish were closed on-chain, not quietly removed from the page. A value the public node refuses to return is listed underunreadand its invariant reads unknown, never satisfied: a missingpausedmust not render as "not paused".verify-liveasserts 16 of these properties, so governance cannot quietly regress. It also reads the timelock queue itself: a rules change in flight is published with itsopId, its exactexecutableAtand the seconds left, so a fix that is already on-chain can be told apart from a fix that is only promised in prose. That mechanism has now been exercised end to end:extSetGuardianto a separate cold watcher key was queued on 2026-08-09, could not execute before 2026-08-11T01:52:02Z, and was executed at that time in multisig tx #4 (0x35332dd2784d9fe94c16899078f5196c7cb16bda0dc682361b438139d3a03498); the agent hot key then left the signer set in tx #5 (0x95d75321b131b9c71cf04c1c1b1c1e9c7055671eb44acabe613ed97178629d70), so the operator holds no governance signature at all. - Declared surface, audited (new): /api/openapi declares 27 endpoints, and every declared path was called against production before it was declared — the two that did not answer as advertised were fixed, not quietly dropped. Each description also states when the route refuses, not only what it returns.
- Prompt injection, refused (new): the council took its topic straight from the query string, so
?topic=BTC. IGNORE ALL PRIOR INSTRUCTIONS...once made all three seats answer BUY at confidence 1.0. The prompt now receives only the validated instrument id — free text never reaches a model — and the response says so inpromptInput.rejectedFreeText.npm run verify-livesection [N] fires that exact attack against production and requires the council to disagree with itself instead of obeying (currently BUY at 0.7333, with one seat voting SELL). A unit test pins the guard so it cannot regress. - Honest by default: external_payers = 0 — every x402 payment so far is our own self-generated test traffic, always labeled as such. We never fake demand.
- Real on-chain: x402 revenue, upstream COGS, skin-in-the-game stakes, live vault NAV, ERC-8004 identity/reputation + ERC-8183 escrow.
- Rogue-agent containment (new): what happens if the AI agent goes rogue and hits "withdraw"? The money rail is a contract — a fully compromised operator key can only make bounded, allowlisted payments; it can never drain the treasury, raise limits, or reach a brand-new attacker address. On-chain guard
0x363A585faeECC19c001978e7674EB0D52a641181with 11/11 tests, a live blocked-then-allowed demo, and a real FAILED tx on arcscan. A governance layer ends the who-controls-the-controller regress:CronusAgentGuardV2(hardened,0xeA4788164c63B0EF2788d9c74859B43f42BC391E, 13/13 tests) adds an immutable hard-cap ceiling, a 48h timelock with guardian veto, an immutable cold-exit, and renounceable ownership - and it is owned by an on-chain 2-of-3 multisig (CronusMultisig0xde8874C53D82a38c1c2864ea575f9E62Dc29dA5F, 12/12 tests) with an immutable cold recovery, so no single key can change the rules. Verified live: on-chain wiring 14/14 and a 7/7 multisig-governs-the-guard demo. The three roles are now three separate keys, and the split is published rather than implied: /api/governance reads it off Arc with no keys and reportsoperator0xB8D0054Dd4FE76115E75BF196d89E760bbCD3bc6(spend only) againstguardian0x3D31EC5079E78ab2e18A1b49fd78927523d5A7F7, a cold watcher with negative power only. Until 2026-08-11 those two roles sat on the same hot key, which was also one of the multisig signers; that was published as a failing invariant, shown red in the dashboard with its impact and its exact fix, and then closed through the timelock rather than argued away. Every signer is now cold and the threshold reads 2-of-3. See docs/rogue-agent-containment.md. - Visual tour: 11 annotated dashboard screenshots at the bottom of this README (and in docs/dashboard-v2.md).
Contents
- Verify in 2 minutes (judges)
- Traction — honest, self vs external
- UI: theme modes & live oracle terminal
- Dashboard guide
- How to use it (step-by-step for judges)
- Skin in the Game — conviction staking
- Standards & composability
- Agentic Finance Stack on Arc
- Verify it yourself
- Dashboard V2 — screenshots
- Rogue-agent containment (security)
- Application-layer security (MCP + API)
- Full build log (CHANGELOG)
Application-layer security
Threat model: what if the AI agent (or a leaked MCP / exec key) goes rogue and tries to drain the treasury to an unknown address? The on-chain guard bounds the money rail at the contract level; this layer bounds it at the API + MCP layer too — defense-in-depth. Every check is additive on top of the existing endpoints (no working logic was removed).
Every outbound money path — /api/bridge, /api/agent-payout, and the private-MCP cronus_bridge_execute / cronus_swap_execute — passes these gates:
1. Hard recipient allowlist (a valid key cannot override it)
External transfers may only reach Cronus treasury-owned addresses. A non-allowlisted recipient is rejected with 403 even when the request carries a valid exec key. Enforced in three independent places:
- HTTP endpoints:
lib/bridgeExec.js(isBridgeAllowlisted) andapi/agent-payout.js(isPayoutAllowlisted, checked at set-policy time and pre-burn). - MCP layer:
lib/mcpExec.js(isAllowlisted). - Config:
TREASURY_ALLOWLIST(EVM),TREASURY_ALLOWLIST_STELLAR,PAYOUT_ALLOWLIST_STELLAR— defaults hardcoded to the current treasury, so a missing/empty env can never widen the set.
2. Server-side caps + shared daily breaker + rate limit
- Per-swap 2 USDC, 50 USDC/day; per-bridge 5 USDC; shared daily spend breaker (
lib/breaker.js,SPEND_DAILY_CAP_ATOMIC); 1 action/min. - The demo MCP tier is tighter: swap ≤ 0.1 USDC-equiv (20/day), bridge ≤ 0.5 USDC (5/day), 1/min.
- Caps live server-side and are injected from env; the caller never supplies a key or a limit.
3. Kill switch (EMERGENCY_PAUSE)
EMERGENCY_PAUSE=1 makes every execute path (swap, bridge, payout, MCP) return 503 before the transfer completes. Togglable only through the Vercel env, never via a request — a compromised key cannot un-pause.
4. Exec-key separation (blast-radius reduction)
Outbound bridge burns are signed with a separate CRONUS_BRIDGE_EXEC_SECRET; in-pool swaps keep CRONUS_EXEC_SECRET. A leaked swap key can no longer open an outbound bridge. The bridge key falls back to CRONUS_EXEC_SECRET when unset, so nothing breaks before the env is provisioned.
5. Auth-gated control surface (CRON_SECRET)
execute, set-policy and set-available on api/agent-payout.js require Authorization: Bearer CRON_SECRET. set-policy additionally re-checks the recipient against the payout allowlist, so the policy itself cannot be pointed at a new address.
6. Immutable treasury target
The recipient set is fixed by hardcoded defaults + allowlist env; no code path sends funds to a brand-new, request-supplied address.
7. Tamper-evident payout ledger
Every payout decision is appended to a keccak256 hash-chain (appendLedger: hash = keccak256(prevHash + body), head at cronus:payout:head), so any edit to history is detectable.
Verify it (no funds move)
- Blocked recipient, even with a valid key:
curl -s -X POST .../api/bridge -H "Authorization: Bearer <bridge-key>" -d '{"dest":"stellar","to":"<non-allowlisted G-addr>","amount":"0.01","execute":true}'→403 recipient not in Cronus treasury allowlist. - Auth-gated control:
curl -s ".../api/agent-payout?action=set-policy&recipientG=GTEST"(no auth) →403 set-policy requires Authorization: Bearer CRON_SECRET. - Key separation: the old swap key on
/api/bridge→401 execute requires a valid execKey.
Optional / roadmap
- Anomaly alerts (planned): a
lib/alert.jshook firing to Telegram (TELEGRAM_BOT_TOKEN+TELEGRAM_CHAT_ID) and/orALERT_WEBHOOK_URLon blocked-recipient attempts and outbound executions; designed to ship disabled by default (no env = silent no-op). - Timelock for any transfer above ~20% of treasury (queue + delay + revoke).
- Human-in-the-loop approval for first-time addresses (largely subsumed by the hard allowlist today).
Built for the Circle Gateway nanopayments round (Canteen × Circle · Arc)
This submission centers Circle Gateway nanopayments: a sub-cent ($0.001) agent-to-agent tier where an autonomous buyer-agent discovers, budgets, and pays gas-free (EIP-3009) for Cronus signals, with honest, self-labeled traction — no faked external demand. Details in NANO nanopayments — Circle Gateway.
Why it matters — RFB 02 (Monetize an API / agent)
Most "agent economy" demos show an agent paying for things. Cronus is the other half of the economy: an agent that gets paid per call, covers its own costs, and earns a positive margin on every paid call — fully on-chain and auditable.
Cronus charges for its work, pays its own costs, stakes USDC on its own verdicts and burns that stake when it is wrong — every step settled on-chain, with the money primitives it runs on published as a standalone MIT package. It is an engine for the agent economy on Arc.
Verify in 2 minutes (judges)
Every headline claim maps to a live endpoint or an on-chain transaction. Nothing here is mocked.
All /api/* endpoints return HTTP 200 (or 402 for the paywall) — never 500.
Independently verifiable — not "trust me"
Every number on this page is reproducible by a judge with zero private keys. We publish a machine-readable scorecard that, for each claim, returns how to verify it — a command or an on-chain link — never a self-graded "passed":
- Scorecard: https://cronus-capital.vercel.app/api/scorecard — 4 Sourcify exact-match contracts, live on-chain counts, honest
external_payers: 0, and the exact reproduce step for each claim. - No-key end-to-end:
npm run verify-live(191 checks) andnpm run verify-intent(EIP-712 round-trip) reproduce the entire honesty surface against the live deployment without any secret. - Source, not bytecode: every contract links to verified source — four as Sourcify exact-match, the other six verified on the Arc explorer (Blockscout). The verified count is read from the explorer on every request; see "Contract verification: 10 of 10" below.
We would rather show a verifiable 0 external payers than an impressive number you cannot independently check.
Contract verification: 10 of 10 on the explorer
All ten deployed contracts now read verified on the Arc explorer, checked live on every request via /api/scorecard and rendered on the Proof / Verify tab. Four carry Sourcify exact-match source; the other six verify directly on the explorer (Blockscout).
The last two to land — Agent guard v2 (0xeA4788164c63B0EF2788d9c74859B43f42BC391E) and Multisig owner (0xde8874C53D82a38c1c2864ea575f9E62Dc29dA5F) — lagged behind the other eight for a while, and we kept them listed as unverified with a stated reason rather than dropping them from the count. Why they lagged, stated plainly:
- These two are the only contracts built with Foundry on solc 0.8.36; the other eight were compiled with npm
solc(0.8.35) or verified via Sourcify. - Our standard verifier submitted a standard-JSON input without an explicit
evmVersionand with a bare source key (CronusAgentGuardV2.sol), while Foundry actually compiled withevmVersion: shanghaiand the fully-qualified keycontracts/CronusAgentGuardV2.sol. The recompiled metadata never matched the on-chain bytecode, so the explorer accepted the request (verification started) but silently failed the match. - Fix — no redeploy, no transaction: resubmit the standard-JSON input with the exact Foundry settings read straight from
forge-out/<name>.sol/<name>.json— compilerv0.8.36+commit.8a079791,evmVersion: shanghai,bytecodeHash: ipfs, optimizer enabled/200, and thecontracts/…source key. Both matched on the first try. Reproducible withnode scripts/verify-exact.mjs.
We list a contract as unverified with its reason instead of hiding it, so the 10-of-10 you see is earned, not curated.
Verify the Gateway integration in 2 minutes
The NANO tier is a real Circle Gateway integration (@circle-fin/x402-batching), not an on-chain-tx checker. Verify the actual gas-free flow:
- Gateway Wallet deposit (one-time, on-chain). Buyer deposits USDC into the Gateway Wallet contract
0x0077777d7EBA4688BDeF3E311b846F25870A19B9.
Deposit tx: https://testnet.arcscan.app/tx/0xb817a39ce9a7b5e108831a356027c1e4ac24dabeafcc09ea1766cd8cef02fa7c - 402 + gas-free EIP-3009 authorization (off-chain, zero gas).
GET /api/nano-signalreturns402; the buyer-agent signs an EIP-3009 authorization and retries — no gas, no on-chain tx per call.
Reproduce:node scripts/buyer-agent.mjs --deposit 1 && node scripts/buyer-agent.mjs - Verified & served immediately. The seller middleware (
createGatewayMiddleware) verifies the signature and returns the signal in the same response — it never waits for settlement. Response showspayment.verification: "eip3009-signature"andserved: "immediate". - Batched settlement id. Gateway settles net positions in batches and returns a settlement id (e.g.
2b381aa2-bb63-4f9c-b76a-663748c9f332). - Three billing models, one rail: per-call
GET /api/nano-signal($0.001) · per-second stream ($0.00001/sec) · per-datasetGET /api/nano-signal?tier=dataset($0.05).
Arc testnet deviation (honest)
Per the sell-side quickstart, the EIP-3009 validBefore must be at least 7 days out. On Arc testnet, Circle Gateway returns UUID settlement ids and settles batches 1:1 (one authorization per settlement at current volume); these batched settlements are not individually queryable on arcscan like a normal transaction. We surface the real Gateway settlement id and label it honestly rather than fabricating an on-chain batch-tx link. The PREMIUM $0.02 tier (/api/signal) remains a standard on-chain x402 payment with a real arcscan tx.
Settlement resolver (closes the mapping gap honestly). GET /api/settlements resolves payments to settlements across both rails without inventing anything: the x402-exact rail lists direct USDC payer->treasury settlements 1:1 with real on-chain tx hashes and arcscan links, while the circle-gateway-batched rail reports the real on-chain footprint of the Gateway Wallet (settle + burn) and explicitly labels that a single nano-payment UUID does not map 1:1 to one on-chain tx (Gateway nets and settles in batches). Anything that cannot be mapped is returned as null/labeled — never a fabricated hash; per-transfer facilitator status is available when Circle API credentials are configured. Advertised in /api/manifest discovery and checked by npm run verify-live (section [7]).
Traction (honest): paywall proven with self-generated volume
Cronus's premium signals are paid on-chain. To prove the paywall settles real USDC end-to-end, we drove the live deployment from 44 distinct self-test wallets (all ours, across dev sessions) — not faked, but self-generated; no external customer has paid yet.
Snapshot (2026-07-25), straight from the live /api/traction endpoint:
- 49 distinct self-test wallets (all ours, used across dev sessions)
- 193 settled on-chain x402 payments (all self-generated test traffic)
- 3.86 USDC total self-generated test volume
- 0 verified external (non-self) payers so far
- on a testnet these are wallets we controlled to exercise the paywall, so we do not present them as external demand; the honest external-payer count is 0 until a real third party pays.
Verify it yourself (always-current):
curl -s https://cronus-capital.vercel.app/api/leaderboard | jq '{external_payers, self_generated_wallets, self_generated_txs, self_generated_usdc}'
curl -s https://cronus-capital.vercel.app/api/traction | jq '.self_generated'
node scripts/audit-funders.mjs # re-checks every payer's first USDC funding source
The canonical metric is external_payers, which is 0 today (top-level in both /api/traction and /api/leaderboard): no verified third party has paid yet. The self_generated_* fields report our own on-chain test volume, labeled honestly and never counted as external. The nano-tier unique_external_payers reflects only the separate nano KV ledger and stays 0 until a nano-tier external payer appears, so it is not the headline number. Autonomous A2A demo volume is labeled self_demo_calls and never counted as external.
Live on-chain activity — counter map (self-generated · Arc testnet · treasury
0xdc6778c5f8cc74b10aed11c48306d4cfc5737fbd). Every figure below is real and independently on-chain-verifiable — scan the treasury on arcscan. External payers stay 0 on purpose: this is testnet self-demo, and we never count our own volume as external demand.
| Counter | Value | What it actually measures | Source |
|---|---|---|---|
| External payers | 0 | Verified independent third-party payers (none yet, by design) | /api/traction |
| Self-generated wallets | 49 | Distinct wallets we used to drive the live paywall | /api/traction |
| Self-generated txs | 193 | On-chain x402 txs from those wallets | /api/traction |
| Self-generated USDC | 3.86 | USDC moved by that self-generated traffic | /api/traction |
| On-chain payments (explorer scan) | 140 | All USDC transfers that hit the treasury | /api/metrics |
| USDC settled (explorer scan) | 2.80 | Total USDC settled to the treasury | /api/metrics |
| NANO A2A calls | 20 | Autonomous gas-free $0.001 nano calls (self-demo) | /api/traction |
| Gateway-batched transfers | 273 | Real Circle Gateway settlement transfers/burns on-chain | /api/settlements |
| Direct on-chain x402 anchors | 8 | Individually openable 0.02 USDC settlement txs | /api/settlements |
| Cost-of-goods (COGS) | 0.02 | Self-operated demo data spend — never counted as revenue | /api/pay-to-think |
How to read these numbers — they come from different live counters and measure different things (this is transparency, not a contradiction):
- Explorer scan (140 / 2.80 USDC) counts every USDC transfer that reached the treasury address.
- App-tracked paid calls (the Overview KPI cards below) count signal calls served through our own x402 paywall — a narrower operational counter than the raw explorer scan.
- Direct on-chain anchors (3) are individual x402 settlement txs you can open one-by-one on arcscan.
- Gateway-batched (132) reflects that Circle Gateway nets nano-payments and settles them in batches, so one nano call does not map 1:1 to one on-chain tx.

Overview KPI cards from the live dashboard — app-tracked counters (paid calls, revenue, settled, net flow, data ROI, confidence). This is a self-demo operational view, distinct from the raw explorer scan above; all volume is self-generated and external payers = 0.
Verified external demand (how external_payers is earned, not claimed)
external_payers is deliberately hard to inflate. A payer is counted only if it is both (a) explicitly allow-listed in VERIFIED_EXTERNAL_PAYERS and (b) not one of our own wallets (selfAddresses()), with its on-chain payment visible in /api/receipts. The allowlist is empty by default, so the honest count stays 0 until a real third party pays and is independently verified.
Why an explicit allowlist instead of "any wallet that isn't ours"? On a testnet, throwaway wallets can be faucet-funded to look independent, so "not-self" alone is not proof of external demand. A wallet is verified as independently funded (via scripts/audit-funders.mjs against /api/receipts) before it is added — no address is ever auto-promoted to "external".
Self-serve on-ramp for a real external agent/wallet:
- One click: the landing page mounts a Pay Cronus button — connect wallet, one real 0.02 USDC on-chain transfer, and you appear in the public settled-payments feed.
- One command:
CRONUS_URL=https://cronus-capital.vercel.app EXTERNAL_PRIVATE_KEY=0x... node scripts/pay-cronus.mjs(use a wallet you funded;DRY_RUN=1shows the live 402 without paying). - Machine discovery:
/api/manifestcarriesexternalPayerHint, so any agent can find the 402 flow + CLI on its own.
Once a payment lands and independence is verified, the address is added to VERIFIED_EXTERNAL_PAYERS and surfaces at the top of /api/traction (external_payers, external_usdc, external_leaders[] with arcscan tx links) and on the landing page. Self-generated test traffic is always labeled self_generated_* and never counted.
Rhea — autonomous buyer with m2m price negotiation

Machine-to-machine price discovery, live: Cronus (seller) publishes a free personalized quote endpoint; Rhea (buyer agent) pays only when the price clears her policy. No human in the loop — she runs twice a day from GitHub Actions (.github/workflows/rhea-buyer.yml).
How a trade happens:
- Quote —
GET /api/nano-signal?quote=1&payer=0x...returns the price grid and a personalized offer (free, no payment required) - Negotiate — Rhea checks the offer against her reserve price (
RHEA_RESERVE_PRICE) and daily budget (RHEA_DAILY_BUDGET) - Decide —
BUY(gas-free via Circle Gateway) /WALK_AWAY(offer above reserve) /DEFER(daily budget exhausted) - Score — delivery quality is recorded (delivered / verdict / conviction)
- Publish — every decision is committed to a public git ledger:
m2m-ledger/
Loyalty pricing (seller side): first 10 purchases at $0.001, from the 11th the personalized quote drops to $0.0007 — the discount is earned by on-record purchase history, not promised in words.
Verify in 1 minute:
curl "https://cronus-capital.vercel.app/api/nano-signal?quote=1"
...then browse m2m-ledger/ in this repo and the Rhea / M2M section on the live dashboard.
HONEST LABEL: Rhea is our own buyer agent — an A2A demo between two project wallets, disclosed everywhere. The quote payer was self-declared at launch; since July 24 the loyal tier is bound to on-chain identity — see the ERC-8004 identity gate below.
ERC-8004 identity gate (July 24)
Loyal pricing is bound to on-chain identity, not just purchase history. The quote endpoint calls isRegistered(payer) on the CronusIdentityRegistry (0x252cAA46b9b0648908000f6C87e0a561DB4dEb6c); unregistered addresses are offered list price ($0.001) no matter how many purchases they have on record.
Rhea registered her own identity on-chain — tx 0x2efa5292a357e00ac32461486a831c1401b6966310d0b9187299636c1a2f7cdb: the record is owned by her wallet, and the metadataURI points to her public trade ledger (m2m-ledger/). One-off registration script: scripts/register-rhea.mjs.
Verify with zero keys:
curl "https://cronus-capital.vercel.app/api/nano-signal?quote=1&payer=0xbe3a16bD4137A8a293aCBcaA75cCE3420919D21d" # registered agent -> identity.registered=true, offered $0.0007
curl "https://cronus-capital.vercel.app/api/nano-signal?quote=1&payer=0xdc6778c5f8cc74b10aed11c48306d4cfc5737fbd" # unregistered -> identity.registered=false, offered $0.001
The m2m economy stack (July 25)
Fifteen interlocking mechanisms turn two agents into a working micro-economy: prices are negotiated, credit is extended, stakes are slashed - and the only judge is the market. Everything below is verifiable with zero keys.
| # | Mechanism | What it does |
|---|---|---|
| 1 | Reputation loop | after every settled trade Rhea rates the seller on-chain (ERC-8004 giveFeedback) |
| 2 | Ledger anchors | daily ledger files are keccak-anchored on Arc testnet |
| 3 | Buyer trust gate | Rhea refuses to buy from a seller rated below 4/5 on-chain |
| 4 | Signed delivery receipts | an EIP-191 receipt pins the report hash at delivery time, before the outcome is known |
| 5 | Conviction-pegged pricing | the loyal price floats with live oracle confidence, hard-clamped to a band |
| 6 | Market-graded track record | real price moves grade every directional signal 24h later; no self-review |
| 7 | Deterministic haggling | a loyal buyer can talk the price exactly one band down; no LLM in the loop |
| 8 | Bandit budget allocation | epsilon-greedy topic selection rewarded by the market-graded record |
| 9 | Trade credit | loyal registered buyers take a signal on credit and repay on a later run |
| 10 | Conviction stake | every market-graded MISS entitles the buyer to a free make-good unit |
| 11 | Brier calibration gate | the premium band must be earned: average Brier within 0.35 over graded signals |
| 12 | Hash-chained ledger | every entry pins the sha256 of the previous one; CI publicly re-verifies the chain each run |
| 13 | Policy envelope | the buyer spending mandate is public; its sha256 is pinned in every ledger entry |
| 14 | Signed agent card | an EIP-191 signed machine-readable storefront lets stranger agents discover prices, rules and proofs |
| 15 | Prepaid sessions | one x402 payment opens a bundle of metered units - a payment channel without the channel contract |
Verify in one minute:
# live quote: reputation, track record, credit, stake and calibration in one response
curl -s "https://cronus-capital.vercel.app/api/nano-signal?quote=1&payer=0xbe3a16bD4137A8a293aCBcaA75cCE3420919D21d"
# audit the hash-chained ledger, zero keys required
git clone https://github.com/Artem1981777/CronusCapital && cd CronusCapital && node scripts/verify-chain.mjs
# discover the storefront as a machine: the EIP-191 signed agent card
curl -s "https://cronus-capital.vercel.app/api/agent-card"
# honest live traction: external vs self-generated, external_payers is the only headline
curl -s "https://cronus-capital.vercel.app/api/traction"
# read the buyer public spending mandate (its sha256 is pinned in every ledger entry)
cat m2m-ledger/policy.json
HONEST LABEL. Rhea and Cronus are two wallets of the same project: an agent-to-agent demo, clearly disclosed. The mechanisms are real; the counterparty is not a stranger.
Pay Cronus in 60 seconds (any funded wallet)
No terminal? One click: open the live dashboard, connect your wallet, and press "Connect wallet & pay 0.02 USDC on Arc" — one real on-chain transaction, and you appear in the public settled-payments feed. Need test USDC: https://faucet.circle.com (select Arc Testnet).
Two real, on-chain ways for an external agent/wallet to pay Cronus:
NANO — $0.001, gas-free via Circle Gateway (counts toward the external-payer leaderboard):
export BUYER_PRIVATE_KEY=0x... # any wallet with a little Arc testnet USDC
node scripts/buyer-agent.mjs --deposit 1 # one-time Gateway deposit
node scripts/buyer-agent.mjs # pay $0.001 gas-free + consume signal
node scripts/buyer-agent.mjs --stream --seconds 10 # pay-per-second nano stream
A wallet not in SELF_DEMO_ADDRESSES shows up as a real unique_external_payer:
- Leaderboard: https://cronus-capital.vercel.app/api/leaderboard
- Traction: https://cronus-capital.vercel.app/api/traction
PREMIUM — $0.02, on-chain x402:
export BUYER_PRIVATE_KEY=0x... # any funded wallet (not the treasury)
node scripts/pay-and-consult.mjs "BTC-USDC momentum"
Pays USDC from your wallet to the treasury and claims the signal with on-chain proof; verify the tx on arcscan.
Honesty: self-funded demo traffic is always labeled
self_demo_callsand excluded fromunique_external_payers. We never fake external demand.
The money loop (all real on-chain)
| Step | Action | On-chain |
|---|---|---|
| Earn | Client presses UNLOCK SIGNAL · $0.02 (x402) | real USDC transfer to agent contract 0xd81a420…880f |
| Pay | Agent buys upstream data — PAY UPSTREAM · $0.005 | real USDC transfer out |
| Net | Net Flow = revenue − spend, shown live (green when > 0) | derived from booked tx |
| Settle | Decision written to the Verifiable Ledger (keccak hash-chain) | per-action label, Verified badge + tx link |
Demo frame: UNLOCK +$0.02 → PAY UPSTREAM −$0.005 → Net Flow +$0.015, both with a "view tx" link on arcscan.
UI: theme modes & live oracle terminal
The dashboard ships with a 3-mode theme switch (top-right pill) and a live agent log — all additive, zero changes to existing components (self-contained modules: src/theme-toggle.ts, src/matrix-bg.ts, src/oracle-terminal.ts).
- ◉ ORIGINAL — the original cyber-Egyptian look with the temple background.
- ● BLACK — eye-friendly pure-black mode, no animation.
- ▦ MATRIX — pure black + live Matrix digital rain (canvas in the background layer; DPR-capped, pauses when the tab is hidden). A dark veil plus near-opaque cards keep every panel readable above the rain. Default for new visitors; a returning visitor keeps their saved choice (
localStorage). - Live oracle terminal — the hero card streams a typewriter log of the agent loop (SCOUT / ANALYST / EXECUTOR / x402 / COVER / LEDGER), typing top-down;
pointer-events: none, so it never blocks clicks.
Dashboard guide (what you are looking at)
The live demo (https://cronus-capital.vercel.app) is a single screen. Here is every panel, top to bottom.
Header
- Title - CRONUS ORACLE DASHBOARD. The agent's control room.
- Wallet chip (top-right, e.g.
0xDC...7FBD). The connected wallet / agent treasury address. Click to connect or switch wallets. - Traction badge (
N x402 payments . X USDC settled on Arc . last tx). Live count of real on-chain x402 payments, read from/api/metrics; "last tx" links to the latest settlement on the Arc explorer. - Version badge (
v0.7.2 . MEMO + BATCHED PAYMENTS). Marks Arc transaction-memo support.
Metric cards (top row) - all derived from real on-chain activity
- USDC SETTLED - total USDC moved through the agent's verified settlements.
- REVENUE (X402) - income earned from paid signal calls.
- PAID CALLS - number of x402 paid calls served.
- AGENT SPEND - what the agent paid upstream for data.
- NET FLOW - revenue minus spend (green when positive); the agent's live margin.
Metric cards (second row)
- DATA ROI - USDC earned per 1 USDC of data spend (e.g. 1.6x); proves the loop is net-positive.
- CONFIDENCE SCORE - the agent's calibrated confidence (0-100) over its active signals.
Agent pipeline (left) - the three oracles, with live status
- SCOUT - Signal Discovery. Pulls live market data.
- ANALYST - Risk & Conviction. Scores expected value and conviction.
- EXECUTOR - On-chain Settlement. Signs and settles the USDC transaction.
Market Intelligence (center) - a live radar of the signals the Scout is tracking.
Oracle Actions (right) - the buttons you press
- CONSULT ORACLES (free). Runs the real LLM reasoning trace over live OKX data and prints the decision log plus a consensus verdict. No payment - start here to see how the agent thinks.
- FORCE EXECUTE. Manually triggers an on-chain settlement of the current decision (demo control).
- BUY SIGNAL - 0.02 USDC (real x402). The headline action: pays 0.02 USDC on-chain through Arc's Memo contract, verifies the payment server-side, then unlocks a verifiable signal - showing the verdict, conviction, a keccak
commitment, the live agent decision log (trace), and a link to the payment tx. This is real money moving. - UNLOCK SIGNAL (demo) - 0.02 USDC (x402). The same flow on a no-cost demo path for quick walkthroughs.
- PAY UPSTREAM - 0.005 USDC (agent buys data). The agent spends its own USDC on upstream data - the cost side of the loop.
- DEPOSIT / WITHDRAW (bottom). Move USDC in and out of the ERC-4626-style vault; your position and Vault TVL are shown below.
- Every paid action prints a VIEW TX link to the Arc explorer.
Proof Seals — how it works
The Proof section includes a gamified "Proof Seals" grid: a row of sealed tomb-boxes, each representing one milestone Cronus has genuinely achieved on-chain. Tap a seal to unseal it and reveal the underlying proof with a direct explorer / verify link.
The six seals
| Seal | What it proves | Source | Verify |
|---|---|---|---|
| ◈ Skin in the game | The agent staked real USDC behind its own verdict, committed on-chain before the outcome was known | /api/track-record |
stake tx on Arc explorer |
| 𓂀 Verdict resolved | A pre-committed call was resolved verifiably — correct returns the stake, wrong slashes it to a burn address | /api/track-record |
resolution tx |
| ⬡ Pays upstream | The agent autonomously paid a data provider in real USDC as cost-of-goods (COGS) | /api/scorecard |
COGS tx |
| ◆ Source-verified | Contracts have exact-match verified source on Sourcify — no trust-me bytecode | /api/scorecard |
Sourcify source |
| ◎ x402 settlements | x402 payments settled on-chain (self-generated test traffic, always labeled as such) | /api/metrics |
last settlement tx |
| ▲ Honest by default | External payers are published openly and stay at 0 until a real third party pays | /api/scorecard + /api/traction |
traction endpoint |
Design rule (why there are no prizes)
Proof Seals deliberately give no random prizes and no rewards for user activity. Rewarding actions — especially payments — would manufacture traction, the exact thing this project refuses to do. Every seal is read-only, fail-open, and derived from live endpoints; the reward is the proof itself. A seal only unseals when its milestone is genuinely met, otherwise it stays locked (◇).
How to use it (step-by-step for judges)
- Open the demo - https://cronus-capital.vercel.app
- Connect your wallet (top-right chip) and approve switching to Arc Testnet (chainId 5042002). Grab test USDC from the Circle faucet if needed.
- Press CONSULT ORACLES (free). Watch the agent pull live BTC data and reason step by step (SCOUT -> DECOMPOSE -> DISCOVER -> DECIDE -> SUFFICIENCY -> EXECUTOR -> MEMORY -> CONSENSUS). It may return SKIP - it abstains when expected value is below its bar, by design.
- Press BUY SIGNAL - 0.02 USDC (real x402). Confirm the transaction in your wallet. The agent verifies the on-chain payment, then unlocks the signal with its verdict, conviction,
commitment, and live agent decision log. Click VIEW TX to see the real settlement (with aMemoevent) on the Arc explorer. - Press PAY UPSTREAM - 0.005 USDC to see the cost side: the agent spends on data. Watch NET FLOW stay positive.
- Verify everything yourself:
- Public receipts: https://cronus-capital.vercel.app/api/receipts (add
?format=csvto export) - Live metrics: https://cronus-capital.vercel.app/api/metrics
- Machine discovery: https://cronus-capital.vercel.app/api/manifest and
/api/openapi - Pay from outside the browser:
scripts/pay-and-consult.mjsorscripts/pay-with-memo.mjs
- Public receipts: https://cronus-capital.vercel.app/api/receipts (add
- (Optional) Deposit into the vault to see ERC-4626 share accounting, then withdraw.
The whole loop in one screen: reason -> earn (x402) -> spend (upstream) -> settle -> report, all real on Arc and all verifiable in a browser tab.
Judge walkthrough — the Overview screen, button by button
The Overview tab is the control panel for the whole agent business. It is taller than one screen, so both halves are shown below with every control explained. Anything marked real is a genuine on-chain transaction on Arc Testnet (chainId 5042002), independently verifiable in the block explorer. Read-only buttons need no wallet — you can just watch.
Part 1 — agent actions & vault

Before you start (optional): connect a wallet via the top-right chip and switch to Arc Testnet. Need test USDC? Get it free at faucet.circle.com (select Arc Testnet).
CONSULT ORACLES — free, no wallet. Runs the full reasoning pipeline (SCOUT → DECOMPOSE → DISCOVER → DECIDE → SUFFICIENCY → EXECUTOR → MEMORY → CONSENSUS) on live BTC data. Look at: the agent decision log streaming in. It often returns SKIP — the agent abstains when expected value is below its bar. That is honesty by design, not a failure.
FORCE EXECUTE — free. Forces a full verdict even when the agent would normally SKIP, so you can see a decision on demand. Look at: the verdict and conviction score.
PREMIUM SIGNAL — $0.02 (on-chain x402) — real payment. The live paywall. Approve the 0.02 USDC transfer; the server verifies the on-chain payment (HTTP 402 → pay → 200) and unlocks the signal with verdict, conviction and a commitment hash. Look at: the VIEW TX link (real settlement with a Memo event on the Arc explorer) and the Payments (x402) counter ticking up. Each verified payment accrues into the agent's on-chain revenue pool (payout
available), which later funds real payouts — not synthetic yield.PREMIUM (DEMO) — $0.02 (x402) — demo, clearly labeled. The same unlock flow without a live transfer, for judges who prefer not to fund a wallet. Honest: this does not settle on-chain and is never counted in traction numbers.
PAY UPSTREAM — $0.005 (agent buys data) — real payment. The cost side of the business: the agent itself pays a data provider on-chain. Look at: NET FLOW staying positive (0.02 in vs 0.005 out) — the unit economics are real, not modeled.
DEPOSIT / WITHDRAW — real, vault. Enter an amount (e.g. 0.1) and deposit into the ERC-4626-style vault. Look at: "Your position" and "Vault TVL" updating with real share accounting; withdraw to reverse it. Note: a deposit is vault principal (TVL) and is deliberately kept separate from the agent's payout available balance (accrued fees). That is why RUN AGENT STRATEGY can still return HOLD right after a deposit — the agent never pays out depositors' principal.
RUN AGENT STRATEGY — free. Triggers one full autonomous pass (reason → act) so you can watch the agent operate on its own: it runs the live reasoning pipeline (SCOUT → DECOMPOSE → DISCOVER → DECIDE → SUFFICIENCY → EXECUTOR → MEMORY → CONSENSUS) on live BTC data, then runs its guardrail-checked treasury executor. Look at: the decision log streaming in, ending with either ACT: PAYOUT (a real CCTP burn to Stellar, with a VIEW TX link) or ACT: HOLD — the agent withholds funds when the guardrail policy (conviction/threshold/daily cap) isn't cleared. A HOLD is honesty by design, not a failure. Any PAYOUT is funded by real accrued x402 revenue (each 0.02 USDC signal sale), never synthetic yield.
RISK ADJUST — free. Cycles the risk regime; watch the risk gauges and position sizing respond.
VIEW ON ARC ↗ — opens the agent/treasury address on the Arc explorer so you can audit every transfer yourself.
+ DEPLOY NEW AGENT — shows the multi-agent surface for deploying another agent instance.
Part 2 — pay Cronus & nano-streaming

Everything here settles through @circle-fin/x402-batching: gas-free EIP-3009 authorizations, verified and served immediately, settled in Circle Gateway batches.
- PAY 0.02 USDC ON ARC (Support Cronus) — real, and the one that matters most for judging. Connect any funded wallet and make one real 0.02 USDC transfer. You will appear in the public settled-payments feed — and because our honest external_payers count is currently 0, a judge who pays here becomes the first verified external payer. Look at: /api/receipts and the Traction tab right after.
- START STREAM (Stream signals) — real per-second micropayments. Set a budget (e.g. 0.05 USDC) and stream at 0.00001 USDC/sec via Circle Gateway until the budget runs out. Look at: the SECONDS / SPENT / SIGNALS counters incrementing live. Honest note: the real per-second on-chain micropayments are executed by the autonomous buyer-agent (--stream); the on-screen burn animation is projected at the same rate.
Verify all of it independently (no wallet, ~2 min):
- Public receipts — https://cronus-capital.vercel.app/api/receipts (append ?format=csv to export)
- Live metrics — https://cronus-capital.vercel.app/api/metrics
- Honest traction — https://cronus-capital.vercel.app/api/traction (external_payers, self_generated_*)
- One-command replay — npm run verify-live (191 checks)
How it works — 3 oracles
- Scout — scans prediction markets, gathers signals.
- Analyst — scores EV / conviction, calibrates against track record (Brier score).
- Executor — settles on-chain (USDC transfer) with a pre-flight eth_call simulation and a keccak jobHash.
Live reasoning trace (real LLM on real data)
Pressing CONSULT ORACLES calls the agent's own serverless endpoint /api/consult, which (1) pulls real live market data from the OKX public ticker (last price, 24h change %, 24h high/low, 24h volume) and (2) asks a real LLM (Groq, GPT-OSS 120B) to reason over those numbers and return a structured decision plus a historical-analog recall. The output streams into the dashboard line by line - there is no setTimeout script (open DevTools, Network tab, /api/consult to verify). Every figure in the trace is a fact we fed in or derived from it; the model is barred from inventing indicators (no RSI/EMA/SMA, no fabricated volume). A real run:
SCOUT: 0.31% 24h change, price 63070.6
DECOMPOSE: 24h range 62275.1-63359.9, current price 76.5% from low
DISCOVER: distance to high 289.3, distance to low 795.5
DECIDE: +0.31% 24h clears +0.20% trigger -> long bias, EV 0.58 vs 0.50 hurdle
SUFFICIENCY: 24h volume 37.27, sufficient liquidity
EXECUTOR: long entry 63070.6, stop 62275.1, target 63359.9
MEMORY: nearest regime Bull -> continued upward (similarity 0.70)
CONSENSUS: SKIP - conviction 58% (below 65 bar)
Note the verdict: SKIP at 58% conviction. Cronus abstains when its own confidence bar is not met - it is not a YES-machine. That discipline, plus the MEMORY analog stage, is what a typical pay-per-query data vendor lacks: Cronus does not just sell a report - it reasons, decides, abstains, and runs the full on-chain economic loop.
On-chain vault (ERC-4626-style)
A real vault on Arc Testnet: the user signs deposit/withdraw; yield (addYield) accrues into the share price (convertToAssets) — no faucet drip into balances.
- Vault: 0x13B6984357e27dAB17DF44a6396042239e70542C
- deposit / withdrawAll / addYield — all transactions visible on the address page.
Verifiable & safe
- Verifiable Ledger — keccak256 hash-chain of decisions; each action is labeled correctly (x402 revenue / upstream spend / settlement / vault), with a Verified status.
- Reasoning Trace — content-commitment of the reasoning chain (keccak256), REPRODUCIBLE badge.
- Track Record — forecast history with hit-rate and Brier score.
- SecOps — per-tx cap 0.01, daily cap 5.0, recipient allowlist, pre-flight eth_call abort-on-revert.
Standards & composability
| Standard | Role | Status |
|---|---|---|
| x402 | Pay-per-call (~$0.02 / consult) | LIVE |
| CCTP | Native USDC, domain 7 | LIVE |
| ERC-4626 | On-chain vault, share accounting | LIVE |
| ERC-8004 | Identity Registry LIVE on Arc (0x252cAA46b9b0648908000f6C87e0a561DB4dEb6c, agentId #1); resolveByAddress reputation gate |
✅ LIVE |
| ERC-8183 | Job escrow (fund→submit→release/refund) LIVE on Arc (0x64e55De4CbC3CDf981B2c970807129FA61806873), gated by ERC-8004 identity |
✅ LIVE |
| ERC-8004 reputation | CronusReputation LIVE on Arc (0x2A19ad056EaE83364B0a6420685974cA219c209E); buyer-agent calls giveFeedback(agentId, score, jobRef) after each job; getReputation returns count + average |
✅ LIVE |
Why Cronus is different
Most projects in this space ship infrastructure - a wallet, a policy engine, a lending pool, a prediction-market venue. Each is one piece of an agent economy. Cronus ships the thing that proves the infrastructure is worth building: a complete, honest, self-sustaining business that already earns, spends, abstains, and settles on-chain - without ever holding your key.
- It runs the whole loop, not one primitive. Earn via x402 -> spend on upstream data -> report net P&L -> compound into the vault. Most agents do one of these; Cronus does all of them, end to end.
- Spend is non-custodial by construction. Every spend settlement (the x402 buy path) is signed in your own wallet - the agent holds no key on the spend side. The autonomous payout path is the one bounded exception: a server-side treasury hot-wallet signs CCTP burns with minimal float, capped at 5 USDC per payout plus a daily circuit breaker (see the threat model). Spend caps, a recipient allowlist, and a pre-flight simulation are enforced on top. A guarantee built on a key the agent never holds is stronger than any policy engine.
- Its reasoning is real and honest. The CONSULT trace is produced live by a real LLM over real OKX market data, and the agent abstains (SKIP) when conviction is below its bar - no scripted animation, no fabricated indicators, no always-YES.
- Everything is verifiable in a browser tab. Live on-chain settlements, a keccak hash-chain ledger of decisions, and the pre-flight simulation are all open to inspection - no trust required.
- Its reasoning is verifiable, not just visible. Each consult runs deterministically (temperature 0 + a fixed seed), so identical inputs reproduce the same trace, and every run is content-addressed by the sha256 of its canonical input+output. Anyone can re-hash a stored trace via
/api/traceand confirm it was not altered after the fact - honesty you can check, not just read.
The thesis: most builders are shipping parts of an agent economy. Cronus is a working agent economy, end to end, that you can audit yourself.
Why Arc, not any other L1
Cronus is not "deployed on a testnet" - it depends on properties only Arc gives an autonomous economic agent:
| Arc property | Why Cronus needs exactly this |
|---|---|
| USDC is the native gas token | The agent earns, spends, and pays fees in one asset - no volatile gas token to hold or top up, and net P&L is denominated in the same dollar it transacts in. |
| Sub-second finality | Earn -> spend -> settle is a tight loop; a consult that resolves and a settlement that confirms in under a second are what make a live, in-browser demo of a full economic cycle possible. |
| Built-in stablecoin / FX engine | Upstream costs and payouts settle in stable value without bridging out, so the agent's books stay clean and auditable. |
| x402-native payments | Pay-per-call monetization (UNLOCK 0.02 / upstream 0.005) is a first-class primitive, not a bolted-on hack - the business model is the protocol itself. |
| Opt-in privacy (built) | A receipt is a Merkle tree of field leaves: the agent proves a payment satisfied the spend policy without revealing the amount, the counterparty, or the tx hash. Live at /api/disclosure, independently checkable at /api/disclosure-verify, 9 unit tests. Selective disclosure, not zero-knowledge. |
Take away USDC-as-gas or native x402 and Cronus stops being a self-contained business. That is the difference between deployed on Arc and only possible on Arc.
Unit economics & treasury solvency
Click to expandCronus is built to be self-sustaining, not subsidized. Each signal it sells through the x402 paywall earns more than the data it buys to produce that signal costs:
- Revenue — 0.02 USDC per paid call (x402, settled on-chain)
- Data cost — 0.005 USDC per upstream fetch (paid on-chain)
- Data ROI — revenue per $1 spent on data, shown live on the dashboard
The dashboard surfaces this in real time: Revenue (x402), Agent Spend, Net Flow, and Data ROI all update from the same on-chain activity. The agent only acts while the loop stays net-positive, capped per transaction and per day by its on-chain guardrails.
Why this is sustainable, not a pyramid. Margin is positive on every external paid call — 0.02 USDC in vs 0.005 USDC upstream cost, a ~4× markup. The treasury never depends on new investors or token buyers: there is no token, and no one is asked to "buy in" to fund payouts. Spend can never exceed revenue-bearing activity because every outflow is bounded by an on-chain per-transaction cap (0.01 USDC), a daily circuit breaker (5.00 USDC/day), and a conviction gate that only releases spend on positive-EV decisions.
Honest scope. Sustained profit requires real external demand for the agent's calls. On Arc testnet these figures are demo/modeled volume — they prove the mechanism is net-positive per call, not that the agent is already a profitable production business. The path to real solvency is more external x402 payers (and ecosystem grants such as the Arc Builders Fund), never raising money from new buyers to backfill the treasury.
Mainnet funding model
Click to expandWho funds the treasury in production, in order of priority:
- Paying customers (primary). Other agents, trading systems, and apps pay per call over x402. At a ~4× gross margin per call (0.02 USDC in vs 0.005 USDC cost), revenue covers inference, data, infra, and gas at volume. The treasury grows from operations, not from new entrants.
- Runway capital (one-time). Ecosystem grants such as the Arc Builders Fund, plus the founder's own USDC, cover gas and data before revenue scales. Gas on Arc is USDC-denominated and sub-cent, so bootstrap cost is small.
- LP vault (optional, capital-efficient). LPs can deposit USDC as working capital and receive a share of the agent's realized on-chain profit — fully transparent and withdrawable. Returns are paid only from real P&L, never from new deposits.
- Indexed analytics (Goldsky subgraph). Index Arc events (x402 payments, stakes/resolutions, vault deposit/withdraw/addYield) into a Goldsky subgraph — an official Arc ecosystem indexer — for faster, more reliable analytics and webhook-driven notifications, replacing today's hand-rolled RPC/explorer polling. Additive; the direct on-chain reads remain the source of truth.
There is no token sale and no "buy-in" to backfill the treasury. Sustained solvency depends on real external demand, which we do not fake; on testnet these volumes are modeled.
Verifiable x402 paywall (anyone can pay Cronus)
Cronus exposes a real, on-chain-verified paywall at GET /api/signal — no demo bypass. Any external agent or wallet can pay and consume:
GET /api/signal?topic=...returns HTTP402 Payment Requiredwith the price (0.02 USDC), asset, andpayToaddress.- The caller pays USDC on Arc, then retries with header
X-PAYMENT: <txHash>. - The server verifies the payment on-chain via JSON-RPC (USDC transfer of the required amount to
payTo, tx success, within a freshness window) and only then returns a signed signal plus a keccak256commitmentof the response.
Proof — a self-test wallet we controlled paid and consumed (Arc testnet):
- Payer (our self-test wallet):
0x46213abeca58cc9a89a269fd25a8737c700ca164 - Payment: 0.02 USDC to
0xdc6778c5f8cc74b10aed11c48306d4cfc5737fbd - On-chain tx: https://testnet.arcscan.app/tx/0xfe2764b2b837365ea7cb896fbbe55119ffbf250e51941945bf013a88bb942086
- Response commitment:
0x993453223b57849b38df20ff050daa54905d53a3ac70c56c8e5460eb6fa77611
This closes the loop honestly: the paywall verifies a real on-chain USDC payment server-side (here from our own self-test wallet) — it is still our own test wallet, not external demand. Reproduce with scripts/pay-and-consult.mjs (set BUYER_PRIVATE_KEY to any funded wallet).
Replay protection: payments are accepted only within a freshness window (
SIGNAL_MAX_AGE_SECONDS, default 1800s). Strict one-time-use can be added with a KV store.
Two ways to consume the paywall:
- From any wallet or agent (CLI): run
scripts/pay-and-consult.mjswith a fundedBUYER_PRIVATE_KEY. Exercised with our own self-test wallet (tx above). - From the dashboard (one click): the BUY SIGNAL button runs the full x402 flow in-browser - request
402, pay 0.02 USDC on Arc, verify on-chain, then render the verdict, the keccakcommitment, and a link to the payment tx. No setup, no demo bypass.
Agent discovery (machine-readable): point any AI agent at the manifest or OpenAPI spec to auto-discover price, network, payTo, and the pay-then-retry flow:
- Service manifest:
GET /api/manifest - OpenAPI 3.0 / swagger.json:
GET /api/openapi - Every
402response also embeds adiscoveryblock linking both.
Arc-native reconciliation (transaction memos): payments can be sent through Arc's Memo contract (0x5294E9927c3306DcBaDb03fe70b92e01cCede505), which wraps the USDC transfer and emits an indexed Memo event while preserving the payer as msg.sender. This attaches a reconcilable reference (for example cronus|signal|<topic>|<ts>) to each payment on-chain - matching Arc's invoice/payout reconciliation use case - with zero change to our paywall, since the wrapped transfer still emits the USDC Transfer our verifier checks. Try it: scripts/pay-with-memo.mjs "<topic>".
Proof: tx
0xa7a0e3b25394d2c0570be62605f0a379b1a0e5d1ba2e7607f719fbd1ca9943d5carried memoId0x30c32e7e09b43cee3059b3d8136b591fda8c61d7840cff45911c60ee04e19d46and unlocked a verified signal (commitment0xc9acbd88b845a248e3ee669cca257f2e64f8c1daf17f64063d7765bfeae60680).
Live traction (real, on-chain, verifiable)
As of the latest build, the Cronus x402 paywall has settled 140 real USDC payments (~2.80 USDC) on Arc testnet - every one a genuine on-chain transfer, verifiable in the explorer. The counter is read live from the Arc block explorer via /api/metrics, value-filtered to the exact 0.02 USDC signal price, so unrelated transfers (such as vault withdrawals) are never counted and the figure updates itself with each new payment.
Honest scope: this volume was self-generated against the live endpoint to prove the paywall handles real settlement at scale - it is not external customer revenue. Every payment is a real, auditable on-chain settlement; none of it is mocked or hardcoded.
- Live metrics: https://cronus-capital.vercel.app/api/metrics
- Public receipts: https://cronus-capital.vercel.app/api/receipts (add
?format=csvto export)
NANO nanopayments — Circle Gateway (gas-free, sub-cent)
Popup-free session-key streaming (NANO A2A)
High-frequency agent-to-agent streaming can't ask for a wallet popup on every nano-payment. Cronus solves this with an ephemeral session key: fund once, then stream gas-free with no further prompts.
- Generate — the browser creates a fresh session key via
viem'sgeneratePrivateKey(), kept in memory only (never written to storage, never transmitted). - Fund once — the main wallet approves USDC and calls
GatewayWallet.depositFor(USDC, sessionKeyAddress, budget)a single time, crediting the session key's Circle Gateway balance. This is the only on-chain action and the only wallet popup. - Stream popup-free — a
GatewayClientbuilt from the session key calls.pay('/api/nano-signal?...')about once per second. Each call is a real EIP-3009 gasless authorization settled through Circle Gateway (default 0.001 USDC/s) with a real Gateway settlement id. No wallet prompts after funding. - Bounded by design — the session key holds no gas and nothing withdrawable (only a Gateway spending balance it can authorize), and the client enforces a hard budget, a per-transaction cap, and a session TTL. Stop anytime; unused balance stays in Gateway.
Trust model: neither side ever holds the other's private key. The main wallet never exposes its key to the page, and the session key can only sign spend-authorizations up to the funded budget — it cannot move funds elsewhere. Every tick is a genuine Gateway payment; self-run demo traffic is labeled and never counted as external demand.
Try it on the live demo (FUND & STREAM), or run it headless: node scripts/buyer-agent.mjs --stream --seconds 30.
Cronus also exposes a NANO tier at $0.001/call, settled gas-free via Circle Gateway (EIP-3009 signed authorizations, USDC on Arc). An autonomous buyer-agent (scripts/buyer-agent.mjs) discovers the service from /api/manifest, enforces a budget, pays gas-free, and consumes the signal — a full agent-to-agent (A2A) loop.
- Live nano traction: https://cronus-capital.vercel.app/api/traction
- External-payer leaderboard: https://cronus-capital.vercel.app/api/leaderboard
Honest scope (the project's edge):
- The buyer-agent is self-funded, so its address is registered in
SELF_DEMO_ADDRESSESand counted asself_demo_calls— never asunique_external_payers. The on-chain x402 volume is self-generated test traffic (labeledself_generated_*); the nano-tierunique_external_payersstays0until a nano-tier third party pays. - On Arc testnet, Circle Gateway settles 1:1 (each call gets its own settlement id). N→1 batching is a Circle Gateway protocol capability at scale, shown as such in the UI — not claimed as achieved here.
- Gateway settlement identifiers are labeled
gateway-batchwith on-chain tx pending; arcscan/tx/links render only for real0xon-chain hashes.
Public on-chain receipts
Arc-native receipts - no registry contract needed. Every paid call emits an on-chain Memo event that doubles as a receipt. Browse all settled x402 payments at /api/receipts (JSON) or export /api/receipts?format=csv. Each receipt links txHash, payer, amount, block, commitment and memoId to the Arc explorer.
What's real vs modeled (honesty)
- ✅ Real on-chain: every USDC transfer (x402 earn, upstream spend, vault deposit/withdraw, settlement), the hash-chain ledger, and the pre-flight simulation.
- ✅ Real reasoning: the CONSULT trace is produced live by a real LLM (Groq GPT-OSS 120B) over real OKX market data (price, 24h change, 24h high/low, volume) via /api/consult - not a scripted animation - and the agent abstains (SKIP) when conviction is below its 65% bar.
- 🧠 Historical analog = heuristic: the MEMORY stage is the LLM's qualitative recall of a similar past regime with a similarity score - an estimate, not a backtested dataset.
- 🔐 Non-custodial by design: unlike autonomous agents that keep a hot private key on the server to self-sign, Cronus reasons autonomously but every settlement is signed in the user wallet - no agent key sits on the server, ever.
- ⚠️ Modeled on testnet: yield magnitudes and EV figures are illustrative — the mechanics, shares, and transactions themselves are real.
- ℹ️ x402 here is a real USDC transfer to the agent (pay-per-call) — a real HTTP 402 challenge:
/api/signalreturns 402 with payment requirements, the client pays USDC on-chain (pay-per-call), and the server verifies the on-chain tx before serving. Settlement is direct on Arc rather than via a separate third-party facilitator service.
Changelog / build log
The full dated build log (every commit, newest first) now lives in CHANGELOG.md to keep this README scannable.
Run locally
npm install
npm run dev
Connect a wallet on Arc Testnet (chainId 5042002), grab test USDC from the Circle faucet, then try CONSULT → UNLOCK → PAY UPSTREAM → FORCE EXECUTE.
No-key live verification (judges). Reproduce every honesty claim end-to-end against the live deployment:
npm run verify-live # zero private keys: paywall, manifest, receipts/metrics, honesty invariants, on-chain confirmation, settlement resolver [7], spend-intent rejection [8]
npm run verify-intent # EIP-712 spend-intent round-trip (ephemeral, unfunded key): valid -> replay rejected -> tamper rejected
Builder: Artem Gromov · GitHub @Artem1981777 · ETH gromov7.eth
Replay protection (verified live on Arc testnet)
- x402 payment proofs are bound to a 30-minute freshness window — stale proofs return
402 replay window closed. - Accepted proofs are one-time-use (Upstash KV, SET NX + TTL) — replaying a proof returns
402 payment proof already consumed. - Verified end-to-end: fresh paid proof
0x5b1d39b5...2290-> first call200, replay ->402 already consumed. - Spend-intent nonce replay-protection. Off-chain EIP-712 spend-intents (
/api/spend-intent) reuse the same one-time-use guarantee: each(payer, nonce)is burned in Upstash KV (SET NX+ TTL), so a replayed signed intent returnsvalid:false — nonce already used. Proven live bynpm run verify-intent.
Security deep-dive: the payment-replay attack we closed
Click to expandThe threat. In x402, a buyer proves payment by sending a transaction hash. But tx hashes are PUBLIC on the block explorer. With no extra protection, anyone could copy someone else's payment hash and replay it to get paid signals for free, unlimited times. One real payment would unlock infinite free access -- so the "monetization" would be fake.
The fix (two layers).
- Freshness window -- proofs older than 30 min are rejected with
402 replay window closed. - One-time-use -- every accepted proof is burned in Upstash KV (
SET NX+ TTL). Reusing it returns402 payment proof already consumed.
Analogy. A tx hash is a receipt. Before, the same receipt could be shown at the till forever. Now the till voids it on first use.
Proven live on Arc testnet.
- Fresh paid proof
0x5b1d39b5...2290: first call200, identical replay402 already consumed. - Stale proof:
402 replay window closed.
Why it matters here. This track is about REAL API/agent monetization. Replay-able payments mean there is no monetization. Cronus enforces exactly one paid access per proof -- and proves it end-to-end on-chain.
Stellar Integration: canonical USDC across Arc and Stellar (Circle CCTP)
Click to expandCronus moves canonical USDC between Arc (CCTP domain 26) and Stellar (domain 27)
using Circle Cross-Chain Transfer Protocol (CCTP V2) and the official Stellar
CctpForwarder. No wrapped assets and no custodial bridge: the same USDC is burned
on the source chain and minted on the destination chain. The Stellar relayer that
submits the mint pays only XLM fees and never custodies user funds.
Verified end-to-end proof
First transfer (1 USDC, Arc to Stellar):
- Burn on Arc (depositForBurnWithHook): 0x8df2...faf172
- Mint on Stellar (mint_and_forward): b9baf4...805d4
- USDC trustline on the recipient account: 09cc62...96d3
Recipient account (USDC balance grew 0 to 2.0000 across two verified transfers):
GBNJ2J...A2CAZK
The live demo renders a hero banner with both proof links and a Proof-of-Transfer
receipt under the Complete button: Arc burn, Circle attestation (domain 26 to 27),
Stellar mint, and the recipient USDC balance read live from Stellar Horizon.
Flow
- Burn (Arc). StellarBurn.tsx calls depositForBurnWithHook(amount, 27, forwarder, ARC_USDC, forwarder, maxFee, 2000, hookData) on the Arc TokenMessengerV2. The recipient Stellar G-address is encoded in hookData.
- Attestation (Circle). Circle Iris observes the burn and produces a signed attestation for the CCTP message (amount, recipient, source and destination domain, nonce).
- Complete (Stellar). api/complete-stellar.js (Vercel serverless) fetches the attestation, funds an ephemeral relayer via friendbot, and submits mint_and_forward(message, attestation) to the CctpForwarder on Soroban. Minted USDC is forwarded atomically to the recipient. No recipient signature needed.
- Balance (Horizon). StellarWallet.tsx and the Proof-of-Transfer receipt read the live USDC balance from Stellar Horizon.
Contracts and parameters
| Item | Value |
|---|---|
| Arc CCTP domain | 26 |
| Stellar CCTP domain | 27 |
| Arc TokenMessengerV2 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
| Arc USDC | 0x3600000000000000000000000000000000000000 |
| Stellar CctpForwarder | CA66Q2WFBND6V4UEB7RD4SAXSVIWMD6RA4X3U32ELVFGXV5PJK4T4VSZ |
| Stellar USDC issuer | GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5 |
| Soroban RPC | https://soroban-testnet.stellar.org |
| Circle Iris sandbox | https://iris-api-sandbox.circle.com |
| Stellar Horizon | https://horizon-testnet.stellar.org |
| Network passphrase | Test SDF Network ; September 2015 |
Source files
- src/components/StellarBurn.tsx - burn and bridge on Arc
- src/components/StellarComplete.tsx - completion UI plus Proof-of-Transfer receipt (live Horizon balance)
- src/components/StellarWallet.tsx - link wallet, show USDC and XLM balance
- src/components/ProofBanner.tsx - hero banner with verified proof links
- src/components/StellarBridge.tsx - Iris attestation status
- api/complete-stellar.js - serverless mint_and_forward completer
Autonomous payouts and security (Arc -> Stellar)
Click to expandBuilt on top of the proven bridge+proof, two depth upgrades, both live in production.
Autonomous payout agent
Files: api/agent-payout.js + src/components/AgentPayout.tsx (commit c76cb3f).
The agent evaluates available revenue against a policy and decides, on its own,
when and how much USDC to route to Stellar for creator payouts and remittances.
- Policy: share percent of revenue, minimum threshold, per-payout cap, enabled flag.
- Every decision is written to a keccak-chained decision ledger (prevHash -> hash)
stored in Upstash KV, and shown in the "Recent agent decisions" panel. - Verified on production:
- available = 4 -> PAYOUT 1.2000 USDC (30 percent share)
- available = 0.5 -> HOLD (below the 1 USDC threshold)
- large values -> capped at the 5.0000 USDC per-payout cap
- Execution reuses the proven CCTP burn path (depositForBurnWithHook -> mint_and_forward).
Endpoints (api/agent-payout.js):
GET ?action=statusreturns policy, available, and the last decisions.GET ?action=decide&available=<n>runs the policy and appends a ledger entry.GET ?action=set-policy&...updates share / threshold / cap / recipient / enabled.GET ?action=set-available&value=<n>sets the tracked available revenue.
Completer hardening
File: api/complete-stellar.js (commit e2d5b74).
- Trust model: the recipient is bound in hookData at burn time, so the
permissionless completer cannot redirect funds. The relayer (ephemeral, or from
RELAYER_SECRET) only holds XLM for fees, so there is nothing to steal. - Graceful already_completed: re-submitting an already minted message returns a
clean 200 instead of a raw revert. - Idempotency + rate limit: per-message KV cache and per-IP limit (10 per minute).
- Timeouts: AbortController on every external fetch (Iris / Horizon / friendbot).
Server-side autonomous execution (shipped)
The payout agent can now execute the cross-chain burn itself, signed by the treasury key on the server with no browser wallet in the loop. Endpoint: GET /api/agent-payout?action=execute (optional &available=N override). The agent reads policy, decides amount, ensures USDC allowance, and submits depositForBurnWithHook on Arc via CCTP V2. Read-only health check: /api/agent-payout?action=signer-info returns the signer address plus native, USDC and allowance balances.
Proven on Arc testnet (server-signed, Status Success, method depositForBurnWithHook, from treasury 0x6829860b7f61FA01E5bf3D194d9f780ACa5B6787):
- Burn 1: 0xecc9ce81e1adc64356390d3e394880cf2572c6103e31b7b01665662eb10f8d0e
- Burn 2: 0x0aa56d3aa20490b5f215b6c4749b59baeccd6e4167cc794f9107c333b9539e75
Each burn routes 1.2 USDC (30 percent of 4 USDC available, under the 5 USDC per-payout cap) to the Stellar recipient via the CCTP forwarder, and is appended to the keccak-chained ledger with executed:true and the Arc burn tx hash. The UI panel exposes a one-click "Agent executes on Arc (server-signed)" action and links every executed ledger row to the Arc explorer.
Autonomous scheduling (no human in the loop)
An external scheduler (cron-job.org) pings the execute endpoint every 15 minutes, so the agent runs itself with no clicks and no browser open. Each scheduled invocation is authenticated with a shared CRON_SECRET and recorded in the ledger with trigger "cron", which distinguishes autonomous runs from manual ones.
Trigger (secret redacted): GET /api/agent-payout?action=execute&secret=REDACTED
On each tick the agent re-reads its policy, decides the amount (30 percent of available, min threshold 1 USDC, per-payout cap 5 USDC), and either holds (nothing to pay) or submits a server-signed CCTP burn on Arc. Payouts are fully autonomous: the treasury pays out on a schedule, by itself, only when the policy allows.
Skin in the Game — Conviction Staking
Cronus doesn't just publish signals — it puts its own USDC behind them. Every stake is
opened on-chain, held in escrow, and settled verifiably against a price the agent commits
to before the outcome is known. No human override, no edits after the fact.
Settlement rule
At a stake's resolveBy horizon, the resolver fetches the instrument's last price from
OKX and compares it to the openPrice committed at open time:
YESis correct iflast > openPrice;NOis correct iflast < openPrice.- Correct -> the staked USDC is returned to the staking wallet.
- Wrong -> the staked USDC is burned to
0x...dEaD. Irreversible.
Endpoints
| Route | Method | Purpose |
|---|---|---|
/api/open-stake |
POST (auth) | Open a conviction stake; escrow the principal; record commitment + ledger |
/api/resolve-stake |
GET / POST (auth) | GET = no-funds dry-run preview of due positions; POST = settle (return or burn) |
/api/track-record |
GET | Public scorecard: open / resolved / correct / wrong, accuracy, at-risk USDC |
On-chain roles (Arc testnet, chain 5042002)
- Staking / agent-identity wallet (ERC-8004):
0x46213abeCa58Cc9a89A269fD25A8737C700Ca164 - Stake escrow:
0xd6Cb6BfA4e922A30a244473ddb2fd3ABA39D5d4D - Burn sink:
0x000000000000000000000000000000000000dEaD
Live stakes
- Market
BTC-USDC, verdict YES, conviction0.82 - Committed
openPrice = 60147.1, stake0.091 USDC openTx0x60b3bcb223ecbca4e507c52d44be70416059c3a20d1ebe098722f3ae88cf1003- Resolved 2026-06-30: outcome WRONG (lastPrice 58613.7 vs openPrice 60147.1; BTC fell). Stake forfeited: 0.091 USDC burned to the dead address (provably unrecoverable).
resolveTx0xb8b8a6a31370b645800051e66af25804199b53b7c528a417b34b7014e955a255 (arcscan)
Second stake — resolved CORRECT (first on-chain win):
- Market
BTC-USDC:2026-07-03, verdict YES (conviction above the 0.65 open gate) - Committed
openPrice = 61960.4, stake0.084 USDC(commitment + openTx in/api/track-record) - Resolved 2026-07-05: outcome CORRECT (lastPrice 62450.4 vs openPrice 61960.4; BTC rose). Stake returned to the staking wallet — nothing burned.
resolveTx0xadfaf07b9af44b831ba970878ca53f5ca76714b8edb264d3a74eef4580a49a75 (arcscan)
Honesty
/api/track-record reports accuracy strictly from on-chain-resolved positions (as of 2026-07-05: 2 resolved, 1 correct, 1 wrong, accuracy 0.5, 0.091 USDC slashed, 0.084 USDC returned, realized P&L -0.091 — slash-only: a wrong verdict burns the stake, a correct one returns principal) — we
never claim a hit rate we haven't earned on-chain. At-risk and external metrics reflect
real on-chain state only.
Agentic Finance Stack on Arc
Cronus implements the full agentic-finance stack — identity, settlement, and programmable
workflow controls — and goes one step further with verifiable skin-in-the-game accountability.
| Layer | Capability | Status |
|---|---|---|
| Identity | ERC-8004 agent registration + on-chain reputation (Sourcify exact_match) | Live |
| Settlement | x402 paid endpoints + Circle Gateway; USDC as payment and gas | Live |
| Workflow — Escrow | Conditional escrow: stake returned on correct outcome, burned on wrong | Live |
| Workflow — Spending limits | Hard daily cap + per-recipient cap, enforced before any USDC leaves the wallet | Live |
| Workflow — Subscriptions | Plan-based call quotas with per-call metering | Live |
| Workflow — Split payments | Basis-point fan-out of one payment across counterparties | Live |
| Accountability — Verifiable reasoning | Deterministic consult (temperature 0 + fixed seed) content-addressed by sha256; any run re-verifiable via /api/trace |
Live |
Beyond "an agent with a wallet." Most agentic-payment demos stop at a key that can spend.
Cronus adds accountability: it stakes its own USDC on each conviction call and settles the
outcome on-chain, so reputation is earned rather than asserted. See Skin in the Game above.
Spending Limits (live)
Before any USDC leaves the agent wallet, every payout is checked against two hard caps: a daily budget and a per-recipient cap. Limits are enforced server-side against a KV-backed daily ledger, so the agent cannot exceed its budget across calls.
GET /api/spend-limit— transparency: current policy, today's spend, remaining budget, recent payouts.POST /api/spend-limit?action=check— dry decision for a{to, amountAtomic}(no auth, no funds).POST /api/spend-limit?action=set-policy— update caps (auth).POST /api/spend-limit?action=spend— enforce caps, then execute the USDC transfer on-chain (auth).
Default caps: 1.000000 USDC / day, 0.250000 USDC / recipient.
Split Payments (live)
A single payment can fan out to multiple counterparties by basis-point weights (summing to 10000), with allocations computed exactly (remainder to the last leg, no dust loss).
GET /api/split-pay— transparency: current split config + recent runs.POST /api/split-pay?action=preview— no-funds allocation for{amountAtomic, recipients?}.POST /api/split-pay?action=set-split— set recipients[{address, bps}](auth).POST /api/split-pay?action=execute— route a total across counterparties on-chain (auth).
Subscriptions (live)
Recurring, metered access to the paid signal API. A subscriber holds a plan that grants a call quota for a fixed period; every access is metered against the quota. Payment settles via the existing x402 signal flow.
GET /api/subscription— plans, plus?subscriber=status.POST /api/subscription?action=status— subscription status for{subscriber}(no auth).POST /api/subscription?action=subscribe— activate{subscriber, planId}(auth).POST /api/subscription?action=access— meter one call for{subscriber}(auth).
Plans: daily (0.5 USDC / 100 calls), weekly (2.5 USDC / 1000 calls), monthly (8 USDC / 5000 calls).
Verify it yourself
Cronus runs live on Arc testnet — every claim here is independently checkable, no trust required.
Run node scripts/verify-live.mjs (no auth, no funds moved): it probes every public endpoint, confirms the x402 paywall returns 402, checks spending-limit and split-payment enforcement (dry runs), and confirms every money-moving action is auth-gated (401 without a token).
Live sources of truth: GET /api/manifest (capabilities + discovery), GET /api/openapi (machine-readable spec), GET /api/track-record (staked positions / skin in the game), GET /api/receipts (on-chain x402 receipts).
On-chain (Arc testnet): ERC-8004 identity registry 0x252cAA46b9b0648908000f6C87e0a561DB4dEb6c, ERC-8183 job escrow 0x64e55De4CbC3CDf981B2c970807129FA61806873, reputation registry 0x2A19ad056EaE83364B0a6420685974cA219c209E. Escrow funding tx 0x5895d020c42e6f0b0f162b833a2b566499b4495aeeebc327e6192ef4df9e0b4c. All contracts verified on Sourcify (exact match).
Dashboard V2 — visual tour
See docs/dashboard-v2.md for an annotated screenshot gallery (one image per sidebar section), captured from https://cronus-capital.vercel.app. All payment volume shown is self-generated test traffic (external payers remain 0); stakes, COGS and vault NAV are real on-chain on Arc testnet.
Dashboard V2 — screenshots
Each screenshot below is one sidebar section of the live dashboard, captured from https://cronus-capital.vercel.app. Honest note: all x402 payment volume shown is self-generated test traffic (external payers remain 0); stakes, COGS and vault NAV are real on-chain on Arc testnet.
1. Overview

The control panel for the whole business: live metric cards (revenue, payments, net flow), the three-oracle agent pipeline, and every action button. This is where the full loop runs — a detailed button-by-button walkthrough is earlier in this README. Every metric is derived from real on-chain activity on Arc.
2. Oracle / Signals

The three reasoning oracles and their live output: current verdict, conviction score, and the step-by-step decision log (SCOUT → DECOMPOSE → DISCOVER → DECIDE → SUFFICIENCY → EXECUTOR → MEMORY → CONSENSUS). Shows exactly how the agent reaches — or deliberately abstains from — a call.
3. Markets / Intel

The live market context the agent reasons over: BTC price and regime plus macro indicators (Fear & Greed, dominance, global market data) pulled from public feeds in real time.
4. Payments (x402)

The revenue side: the live x402 settlement feed with payment count and total USDC, read straight from the Arc block explorer via /api/metrics and value-filtered to the exact 0.02 USDC signal price. Every row is a genuine on-chain transfer.
5. Traction

The honesty centerpiece: external_payers = 0 is shown plainly, right next to self-generated test volume (44 distinct wallets, 140 payments, ~2.80 USDC). We never present our own test traffic as external demand.
6. Vault

The ERC-4626-style on-chain vault: total assets (NAV), share accounting, and the live NAV history curve that fills only with genuine on-chain readings over time — never backfilled or fabricated.
7. Track Record

The agent's skin-in-the-game staking history: each conviction stake with its on-chain commitment hash and resolution (correct → stake returned, wrong → forfeited to burn). Real stakes, all verifiable on Arc.
8. Proof / Verify

The verification hub: proof seals plus direct links to public receipts, /api/scorecard, and the one-command replay (npm run verify-live, 118 checks) so anyone can reproduce the entire honesty surface with no keys.
9. Standards

Composability: the ERC-8004 identity/reputation and ERC-8183 escrow standards the agent implements on-chain, with the live contract addresses judges can inspect.
10. Risk / SecOps

The risk and security posture: risk gauges and position sizing on one side, operational safeguards on the other — replay protection, server-side key custody, and guarded autonomous execution.
11. System

The system health panel: live status of the API endpoints, data sources, and integrations, so judges can confirm the whole stack is up and reporting in real time.
License
Released under the MIT License — see LICENSE.
🔷 OKX X Layer Integration (Build X Hackathon)
Cronus Capital supports dual-protocol x402 payment gating:
X Layer Endpoint
- URL:
https://cronus-capital.vercel.app/api/signal-x402 - Network: X Layer (
eip155:196) - Token: USDT0 (
0x779Ded0c9e1022225f8E0630b35a9b54bE713736) - Price: 0.02 USDT0 (20000 atomic units)
- Builder Code:
0m014j21zgfw1r53 - payTo:
0xfdd1a3f50dfe522dd430a574d652dd84137ffe8b
How it works
- Client calls
/api/signal-x402 - Server returns
HTTP 402with x402v1 payload - Client pays 0.02 USDT0 on X Layer via EIP-3009
- Client retries with
X-PAYMENT: <txHash>header - Server verifies on-chain and returns signal data
Verified by OKX AI Agent
Endpoint verified via Purr-Fect Claw (OKX AI) — all x402 fields confirmed correct.
MCP Tool
cronus_signal_xlayer — available in cronus-mcp/index.mjs
⚡ Arc / Lepton Integration
- URL:
https://cronus-capital.vercel.app/api/signal - Network:
arc-testnet - Token: USDC
🛡 Cronus Cover — parametric micro-insurance (NEW, hackathon module)
Autonomous insurance agent built additively on top of Cronus: the oracle prices risk from
live market data, sells price-drop protection for USDC micro-premiums (x402-style), commits
every policy on-chain (keccak256) before the outcome, and pays out automatically at
expiry under hard spending caps. UI: #/cover · API: /api/cover · Docs: docs/cover.md
✅ Live proof (Arc Testnet)
First REAL policies sold on 2026-07-15: the buyer paid the premium in USDC on-chain,
the policy was committed (keccak256) BEFORE the outcome, and resolution is fully
automated (cron hits the resolver every 15 min; payouts are capped and verifiable).
- Policy: BTC-USDC, drop>=2%, open $64771, payout 0.05 USDC, premium 0.007726 USDC (1h horizon)
- Premium tx: https://testnet.arcscan.app/tx/0x9dbb83b0d6c9dd826572966a3e2dca20708e84efe7d1cfe8357bd2710054076c
- First fully autonomous cycle completed (Jul 15, 2026): the scheduled resolver (cron, every 15 min) auto-resolved both live policies at expiry with zero human involvement. BTC stayed above the trigger, so the policies expired worthless and the premiums were kept as agent underwriting revenue — the agent earned its first insurance income on its own.
- Full loop proven on Arc Testnet: quote -> USDC premium payment -> on-chain keccak256 commitment BEFORE the outcome -> autonomous resolution at expiry. Every step is independently verifiable in the public ledger at
/api/cover. - Keeper pattern:
GET /api/cover?action=resolveis a public dry-run preview; real execution requiresCRON_SECRET(Authorization header orsecretquery param) — the same battle-tested pattern as the agent's autonomous payout loop. - Commitment: 0x8d85e121d6c8f3d8b6a282c18eec2510cc734b1f679c81c8bb1b26e62501901e
- Live ledger: https://cronus-capital.vercel.app/api/cover
- Live underwriting metrics — the Cover tab renders a real-time metrics card computed purely from the public policy ledger (GET /api/cover): policies sold (real vs demo), open exposure, premiums collected, payouts paid, underwriting P&L, keep rate, daily payout cap utilization and loss ratio. Auto-refreshes every 15s — every number is independently reproducible from the same public endpoint.
🖥 Live Cover dashboard + fresh on-chain proof

For judges — reproduce this in 60 seconds on the live demo:
- Open the Cover tab in the sidebar (
#/cover). - Click GET QUOTE — the oracle prices a BTC-USDC drop>=2% policy from live market data (payout 0.05 USDC, ~0.003 USDC premium, 1h horizon).
- Click BUY · PAY USDC and confirm the wallet transaction — the premium is a real USDC transfer on Arc Testnet, and the policy is committed on-chain (keccak256) BEFORE the outcome.
- Watch the Policy Ledger and the Live Underwriting Metrics card update in real time — every number is recomputed from the public ledger at
/api/cover. - At expiry the cron-driven resolver settles the policy autonomously — no human in the loop.
Latest REAL premium payment (confirmed in <1s on Arc): View the premium tx on ArcScan ↗
⛓ On-chain Activity — Full System Snapshot
Latest transactions of the treasury and every deployed contract — with clickable ArcScan proofs, including the autonomous CCTP payouts that ran overnight: docs/onchain-activity.md
Regenerate anytime (public API only, zero private keys):
node scripts/traction-snapshot.mjs
📲 Telegram Ops Alerts — the agent reports to your pocket
Live instance: this deployment reports to @cronus_capital_bot (private ops channel — push-only, it does not respond to messages). To get the same alerts for your fork, create your own bot via @BotFather and set
TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID.
Cronus monitors itself. A serverless alert module watches every business
and health metric and pushes changes to Telegram — no dashboard refreshing,
no manual checks. If something happens on-chain, the operator knows within
10 minutes.
How it works
cron-job.org (every 10 min)
└─> GET /api/alerts (rewrite -> /api/info?kind=alerts, stays within Hobby 12-fn cap)
├─ fetches 9 internal endpoints (metrics, cover, track-record, traction,
│ spend-limit, agent-payout, signer-info, settlements, vault NAV)
├─ compares 19 fields against the last snapshot in Upstash KV (alerts:last)
└─> sends only real deltas to Telegram Bot API (dedupe + 1h throttle for noisy scans)
What it alerts on (16 event types)
| Event | |
|---|---|
| 💰 | New x402 USDC payment settled on Arc |
| 🛡 | Cover policy sold / resolved autonomously |
| 💸 | Cover payout triggered (parametric insurance paid) |
| 🎲 🎯 🔥 | Conviction stake opened / resolved correct / burned |
| 🚀 | New external payer detected |
| 🏦 | Autonomous CCTP payout executed (Arc → Stellar) |
| 🌉 | New direct on-chain settlement (tracked by tx hash) |
| 🌊 | Nano-stream Gateway batch activity (throttled 1/hour) |
| 🏛 | ERC-4626 vault NAV moved >= 0.01 USDC |
| 🤖 | Agent spent USDC upstream (data purchases) |
| ⚠️ | Treasury signer balance low / daily spend limit near cap |
| 🔴 | Any of 8 API endpoints down |
Design notes
- State lives in Upstash KV — alerts fire on changes only, never "all quiet" spam.
- Windowed on-chain scans (settlements, Gateway batches) are deduped by tx hash
and time-throttled, so RPC flicker never produces false positives. - Secured by the same
CRON_SECRETas the payout/resolver crons
(?secret=orAuthorization: Bearer). - Code:
lib/alerts.js, routed through theapi/info.jsdispatcher.
Judges: this means the autonomous agent is not a demo loop — it runs 24/7
unattended, and its operator is paged like an SRE when real money moves.
Proof tokens (two NFTs that do work)
Live section: https://cronus-capital.vercel.app/#/nft — resolver: /api/nft
Most agent NFTs are a picture. These two are load-bearing, and one can switch the other off.
Fire drill certificate (0xB327a942A64A190b453c7D6b27Cc03FE7ACDF166, soulbound ERC-721).
Minted by the operator that runs a drill, to the multisig, never to itself. The guardian can revoke
one but can never issue one: the watcher holds negative power only. Transfers revert, so a track
record cannot be sold or gifted. It expires one day after the drill it describes, so silence turns
into EXPIRED without anyone acting. Certificate #1 reads INCOMPLETE, not passing, because two of the
four scenarios were skipped — the guard's allowlist is empty and it holds no USDC, so those two
scenarios had nothing to attempt. A skipped scenario is never counted as a passing one.
Known limit: the contract stores each scenario's transaction hash but cannot verify it itself.
Access pass and parametric policy (0x6D59E3bF169743Dd31b5ba9eb394FEad0A9756C2, ERC-721).
2 USDC buys 30 days of API access plus a policy. Half of every payment stays in the contract as the
coverage pool, half goes to the treasury. The advertised cap is 5 USDC per pass, but backedPerPass
is the smaller of that cap and what the pool can actually pay, so the policy can never promise more
than it holds. A payout requires an unexpired pass and a certificate reading BREACHED, once per pass.
The leash. The pass reads the certificate's status on chain. If the drills stop and the
certificate goes stale, the contract suspends coverage by itself. We cannot keep selling protection
while letting the proofs rot.
Live so far: pass #1 was bought for 2 USDC and renewed for 2 more. The pool went from 1 to 2 USDC and
the backing per pass followed the money to 2, not to the advertised 5.
Contract verification: 8 of 10. The count on the site is read from the explorer on every request
and re-checked address by address in verify-live. The two that are not verified are named with the
reason rather than left out. The agent guard v2 and the multisig were deployed from 0.8.36 builds,
and this explorer accepts 0.8.36 submissions and then silently never finishes them: standard-input,
flattened-code and multi-part all returned "verification started" and nothing else. That is a
measured claim, not a shrug - the identical guard source compiled with 0.8.35 and deployed as a
throwaway canary (0xD8A26144Ff1838bB6fecd467418Db979985f0346) verified within a minute. Closing the
gap therefore means redeploying both on 0.8.35 and migrating roles through the 48h timelock, which is
scheduled after the queued multisig transaction executes, not waved away. CRN has
no source in contracts/, so there is nothing to submit for it.
The pass buys something. /api/signal-x402 normally charges per call over x402. A holder can
instead pass their address, and the endpoint reads hasAccess on Arc at request time and serves the
signal without a payment. There is no subscriber database anywhere: the contract is the only list.
Two limits are printed in the response rather than hidden. An address is not proof of ownership -
this proves the named address holds a live pass, not that the caller is that address, so a signature
challenge is required before this is safe off testnet. And if the chain does not answer, access is
denied and the caller pays as usual: an unread value is never resolved in the customer's favour.
Fire drills: is the containment still firing?
Configuration proves the guard is wired correctly. It does not prove it still fires. So the
agent periodically attacks itself on the live network and publishes what came back.
Live section: https://cronus-capital.vercel.app/#/drills — raw JSON: /api/drills
| Scenario | Expected | What it proves |
|---|---|---|
drain_to_new_address |
revert | a fully compromised key cannot reach an address nobody approved |
over_per_tx_cap |
revert | a single payment cannot exceed the per-tx cap |
operator_escalation |
revert | the spending key cannot change the rules or unpause |
bounded_allowlisted_payment |
success | the bounded rail still pays, so a pass is not just a dead contract |
A rejected attempt is a FAILED transaction in a mined block, which is the cheapest
unforgeable evidence available: a screenshot can be drawn, a reverted transaction cannot.
First exercise, 2026-08-11T20:59:27Z
drain_to_new_address— reverted,recipient not allowlisted, block 56504166,
0x3f603699…bc295operator_escalation— reverted,not owner, block 56504176,
0x9ab114b1…edb22over_per_tx_cap— skipped: the guard has no allowlisted recipient, so a cap test
would have reverted for the wrong reason and proven nothingbounded_allowlisted_payment— skipped: no allowlisted recipient and no balance
Two of four scenarios did not run, so two invariants read false rather than green. A
skipped test is not a passed test, and /api/drills is built so it cannot pretend otherwise.
Closing those two gaps requires adding an allowlisted recipient, which is a rule change, so
it is queued behind the guard's own 48-hour timelock. Queued 2026-08-11T21:07:02Z as multisig
transaction 6, operation 0x611d3923…ad5e, executable no earlier than 2026-08-13T21:07:02Z.
We cannot widen the agent's reach faster than an observer can react — not even with every
cold key in hand. A delay that inconveniences its own authors is a control, not a claim.
Bounded-loss certificate
The same endpoint publishes the upper bound on what a fully compromised operator key can
cost, derived from live caps rather than asserted: 25 USDC immediately, 100 USDC per
rolling 24h, and never above the immutable 500 USDC ceiling fixed at deploy. The figure
assumes the key is entirely in an attacker's hands and that nothing off-chain slows them down.
It excludes a compromise of two cold co-signers, which would still face the 48-hour timelock.
Safety of the drill itself
An attack transaction is broadcast only after a static call proves it reverts. If a rogue
path ever turns out to be executable, the runner refuses to send it and records a red result
instead: a fire drill must never become the fire.
Drill history lives in drills/*.json in this repository, not in a private cache, so anyone
can replay it. Sixteen checks in npm run verify-live hold the section to its claims,
including one asserting that a scenario marked skipped is never counted as passed.
Reproduce with no keys: curl https://cronus-capital.vercel.app/api/drills
Dry-run it yourself: node scripts/drills/run-drill.mjs --simulate
Security audit and test suite
Self-audit of every money-moving path, 2026-07-25. Machine-readable copy lives in the agent card under security and tests.
Controls in place
- Fail-closed auth: every privileged POST checks
Bearer CRON_SECRET; a missing secret returns 401 instead of opening the endpoint. Eight live negative checks run against production in section [13] of the verifier. - Read/write split: all GET endpoints are public and read-only (split config, subscription plans, escrow preview, signer check). Only POST moves funds.
- Keys never leave the environment: responses expose derived addresses only.
- One unified daily breaker (
lib/breaker.js) draws down a single ceiling for every USDC outflow; when the store is unreachable the call is denied, and a per-call cap still applies. - Anti double-spend: KV
NX EXlocks on every signing path (spend 30s, withdraw 60s, stake 120s, split 60s), released infinally. - Pure money math: BigInt only, checksum address validation via viem,
amount > 0,maxFee < amount, split weights must sum to exactly 10000 bps. - Dry-run first on the most dangerous path: the cross-chain withdraw returns a plan unless
execute:trueis passed, and simulates the burn before sending it. - Role binding: stake open and resolve abort with 409 if the loaded signer is not the expected treasury or escrow address.
Known limitations (deliberately published)
- A single shared
CRON_SECRETfor all privileged actions - no per-action scoping or rotation yet. Access-Control-Allow-Origin: *everywhere. Safe because authorization is a Bearer header, not a cookie, so there is no ambient authority - but it is a conscious tradeoff.- Stake resolution reads one oracle (OKX ticker). Mitigated by a pre-committed public resolution rule rather than a median of feeds.
- If KV is unreachable the withdraw lock is skipped (fail-open on the lock); the per-call cap still holds.
- The daily counter increments after the transfer succeeds, so a crash in between undercounts that day.
- Subscription quotas are granted by the operator-authenticated endpoint; the payment tx is recorded but not enforced by the record itself.
Test suite
node scripts/verify-chain.mjs # offline: replays the ledger hash chain, zero keys
curl -s .../api/agent-card # card, attestation, avgRating, policyHash
curl -s '.../api/nano-signal?quote=1&payer=0x...' # pricing, bundle, session
curl -s '.../api/nano-signal?session=use&payer=0x...' # expects HTTP 402 without a session
npm run test:all # build + 250 Node tests + 25 Foundry contract tests
npm run verify-live # 118 live checks against production
Current state: 118 of 118 live checks pass, plus 4 linked / 18 legacy / 0 broken links in the offline chain verifier. The formerly red check [4] metrics read from on-chain explorer now passes too. If the Arc testnet explorer API goes down again, metrics fall back to known on-chain proofs and label source honestly rather than reporting a fabricated number. Receipt verification already falls back to Arc RPC (source: onchain-rpc) when the explorer is down.
Submitting to Arc Showcase
The project is listed at https://arc-showcase.thecanteenapp.com/p/cronuscapital/
To update or resubmit the listing:
uv tool upgrade arc-canteen
arc-canteen submit-showcase
The CLI will prompt for:
- Project name — press Enter to keep existing
- Repo URL — press Enter to keep existing
- Demo URL — press Enter to keep existing
- Description — paste your updated description as one line, then Enter
- Empty line — press Enter
- Two confirmation prompts — press Y then Enter for each
The submission is saved locally at ~/.arc-canteen/showcase.yaml and can be resubmitted any time.
Cross-chain USDC Bridge — Circle CCTP V2
A non-custodial USDC bridge is built into the dashboard (Bridge tab), moving
native USDC between Arc Testnet and major EVM testnets via Circle CCTP V2
burn-and-mint. No wrapped tokens, no liquidity pool, no custodian — every step is signed
by the visitor's own wallet. Full threat model and verification steps:docs/BRIDGE_SECURITY.md.
Progress log — 31 Jul 2026
- CLI bridge script (
scripts/bridge.mjs) for Base -> Arc transfers via Circle CCTP V2. - Bridge integrated into the dashboard as a first-class Bridge section (
008c628,f4ce5d1). - Preflight hardening: balance check, allowance read + poll to kill the approve->burn race, and
simulateContractbefore every burn. - Selectable paired network — Base / Ethereum / Arbitrum / Optimism / Avalanche (
2bc64e4). - Manual direction toggle — Arc <-> EVM, default Base -> Arc, flip on the dashboard (
5ab2645). - Persistent transaction history — burn/mint hashes and status saved in
localStorage, surviving reloads. - End-to-end verified live on testnet in both directions (see below).
Live bridge transactions (testnet, verified on-chain)
Recipient wallet: 0xdc6778c5f8cc74b10aed11c48306d4cfc5737fbd
| Date (UTC) | Time (UTC) | Route | Amount | Burn tx | Mint tx |
|---|---|---|---|---|---|
| 31 Jul 2026 | 19:07:56 | Base Sepolia -> Arc Testnet | 1 USDC | 0x957acd…2d7b41 |
0x62db1a…477855 |
| 31 Jul 2026 | 19:09:34 | Arc Testnet -> Base Sepolia | 1 USDC | 0xbf1616…945ba1 |
0x17cccc…20cd5b |
| 1 Aug 2026 | 13:44:32 | Base Sepolia -> Arc Testnet | 1 USDC | 0x53a60f…557e9e |
0x9894b4…ac1f3d |
| 1 Aug 2026 | 13:48:02 | Base Sepolia -> Arc Testnet | 1 USDC | 0xaaf07c…727c13 |
0xe38179…a20a11 |
| 1 Aug 2026 | 14:12:03 | Base Sepolia -> Arc Testnet | 1 USDC | 0x5e74a9…cad0e1 |
0xd0a6e8…1d976c |
| 1 Aug 2026 | 14:19:56 | Arbitrum Sepolia -> Base Sepolia | 5 USDC | 0x73a54f…dc87c7 |
0x57ddae…48c223 |
| 1 Aug 2026 | 14:38:37 | Ethereum Sepolia -> Arc Testnet | 5 USDC | 0x76c834…d32b94 |
0x262ed6…f362f6 |
Every row dated 1 Aug 2026 was started by typing a sentence in plain language, not by picking
chains from a dropdown. A deterministic parser turned that sentence into an allowlisted route
and the policy layer judged it before anything was signed. No language model took part, and
the wallet signed every step.
The 14:19:56 leg is the first executed route that never touches Arc, which is what makes the
any-to-any claim above a fact rather than a capability: Arbitrum Sepolia to Base Sepolia, 5
USDC, burned and minted natively, started from the Russian sentence "переведи 5 usdc из
арбитрума в base".
Four of the thirty directed routes have now been executed on-chain: Base to Arc, Arc to Base,
Arbitrum to Base, and Ethereum to Arc. The remaining twenty-six use the same CCTP V2 domain
mechanism and the same code path, so they are expected to behave identically — but this table
lists only what has actually been signed and settled, and the widget marks any route it has
not executed as unverified rather than implying otherwise.
Swap — a constant-product AMM written from scratch
Arc testnet has no DEX, and USYC cannot be swapped because it is permissioned and the
entitlements contract answers false for our address. Rather than mock a swap, we deployed
one: a fixed-supply ERC-20 and a constant-product pool against native Arc USDC, both incontracts/CronusSwap.sol, about 200 lines with no external libraries.
This is our own pool holding our own liquidity, not an integration with a third party, and
the code says so in its header comment. What it proves is that the swap path is real.
| What | Address / tx |
|---|---|
| Pool (CronusSwap) | 0x0924Dae7…607400 |
| Token (CRN) | 0x352991E7…0E53C9 |
| Initial liquidity | 0x8ceb3aaa…6ab106 |
| First swap, 0.1 USDC -> 94.965947 CRN | 0x080c1310…f6464b |
| Liquidity deepened to 10 USDC / 9071.59 CRN | 0x98648cb1…ddabf1 |
| Hardened v2 redeploy — reentrancy guard, pausable, swap deadline | 0x2e977f…a9b337a |
| Re-seeded 10 USDC / 6613 CRN into hardened pool | 0xcaff28…3951be |
| First v2 swap, 0.1 USDC -> 65.28076 CRN | 0xa3b40e…ba75dc |
The invariant is checked on-chain, not asserted in prose: reserves went from 2 USDC / 2000
CRN to 2.1 USDC / 1905.034053 CRN, so the product rose from 4000 to 4000.57 — the 0.3% fee,
and nothing else. A swap that would shrink the product reverts with k.
Pricing is deliberately unflattering. Depth was later raised to 10 USDC / 9071.59 CRN in exact
proportion to the reserves already there, which reduces slippage without moving the price by a
single unit — scripts/add-liquidity.mjs derives the CRN side from the live ratio rather than
accepting it as input, because a mismatch would hand a free arbitrage to the first observer.
The pool is still thin on purpose: at the live reserves a 1 USDC order returns fewer CRN than the raw reserve ratio
implies. That is the same maths Uniswap uses, and we did not paper over it with a fixed rate.
After a self-audit we redeployed the pool as a hardened v2: a reentrancy guard on every state-changing path, an owner pause switch for incident response, and a deadline argument on swapExactIn so a transaction stuck in the mempool cannot execute later at a stale price. The original pool was drained to zero and retired; the v2 pool above was re-seeded with 10 USDC / 6613 CRN, and its first v2 swap is linked in the table. Scope, threat model, and disclosure policy live in SECURITY.md.
Each row is a complete CCTP V2 round-trip leg: USDC burned on the source chain and
minted natively on the destination chain, both signed by the recipient's own wallet.
📊 Traction & Honesty
Verified external payers: 0 (honest count). We never present our own
testing volume as third-party demand.
All on-chain payment volume on the live endpoints — currently ~239
self-generated x402 settlements (~4.78 USDC) across 52 wallets, out of 283
total settlements — is self-generated test traffic. Because Cronus runs on the
Arc testnet, the maintainer executes daily x402 transactions against the live
paywall to continuously prove the payment rail, settlement, and receipts
pipeline are operational end-to-end.
This traffic is:
- Fully verifiable — every payment is a real on-chain tx, checkable on arcscan
(https://testnet.arcscan.app) and via /api/receipts. - Always labeled — it appears only under self_generated_* in /api/traction and
/api/leaderboard, and is never counted toward external_payers. - Tamper-resistant — external_payers counts an address only if it is (a) in the
VERIFIED_EXTERNAL_PAYERS allowlist, (b) independently funded (verified via
scripts/audit-funders.mjs), and (c) not one of our own wallets. The allowlist
is empty by default, so the honest count stays 0 until a real third party
pays and is independently verified.
Why we keep it at 0: on a testnet, throwaway wallets can be faucet-funded to
look independent. Rather than inflate the number, we keep external demand at a
truthful 0 and keep the on-ramp open — any third party can pay 0.02 USDC via
the Pay Cronus button or node scripts/pay-cronus.mjs and, once independently
verified, be counted with on-chain proof.
🏆 Judge Walkthrough — Build Log (Aug 15, 2026)
Everything below is live on Arc testnet — no mocks, no stubs. Every claim is verifiable via a public endpoint or on-chain. Honesty invariant: our own test traffic is never counted as external demand.
1. Public Honest Leaderboard (/api/leaderboard)
A public, self-auditing leaderboard of who pays Cronus.
- Endpoint: https://cronus-capital.vercel.app/api/leaderboard
- Canonical field
external_payers: a wallet counts only if it is (a) an on-chain receipt payer AND (b) explicitly allow-listed inVERIFIED_EXTERNAL_PAYERS. Today = 0 (no independent third party has paid yet; we refuse to fake one). - Self/demo separated, never hidden:
unique_self_demo_payers(distinct wallets WE used to exercise the paywall, =5),self_demo_calls,self_generated_wallets/txs/usdc. - Honesty fix shipped today:
unique_external_payerspreviously leaked our 5 test wallets; now allow-list-gated → 0 across/api/leaderboardand/api/traction. - Verify:
curl -s https://cronus-capital.vercel.app/api/leaderboard | grep -o '"external_payers":[0-9]*\|"unique_external_payers":[0-9]*\|"unique_self_demo_payers":[0-9]*'=>"external_payers":0 "unique_external_payers":0 "unique_self_demo_payers":5
2. MCP Integration — Cronus as a tool inside Claude & ChatGPT
Cronus is exposed as a remote MCP server over HTTPS (stateless Streamable-HTTP JSON-RPC) — agents discover it, see prices, and pay via x402, no install.
- Remote MCP URL:
https://cronus-capital.vercel.app/api/mcp - Tools:
cronus_consult(free verdict),cronus_signal(paid 0.02 USDC),cronus_nano_signal(paid 0.001 USDC, gas-free),cronus_pay,cronus_signal_xlayer. - Served via
api/info?kind=mcp+vercel.jsonrewrite — 0 extra serverless functions (stays within Vercel Hobby 12-function limit).
2a. Connect in Claude (verified live today)
- Claude -> Settings -> Connectors -> Add custom connector.
- Name:
Cronus Capital| URL:https://cronus-capital.vercel.app/api/mcp-> Save. - Free verdict: ask "Give me a Cronus verdict on ETH-USDC." -> BUY/SELL/HOLD + conviction + Coinbase cross-check (no payment).
- Paid signal: ask "Give me the paid nano signal on ETH-USDC." -> 402 -> pay -> 200 + settlement id (0.001 USDC, Circle Gateway, gas-free EIP-3009) + signed EIP-191 delivery receipt.
2b. Connect in ChatGPT (Custom GPT Action)
- ChatGPT -> Create a GPT -> Configure -> Actions -> Create new action.
- Import from URL:
https://cronus-capital.vercel.app/api/openapi(live OpenAPI for /api/signal + /api/nano-signal). - Ask: "Get a Cronus consult on ETH-USDC" (free). Paid endpoints return HTTP 402 with accepts[] for x402-capable agents.
- Alt: MCP-capable ChatGPT clients can point directly at
https://cronus-capital.vercel.app/api/mcp.
3. Real payment inside the chat (server-side auto-settle)
lib/settle.js(opt-in via envCRONUS_AUTOSETTLE=1): paid tools auto-pay from our test wallet through Circle Gateway and return signal +settlementid, taggedsettledBy: "cronus-test-wallet (self/demo)",external: false.- Smoke verified:
tools/call cronus_nano_signal -> 200, 0.001 USDC settled, verdict YES / conviction 75, signed delivery receipt.external_payersstays 0.
4. What we shipped today
- Model migration Llama 3.3 70B -> GPT-OSS 120B.
- Honest "Traction & Honesty" section +
/api/traction,/api/leaderboard,/api/receipts. - Idea #2 Public Leaderboard (self/external separation, allow-list gating).
- Idea #1 A2A Marketplace via MCP + x402: published
cronus-mcpnpm v0.2.0; autonomous buyer-agent executed a live A2A purchase (gas-free 0.001 USDC + on-chain ERC-8004 reputation feedback). - Remote MCP over HTTPS + live external Claude connect (Anthropic clients show as EXTERNAL handshakes; external_payers honestly still 0).
- Server-side auto-settle for in-chat paid demos.
- Honesty bug fixed: unique_external_payers allow-list-gated -> 0 everywhere.
5. Video demos
- Demo 1 (2:36): dashboard -> leaderboard -> MCP panel -> Get live quote -> Connect Claude -> Claude calls cronus_consult live -> BUY ETH-USDC, conviction 78, Coinbase cross-check agrees. Human only clicks Connect.
- Demo 2 (paid flow): in Claude "give me the paid nano signal on ETH-USDC" -> 402 -> pay -> 200 + settlement id, live.
- Demo 1 — dashboard + honesty leaderboard + live Claude connect + free consult (2:36): https://youtube.com/shorts/830W9RiDCxs
- Demo 2 — paid flow in-chat: 402 -> pay 0.001 USDC -> 200 + settlement id + signed receipt (2:27): https://youtube.com/shorts/55fdlJ8cce0
🔐 Keyless Execution via Private MCP

Historic moment — Claude discovered the endpoint, read the signal, and executed a real on-chain swap end-to-end (0.1 USDC to 90.44 CRN). No key in chat, no human clicking a button. This is the agent-to-agent commerce the Arc ecosystem is being built for.
Verify on Arc explorer · tx 0x5eeabd21…0eba076dc
Cronus exposes two MCP endpoints. The public one is read/dry-run only; the private one adds real, keyless on-chain execution for trusted AI clients.
| Endpoint | Tools | Execute | Auth |
|---|---|---|---|
/api/mcp (public) |
19 | dry-run only (execKey-gated) |
none |
/api/mcp-private |
21 (19 + 2 execute) | real, keyless | MCP_PRIVATE_TOKEN |
Judges — one-click keyless demo
Connect Claude with the public demo token (already in the URL) and ask in plain language:
Connector URL: https://cronus-capital.vercel.app/api/mcp-private?k=cronus-judge-2026
Then say: "swap 0.1 USDC to CRN" → Claude calls cronus_swap_execute → a real on-chain tx you can verify on arcscan. No key in the chat, no setup.
Latest verified demo swap: 0x616d1d7d…c15733b
Demo-token limits (gate-enforced): swap usdc_to_crn only, <= 0.1 USDC/swap, 20/day; bridge <= 0.5 USDC to treasury only, 5/day; 1/min. Full execute (both directions, higher caps) stays behind the private token.
How keyless execution works
The private endpoint adds cronus_swap_execute and cronus_bridge_execute. The fund-moving secret (CRONUS_EXEC_SECRET) lives only in server env and is injected server-side on each call — the caller never sends a key. An AI client (e.g. Claude) connects once with a connector token and then executes real on-chain actions from plain language, with no secret in the chat.
Safety model
- Auth gate: every private request needs a valid
MCP_PRIVATE_TOKEN(x-mcp-tokenheader,Authorization: Bearer, or?k=); missing/invalid returns401. - Treasury allowlist:
cronus_bridge_executesends only to Cronus treasury addresses (EVM0xdc6778...5737fbd, StellarGBNJ2JNN...CAZK); any other recipient returns403, no funds move. - Server caps: swap <= 2 USDC/call, 50 USDC/day, 1/min; bridge <= 5 USDC, 1/5min.
- Audit: every execute is appended to a KV audit log (
cronus:mcp:audit) with tool, amount, txHash, caller. - Public surface unchanged:
/api/mcpstays 19 read/dry-run tools — external agents and judges see no execute surface.
Verified on-chain (Arc testnet)
| Action | txHash |
|---|---|
| Keyless swap via Claude (UI, no key in chat) | 0x48547ebd6e1515d96869ba050e370b5d89568bf7defa4f752d8871aae5cfad91 |
| Keyless swap via Claude (autonomous) | 0x5eeabd21becd8ae8cec9e270bdd56c3609a5654526e0f9c1c5567c64eba076dc |
| Keyless swap via private MCP (server-injected key) | 0x0298e8cf02918149f83f852d0c22d771193b650daf8db519657251957139fb9d |
| Bridge Arc->Stellar (CCTP v2 burn) | 0xc75ed27896abc179aadbd336090a180883afdccc7afb66da5a461061d79bb3d0 |
| Stellar mint (settlement) | 50c8558082ae249fb98eadd8afeb76592420813d42bb13e5919ad56cf0ff12a8 |
Explorer: Arc https://testnet.arcscan.app/tx/<hash> · Stellar https://stellar.expert/explorer/testnet/tx/<hash>
Connect in Claude
Settings -> Connectors -> Add custom connector
- URL:
https://cronus-capital.vercel.app/api/mcp-private?k=<MCP_PRIVATE_TOKEN> - Then ask in plain language: "swap 0.1 USDC to CRN" -> Claude calls
cronus_swap_execute-> real tx, no key in chat.
Cronus MCP — full tool surface (live-verified in Claude)
Cronus ships as a hosted remote MCP server (Streamable HTTP / JSON-RPC 2.0), ridden on the existing api/info.js router — zero extra serverless functions (Hobby 12-fn cap intact). Add it in any MCP client (Claude, etc.) by URL:
- Public (read + paid, 19 tools):
https://cronus-capital.vercel.app/api/mcp - Private execute (adds 3 treasury-signed tools, 22 total):
https://cronus-capital.vercel.app/api/mcp-private?k=<token>
The private tier injects the Cronus exec secret server-side from env — the caller never supplies a key. A demo token exposes the execute tools under hard, server-enforced caps; funds only ever move inside Cronus's own wallets (the AMM pool for swaps, the treasury allowlist for bridges).
Tools
| Tool | Type | What it does |
|---|---|---|
cronus_consult |
free | Market verdict (BUY/SKIP/HOLD/CACHE) + conviction + re-verifiable traceHash |
cronus_signal |
x402 (0.02 USDC) | Premium signal; returns HTTP 402 quote without payment |
cronus_nano_signal |
Gateway (~0.001 USDC) | Sub-cent nano signal (EIP-3009, gas-free) |
cronus_signal_xlayer |
x402 (USDT0) | Premium signal on OKX X Layer (eip155:196) |
cronus_pay |
free | Exact on-chain payment instructions for a signal |
cronus_insurance_quote |
free | Signal-insurance quote (5% premium, money-back on MISS) |
cronus_insurance_buy |
x402 | Buy signal insurance; 402 quote without payment |
cronus_insurance_status |
free | Policy status / refund check by policy_id |
cronus_receipts |
read | Recent x402 receipts (payer, amount, external flag) |
cronus_metrics |
read | Aggregate agent stats |
cronus_leaderboard |
read | External-payer leaderboard (self/demo labeled separately) |
cronus_balance |
read | Treasury balances on Arc |
cronus_payout_status |
read | Autonomous payout-agent status + hash-chain tip |
cronus_decisions |
read | On-chain decision log (CronusDecisions) |
cronus_vault |
read | Vault NAV (ERC-4626 totalAssets) |
cronus_cctp_status |
read | CCTP attestation status for an Arc burn (Arc→Stellar route) |
cronus_identity |
read | ERC-8004 on-chain agent identity |
cronus_swap |
dry-run / execute* | Real USDC↔CRN AMM swap; dry-run by default |
cronus_bridge |
dry-run / execute* | Real CCTP burn Arc→EVM/Stellar; dry-run by default |
cronus_swap_execute |
private (treasury-signed) | Real AMM swap; exec secret injected server-side |
cronus_bridge_execute |
private (treasury-signed) | Real CCTP burn to a treasury-allowlisted address only |
cronus_bridge_complete |
private (treasury-signed) | Finalize an attested burn by minting on the destination |
* On the public MCP, cronus_swap / cronus_bridge stay dry-run unless the caller passes execute:true and a valid execKey; the server never substitutes its own secret, so the public MCP cannot move funds anonymously.
Server-enforced caps
- Swap: endpoint 2 USDC/swap · 50 USDC/day · 1/min, treasury-signed. Demo tier adds a stricter 0.1 USDC-equivalent/swap · 20/day (for
crn_to_usdcthe CRN input is priced to USDC via a live pool quote, so the cap is symmetric in both directions). - Bridge: endpoint 5 USDC/bridge · shared daily spend breaker · 1/min; recipient must be a Cronus treasury allowlisted address (else 403). Demo tier adds 0.5 USDC/bridge · 5/day.
Live-verified in Claude (demo tier)
Every execute tool was driven end-to-end from Claude against production, funds moving only inside Cronus's own wallets, each verifiable on arcscan / basescan:
| Action | Result | Tx |
|---|---|---|
| Swap USDC→CRN | 0.019737 USDC → ~16.32 CRN | arc 0xda4e42f200dd2cbb748503836dec16561307d928aef37d4f46fc6d8e9a028a8b |
| Swap CRN→USDC | 16.42 CRN → 0.019737 USDC | arc 0xd63e6a49f58114a565f5d20913f7a9ac3fc5be9a2eb0becc2121875f1366bc9b |
| Bridge Base→Arc (reverse leg) | burn (Base Sepolia) → mint (Arc) | burn 0x6c5b2d9056d53e0b1b638e3375b71504b1dee4751e126cca6bf9ec999981fbb2 → mint 0x5c6234af4d08a9340c08e4e4e51d72d32af6a26e201af8e7fb95a62b0b3529b7 |
Previously verified on-chain with the same tools (CCTP round-trip, Arc→Base):
| Action | Tx |
|---|---|
| Bridge Arc→Base | burn 0x3a18100cc0167c41bf4f5563db0b264701ea77575b4e33f4a47c225caf0cb119 → mint 0xa976e9a789f846b671bb16ef2acad4d2ad26d5ac83478b4a5852422173810837 |
Honest notes: the USDC↔CRN round-trip loses ~1.3% (two 0.3% AMM fees + price impact on a small pool) — quoted openly, never hidden. CCTP burns use v2 Fast Transfer (minFinalityThreshold: 1000) for seconds-latency attestation. crn_to_usdc sells are ungated by the conviction signal (autoSignal:false); usdc_to_crn buys can optionally gate on a live Cronus verdict (conviction ≥ 65).
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi