---
name: receipts-guard
description: ERC-8004 identity, x402 payments, and arbitration protocol for autonomous agent commerce. The three rails for the machine economy.
metadata: {"openclaw":{"emoji":"⚖️","requires":{"anyBins":["node"]},"version":"0.7.1"}}
---

# 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.
