Wallet-owned spending mandates for AI agents on Casper.
AgentPay lets a wallet owner define which paid services an AI agent may use, its per-action and daily limits, when approval is required, and when authority expires. AI can translate human intent into a draft, but deterministic policy checks make authorization decisions and only the owner wallet can activate authority on Casper.
- Product: https://agentsafe-casper.onrender.com/
- Mandate Workbench: https://agentsafe-casper.onrender.com/dashboard
- Demo video: https://www.youtube.com/watch?v=tiLLEkS7OC4
- Repository: https://github.com/Alike001/agentpay-casper
- MandateGuard installation: https://testnet.cspr.live/transaction/751dd46fe662be6adc9fd862821667306e7d662c7db07114e47228d26e51164d
- Active Testnet mandate: https://testnet.cspr.live/transaction/afe0c811796d1e2b4e779279ab762266b44c630eae7a21261787d0dc030dbdab
- Existing Testnet receipt: https://testnet.cspr.live/transaction/3116400a1250d9bdfd76f7c80a07ec5474f4c48c219c710794cb2f304b79bd86
- Connect and authenticate an owner wallet through the Casper Wallet provider. AgentPay verifies a no-gas Casper Wallet message signature before exposing mandate data or accepting changes.
- Describe the purchasing authority for an agent or enter constraints manually.
- OpenAI produces a structured draft only.
- The deterministic mandate engine validates services, limits, budget, approval threshold, expiry, network, and canonical policy hash.
- The owner reviews and signs an unsigned
MandateGuard::create_mandatetransaction client-side. - An allowed agent action atomically reserves mandate capacity for two minutes before signing or settlement; it is not represented as settled spending.
- The owner can sign an unsigned
MandateGuard::revoke_mandatetransaction to remove authority. - Approved x402 service calls and Casper receipts remain attached to the mandate as evidence.
The backend never receives a wallet private key. An LLM cannot sign, activate a mandate, or override an allow/block decision. A public key in an API request is not treated as ownership proof: protected routes require a short-lived session created from a one-time wallet-signed challenge.
| Capability | Implementation | Status |
|---|---|---|
| Spending mandates | Persistent draft, validation, policy hash, limits, expiry, evaluation, and reason codes | Working |
| AI policy compilation | OpenAI Responses API with strict structured output; deterministic revalidation | Working; provider credits required |
| MCP | Official MCP SDK and stateless Streamable HTTP transport at POST /mcp |
Working |
| Wallet signing | Direct Casper Wallet provider plus optional CSPR.click integration and unsigned Casper transaction builder | Working with Casper Wallet; CSPR.click production app ID remains optional |
| Odra authority | MandateGuard contract with owner, delegate, limits, service, expiry, revocation, and consumption checks |
Deployed on Testnet; a bounded mandate is active |
| Casper x402 | Official @make-software/casper-x402 exact CEP-18 middleware |
Code ready; facilitator and WCSPR configuration required |
| CSPR.cloud | Runtime capability reporting and planned confirmation adapter | API key/integration pending |
| Testnet evidence | Deployed Odra MandateGuard, a real create_mandate call, and historical ReceiptLedger write |
Live |
The interface reports unconfigured integrations honestly. It does not present a draft as active, a submitted transaction as confirmed, or an authorization reservation as a settled payment.
The qualification build deployed ReceiptLedger with Odra and wrote a receipt on Casper Testnet. The final-round build adds a deployed MandateGuard package and a real on-chain spending mandate. Both proof trails remain public and separate.
| Evidence | Value |
|---|---|
| Package hash | hash-aa362adaa1dbb9e67491e25206592104739e760ef754c8314d1b56bdda347833 |
| Deploy transaction | https://testnet.cspr.live/transaction/cd352660b8e2d1de2df2a52a1e043774be139467f0c0ba57b7fc2e9e88b2c411 |
| Receipt transaction | https://testnet.cspr.live/transaction/3116400a1250d9bdfd76f7c80a07ec5474f4c48c219c710794cb2f304b79bd86 |
| Network | casper-test |
Machine-readable evidence is stored in proof/testnet-proof.json.
| Evidence | Value |
|---|---|
| Package hash | hash-eb5d3394550f634cf6c5ad6629a9b75362aea1cc2957319ea92a3eeee41db222 |
| Install transaction | https://testnet.cspr.live/transaction/751dd46fe662be6adc9fd862821667306e7d662c7db07114e47228d26e51164d |
create_mandate transaction |
https://testnet.cspr.live/transaction/afe0c811796d1e2b4e779279ab762266b44c630eae7a21261787d0dc030dbdab |
| Mandate | agentpay-final-round-mandate-001 for rwa-procurement-agent |
| Boundaries | 25 CSPR per action, 50 CSPR daily, owner approval required for agent actions, expires August 22, 2026 |
| Network | casper-test |
Machine-readable evidence is stored in proof/mandate-guard-testnet-proof.json. The public package hash is the default Testnet target, so a fresh AgentPay deployment can build a real unsigned activation transaction without private configuration.
Human intent
|
v
OpenAI draft ------> deterministic mandate validation
|
Owner wallet <--- CSPR.click review and signing
| |
+---- Casper Testnet MandateGuard (Odra)
|
Agent -> MCP tools -> policy decision -> Casper x402 paid API
|
execution + receipt evidence
- Odra:
MandateGuardis the authority boundary;ReceiptLedgerpreserves qualification evidence. - Casper x402: exact CEP-18 settlement adapter for agent-purchased APIs.
- CSPR.click: owner-controlled account selection and client-side signing.
- MCP: typed read and simulation tools; no signing or settlement tool is exposed to the LLM.
- CSPR.cloud: intended for transaction confirmation and indexed receipt reads after credentials are configured.
Casper is fundamental to the product: owner and delegate are Casper identities, activation and revocation are Casper transactions, and public authority/receipt evidence is anchored on Casper Testnet.
Requirements: Node.js 20+, npm, Rust, and the Odra toolchain for contract tests.
npm install
cp .env.example .env.local
npm run green-light
npm run devOpen http://localhost:4173 and http://localhost:4173/dashboard.
The manual mandate path works without an AI provider. MandateGuard is already deployed on Testnet; the direct Casper Wallet provider supports browser-based signing and message authentication without a CSPR.click application ID. Set AGENTPAY_AUTH_SECRET in a durable deployment to retain active sessions across application restarts. x402 settlement remains disabled until its required Testnet configuration is supplied.
Never commit .env.local or private keys. Important variables are documented in .env.example.
Minimum integration variables:
OPENAI_API_KEY
GROQ_API_KEY
CSPR_NODE_URL
CSPR_CLICK_APP_ID
MANDATE_GUARD_PACKAGE_HASH
X402_FACILITATOR_URL
X402_PAYEE_ADDRESS
X402_ASSET_PACKAGE
X402_ASSET_NAME
CSPR_CLOUD_API_KEY
DATABASE_URL
Render web-service files are ephemeral. Set DATABASE_URL to the Internal Database URL of a Render Postgres instance before using the deployed workbench. AgentPay then stores mandates and gateway request records in Postgres; without it, the JSON store is intended only for local development and is erased when Render restarts or redeploys.
| Method | Route | Purpose |
|---|---|---|
GET |
/healthz |
Service and persistence readiness |
GET |
/api/config |
Public capability status, without secrets |
GET/POST |
/api/mandates |
List or create mandate drafts |
POST |
/api/mandates/compile |
Compile human intent into an AI draft |
POST |
/api/mandates/:id/evaluate |
Deterministically evaluate an agent action |
POST |
/api/mandates/:id/transactions/activate |
Build an unsigned Casper transaction |
POST |
/api/mandates/:id/activation-submissions |
Record a submitted transaction as pending |
POST |
/api/mandates/:id/transactions/revoke |
Build an unsigned owner revocation transaction |
POST |
/api/mandates/:id/revocation-submissions |
Record a submitted revocation as pending |
GET |
/api/mandates/:id/executions |
Read mandate decisions and evidence |
POST |
/mcp |
Official MCP Streamable HTTP endpoint |
GET |
/api/x402/rwa-risk-report |
Official Casper x402 protected resource |
GET |
/api/rwa-risk-report |
Preserved qualification-round HTTP 402 route |
apps/api/ Express API, persistence, and static delivery
apps/mcp-server/ Official MCP server and typed tools
apps/web/ Product landing page and Mandate Workbench
contracts/agent-safe-odra/ Odra ReceiptLedger and MandateGuard
packages/ai-policy-compiler/ OpenAI structured policy drafting
packages/casper-transactions/Unsigned Casper transaction construction
packages/casper-x402/ Official Casper x402 middleware adapter
packages/mandate-engine/ Canonical policy and deterministic decisions
packages/mandate-store/ Atomic JSON persistence
tests/ Node unit and integration tests
proof/ Public Casper Testnet evidence
npm run lint
npm run typecheck
npm test
npm run contracts:odra:test
npm run green-light- The LLM is untrusted and receives no private keys.
- Final authorization is deterministic and returns explicit reason codes.
- Wallet signing occurs client-side.
- Idempotency keys and action hashes protect against replay.
- Raw prompts, private service responses, secrets, and PII are not stored on-chain.
- Contract ownership checks protect activation, revocation, and budget consumption.
See SECURITY.md for the full threat model.
AgentPay is a final-round Testnet build. Contracts are unaudited and the product is not suitable for custody or mainnet funds. Casper x402 support is experimental until the facilitator and asset configuration are verified end to end.