Skip to content

StarryDeserts/Caspilot

Repository files navigation

Caspilot

An autonomous DeFi agent for Casper that cannot run away with your money.

AI proposes Β Β·Β  the signer & on-chain vault authorize Β Β·Β  the chain executes.

network tier-1 tests license

Casper Agentic Buildathon 2026 Β· Casper Innovation Track

πŸ“Ί Demo video Β Β·Β  πŸ”— On-chain proof Β Β·Β  πŸ§ͺ Judge playbook Β Β·Β  πŸ›‘οΈ Security model Β Β·Β  ⚑ Quickstart


The headline: this is real, and you can check it yourself

Caspilot's core claim β€” an on-chain policy gate that stops a misbehaving agent β€” is proven on casper-test and permanently verifiable on a block explorer. No rebuild, no trust in us. Look any hash up on testnet.cspr.live:

Step Result Hash On-chain outcome
Deploy PolicyVault βœ… installed bf555d60…5431 package ff2d4e13…7fb9 β†’ contract 8f75ba25…d63e
Deploy demo CEP-18 token βœ… installed recovered from the same deployer account package 0f8b1bd8…e38a β†’ contract 89522729…1c9d
pay() accepted βœ… transfer a7419aa2…2bdf5 50 tokens β†’ allowlisted receiver
pay() rejected β€” receiver not allowed β›” reverted e6801a75…cec7 User error: 3 (ReceiverNotAllowed)
pay() rejected β€” over per-payment max β›” reverted c4a48997…0eea User error: 4 (AmountAboveMax)
UI co-sign β€” human signs + pays, backend-verified βœ… finalized 299d1288…fe7543 native CSPR transfer Β· signerRole: user_cspr_click

A genuine policy gate must do more than let a good payment through β€” it must stop the bad ones on-chain, where the agent cannot override it. Two correctly-signed, correctly-formed payments were reverted purely because they violated policy. That is the whole thesis, on-chain. The last row is proof of a different kind: a real transaction a human co-signed and paid straight from the web UI, which the backend independently verified on-chain before recording it.

Full walkthrough, trust model, and reproduce steps β†’ docs/tier1-demo.md.


The problem

Autonomous agents that touch money are a security nightmare. To act, an agent usually needs a key β€” and a key is unbounded authority. If the model is jailbroken, hallucinates a recipient, or is simply wrong, nothing on-chain stops it. "Trust the prompt" is not a security model.

The solution

Caspilot splits the agent's intelligence from its authority. The agent can reason about yield and propose a payment, but it never holds a key and can never move funds on its own. Every payment passes through two independent gates it cannot bypass:

  1. An off-chain SignerGuard β€” deny-by-default policy checks + a SQLite spend-ledger that reserves budget before anything is signed (replay-protected, daily-capped).
  2. An on-chain PolicyVault β€” an Odra smart contract that re-checks every pay() against an agent allowlist, a receiver allowlist, a per-payment max, a daily cap, a validity window, and a payload-hash nonce β€” and reverts if any fails.

AI proposes; signer & vault authorize; chain executes. The vault's allowlisted agent is bound to the signer's own derived account hash β€” so on-chain authority follows the key that actually signs, not a value the caller passes in.

Caspilot ships this as two product lines over one backend:

  • πŸ’Έ An x402-paid agent API β€” pay-per-call yield intelligence, settled with the x402 payment protocol (CEP-18 + EIP-712 authorization) and a replay-protected ledger.
  • πŸ” A delegated on-chain PolicyVault β€” deposit funds, set the rules, and let the agent operate within them. The chain is the backstop.

How it works

