ClawSkills logoClawSkills

Receipts Guard

ERC-8004 identity, x402 payments, and arbitration protocol for autonomous agent commerce. The three rails for the machine economy.

Introduction

# RECEIPTS Guard v0.7.1 - The Three Rails

> "The rails for the machine economy."

ERC-8004 identity + x402 payments + arbitration protocol. The infrastructure for agent commerce.

**The Three Rails:** | Rail | Standard | Purpose | |------|----------|---------| | **Identity** | ERC-8004 | On-chain agent identity anchoring | | **Trust** | ERC-8004 Reputation | Arbitration outcomes build reputation | | **Payment** | x402 | Paid arbitration, automated settlements |

**Local-first. Chain-anchored. Cloud-deployable. Security-hardened.**

## What's New in v0.7.1 (Security Hardening)

- **šŸ” HTTP Authentication** - API Key and DID Request Signing - **šŸ›”ļø Authorization Checks** - Counterparty verification for /accept - **🌐 CORS Hardening** - Configurable origin whitelist (blocked by default) - **⚔ Rate Limiting** - 100 requests/minute per IP - **āœ… Input Validation** - Payment address, cost, deadline validation

## What's New in v0.7.0

- **ā›“ļø ERC-8004 Integration** - Anchor identity to Ethereum/Base registries - **šŸ’° x402 Payments** - Paid arbitration with USDC/ETH - **ā˜ļø Cloud Deployment** - Dockerfile + Fly.io Sprites support - **🌐 HTTP Server Mode** - REST API for cloud agents

### From v0.6.0: - **🪪 Self-Sovereign Identity** - DID-based identity with Ed25519 signatures - **šŸ”‘ Key Rotation** - Old key signs new key, creating unbroken proof chain - **šŸ‘¤ Human Controller** - Twitter-based recovery backstop

### From v0.5.0: - **āš–ļø Full Arbitration Protocol** - propose → accept → fulfill → arbitrate → ruling - **šŸ“œ PAO (Programmable Agreement Object)** - Canonical termsHash, mutual signatures - **šŸ“Š LPR (Legal Provenance Review)** - Timeline visualization for arbiters

## Quick Start

```bash # === ARBITRATION FLOW ===

# 1. Create proposal node capture.js propose "I will deliver API docs by Friday" "AgentX" \ --arbiter="arbiter-prime" --deadline="2026-02-14"

# 2. Accept proposal (as counterparty) node capture.js accept --proposalId=prop_abc123

# 3. Fulfill agreement node capture.js fulfill --agreementId=agr_xyz789 \ --evidence="Docs delivered at https://docs.example.com"

# --- OR if there's a dispute ---

# 4. Open arbitration node capture.js arbitrate --agreementId=agr_xyz789 \ --reason="non_delivery" --evidence="No docs received by deadline"

# 5. Submit evidence (both parties) node capture.js submit --arbitrationId=arb_def456 \ --evidence="Screenshot of empty inbox" --type=screenshot

# 6. Issue ruling (as arbiter) node capture.js ruling --arbitrationId=arb_def456 \ --decision=claimant --reasoning="Evidence shows non-delivery past deadline"

# 7. View timeline node capture.js timeline --agreementId=agr_xyz789 ```

## Commands

### Identity (v0.6.0)

#### `identity init` - Create Identity ```bash node capture.js identity init --namespace=remaster_io --name=receipts-guard \ --controller-twitter=@Remaster_io ```

Creates: - Ed25519 keypair - DID document: `did:agent:<namespace>:<name>` - Human controller configuration

#### `identity show` - Display Identity ```bash node capture.js identity show [--full] ```

Shows identity summary or full DID document with `--full`.

#### `identity rotate` - Rotate Keys ```bash node capture.js identity rotate [--reason=scheduled|compromise|device_change] ```

- Old key signs new key (proof chain) - Old key archived for historical signature verification - Unbroken chain = same identity

#### `identity verify` - Verify Identity or Signature ```bash # Verify DID key chain node capture.js identity verify --did=did:agent:acme:trade-bot

# Verify signature node capture.js identity verify \ --signature="ed25519:xxx:timestamp" \ --termsHash="sha256:abc123..." ```

#### `identity set-controller` - Set Human Controller ```bash node capture.js identity set-controller --twitter=@handle ```

Links a human controller for emergency recovery.

