Skip to content
SachuJamesPublic

About

Payment rails for AI agents: agent wallets, spending limits, human-in-the-loop approvals, double-entry ledger, and on-chain settlement

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentPay

MIT TypeScript Fastify Solana

Payment rails for AI agents. Give every agent a wallet, enforce spending limits, hold over-limit payments for human approval, and settle on-chain. Every state change is audited, every mutation is idempotent, every webhook is signed.

AgentPay hero

What it does

  • Agent wallets - one wallet per agent, scoped to an API key, with a USD ledger balance plus a Solana address and an EVM address.
  • Spending limits - per-transaction, daily, and weekly caps per wallet. Over-limit payments are automatically held in an approval queue instead of failing.
  • Human-in-the-loop approvals - approve or reject held payments with reason codes. Funds are re-checked at decision time, so money that moved while pending cannot be double-spent. Held payments expire after 24 hours by default (APPROVAL_TTL_MS) instead of waiting forever.
  • Refunds - refund a completed payment in full or in part. Refunds run backwards as their own payment linked to the original, cumulative refunds cannot exceed the original amount, and the recipient's balance is checked first.
  • Wallet freeze - freeze a wallet to stop it sending (and stop its held payments being approved) while still letting it receive. Unfreeze restores normal operation.
  • Double-entry ledger - every payment writes a debit and a credit in one transaction. Conservation is structural, not aspirational. Amounts are integer minor units with checked arithmetic.
  • On-chain settlement - settle a completed ledger payment over Solana as an SPL transfer on a local validator (2-decimal mint, so 1 cent = 1 base unit). EVM settlement is recorded as an honest local record; no chain is attached in this build.
  • Audit log - append-only. No update or delete path exists.
  • Webhooks - HMAC-SHA256 signed deliveries with exponential-backoff retries. Subscriptions can be paused, resumed, and deleted.
  • Statements, limit usage, metrics - per-wallet statement with running balances, live spent/remaining against each cap, and an admin metrics summary (counts by status, completed volume, delivery health).
  • Auth and rate limiting - bearer API keys with scopes (read, wallets:write, payments:write, approvals:write, admin), per-key token-bucket rate limiting.
  • Dashboard - React app for wallets, payments, the approval queue, and the audit log.

Quickstart

Requirements: Node 22+, a local solana-test-validator for the Solana leg of the demo.

# API
cd api && npm install && npm run build

# fresh DB, prints a master key once
DB_PATH=./agentpay.db PORT=8787 node dist/index.js

# Dashboard (dev)
cd dashboard && npm install && npm run dev

The full end-to-end demo (validator, mint, fund, pay, hold, approve, settle on Solana, verify) runs with:

./demo.sh

It prints DEMO RESULT: ALL CHECKS PASSED when every assertion holds.

API sketch

KEY=<master key from first boot>

# agent key with scopes
curl -X POST localhost:8787/v1/api-keys -H "Authorization: Bearer $KEY" \
  -d '{"name":"ops-agent","scopes":["read","wallets:write","payments:write","approvals:write"]}'

# wallets
curl -X POST localhost:8787/v1/wallets -H "Authorization: Bearer $AGENT" \
  -d '{"agent_id":"ops-agent","name":"ops wallet","per_tx_cap":5000,"daily_cap":20000}'

# fund from treasury (dev helper)
curl -X POST localhost:8787/v1/wallets/<id>/fund -H "Authorization: Bearer $AGENT" \
  -d '{"amount":50000}'

# pay (idempotent). 202 + pending_approval when over a limit.
curl -X POST localhost:8787/v1/payments -H "Authorization: Bearer $AGENT" \
  -H 'Idempotency-Key: abc123' \
  -d '{"from_wallet":"<a>","to_wallet":"<b>","amount":3000,"memo":"api credits"}'

# approve / reject
curl -X POST localhost:8787/v1/approvals/<payment_id>/approve -H "Authorization: Bearer $AGENT" \
  -d '{"reason_code":"manager_ok"}'

# refund (full, or pass {"amount": <minor>} for a partial one)
curl -X POST localhost:8787/v1/payments/<payment_id>/refund -H "Authorization: Bearer $AGENT" -d '{}'

# freeze a wallet that is misbehaving, unfreeze when sorted
curl -X POST localhost:8787/v1/wallets/<id>/freeze -H "Authorization: Bearer $AGENT"

# settle a completed payment (needs SETTLEMENT_MINT / SETTLEMENT_PAYER env, see demo.sh)
curl -X POST localhost:8787/v1/payments/<payment_id>/settle -H "Authorization: Bearer $AGENT" \
  -d '{"rail":"solana"}'

Amounts are integer cents. GET /v1/audit streams the audit log; POST /v1/webhooks subscribes a URL to events (payment.completed, payment.pending_approval, payment.rejected, payment.failed, payment.expired, payment.refunded, payment.settled, wallet.created, wallet.frozen, wallet.unfrozen).

Repo layout

api/            Fastify API (TypeScript, SQLite via node:sqlite)
  src/          wallets, payments, approvals, settlement, webhooks, auth, ledger
  test/         vitest suite (39 tests)
  scripts/      solana demo setup
dashboard/      React + Vite dashboard
scripts/        UDP shim for sandboxed validators (see demo.sh)
docs/           ARCHITECTURE.md, hero art
demo.sh         end-to-end demo against a local validator

Honest limits

  • Wallet Solana keys are held server-side for the demo settlement worker. Production would use an HSM or MPC signer, never a database column.
  • EVM settlement writes a local record only; nothing is broadcast to a chain.
  • Rate limiting is in-memory per process; fine for a single instance, not for a fleet.
  • The demo pins the Solana 2.1.x validator because the 4.x validator needs io_uring, which some sandboxes block. On a normal machine any recent validator works.

License

MIT

About

Payment rails for AI agents: agent wallets, spending limits, human-in-the-loop approvals, double-entry ledger, and on-chain settlement

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages