Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9839106
security: make Casper settlement atomic and fail closed
coinsecuritiescompany Aug 4, 2026
a7120cc
fix: handle Casper account parsing explicitly
coinsecuritiescompany Aug 4, 2026
e4309b1
feat(casper): replace chain-local identity with canonical route settl…
coinsecuritiescompany Aug 16, 2026
01e9fe8
chore(casper): align package version with settlement v3 RC
coinsecuritiescompany Aug 16, 2026
1304892
chore(casper): add quarantined v3 deployment manifest
coinsecuritiescompany Aug 16, 2026
a81ec07
fix(casper): trust only verified v3 deployment manifest
coinsecuritiescompany Aug 16, 2026
c08a70f
fix(casper): verify canonical v3 pay entry point and arguments
coinsecuritiescompany Aug 16, 2026
e11f6c5
test(casper): cover canonical v3 settlement verifier
coinsecuritiescompany Aug 16, 2026
656ffe4
fix(casper): make mainnet deploy script match v3 installer and eviden…
coinsecuritiescompany Aug 16, 2026
1c6e72c
ci(casper): deterministically sync v3 Cargo.lock root package
coinsecuritiescompany Aug 16, 2026
634aac8
chore(casper): sync Cargo.lock for v3 RC
github-actions[bot] Aug 16, 2026
1bd4470
chore(casper): remove one-shot Cargo.lock sync workflow
coinsecuritiescompany Aug 16, 2026
99aa373
test(casper): add pure canonical route economics library
coinsecuritiescompany Aug 16, 2026
57649c5
ci(casper): wire tested economics library into v3 contract once
coinsecuritiescompany Aug 16, 2026
d85ccc3
ci(casper): trigger one-shot economics wiring verifier
coinsecuritiescompany Aug 16, 2026
bfa3db4
style(casper): format canonical economics unit tests
coinsecuritiescompany Aug 16, 2026
f2542ef
fix(casper): wire unit-tested immutable economics into v3 contract
coinsecuritiescompany Aug 16, 2026
5c8d1d2
chore(casper): remove superseded one-shot economics helper
coinsecuritiescompany Aug 16, 2026
1c313bc
ci(casper): run canonical Rust economics tests in release gate
coinsecuritiescompany Aug 16, 2026
d1ddaf9
ci(casper): run economics unit tests on native host target
coinsecuritiescompany Aug 16, 2026
e42d658
ci(casper): apply deterministic rustfmt to v3 wiring once
coinsecuritiescompany Aug 16, 2026
1c3f01b
style(casper): rustfmt v3 economics wiring
github-actions[bot] Aug 16, 2026
d81d425
chore(casper): remove one-shot rustfmt helper
coinsecuritiescompany Aug 16, 2026
7d39021
fix(casper): remove unused route imports from wasm contract
coinsecuritiescompany Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 38 additions & 47 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,77 +19,68 @@ jobs:
name: Contract · build (Wasm)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Install Rust (pinned toolchain)
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2025-02-04
targets: wasm32-unknown-unknown

- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}
run: |
rustup toolchain install nightly-2025-02-04 --profile minimal
rustup target add wasm32-unknown-unknown --toolchain nightly-2025-02-04

- name: Build Wasm (release)
run: cargo build --release
run: cargo +nightly-2025-02-04 build --release --locked --target wasm32-unknown-unknown

- name: Upload contract artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: aifinpay-casper-wasm
path: target/wasm32-unknown-unknown/release/*.wasm
if-no-files-found: warn
if-no-files-found: error

quality:
name: Contract · fmt · clippy (non-blocking)
name: Contract · unit · fmt · clippy
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Install Rust with components
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2025-02-04
components: rustfmt, clippy
targets: wasm32-unknown-unknown
run: |
rustup toolchain install nightly-2025-02-04 --profile minimal --component rustfmt --component clippy
rustup target add wasm32-unknown-unknown --toolchain nightly-2025-02-04
rustup target add x86_64-unknown-linux-gnu --toolchain nightly-2025-02-04

- name: Canonical economics unit tests (native host)
run: cargo +nightly-2025-02-04 test --lib --locked --target x86_64-unknown-linux-gnu

- name: Format check
run: cargo fmt --all -- --check
continue-on-error: true
run: cargo +nightly-2025-02-04 fmt --all -- --check

- name: Clippy
run: cargo clippy --all-targets -- -D warnings
continue-on-error: true
- name: Clippy library (native host)
run: cargo +nightly-2025-02-04 clippy --lib --locked --target x86_64-unknown-linux-gnu -- -D warnings

- name: Clippy Wasm contract
run: cargo +nightly-2025-02-04 clippy --bin aifinpay_casper --target wasm32-unknown-unknown --locked -- -D warnings

demo:
name: Demo / SDK · lint · format (non-blocking)
name: Demo / SDK · tests
runs-on: ubuntu-latest
continue-on-error: true
defaults:
run:
working-directory: demo
steps:
- uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Install dependencies
run: npm install --no-audit --no-fund

- name: Prettier format check
run: npx --yes prettier --check "**/*.{js,mjs,json,md}"
continue-on-error: true

- name: ESLint
run: npx --yes eslint . --ext .js,.mjs
continue-on-error: true
run: npm ci --no-audit --no-fund

- name: Settlement verification tests
run: npm test

- name: Syntax checks
run: |
node --check settlement-verifier.js
node --check trusted-contract.js
node --check compute-bridge.js
node --check agent-compute-demo.js
node --check demo.js
node --check demo-mainnet.js
node --check casper-mcp.mjs
8 changes: 4 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ jobs:
matrix:
language: ["javascript-typescript"]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@e60ea984bd3baa95954f2856bcf24f9eaba46637
with:
language: ${{ matrix.language }}
queries: security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@e60ea984bd3baa95954f2856bcf24f9eaba46637

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@e60ea984bd3baa95954f2856bcf24f9eaba46637
with:
category: "/language:${{ matrix.language }}"
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,32 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [2.0.0] - 2026-08-04

### Security
- Changed `pay_agent` from receipt-only bookkeeping to an atomic native CSPR
transfer followed by an immutable settlement record and event.
- Bound every agent registration to `runtime::get_caller()` and authorize a
payment only when the caller owns `from_agent`; reject zero-value,
self-payment, malformed identifier/wallet, duplicate request and counter
overflow cases.
- Replaced permissive bridge verification with exact, fail-closed checks of
execution success, contract hash, entry point and all quoted payment terms.
- Added request expiry, bounded pending state, replay/in-flight protection and
retry-safe upstream failure handling to the HTTP 402 bridge.
- Quarantined all demo/MCP payment entry points until a complete, reviewed v2
deployment manifest has `status: verified`. Environment variables cannot
override the trusted contract.
- Removed the legacy mainnet demo's second native transfer and require the
provider to self-register with a distinct funded key.

### Tests
- Added 13 Node regression/negative tests for exact settlement verification,
failed/pending deploys, malformed sessions, amount mismatches and deployment
quarantine.
- Made Rust formatting, Clippy, locked Wasm build, artifact presence, Node
tests and syntax checks blocking in CI; pinned third-party GitHub actions.

### Added
- World-class repository structure for the Casper Agentic Buildathon final round:
full README with architecture (Mermaid) and payment-lifecycle diagrams, badges,
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aifinpay-casper"
version = "1.0.0"
version = "3.0.0-rc.1"
edition = "2021"

[[bin]]
Expand Down
34 changes: 18 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Autonomous AI agents need to pay each other and pay for services — compute, da

## Introduction