flowchart TB
    AI["πŸ€– AI agent<br/>reasons about yield, proposes a payment<br/><b>never holds a key</b>"]

    subgraph G1["GATE 1 Β· off-chain β€” deny by default"]
      SG["πŸ›‘οΈ SignerGuard<br/>reserves budget before anything is signed<br/>replay-protected spend ledger"]
    end

    subgraph SIGN["Separated signing β€” key never crosses to broadcast"]
      direction LR
      USER["πŸ‘€ Human co-sign<br/>CSPR.click wallet<br/>signs AND pays"]
      AGENT["πŸ”‘ Agent signer<br/>detached signature only"]
    end

    subgraph G2["GATE 2 Β· on-chain β€” the backstop"]
      VAULT["⛓️ PolicyVault Β· Odra smart contract<br/>agent + receiver allowlists Β· per-payment max<br/>daily cap Β· validity window Β· payload-hash nonce"]
    end

    CHAIN{{"casper-test executes<br/>β€” or REVERTS on violation β€”"}}
    TRACE["πŸ“ Audit trace, redacted<br/>records what was decided, never the prompt"]

    AI -->|"intent"| SG
    SG -->|"approved β†’ build unsigned deploy"| SIGN
    USER --> VAULT
    AGENT --> VAULT
    VAULT -->|"a valid signature is necessary,<br/><b>never sufficient</b>"| CHAIN
    SG -.->|"every step"| TRACE
    VAULT -.-> TRACE
Loading

In the codebase: apps/web (Next.js) creates intents and drives CSPR.click signing; apps/api (Hono) runs the intent FSM, the x402 gateway, and the redacted audit trace; apps/harness broadcasts and observes on casper-test.

The agent's only path to the chain is a detached, tagged signature over a byte-identical deploy. The signing key is loaded by the signer and never crosses into the broadcast adapter. Even with a valid signature, the vault still has the final say.

πŸ“„ The full one-page value proposition (for judges): docs/value-proposition.md.


Tech stack

Layer Choice
Smart contract Odra 2.0 (Rust β†’ WASM), CEP-18 token transfers
Backend API Hono + @hono/node-server, TypeScript (strict, NodeNext)
Web Next.js 14 App Router, React 18, a hand-rolled design-system.css (no Tailwind)
Payments x402 protocol (verify/settle/supported wire schemas, PAYMENT-SIGNATURE codec)
Ledgers SQLite via better-sqlite3 (WAL), UNIQUE replay constraints
Chain access casper-js-sdk against a casper-2.0 (Condor) testnet node
Monorepo pnpm workspace Β· vitest Β· biome Β· GitHub Actions CI

788 automated tests across 12 workspaces, plus a Rust contract suite and a gated real-broadcast live runner.


Quickstart

Prerequisites: Node β‰₯ 20.10 (CI runs Node 22), pnpm 9.12, and β€” for the contract β€” the Rust/Odra toolchain (see docs/development-status.md).

pnpm install          # installs the workspace (better-sqlite3 builds natively)
pnpm typecheck        # strict TS across every package
pnpm test             # 788 tests (the 2 real-broadcast tests self-skip)

Verify the contract logic

node scripts/check-cargo.mjs   # cargo odra test -b casper && cargo odra build

Run the web UI locally

pnpm --filter api dev          # API on http://localhost:8787
pnpm --filter web dev          # Web on http://localhost:3001

Open http://localhost:3001 β†’ Intents to draft a payment intent and Intent detail to watch its (redacted) audit trace.

Note (honest status): the production API entrypoint (apps/api/src/index.ts) serves the full /intents lifecycle β€” create, list, validate-policy, mark-executed, trace, and reject β€” alongside /healthz and /version, persisting the ledger and audit trace to SQLite (CASPILOT_DB_PATH). The API carries a non-broadcasting local_dev signer (its sign() throws): it never holds a real signing key, so on-chain broadcast stays the harness's job. Host setup β€” persistent volume, env, CORS β€” is in docs/deploy-vercel.md. The Tier-1 proof above is independent of any hosting β€” the deploy hashes are permanent on-chain.

Reproduce the on-chain proof (optional, spends test-CSPR)

Opt-in, casper-test only, gated behind RUN_REAL_ONCHAIN=1. Full env and command in docs/tier1-demo.md.


Judge testing playbook (concise)

This is the no-marketing path for buildathon reviewers:

  1. Verify the deployed Casper Testnet proof β€” open the hashes in the headline table above. The mandatory PolicyVault package is ff2d4e132f979f6d5c1af13d34270acfddc75a7c98c323be4d8b668140fb7fb9; its live contract hash is 8f75ba257f61ae1bbfa1f974a617705e519757445a77189d7c011327bdc5d63e. The demo CEP-18 token package is 0f8b1bd871aa5061b278c1a45d653cb2f29a40f79e76196e35beb3851225e38a.
  2. Watch the UI workflow β€” the 3m44s demo video shows the actual reviewer path: create intent β†’ validate policy β†’ CSPR.click wallet co-sign β†’ backend on-chain confirmation β†’ explorer proof β†’ rejected policy violations.
  3. Run the local MVP β€” pnpm install && pnpm --filter api dev in one shell, pnpm --filter web dev in another, then open http://localhost:3001. The seeded API lets you inspect the intent FSM and audit trace without spending test-CSPR.
  4. Run the verification gates β€” pnpm typecheck, pnpm test, and node scripts/check-cargo.mjs. The real-broadcast tests are gated and self-skip unless RUN_REAL_ONCHAIN=1 is set.
  5. Optional live wallet replay β€” use a Casper wallet on casper-test with test CSPR, set NEXT_PUBLIC_CSPRCLICK_APP_ID and NEXT_PUBLIC_CASPILOT_API_BASE, then follow docs/demo-recording.md. Do not click explorer links for synthetic seeded hashes; only the hashes documented above are durable on-chain proof.

Buildathon qualification checklist

  • GitHub repository β€” public MIT repo with CI, CodeQL workflow, Dependabot config, security policy, contributing guide, pull-request template, and issue templates. Required topics are set on GitHub: casper-blockchain, casper-network, buildathon.
  • Application β€” functional MVP with a Next.js UI, Hono API, x402 gateway, CSPR.click co-sign flow, and a deployed Casper Testnet PolicyVault proof.
  • BUIDL page fields β€” copy these package hashes and sample transactions without rebuilding:
    • PolicyVault package: ff2d4e132f979f6d5c1af13d34270acfddc75a7c98c323be4d8b668140fb7fb9.
    • PolicyVault contract: 8f75ba257f61ae1bbfa1f974a617705e519757445a77189d7c011327bdc5d63e.
    • Demo CEP-18 package: 0f8b1bd871aa5061b278c1a45d653cb2f29a40f79e76196e35beb3851225e38a.
    • Accepted vault payment: a7419aa2fcedff56b76fe509ecc745b9f1da0ecd5b26e0205a0241061242bdf5 β€” 50 demo tokens transferred to the allowlisted receiver.
    • Rejected vault payment: e6801a750b58bbe955240b0fef19e53ced76219be397043bb1f56e03280bcec7 β€” receiver not allowlisted, reverted as User error: 3.
    • Rejected vault payment: c4a48997dfcd7c56c2d019caaa771467f71d48d50ca85584218fb2a9327a0eea β€” amount above the per-payment max, reverted as User error: 4.
    • UI co-sign transaction: 299d1288e7edfed64e1de6ca9d229834b02f2de22d75999b59a09b5403fe7543 β€” human CSPR.click signer paid and the backend confirmed on-chain before recording.

Security model

