OpenClaw Capture
The OpenClaw adapter provides a one-call setup for capturing interaction evidence. It combines the capture pipeline -- spool store, deduplication index, export, and query -- into a single activate() call.
Install
pnpm add @peac/adapter-openclaw @peac/capture-core @peac/capture-node
Quick start
import { activate } from '@peac/adapter-openclaw';
const claw = await activate({
privateKey: process.env.PEAC_PRIVATE_KEY,
kid: 'peac-2026-02',
issuer: 'https://api.example.com',
});
// Capture an interaction
await claw.capture({
type: 'api.request',
subject: 'user:agent-123',
status: 'executed',
metadata: {
path: '/api/data',
method: 'GET',
statusCode: 200,
},
});
A single activate() call configures Ed25519 signing, spool store buffering, deduplication indexing, and the export pipeline. No manual wiring required.
Key generation
Generate an Ed25519 keypair for receipt signing:
npx peac-keygen
Private key (keep secret):
<base64url-encoded-private-key>
Public key (publish at .well-known/peac-issuer.json):
{
"kty": "OKP",
"crv": "Ed25519",
"use": "sig",
"kid": "peac-2026-02",
"x": "<base64url-encoded-public-key>",
"alg": "EdDSA"
}
Set the private key as PEAC_PRIVATE_KEY in your environment. Publish the public key JSON at your issuer's /.well-known/peac-issuer.json endpoint.
Capture stores
In-memory
In-memory stores do not survive process restarts. Use file-system stores for production workloads.
import { MemorySpoolStore, MemoryDedupeIndex } from '@peac/capture-core';
const store = new MemorySpoolStore();
const index = new MemoryDedupeIndex();
File-system
import { FileSpoolStore, FileDedupeIndex } from '@peac/capture-node';
const store = new FileSpoolStore({ dir: './spool' });
const index = new FileDedupeIndex({ path: './dedupe.json' });
File-system stores provide:
- Durable persistence -- survives process restarts and deployments
- Atomic writes -- no partial writes on crash or power loss
- Deduplication -- prevents duplicate captures for the same interaction
Pass custom stores to activate() via the spoolStore and dedupeIndex options.
Export
Export captured receipts as an evidence bundle (.peac.tar.gz):
const result = await claw.export({
output: './evidence.peac.tar.gz',
since: new Date('2026-02-01'),
});
console.log(result.counters);
{ "scanned": 150, "exported": 148, "skipped": 2 }
The structured counters give you a precise breakdown: how many receipts were scanned from the spool, how many made it into the bundle, and how many were skipped (duplicates or invalid).
Query
Query the capture store for receipts matching specific criteria:
const receipts = await claw.query({
since: new Date('2026-02-19'),
type: 'api.request',
limit: 100,
});
console.log(receipts.counters);
// { scanned: 500, exported: 100, skipped: 0 }
Configuration
Required options
| Option | Type | Description |
|---|---|---|
privateKey | string | Ed25519 private key (base64url or hex encoded) |
kid | string | Key ID -- must match your published JWKS |
issuer | string | Issuer URL (becomes the iss claim) |
Optional options
| Option | Type | Default | Description |
|---|---|---|---|
spoolStore | SpoolStore | MemorySpoolStore | Custom spool store for receipt buffering |
dedupeIndex | DedupeIndex | MemoryDedupeIndex | Custom deduplication index |
attestationType | string | 'interaction' | Default attestation type for captures |