Reference Node.js runtime for CommandLayer Commons verbs. This service executes deterministic verb handlers, signs receipts with Ed25519, and verifies receipts using local keys or ENS-discovered public keys.
- Exposes
POST /<verb>/v1.0.0endpoints for Commons verbs (fetch,describe,format,clean,parse,summarize,convert,explain,analyze,classify). - Returns signed receipts containing:
- deterministic result payloads,
- execution trace metadata,
- proof metadata (
alg, canonical mode, SHA-256 hash, signature).
- Exposes
POST /verifyto verify receipt hash/signature, and optionally validate schema + fetch public key from ENS. - Includes schema validator caching, warmup queueing, SSRF protections for
fetch, and runtime safety budgets.
GET /— service index with links and enabled verbs.GET /health— process/service health and signer readiness.POST /<verb>/v1.0.0— execute a single verb and return a signed receipt.POST /verify— verify receipt integrity/signature; optional schema and ENS verification.
GET /debug/env— effective runtime configuration.GET /debug/enskey— ENS TXT key discovery state.GET /debug/schemafetch?verb=<verb>— computed receipt schema URL.GET /debug/validators— validator cache and warm-queue state.POST /debug/prewarm— queue schema validator warmup.
npm installopenssl genpkey -algorithm Ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem
export RECEIPT_SIGNING_PRIVATE_KEY_PEM_B64="$(base64 -w0 < private.pem)"
export RECEIPT_SIGNING_PUBLIC_KEY="ed25519:$(openssl pkey -in public.pem -pubin -outform DER | tail -c 32 | base64 -w0)"
export RECEIPT_SIGNER_ID="runtime.local"macOS note: replace
base64 -w0withbase64 | tr -d '\n'.
npm startDefault port is 8080 (override with PORT).
curl -s http://localhost:8080/health | jq .You should see "ok": true and "signer_ok": true.
RECEIPT=$(curl -s -X POST "http://localhost:8080/fetch/v1.0.0" \
-H "Content-Type: application/json" \
-d '{
"x402": {
"entry": "x402://fetchagent.eth/fetch/v1.0.0",
"verb": "fetch",
"version": "1.0.0"
},
"source": "https://example.com"
}')
printf '%s\n' "$RECEIPT" | jq .printf '%s' "$RECEIPT" | curl -s -X POST "http://localhost:8080/verify" \
-H "Content-Type: application/json" \
-d @- | jq .printf '%s' "$RECEIPT" | curl -s -X POST "http://localhost:8080/verify?ens=1" \
-H "Content-Type: application/json" \
-d @- | jq .POST /verify supports query flags:
ens=1— fetch verifier pubkey from ENS TXT records (VERIFIER_ENS_NAME,cl.receipt.signer,cl.sig.pub,cl.sig.kid).refresh=1— bypass ENS cache and refresh lookup.schema=1— validate receipt against verb schema.
When VERIFY_SCHEMA_CACHED_ONLY=1 (default), schema validation is edge-safe:
- if validator is warm: request is fully validated,
- if validator is cold: service returns
202withvalidator_not_warmed_yetand queues async prewarm.
Use POST /debug/prewarm and GET /debug/validators for schema prewarming workflows.
Detailed environment variable documentation lives in docs/CONFIGURATION.md.
fetchonly allowshttp(s)URLs.- SSRF guard blocks localhost/private IP ranges and DNS resolutions to private ranges.
- Optional host allowlist (
ALLOW_FETCH_HOSTS) can strictly bound outboundfetch. - Request-level limits are capped by server-side
SERVER_MAX_HANDLER_MS. /verifyexecution is bounded byVERIFY_MAX_MS.
- Validator/schema caches are in-memory (per process).
- Prewarm is best-effort and asynchronous.
- In multi-replica deployments, warm each replica independently.
See docs/OPERATIONS.md for deployment and runbook guidance.
# mint
curl -s -X POST http://localhost:8080/describe/v1.0.0 -H "Content-Type: application/json" -d '{"x402":{"verb":"describe","version":"1.0.0","entry":"x402://describeagent.eth/describe/v1.0.0"},"input":{"subject":"CommandLayer","detail_level":"short"}}' | tee receipt.json | jq '.metadata.proof | {kid, canonical_id, hash_sha256, signature_b64}'
# verify env
curl -s -X POST http://localhost:8080/verify -H "Content-Type: application/json" --data-binary @receipt.json | jq .
# verify ens
curl -s -X POST "http://localhost:8080/verify?ens=1" -H "Content-Type: application/json" --data-binary @receipt.json | jq .