The Etchd CLI
The etchd command stamps files, text and digests, upgrades the proofs and checks them against Ethereum Classic, and a shell script or an agent calls it the same way a person does. It hashes on your machine and never prompts. Piped, it prints JSON. Every run ends with one of seven fixed exit codes.
Install
The CLI lives in packages/cli and needs Node 22.18 or later. Each cli-v* release on GitHub carries etchd-cli.tgz, the CLI bundled into one file with no dependencies, and its SHA-256 in etchd-cli.tgz.sha256. It is not on npm. The link answers 404 until we push the first cli-v* tag.
npm i -g https://github.com/classix-dev/etchd/releases/latest/download/etchd-cli.tgznpx runs it once without installing. It keeps the first copy it fetched for that URL, and moving to a newer release takes npm i -g.
npx https://github.com/classix-dev/etchd/releases/latest/download/etchd-cli.tgz stamp report.pdfBuild it from a clonegit clone https://github.com/classix-dev/etchd
cd etchd
pnpm install
pnpm cli:pack
npm i -g ./packages/cli/dist/etchd-cli.tgzWithout a calendar set, the CLI stamps on ours at https://a.etc.calendar.etchd.app, and ETCHD_CALENDAR picks another one, such as the local dev Worker from pnpm dev.
export ETCHD_CALENDAR=http://127.0.0.1:8787Stamp, Upgrade, Verify
etchd stamp hashes each input locally, gives each digest a random 16-byte nonce and folds them into one Merkle tree, and only the root goes to the calendar, in a single request, while each input still gets its own .ots file. A second run skips inputs that already have a proof. --force stamps them again. Use --text to stamp a string, or --digest with --alg for a hash you computed yourself, BLAKE3 included.
etchd stamp report.pdf # writes report.pdf.ots
etchd stamp dist/* --out proofs # one submission for every file
etchd stamp --text "release 1.2.0" # writes <sha256>.otsA fresh proof is pending. Once the tick's anchor transaction is mined, usually a minute or two after the stamp, etchd upgrade asks the calendar named in the proof for the rest of the path. Until then it exits 2 or, with --wait, keeps polling for up to --timeout seconds. A run a few hours later usually merges the Bitcoin branch too.
etchd upgrade report.pdf.ots --wait --timeout 600etchd verify replays the proof on the original and looks up the anchor transaction on ETC, with the checks set out in Verifying. It exits 0 from one confirmation and prints the count, and --min-confirmations asks for more. Two or more RPCs have to return the same block. To use your own node, pass --etc-rpc and add --min-sources 1 to accept that one source. The verifier also matches the sender against the calendar's signer list. Only --require-known-signer makes that match change the result.
etchd verify report.pdf.ots
etchd verify report.pdf.ots --etc-rpc http://127.0.0.1:8545 --min-sources 1
etchd verify report.pdf.ots --min-confirmations 400
etchd verify report.pdf.ots --signers https://etchd.app/v1/signers --require-known-signerInspecting Proofs and the Calendar
etchd info lists what a .ots file holds and works offline. etchd status shows calendar health. To see what a tick committed, down to one chain's leaf and its Merkle path, use etchd tick latest and etchd beacon <n> [chain]. etchd chains lists the chains the beacon follows, and with --local it reads the registry built into the CLI without the network. etchd mirror copies the daily exports and checks each one before it stores it, as set up on Mirrors.
Output for Scripts
In a terminal the CLI prints text for people, and when its output goes to a pipe it prints one JSON object, with --json asking for JSON anywhere. --ndjson prints one object per item followed by a result line. --human forces text, and -q prints nothing. Every JSON result carries ok, command and exitCode, and a failure adds error.code and error.message. etchd schema stamp prints the JSON Schema for a command's output.
Exit Codes
| Code | Meaning | What to do |
|---|---|---|
| 0 | Done, or the proof verified with at least --min-confirmations confirmations, 1 by default | Nothing |
| 1 | Bad arguments, or the original file is missing | Fix the command. etchd <command> --help lists every option |
| 2 | Pending, or anchored with fewer confirmations than --min-confirmations asks for | Run upgrade or verify again later |
| 3 | The proof or the original does not match, or there is no attestation Etchd can check | Stop and report it, a retry changes nothing |
| 4 | A calendar, an RPC or a mirror target could not be reached | Retry later or pass other URLs |
| 5 | An internal error in the CLI | Report the error message |
| 6 | The anchor transaction is no longer at the block and index the proof names, after a reorg or in a wrong proof | Run etchd upgrade on the proof, then verify again |
With --require-known-signer, an anchor sent by a key outside the signer list also exits 3, and one whose list could not be fetched exits 4.
Environment Variables
ETCHD_CALENDAR holds the calendar URLs used when -c is not given. ETCHD_ETC_RPC holds the ETC RPC URLs used when --etc-rpc is not given, and without either the CLI falls back to three public RPCs. Both variables take a comma-separated list. etchd mirror reads a pinning service token from the variable that --token-env names, which keeps the token off the command line.
The Agent Skill
skills/etchd/SKILL.md teaches an agent the same commands, how to read each status and which exit codes to retry, and to install it you copy the skills/etchd directory into your agent's skills folder, which for Claude Code is ~/.claude/skills/etchd.