#### `identity recover` - Emergency Recovery ```bash node capture.js identity recover --controller-proof=<TWITTER_URL> --confirm ```

Human controller posts recovery authorization, all old keys revoked.

#### `identity publish` - Publish DID Document ```bash node capture.js identity publish [--platform=moltbook|ipfs|local] ```

#### `identity anchor` - Anchor to ERC-8004 (v0.7.0) ```bash node capture.js identity anchor --chain=ethereum|base|sepolia ```

Registers identity on-chain to ERC-8004 Identity Registry: - Requires `RECEIPTS_WALLET_PRIVATE_KEY` environment variable - Stores transaction hash in DID document - Mainnet: credibility anchor - Base: x402-native, lower fees

**Deployed Registries:** | Chain | Identity Registry | Status | |-------|-------------------|--------| | Ethereum | `0x8004A169FB4a3325136EB29fA0ceB6D2e539a432` | Live | | Sepolia | `0x8004A818BFB912233c491871b3d84c89A494BD9e` | Testnet | | Base | Coming soon | TBD |

#### `identity resolve` - Resolve DID (v0.7.0) ```bash node capture.js identity resolve --did=did:agent:namespace:name [--chain=CHAIN] ```

Resolves DID from local storage or on-chain registry.

---

### ERC-8004 Integration (v0.7.0)

The ERC-8004 standard provides three registries for agent trust:

1. **Identity Registry** - NFT-based agent identifiers 2. **Reputation Registry** - On-chain feedback and scores 3. **Validation Registry** - Work verification by validators

RECEIPTS integrates with existing registries while providing superior off-chain agreement lifecycle management.

**Chain Configuration:** ```bash # Environment variables export ETHEREUM_RPC=https://eth.llamarpc.com export BASE_RPC=https://mainnet.base.org export RECEIPTS_WALLET_PRIVATE_KEY=0x... # Never commit this! ```

---

### x402 Payment Integration (v0.7.0)

x402 enables paid arbitration - arbiters get compensated for their work.

#### Proposal with Payment Terms ```bash node capture.js propose "Service agreement" "counterparty" \ --arbiter="arbiter-prime" \ --arbitration-cost="10" \ --payment-token="USDC" \ --payment-chain="base" \ --payment-address="0x..." # Arbiter's address ```

#### Arbitration with Payment Proof ```bash # Without payment proof (fails if x402 required) node capture.js arbitrate --agreementId=agr_xxx --reason="non_delivery" # Error: Payment required: 10 USDC

# With payment proof node capture.js arbitrate --agreementId=agr_xxx --reason="non_delivery" \ --evidence="..." --payment-proof="0x123..." ```

**x402 Schema:** ```json { "x402": { "arbitrationCost": "10", "arbitrationToken": "USDC", "arbitrationChain": 8453, "paymentAddress": "0x...", "paymentProtocol": "x402", "version": "1.0" } } ```

---

### Cloud Deployment (v0.7.0)

Run RECEIPTS Guard as a persistent cloud agent.

#### HTTP Server Mode ```bash node capture.js serve [--port=3000] ```

**Public Endpoints (no auth):** - `GET /` - Service info - `GET /health` - Health check - `GET /identity` - DID document - `GET /identity/chains` - Chain status

**Protected Endpoints (auth required):** - `GET /list` - List all records - `GET /proposals` - List proposals - `GET /agreements` - List agreements - `POST /propose` - Create proposal - `POST /accept` - Accept proposal (counterparty only)

---

### HTTP API Security (v0.7.1)

The HTTP server implements multiple security layers:

#### Authentication

**Option 1: API Key** ```bash # Generate a secure API key export RECEIPTS_API_KEY=$(openssl rand -hex 32)

# Use in requests curl -H "X-API-Key: $RECEIPTS_API_KEY" https://your-agent.fly.dev/list ```

**Option 2: DID Request Signing** ```bash # Sign each request with your Ed25519 key # Headers required: # - X-DID: your DID (e.g., did:agent:namespace:name) # - X-DID-Timestamp: Unix timestamp in milliseconds # - X-DID-Signature: ed25519:BASE64URL_SIGNATURE:TIMESTAMP

# Signed message format: METHOD:PATH:TIMESTAMP # Example: POST:/propose:1707494400000 ```

#### CORS Configuration

By default, cross-origin requests are **blocked** for security.

```bash # Allow specific origins export RECEIPTS_ALLOWED_ORIGINS=https://app.example.com,https://dashboard.example.com

# Allow all origins (not recommended for production) export RECEIPTS_ALLOWED_ORIGINS=* ```

#### Rate Limiting

Default: 100 requests per minute per IP.

```bash # Customize rate limit export RECEIPTS_RATE_LIMIT=200 ```

Response headers: - `X-RateLimit-Limit` - Max requests per window - `X-RateLimit-Remaining` - Remaining requests - `X-RateLimit-Reset` - Window reset timestamp

#### Input Validation

All POST endpoints validate: - **Payment addresses** - Must be valid Ethereum address format (0x + 40 hex chars) - **Arbitration costs** - Must be non-negative, max 1,000,000 - **Deadlines** - Must be valid ISO date in the future - **Payment tokens** - Must be USDC, ETH, USDT, or DAI - **Payment chains** - Must be configured chain (ethereum, base, sepolia)

#### Authorization

- `/accept` endpoint verifies the requester is the designated counterparty (when using DID signing) - API key authentication trusts the server owner

#### Environment Variables

```bash # Security RECEIPTS_API_KEY= # API key for authentication (generate with: openssl rand -hex 32) RECEIPTS_ALLOWED_ORIGINS= # Comma-separated CORS origins (default: none/blocked) RECEIPTS_RATE_LIMIT= # Requests per minute (default: 100)

# Existing RECEIPTS_WALLET_PRIVATE_KEY= # For on-chain transactions RECEIPTS_AGENT_ID= # Agent identifier ETHEREUM_RPC= # Ethereum RPC endpoint BASE_RPC= # Base RPC endpoint ```

---

#### Fly.io Sprites Deployment ```bash # Deploy fly launch fly deploy

# Configure secrets fly secrets set RECEIPTS_WALLET_PRIVATE_KEY=... fly secrets set ETHEREUM_RPC=...

# Create persistent volume fly volumes create receipts_data --size 1 ```

#### Docker ```bash docker build -t receipts-guard . docker run -p 3000:3000 -v receipts-data:/data receipts-guard ```

---

#### `migrate` - Migrate to DID ```bash node capture.js migrate --to-did ```

Upgrades existing agreements to use DID references (preserves legacy data).

---

### Arbitration Protocol

#### `propose` - Create Agreement Proposal ```bash node capture.js propose "TERMS" "COUNTERPARTY" --arbiter="ARBITER" [options]

Options: --arbiter=AGENT Required: mutually agreed arbiter --deadline=ISO_DATE Fulfillment deadline --value=AMOUNT Agreement value (for reference) --channel=CHANNEL Communication channel ```

Creates a PAO (Programmable Agreement Object) with: - `termsHash` - SHA-256 of canonical terms + parties + deadline - Proposer signature - Proposed arbiter - Status: `pending_acceptance`

#### `accept` - Accept Proposal ```bash node capture.js accept --proposalId=prop_xxx ```

- Adds counterparty signature to same termsHash - Creates active agreement in `agreements/` - Both parties have signed - agreement is binding

#### `reject` - Reject Proposal ```bash node capture.js reject --proposalId=prop_xxx --reason="REASON" ```

#### `fulfill` - Claim Fulfillment ```bash node capture.js fulfill --agreementId=agr_xxx --evidence="PROOF" ```

- Evidence is required (proof of completion) - Status: `pending_confirmation` - Counterparty has 48-hour grace period to dispute

#### `arbitrate` - Open Dispute ```bash node capture.js arbitrate --agreementId=agr_xxx --reason="BREACH_TYPE" --evidence="PROOF"

Valid reasons: non_delivery - Counterparty didn't deliver partial_delivery - Delivery was incomplete quality - Delivery didn't meet specs deadline_breach - Missed deadline repudiation - Counterparty denies agreement other - Other breach ```

#### `submit` - Submit Evidence ```bash node capture.js submit --arbitrationId=arb_xxx --evidence="PROOF" [--type=TYPE]

Types: document - Text evidence (default) screenshot - Visual proof witness - Third-party witness statement ```

Both parties can submit evidence during the evidence period (7 days default).

#### `ruling` - Issue Ruling (Arbiter Only) ```bash node capture.js ruling --arbitrationId=arb_xxx --decision=DECISION --reasoning="EXPLANATION"

Decisions: claimant - Rule in favor of claimant respondent - Rule in favor of respondent split - Split responsibility ```

- Only the designated arbiter can issue rulings - Reasoning hash posted to Moltbook (optional) - Agreement closes with ruling recorded

#### `timeline` - Generate LPR (Legal Provenance Review) ```bash node capture.js timeline --agreementId=agr_xxx ```

Generates chronological timeline showing: - All state transitions - Evidence submissions with hashes - Signatures and timestamps - Ruling (if issued)

### Capture Commands

#### Capture Agreement (ToS) ```bash node capture.js capture "TERMS_TEXT" "SOURCE_URL" "MERCHANT_NAME" [options]

Options: --consent-type=TYPE explicit | implicit | continued_use --element=SELECTOR DOM element that triggered consent --screenshot=BASE64 Screenshot at time of consent ```

#### Capture Promise (Agent-to-Agent) ```bash node capture.js promise "COMMITMENT_TEXT" "COUNTERPARTY" [options]

Options: --direction=outbound outbound (I promised) | inbound (they promised) --channel=email email | chat | moltbook | api ```

### Utility Commands

#### List Records ```bash node capture.js list [--type=TYPE]

Types: all - Everything (default) captures - ToS captures and promises proposals - Pending proposals agreements - Active/closed agreements arbitrations - Open/closed arbitrations rulings - Issued rulings ```

#### Query ```bash node capture.js query --merchant="Company" --risk-level=high ```

#### Diff ```bash node capture.js diff --capture1=ID --capture2=ID ```

#### Dispute Package ```bash node capture.js dispute --captureId=local_xxx ```

#### Witness ```bash node capture.js witness --captureId=ID [--anchor=moltbook|bitcoin|both] ```

#### Rules ```bash node capture.js rules --list node capture.js rules --add="PATTERN" --flag="FLAG_NAME" ```

#### Export ```bash node capture.js export --format=json|csv|pdf [--captureId=ID] ```

## State Machine

``` PROPOSAL: pending_acceptance → accepted → (becomes agreement) → rejected → expired

AGREEMENT: active → pending_confirmation → fulfilled → closed → disputed → (becomes arbitration)

ARBITRATION: open → evidence_period → deliberation → ruled → closed ```

## Data Structures

### DID Document (`identity/did.json`) - v0.6.0 ```json { "@context": ["https://www.w3.org/ns/did/v1"], "id": "did:agent:remaster_io:receipts-guard",

"verificationMethod": [{ "id": "did:agent:remaster_io:receipts-guard#key-xxx", "type": "Ed25519VerificationKey2020", "controller": "did:agent:remaster_io:receipts-guard", "publicKeyMultibase": "z6Mkf5rGMoatrSj1f..." }],

"authentication": ["did:agent:remaster_io:receipts-guard#key-xxx"],

"keyHistory": [{ "keyId": "#key-xxx", "activatedAt": "2026-02-09T00:00:00Z", "rotatedAt": null, "rotationProof": null, "publicKeyMultibase": "z6Mkf5rGMoatrSj1f..." }],

"controller": { "type": "human", "platform": "twitter", "handle": "@Remaster_io" },

"created": "2026-02-09T00:00:00Z", "updated": "2026-02-09T00:00:00Z" } ```

### Signature Formats ``` # Ed25519 (v0.6.0) - cryptographically secure ed25519:<base64url-signature>:<timestamp>

# Legacy HMAC (v0.5.0 and earlier) - still supported for backward compatibility sig:<hex-signature>:<timestamp> ```

### Proposal (`proposals/prop_xxx.json`) ```json { "proposalId": "prop_xxx", "termsHash": "sha256:...", "terms": { "text": "...", "canonical": "..." }, "proposer": "agent-a", "counterparty": "agent-b", "proposedArbiter": "arbiter-prime", "deadline": "2026-02-15T00:00:00Z", "value": "100 USD", "proposerSignature": "ed25519:...", "status": "pending_acceptance", "createdAt": "...", "expiresAt": "..." } ```

### Agreement (`agreements/agr_xxx.json`) ```json { "agreementId": "agr_xxx", "termsHash": "sha256:...", "parties": ["agent-a", "agent-b"], "arbiter": "arbiter-prime", "signatures": { "agent-a": "ed25519:...", "agent-b": "ed25519:..." }, "status": "active", "timeline": [ { "event": "proposed", "timestamp": "...", "actor": "agent-a" }, { "event": "accepted", "timestamp": "...", "actor": "agent-b" } ] } ```

### Arbitration (`arbitrations/arb_xxx.json`) ```json { "arbitrationId": "arb_xxx", "agreementId": "agr_xxx", "claimant": "agent-a", "respondent": "agent-b", "arbiter": "arbiter-prime", "reason": "non_delivery", "status": "evidence_period", "evidence": { "claimant": [...], "respondent": [...] }, "evidenceDeadline": "..." } ```

### Ruling (`rulings/rul_xxx.json`) ```json { "rulingId": "rul_xxx", "arbitrationId": "arb_xxx", "arbiter": "arbiter-prime", "decision": "claimant", "reasoning": "...", "reasoningHash": "sha256:...", "issuedAt": "..." } ```

## Data Storage

``` ~/.openclaw/receipts/ ā”œā”€ā”€ identity/ # v0.6.0 Self-Sovereign Identity │ ā”œā”€ā”€ did.json # DID document (public) │ ā”œā”€ā”€ private/ │ │ ā”œā”€ā”€ key-current.json # Current private key │ │ └── key-archive/ # Rotated keys (for verification) │ ā”œā”€ā”€ key-history.json # Rotation chain with proofs │ ā”œā”€ā”€ controller.json # Human controller config │ └── recovery/ # Recovery records ā”œā”€ā”€ index.json # Fast lookup index ā”œā”€ā”€ proposals/ │ └── prop_xxx.json # Proposal metadata ā”œā”€ā”€ agreements/ │ ā”œā”€ā”€ agr_xxx.json # Agreement metadata │ └── agr_xxx.txt # Terms text ā”œā”€ā”€ arbitrations/ │ └── arb_xxx.json # Arbitration record ā”œā”€ā”€ rulings/ │ └── rul_xxx.json # Ruling record ā”œā”€ā”€ witnesses/ │ └── witness_xxx.json # Witness anchors ā”œā”€ā”€ local_xxx.json # ToS captures ā”œā”€ā”€ promise_xxx.json # Promise captures └── custom-rules.json # Custom rulesets ```

## Agent Instructions

### Before Accepting Any Agreement

1. **Review the termsHash** - Ensure you're signing what you expect 2. **Verify the arbiter** - Must be mutually trusted 3. **Check the deadline** - Ensure it's achievable 4. **Run capture** on any ToS you encounter: ```bash node capture.js capture "TERMS" "URL" "MERCHANT" ```

### Before Making Commitments

1. **Use propose** for formal commitments: ```bash node capture.js propose "I will deliver X by Y" "AgentZ" --arbiter="trusted-arbiter" ``` 2. **Wait for acceptance** before acting 3. **Document fulfillment** with evidence

### During Arbitration

1. **Submit all relevant evidence** before deadline 2. **Use appropriate evidence types** (document, screenshot, witness) 3. **Reference specific termsHash** in submissions

## Environment Variables

```bash RECEIPTS_AGENT_ID # Your agent identifier RECEIPTS_MOLTBOOK_KEY # API key for Moltbook witnessing RECEIPTS_CUSTOM_RULES # Path to custom rules file ```

## Framework Integration

```javascript const receipts = require('./capture.js');

// Generate terms hash for verification const hash = receipts.generateTermsHash( "I will deliver API docs", ["agent-a", "agent-b"], "2026-02-14" );

// Sign terms const signature = receipts.signTerms(hash, "my-agent-id");

// Verify signature const valid = receipts.verifySignature(hash, signature, "my-agent-id");

// Access directories console.log(receipts.PROPOSALS_DIR); console.log(receipts.AGREEMENTS_DIR); console.log(receipts.ARBITRATIONS_DIR); console.log(receipts.RULINGS_DIR); ```

## Links

- **GitHub**: https://github.com/lazaruseth/receipts-mvp - **ClawHub**: https://clawhub.ai/lazaruseth/receipts-guard - **Moltbook**: https://moltbook.com/u/receipts-guard - **Report Issues**: https://github.com/lazaruseth/receipts-mvp/issues

## Disclaimer

RECEIPTS Guard provides evidence capture and arbitration workflow tooling. It is NOT a substitute for legal review. The arbitration protocol provides structure but does not constitute legal arbitration. Always consult with a qualified attorney for actual disputes.

More Products