# 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](https://github.com/classix-dev/etchd/blob/main/packages/cli) and needs Node 22.18 or later. Each `cli-v*` release on [GitHub](https://github.com/classix-dev/etchd/releases) 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.

Install

```
npm i -g https://github.com/classix-dev/etchd/releases/latest/download/etchd-cli.tgz
```

`npx` 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`.

Run once

```
npx https://github.com/classix-dev/etchd/releases/latest/download/etchd-cli.tgz stamp report.pdf
```

Build it from a clone

```
git clone https://github.com/classix-dev/etchd
cd etchd
pnpm install
pnpm cli:pack
npm i -g ./packages/cli/dist/etchd-cli.tgz
```

Without 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`.

Use the local dev calendar

```
export ETCHD_CALENDAR=http://127.0.0.1:8787
```

## Stamp, Upgrade, Verify

etchd stamp writes a pending proof next to the file. etchd upgrade adds the path to the ETC transaction, and etchd verify exits 0 once two RPCs agree on the anchor block. Pass --min-confirmations to ask for more blocks on top.

`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.

Stamp

```
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>.ots
```

A 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.

Upgrade

```
etchd upgrade report.pdf.ots --wait --timeout 600
```

`etchd verify` replays the proof on the original and looks up the anchor transaction on ETC, with the checks set out in [Verifying](https://etchd.app/docs/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.

Verify

```
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-signer
```

## Inspecting 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](https://etchd.app/docs/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](https://github.com/classix-dev/etchd/blob/main/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](https://github.com/classix-dev/etchd/tree/main/skills/etchd) directory into your agent's skills folder, which for Claude Code is `~/.claude/skills/etchd`.
