Skill: lazaruseth/receipts-guard (version 0.7.1)

--- 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 | [REDACTED_SECRET] | Live | | Sepolia | [REDACTED_SECRET] | 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-[REDACTED_SECRET]" 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.

path: fly.toml
content: # RECEIPTS Guard - Fly.io Sprites Configuration
# Persistent agent with auto-sleep and fast wake-up

app = "receipts-guard"
primary_region = "iad"

[build]
  dockerfile = "Dockerfile"

# Persistent volume for identity and receipts data
[mounts]
  source = "receipts_data"
  destination = "/data"

[env]
  NODE_ENV = "production"
  RECEIPTS_DATA_DIR = "/data/receipts"

[http_service]
  internal_port = 3000
  force_https = true

  # Fly.io Sprites: auto-stop when idle, auto-start on request
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0

  [http_service.concurrency]
    type = "requests"
    hard_limit = 100
    soft_limit = 50

# Machine configuration for cost efficiency
[vm]
  cpu_kind = "shared"
  cpus = 1
  memory_mb = 256

# Health checks
[[services]]
  internal_port = 3000
  protocol = "tcp"

  [[services.http_checks]]
    interval = "30s"
    grace_period = "10s"
    method = "GET"
    path = "/health"
    protocol = "http"
    timeout = "5s"

# Secrets (set via `fly secrets set KEY=value`)
# RECEIPTS_WALLET_PRIVATE_KEY - For on-chain transactions (encrypted)
# ETHEREUM_RPC - Ethereum RPC endpoint
# BASE_RPC - Base RPC endpoint
# RECEIPTS_MOLTBOOK_KEY - Moltbook API key (optional)


path: package.json
content: {
  "name": "receipts-guard",
  "version": "0.7.1",
  "description": "Agent commerce infrastructure with ERC-8004 identity, x402 payments, and arbitration protocol",
  "main": "capture.js",
  "bin": {
    "receipts": "./capture.js"
  },
  "scripts": {
    "start": "node capture.js",
    "serve": "node capture.js serve",
    "test": "node capture.js identity show"
  },
  "keywords": [
    "ai-agents",
    "erc-8004",
    "x402",
    "arbitration",
    "did",
    "receipts"
  ],
  "author": "Remaster.io",
  "license": "MIT",
  "dependencies": {
    "ethers": "^6.11.0",
    "tweetnacl": "^1.0.3"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)