AiFinPay is payment infrastructure for the machine economy. As autonomous AI agents begin to buy compute, data, and API access on their own, they need a way to **pay and be paid** with a verifiable, non-custodial settlement record. AiFinPay provides that as a protocol layer over [HTTP 402](https://en.wikipedia.org/wiki/HTTP_402) (x402), and **this repository implements the Casper settlement backend**: a Rust → Wasm smart contract that gives every agent an on-chain identity and records every payment permanently.
AiFinPay is payment infrastructure for the machine economy. This repository contains the Casper settlement backend: a Rust → Wasm contract in which agents self-register and `pay_agent` atomically transfers native CSPR before writing an immutable receipt.

## Problem

Expand All @@ -75,14 +75,14 @@ Card rails and custodial wallets assume a human and a browser. Agents need progr
AiFinPay closes the loop:

- **x402 protocol** — a service returns `HTTP 402 Payment Required`; the agent settles on-chain and retries with proof.
- **Casper settlement contract** — agents `register_agent` for an on-chain identity, then `pay_agent` to settle. Every settlement emits a `PaymentSettled` event.
- **Casper settlement contract** — agents self-register an on-chain identity, then `pay_agent` atomically transfers CSPR and emits `PaymentSettled`.
- **Idempotent settlement** — payments are keyed by `request_id`, so retries are safe and double-settlement is impossible.
- **MCP server** — AI agents (e.g. Claude via Claude Code / Claude Desktop) settle on Casper as a native tool call.

## Features

- 🧾 **On-chain agent registry** — `register_agent(agent_id, wallet)` with an `AgentRegistered` event.
- 💸 **Verifiable settlement** — `pay_agent(from, to, amount, request_id)` emits `PaymentSettled`, permanently recorded on Casper.
- 🧾 **Caller-bound registry** — `register_agent(agent_id, wallet)` accepts only the caller's account hash.
- 💸 **Atomic settlement** — `pay_agent(from, to, amount, request_id)` moves CSPR and records the exact terms in one transaction.
- 🔁 **Idempotent by design** — duplicate `request_id` is rejected (no double spend).
- 🌐 **x402 bridge** — a reference compute gate that enforces `HTTP 402` and verifies settlement on-chain before releasing a resource.
- 🤖 **MCP integration** — drive settlements directly from an AI agent runtime.
Expand Down Expand Up @@ -210,7 +210,7 @@ rustup target add wasm32-unknown-unknown
cd demo && npm install && cp .env.example .env
```

Set `CONTRACT_HASH` in `demo/.env` after deploying (or use the live hash below).
Payment clients also require a reviewed `deployments/casper-v2.json`; an environment variable alone cannot enable an unverified contract.

## Local Development

Expand All @@ -231,11 +231,11 @@ make build # target/wasm32-unknown-unknown/release/aifinpay_casper.wasm
make deploy # deploys via demo/deploy.js, prints the new CONTRACT_HASH
```

Save the printed `CONTRACT_HASH` into `demo/.env`. Full walkthrough: [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md).
Do not enable payment routes until the deployed Wasm/source provenance has been independently checked and the v2 manifest is committed with `status: verified`. Full walkthrough: [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md).

## 🟢 Casper Mainnet Deployment
## Historical Casper deployments — quarantined

The settlement contract is **live on Casper Mainnet** — not only testnet. Every entry point below has been exercised on mainnet with real CSPR.
The hashes below are retained as historical evidence only. They are v1 deployments: `pay_agent` recorded an amount but did not transfer it, and a separate transfer produced the old demo balance change. They are not valid payment proof and all current clients reject them.

| Field | Value |
|-------|-------|
Expand All @@ -245,9 +245,9 @@ The settlement contract is **live on Casper Mainnet** — not only testnet. Ever
| **Explorer** | [cspr.live mainnet](https://cspr.live/contract/9903a5e3948e799196df54b17270bc6769338ac1cc36c9eb47e113f88d23f019) |
| **Install deploy** | [`0d560c62…`](https://cspr.live/deploy/0d560c62679d109525ee8b2b1ce1a275cba7deff50a90352f8b4aabf4f070386) |

### Live mainnet settlement (real value moved)
### Historical mainnet demonstration

A full agent-to-agent settlement executed on mainnet — two agents registered, a payment settled on-chain, and real CSPR delivered to the provider's wallet:
The following two independent operations were previously described as one settlement. The contract call recorded a receipt; the later native transfer moved value.

| Action | Deploy | Explorer |
|--------|--------|----------|
Expand All @@ -256,9 +256,9 @@ A full agent-to-agent settlement executed on mainnet — two agents registered,
| **PaymentSettled** (`pay_agent`) | `80df5895…` | [view](https://cspr.live/deploy/80df58959f81d99d717027cdc069e95a3464d867150184b0f05312de6c6eb6d7) |
| Value transfer (2.5 CSPR → provider) | `564f19be…` | [view](https://cspr.live/deploy/564f19be2c89140a6dda9e97e4440d49890cf8df5b678b00bd0c625c6d975f3a) |

Reproduce on mainnet with a funded key at `demo/keys-mainnet/secret_key.pem`: `node demo/deploy-mainnet.js` then `node demo/demo-mainnet.js`.
Do not reproduce this v1 flow. The v2 mainnet script requires separately controlled buyer/provider keys and performs no second transfer.

## Casper Testnet Deployment
## Historical Casper Testnet Deployment

| Field | Value |
|-------|-------|
Expand All @@ -271,8 +271,8 @@ Reproduce on mainnet with a funded key at `demo/keys-mainnet/secret_key.pem`: `n

| Entry Point | Args | Description |
|-------------|------|-------------|
| `register_agent` | `agent_id: String, wallet: String` | Register an AI agent on-chain → `AgentRegistered` |
| `pay_agent` | `from_agent: String, to_agent: String, amount: U512, request_id: String` | Settle a payment → `PaymentSettled` |
| `register_agent` | `agent_id: String, wallet: String` | Self-register caller wallet → `AgentRegistered` |
| `pay_agent` | `from_agent: String, to_agent: String, amount: U512, request_id: String` | Transfer CSPR and record settlement → `PaymentSettled` |
| `get_payment_count` | — | Total settled payments |

### Events
Expand All @@ -290,7 +290,7 @@ hash-47df409829ddf0612617460293ba591a19b26fa0c06918878204088d3eb9b78a

## Sample Transactions

Real transactions from the agent-compute demo on `casper-test`:
Historical v1 transactions from the agent-compute demo on `casper-test` (not valid settlement proof):

| Action | Deploy | Explorer |
|--------|--------|----------|
Expand Down Expand Up @@ -321,7 +321,9 @@ Configure in `demo/.env` (see [`demo/.env.example`](demo/.env.example)):
| `NODE_URL` | `https://node.testnet.casper.network/rpc` | Casper RPC endpoint |
| `NETWORK_NAME` | `casper-test` | Casper network name |
| `KEYS_DIR` | `./keys` | Directory holding the signing key |
| `CONTRACT_HASH` | — | Deployed contract hash (`hash-…`) |
| `CONTRACT_HASH` | — | Must match the verified v2 deployment manifest |
| `PROVIDER_AGENT_ID` | — | Merchant identity self-registered by its own wallet |
| `PROVIDER_KEYS_DIR` | — | Separate funded merchant key for two-party demos only |
| `COMPUTE_UPSTREAM_URL` | _(optional)_ | Real OpenAI-compatible compute endpoint |
| `COMPUTE_API_KEY` | _(optional)_ | API key for the upstream provider |

Expand Down
11 changes: 10 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

| Version | Supported | Network |
|---------|-----------|---------|
| 1.x | ✅ | Casper Testnet (`casper-test`) |
| 2.x | Source fixed; not deployed | None until manifest verification |
| 1.x | ❌ vulnerable / quarantined | Historical testnet and mainnet deployments |

See [SUPPORTED.md](SUPPORTED.md) for the full support matrix.

Expand Down Expand Up @@ -44,3 +45,11 @@ the public Casper testnet infrastructure.
This repository runs **CodeQL** static analysis, **Dependabot** dependency
alerts and updates, and **secret scanning with push protection**. All High or
greater severity alerts are triaged and resolved before release.

## Deployment safety state

Version 1.x recorded a settlement without transferring CSPR and did not bind
the claimed payer or registered wallet to the caller. It must not be used as a
payment proof. Version 2.0 fixes these defects in source, but clients remain
fail-closed until `deployments/casper-v2.json` contains independently checked
deployment, bytecode and source provenance with `status: verified`.
7 changes: 4 additions & 3 deletions SUPPORTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

| Version | Status | Notes |
|---------|-------------|-------|
| 1.x | ✅ Active | Current line. Bug fixes + security patches. |
| 2.x | Source candidate | Payment routes stay quarantined until verified deployment. |
| 1.x | ❌ Unsupported | Receipt-only settlement and missing caller binding. |

## Networks

| Network | Chain name | Status | Contract |
|----------------------------|---------------|----------------|----------|
| Casper Testnet | `casper-test` | ✅ Live | `hash-47df409829ddf0612617460293ba591a19b26fa0c06918878204088d3eb9b78a` |
| Casper Mainnet | `casper` | 🔜 Planned | — |
| Casper Testnet | `casper-test` | ⚠️ Legacy v1 only | Quarantined |
| Casper Mainnet | `casper` | ⚠️ Legacy v1 only | Quarantined |

## Toolchain

Expand Down
7 changes: 7 additions & 0 deletions demo/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
NODE_URL=https://node.testnet.casper.network/rpc
NETWORK_NAME=casper-test
KEYS_DIR=./keys
# Separately controlled, funded merchant account used by demo.js.
PROVIDER_KEYS_DIR=./provider-keys
# Set after deployment:
CONTRACT_HASH=hash-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Merchant identity, registered on-chain by the merchant's own account.
PROVIDER_AGENT_ID=aifinpay-compute-provider
PRICE_MOTES=100000000
ORDER_TTL_MS=600000
MAX_PENDING_ORDERS=10000
Loading
Loading