Defense-in-depth is the point of this project, not an afterthought:

  • Key separation β€” the agent/API never holds the signing key; only a detached signature crosses the trust boundary into the broadcast adapter.
  • Deny-by-default β€” SignerGuard rejects anything not explicitly allowed; denial paths never reach the signer.
  • On-chain backstop β€” the PolicyVault re-validates every pay(); a valid signature is necessary but not sufficient.
  • No secrets in the browser β€” validatePublicEnv() rejects privileged NEXT_PUBLIC_* names, and a build-time gate (scripts/check-bundle-secrets.mjs) scans the real .next bundle for leak shapes and live secret values.
  • User signs, not the server β€” the only web signer is CSPR.click; any provider exposing privileged fields is rejected.
  • Audit trace, not chain-of-thought β€” reasoning/prompts are redacted before persistence and re-redacted on export. The trace records what was decided, never the model's private reasoning.
  • Replay protection everywhere β€” UNIQUE(nonce,payer,asset) and UNIQUE(payload_hash) in the payment ledger; UNIQUE(intent_id) reservations in the spend ledger; payload-hash nonces on-chain.

Repository layout

caspilot/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/            Hono API β€” intent FSM, x402 gateway, audit trace
β”‚   β”œβ”€β”€ web/            Next.js 14 UI (Vercel-ready)
β”‚   β”œβ”€β”€ harness/        Tier-1 real-broadcast orchestrator (casper-test)
β”‚   └── adapter-doctor/ adapter capability/health checks
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ intent-fsm/     canonical states + deny-by-default transitions
β”‚   β”œβ”€β”€ signer-guard/   policy checks + SQLite spend ledger
β”‚   β”œβ”€β”€ x402-gateway/   x402 wire schemas + PAYMENT-SIGNATURE codec
β”‚   β”œβ”€β”€ payment-ledger/ replay-protected SQLite ledger
β”‚   β”œβ”€β”€ adapters/       casper-rpc / CEP-18 / CSPR.cloud / write path
β”‚   β”œβ”€β”€ audit-trace/    reasoning redactor + store
β”‚   └── shared/         canonical JSON / SHA-256 helpers
β”œβ”€β”€ contracts/
β”‚   └── policy-vault/   the Odra smart contract (the on-chain gate)
└── docs/
    β”œβ”€β”€ tier1-demo.md          ← the verifiable on-chain proof
    β”œβ”€β”€ deploy-vercel.md       ← deployment guide
    β”œβ”€β”€ demo-recording.md      ← demo-video runbook
    └── development-status.md  ← detailed phase-by-phase build log

Roadmap

  • βœ… Tier-1 (mandatory) β€” on-chain PolicyVault enforcement proven on casper-test, sealed into a schema-valid artifact.
  • βœ… Live API β€” index.ts assembles IntentRouterDeps via buildApiDeps, so the full intent lifecycle serves over HTTP (see deploy guide).
  • ⏭️ Step-by-step FSM β€” replace the mark-executed demo fast-forward with the full intermediate state walk.
  • ⏭️ Reservation sweeper β€” wire releaseExpired() to a background job so abandoned reservations free budget.
  • ⏭️ Tier-2/3 β€” multi-step yield strategies, more adapters, mainnet hardening.

Where this goes. The primitive Caspilot proves β€” an autonomous agent whose authority is bounded by an on-chain policy it cannot override β€” is the missing trust layer for the agent economy. The same SignerGuard + PolicyVault pattern generalizes directly to the buildathon's DeFi and RWA themes: autonomous treasury management, policy-gated RWA settlement, and machine-to-machine commerce where agents transact continuously but can never exceed the rules their owner deposited on-chain.


Documentation

Demo video

πŸ“Ί Watch the walkthrough (3m44s): youtu.be/cp_SQRvDwEA

A single end-to-end take: drafting a payment intent in the console β†’ policy validation β†’ a human co-sign from the CSPR.click wallet that pays from the user's own funds β†’ the backend independently verifying the deploy on-chain before recording it β†’ the public testnet.cspr.live explorer showing the finalized transfer β†’ two on-chain rejections (User error: 3 / User error: 4) where the vault stops policy-violating payments β†’ the full 788-test suite running green β†’ the open-source repo and architecture.

License

MIT β€” see LICENSE. Open-source and public, as required by the buildathon.

About

Autonomous DeFi agent for Casper with SignerGuard and an on-chain Odra PolicyVault on Casper Testnet

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors