CLI Reference
This is the command surface for @ckb-firewall/cli.
Global behavior
Section titled “Global behavior”- Node 20+ required
- ESM only
- Defaults point to the canonical testnet registry cell and contracts
- Registry-touching commands fetch live cell data through the CKB RPC before building anything
inspect,check, andexecuteauto-discover the current registry cell outpoint via the CKB indexer (get_cells) when using testnet defaults, so they keep working after governance updates without requiring--registry-txoverrides. Falls back silently to the configured outpoint if the indexer is unavailable.
Commands
Section titled “Commands”inspect
Section titled “inspect”Show the current registry entries with their expiry status.
ckb-firewall inspectckb-firewall inspect --rpc-url https://testnet.ckb.devOptions: --rpc-url, --registry-tx, --registry-index
Test whether a specific lock args is currently blacklisted.
ckb-firewall check --lock-args 0xabc123...Options: --lock-args (required), --rpc-url, --registry-tx, --registry-index
propose
Section titled “propose”Create a governance proposal. All fields are hashed together into a canonical proposalIdHash — every field is immutable after creation.
ckb-firewall propose \ --action add \ --lock-args 0xabc123... \ --evidence https://evidence.example/... \ --classification theft \ --severity high \ --rationale "Drained 50k CKB from multiple wallets in a single transaction." \ --proposer aliceTo activate or rotate the registry treasury metadata, create a metadata proposal:
ckb-firewall propose \ --action set-treasury \ --treasury-lock-code-hash 0x... \ --treasury-lock-hash-type type \ --treasury-lock-args 0x... \ --evidence https://evidence.example/treasury \ --classification other \ --severity high \ --rationale "Activate the public registry treasury for proposal anchors and growth." \ --proposer aliceOptions: --action, --lock-args, --expires-at, --evidence, --classification, --severity, --rationale, --proposer, --treasury-lock-code-hash, --treasury-lock-hash-type, --treasury-lock-args, --review-delay-ms (override the on-chain review delay in ms; testnet/drill use only)
Classifications: theft, scam, hack, sanctions, other
Severities: critical, high, medium, low
Proposal actions: add, remove, set-treasury. set-treasury creates a PBLK v2 proposal cell that binds the target treasury lock hash. It keeps the blacklist entries unchanged and updates only the governance header treasury metadata.
After creation the CLI prints an export command. Share the exported JSON with other governance participants via export / import.
proposals
Section titled “proposals”List proposals and their current status.
ckb-firewall proposalsckb-firewall proposals --status votingOptions: --status (pending-review, voting, approved, executed, rejected)
Record a cryptographically signed validator vote on a proposal.
ckb-firewall vote --proposal abc123 --vote yes# prompts for private keyOptions: --proposal, --vote (yes, no, abstain), --rpc-url, --registry-tx, --registry-index
The CLI prompts for the validator private key with masked input. Pass --private-key <hex> to provide it non-interactively (scripted use only — do not use in shared environments).
What this command does:
- Derives the compressed public key from the provided private key
- Checks the pubkey is in the authorized validator set (Merkle membership proof against the on-chain
validatorMerkleRootin the BLKL governance header) - Rejects the vote if the key is not an authorized validator
- Signs the vote:
blake2b({domain:"ckb-firewall:vote", proposalIdHash, vote, timestamp, pubkey}) - Stores the vote locally with signature and Merkle proof
- Updates the
voteDigestHash— a commitment to the full set of votes cast so far
Votes are local until execute. Export and share the updated proposal so other participants can import your vote.
anchor
Section titled “anchor”Build or submit the on-chain PBLK proposal cell used by GOV1 v4 execution.
ckb-firewall anchor --proposal abc123 --to-address ckt1...
ckb-firewall anchor \ --proposal abc123 \ --to-address ckt1... \ --from-account ckt1... \ --submit
ckb-firewall anchor \ --proposal abc123 \ --proposal-tx 0x... \ --proposal-index 0Options: --proposal (required), --rpc-url, --registry-tx, --registry-index, --to-address, --from-account, --capacity, --fee-rate, --privkey-path, --output-index, --proposal-tx, --proposal-index, --proposal-anchor-code-tx, --proposal-anchor-code-index, --treasury-cell, --treasury-lock-dep, --tx-out, --submit
For non-treasury registries, without --submit, the command prints the exact ckb-cli wallet transfer --to-data ... command. With --submit, it runs ckb-cli, submits the proposal cell transfer, and stores the resulting proposal-cell outpoint on the proposal JSON.
For treasury-backed registries, anchor builds a keyless proposal-anchor transaction funded by the autonomous treasury pool — no private key required:
# Build the TX (keyless — treasury-lock validates without a signature)ckb-firewall anchor \ --proposal abc123 \ --tx-out gov_anchor_tx.json
# Build and submit in one step (still keyless)ckb-firewall anchor \ --proposal abc123 \ --submitThe CLI auto-discovers treasury cells from the registry’s governance header. To select specific treasury cells manually, add --treasury-cell <tx-hash>:<index> one or more times. For private deployments, override the proposal-anchor code outpoint with --proposal-anchor-code-tx and --proposal-anchor-code-index, and add --treasury-lock-dep <tx-hash>:<index>[:code|dep_group] for any extra cell deps required by a custom treasury lock.
If you create the cell separately, run anchor again with --proposal-tx and --proposal-index to record the outpoint.
After the outpoint is stored, execute can infer it:
ckb-firewall execute --proposal abc123execute
Section titled “execute”Build the registry update transaction from an approved validator-voted proposal. Verifies vote signatures and Merkle proofs before building a witness that the on-chain governance lock verifies again.
ckb-firewall execute \ --proposal abc123 \ --tx-out ./gov_tx.jsonOptions: --proposal, --rpc-url, --registry-tx, --registry-index, --proposal-tx, --proposal-index, --proposal-anchor-code-tx, --proposal-anchor-code-index, --treasury-cell, --treasury-lock-dep, --tx-out, --sign, --from-account, --privkey-path (non-interactive key file for signing), --ready (find and execute all proposals whose review window has passed and vote threshold is met)
--proposal-tx and --proposal-index override the stored live PBLK proposal-cell outpoint when needed. The generated transaction spends that proposal cell with a relative timestamp since delay and returns its remaining capacity as change.
For treasury-backed registries, execute is also fully keyless — the autonomous treasury-lock funds any registry capacity growth:
# Default: keyless — treasury cells auto-discovered, no private key requiredckb-firewall execute --proposal abc123
# Override: specify treasury cells manually (still keyless)ckb-firewall execute \ --proposal abc123 \ --treasury-cell 0x...:0 \ --treasury-cell 0x...:1The treasury-lock contract validates the TX by detecting the proposal-anchor input being consumed, so no signature is needed. Proposal cell capacity is returned to the treasury pool automatically.
For private deployments, override the proposal-anchor code outpoint with --proposal-anchor-code-tx/--proposal-anchor-code-index, and add --treasury-lock-dep <tx-hash>:<index>[:code|dep_group] for extra treasury cell deps.
reclaim
Section titled “reclaim”Build a transaction that reclaims a rejected or abandoned treasury-funded proposal anchor without changing the registry.
ckb-firewall reclaim \ --proposal abc123 \ --tx-out ./gov_reclaim_tx.jsonOptions: --proposal, --rpc-url, --registry-tx, --registry-index, --proposal-tx, --proposal-index, --proposal-anchor-code-tx, --proposal-anchor-code-index, --treasury-lock-dep, --tx-out, --sign, --from-account, --force
reclaim verifies the live PBLK cell data against the local proposal and current registry type ID, checks that the anchor is locked to the registry treasury, checks that the anchor carries the proposal-anchor type args, sets the same relative timestamp since delay used by execution, and returns the remaining capacity to the treasury lock. On canonical testnet, the deployed proposal-anchor code outpoint is used by default. Use --treasury-lock-dep for any extra cell deps required by a custom treasury lock.
By default, reclaim refuses proposals that are still in their review window or that appear executable. Use --force only after governance has decided not to execute the proposal.
Launch the browser-based governance dashboard.
ckb-firewall guickb-firewall gui --port 8080ckb-firewall gui --no-openOptions:
| Option | Default | Description |
|---|---|---|
--port | 7979 | Port for the local app server |
--no-open | — | Start the server without opening a browser tab |
The command attempts to bind port 80 and serve the dashboard at http://ckb-firewall.localhost (no port in the URL). If port 80 is unavailable it falls back to http://ckb-firewall.localhost:<port>. To get the portless URL without sudo, grant Node the capability to bind low ports:
# Linuxsudo setcap cap_net_bind_service+eip $(which node)
# macOSsudo ckb-firewall gui
# Windows (run terminal as Administrator)ckb-firewall guiPress Ctrl+C to stop the server. The server uses the same --rpc-url and registry defaults as inspect.
For a walkthrough of the GUI interface see GUI mode.
export
Section titled “export”Export a proposal to a shareable JSON file for multi-party governance coordination.
ckb-firewall export --proposal abc123 --out proposal-abc123.jsonckb-firewall export --proposal abc123 # prints to stdoutOptions: --proposal, --out
import
Section titled “import”Import a proposal shared by another governance participant. Validates proposalIdHash and voteDigestHash integrity before saving. If the proposal already exists locally, votes are merged rather than overwritten.
ckb-firewall import proposal-abc123.jsonckb-firewall import proposal-abc123.json --forceArguments: <file> (required)
Options: --force (skip overwrite confirmation)
Full governance flow
Section titled “Full governance flow”All registry changes go through governance. The proposal is a local JSON file until execute submits it on-chain. No private key is required for anchor or execute — the autonomous treasury-lock funds both operations.
propose → anchor → export → [share] → import → vote → export → [share] → import → execute- Any participant runs
proposeto create the proposal file, thenanchorto lock it on-chain (funded by the treasury pool — no key needed). Anchoring first starts the review window clock. - The JSON is exported and shared out-of-band (email, Signal, IPFS, etc.)
- Each validator runs
importto receive it, thenvotewith their validator key, thenexportagain to share their vote - After the review window and vote threshold are met, any participant runs
execute— also funded by the treasury pool, no key needed
There is no sign command. Validator vote signatures are collected during vote and embedded in the execute witness by execute itself.
The minimum timeline is approximately 96 hours (72h review window + time for validators to vote). The CLI warns if a temporary entry’s expiresAt falls within this window.
See also
Section titled “See also”- Governance validator tutorial — hands-on walk-through of the full CLI governance flow
- How to inspect the registry —
ckb-firewall inspectandcheck - How to create a proposal —
ckb-firewall propose - How to anchor a proposal —
ckb-firewall anchor - How to vote on a proposal —
ckb-firewall vote - How to share proposals —
ckb-firewall exportandimport - How to execute an approved proposal —
ckb-firewall execute - Fix: vote digest mismatch — when
executefails with a hash error