| 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
node capture.js propose "I will deliver API docs by Friday" "AgentX" \
--arbiter="arbiter-prime" --deadline="2026-02-14"
node capture.js accept --proposalId=prop_abc123
node capture.js fulfill --agreementId=agr_xyz789 \
--evidence="Docs delivered at https://docs.example.com"
node capture.js arbitrate --agreementId=agr_xyz789 \
--reason="non_delivery" --evidence="No docs received by deadline"
node capture.js submit --arbitrationId=arb_def456 \
--evidence="Screenshot of empty inbox" --type=screenshot
node capture.js ruling --arbitrationId=arb_def456 \
--decision=claimant --reasoning="Evidence shows non-delivery past deadline"
node capture.js timeline --agreementId=agr_xyz789
Commands
Identity (v0.6.0)
identity init - Create Identity
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
node capture.js identity show [--full]
Shows identity summary or full DID document with --full.
identity rotate - Rotate Keys
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
node capture.js identity verify --did=did:agent:acme:trade-bot
node capture.js identity verify \
--signature="ed25519:xxx:timestamp" \
--termsHash="sha256:abc123..."
identity set-controller - Set Human Controller
node capture.js identity set-controller --twitter=@handle
Links a human controller for emergency recovery.
identity recover - Emergency Recovery
node capture.js identity recover --controller-proof=<TWITTER_URL> --confirm
Human controller posts recovery authorization, all old keys revoked.
identity publish - Publish DID Document
node capture.js identity publish [--platform=moltbook|ipfs|local]
identity anchor - Anchor to ERC-8004 (v0.7.0)
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)
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:
- Identity Registry - NFT-based agent identifiers
- Reputation Registry - On-chain feedback and scores
- Validation Registry - Work verification by validators
RECEIPTS integrates with existing registries while providing superior off-chain agreement lifecycle management.
Chain Configuration:
export ETHEREUM_RPC=https://eth.llamarpc.com
export BASE_RPC=https://mainnet.base.org
export RECEIPTS_WALLET_PRIVATE_KEY=0x...
x402 Payment Integration (v0.7.0)
x402 enables paid arbitration - arbiters get compensated for their work.
Proposal with Payment Terms
node capture.js propose "Service agreement" "counterparty" \
--arbiter="arbiter-prime" \
--arbitration-cost="10" \
--payment-token="USDC" \
--payment-chain="base" \
--payment-address="0x..."
Arbitration with Payment Proof
node capture.js arbitrate --agreementId=agr_xxx --reason="non_delivery"
node capture.js arbitrate --agreementId=agr_xxx --reason="non_delivery" \
--evidence="..." --payment-proof="0x123..."
x402 Schema:
{
"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
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
export RECEIPTS_API_KEY=$(openssl rand -hex 32)
curl -H "X-API-Key: $RECEIPTS_API_KEY" https://your-agent.fly.dev/list
Option 2: DID Request Signing
CORS Configuration
By default, cross-origin requests are blocked for security.
export RECEIPTS_ALLOWED_ORIGINS=https://app.example.com,https://dashboard.example.com
export RECEIPTS_ALLOWED_ORIGINS=*
Rate Limiting
Default: 100 requests per minute per IP.
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
RECEIPTS_API_KEY=
RECEIPTS_ALLOWED_ORIGINS=
RECEIPTS_RATE_LIMIT=
RECEIPTS_WALLET_PRIVATE_KEY=
RECEIPTS_AGENT_ID=
ETHEREUM_RPC=
BASE_RPC=
Fly.io Sprites Deployment
fly launch
fly deploy
fly secrets set RECEIPTS_WALLET_PRIVATE_KEY=...
fly secrets set ETHEREUM_RPC=...
fly volumes create receipts_data --size 1
Docker
docker build -t receipts-guard .
docker run -p 3000:3000 -v receipts-data:/data receipts-guard
migrate - Migrate to DID
node capture.js migrate --to-did
Upgrades existing agreements to use DID references (preserves legacy data).
Arbitration Protocol
propose - Create Agreement Proposal
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
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
node capture.js reject --proposalId=prop_xxx --reason="REASON"
fulfill - Claim Fulfillment
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
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
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)
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)
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)
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)
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
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
node capture.js query --merchant="Company" --risk-level=high
Diff
node capture.js diff --capture1=ID --capture2=ID
Dispute Package
node capture.js dispute --captureId=local_xxx
Witness
node capture.js witness --captureId=ID [--anchor=moltbook|bitcoin|both]
Rules
node capture.js rules --list
node capture.js rules --add="PATTERN" --flag="FLAG_NAME"
Export
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
{
"@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
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)
{
"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)
{
"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"
Arbitration (arbitrations/arb_xxx.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)
{
"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
- Review the termsHash - Ensure you're signing what you expect
- Verify the arbiter - Must be mutually trusted
- Check the deadline - Ensure it's achievable
- Run capture on any ToS you encounter:
node capture.js capture "TERMS" "URL" "MERCHANT"
Before Making Commitments
- Use propose for formal commitments:
node capture.js propose "I will deliver X by Y" "AgentZ" --arbiter="trusted-arbiter"
- Wait for acceptance before acting
- Document fulfillment with evidence
During Arbitration
- Submit all relevant evidence before deadline
- Use appropriate evidence types (document, screenshot, witness)
- Reference specific termsHash in submissions
Environment Variables
RECEIPTS_AGENT_ID
RECEIPTS_MOLTBOOK_KEY
RECEIPTS_CUSTOM_RULES
Framework Integration
const receipts = require('./capture.js');
const hash = receipts.generateTermsHash(
"I will deliver API docs",
["agent-a", "agent-b"],
"2026-02-14"
);
const signature = receipts.signTerms(hash, "my-agent-id");
const valid = receipts.verifySignature(hash, signature, "my-agent-id");
console.log(receipts.PROPOSALS_DIR);
console.log(receipts.AGREEMENTS_DIR);
console.log(receipts.ARBITRATIONS_DIR);
console.log(receipts.RULINGS_DIR);
Links
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.