Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .changeset/brave-falcons-dance.md

This file was deleted.

10 changes: 0 additions & 10 deletions .changeset/devnet-fork.md

This file was deleted.

14 changes: 0 additions & 14 deletions .changeset/fix-dependabot-alerts.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/integrate-ckb-tui.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/tasty-walls-appear.md

This file was deleted.

33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# @offckb/cli

## 0.4.9

### Patch Changes

- 6f54296: Add daemon mode and structured JSON output for agent-friendly usage, plus a `node stop` command to terminate the daemon.

- `offckb node --daemon` starts the CKB devnet as a detached background process and writes the PID and logs to the devnet data folder.
- `offckb --json <command>` emits structured JSON log output for programmatic consumption.
- `offckb node stop` reads the daemon PID file and gracefully shuts down the daemon, falling back to force-kill if necessary. It now verifies the target process identity, handles stale PID files, and cleans up on error paths.
- Hardened daemon lifecycle: duplicate daemon starts are rejected, CLI entry resolution supports packaged/npx environments via `OFFCKB_CLI_PATH`, and log/PID directory creation failures are handled gracefully.

- 8f8d0a4: Fix canary DevRel findings across daemon lifecycle, SUDT type args, fork isolation and migration, Indexer readiness, account safety, verified ckb-tui downloads, private-key input, and stable JSON command results.
- b3fe233: Add `offckb devnet fork` to fork an existing mainnet/testnet data directory into the local devnet ([Devnet From Existing Data](https://docs.nervos.org/docs/node/devnet-from-existing-data) flow), plus fork-aware system scripts and local-first debugging.

- `offckb devnet fork --from <dir> [--source mainnet|testnet] [--spec-file <path>] [--force]` copies the source chain data, imports the matching chain spec, patches it for local mining (Dummy PoW, `cellbase_maturity = 0`, correct `genesis_epoch_length` per chain), verifies the genesis hash, and records the fork state. The first `offckb node` run boots with `--skip-spec-check --overwrite-spec` automatically; `offckb clean` resets back to a pure devnet.
- Devnet system scripts now self-identify the chain via the genesis hash in `ckb list-hashes`: on a mainnet/testnet fork, genesis scripts come from the chain's own spec and post-genesis deployments (sudt/xudt/omnilock/spore/…) are filled from the well-known static records, so `system-scripts`, transfers, deploys and fee estimation keep working on a fork.
- The devnet ccc client follows the forked chain too: a mainnet fork uses the `ckb` address prefix.
- `offckb debug` falls back to fetching the transaction from the node when it is not in the local proxy cache, and the tx dumper now embeds full header objects in `mock_info.header_deps` (previously bare hashes, which broke debugging for transactions with header deps).

- 303f54e: Resolve Dependabot security alerts via pnpm overrides for transitive dependencies:

- `qs` 6.15.0 → 6.15.2
- `ip-address` 10.1.0 → 10.1.1
- `js-yaml` 3.14.2 → 3.15.0 / 4.1.1 → 4.2.0
- `@babel/core` 7.28.6 → 7.29.7
- `@eslint/plugin-kit` 0.2.8 → 0.3.4
- `brace-expansion` 5.0.5 → 5.0.6

`elliptic` remains unfixed because a patched version (>=6.6.2) is not yet published on npm.

- 43ce3a3: Add `status` command to launch ckb-tui for monitoring CKB network from your node
- 463b2ff: Refactor UDT CLI support: reuse `balance` and `transfer` commands for CKB and UDT queries, and add `offckb udt issue` / `offckb udt destroy` subcommands.

## 0.4.8

### Patch Changes
Expand Down
53 changes: 42 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ ckb development network for your first try

Options:
-V, --version output the version number
--json Output one command result as JSON on stdout and logs as NDJSON on stderr
-h, --help display help for command

Commands:
Expand All @@ -84,6 +85,9 @@ Commands:
debugger Port of the raw CKB Standalone Debugger
status [options] Show ckb-tui status interface
config <action> [item] [value] do a configuration action
devnet config Edit devnet configuration
devnet info Show fork metadata and node/indexer readiness
devnet fork [options] Fork Mainnet/Testnet state into the local devnet
help [command] display help for command
```

Expand Down Expand Up @@ -141,17 +145,17 @@ offckb node stop

**Agent-Friendly JSON Output**

For programmatic consumption or agent integration, add `--json` to any command to emit structured JSON logs:
For programmatic consumption or agent integration, add `--json` before or after the command:

```sh
offckb node --json
offckb node --daemon --json
offckb --json balance ckt1...
offckb devnet info --json
```

Each log line is a single JSON object:
In JSON mode, stdout is reserved for one stable command result. Progress logs are newline-delimited JSON on stderr, and failures use `{ "ok": false, "code", "message" }` with a non-zero exit code. This lets scripts parse stdout without scraping log messages or stack traces:

```json
{ "level": "info", "message": "Launching CKB devnet Node...", "timestamp": "2026-07-07T07:10:00.000Z" }
{ "ok": true, "command": "balance", "network": "devnet", "address": "ckt1...", "ckb": "4200", "udt": [] }
```

**RPC & Proxy RPC**
Expand All @@ -173,7 +177,15 @@ Using a proxy RPC server for Testnet/Mainnet is especially helpful for debugging

**Watch Network with TUI**

Once you start the CKB Node, you can use `offckb status --network devnet/testnet/mainnet` to start a CKB-TUI interface to monitor the CKB network from your node.
Once you start the CKB Node, launch the interactive CKB-TUI for one network:

```sh
offckb status --network devnet
offckb status --network testnet
offckb status --network mainnet
```

`status` performs a JSON-RPC health check through the proxy before opening the TUI and requires an interactive terminal.

### 2. Create a New Contract Project {#create-project}

Expand Down Expand Up @@ -379,21 +391,31 @@ Pay attention to the `devnet.configPath` and `devnet.dataPath`.
You can fork an existing Mainnet/Testnet data directory into your local devnet, so it keeps the real on-chain state (deployed contracts, cells) while mining locally with Dummy PoW. This implements the same flow as [Devnet From Existing Data](https://docs.nervos.org/docs/node/devnet-from-existing-data).

```sh
# Point at the directory used by the source node's `ckb -C`:
offckb devnet fork --from /path/to/ckb-data --dry-run
offckb devnet fork --from /path/to/ckb-data
offckb node
offckb node --daemon
offckb devnet info
```

- `--from` points at the directory the source node runs with (`-C`), which must contain `data/db`. Stop the source node first.
- Database fork mode requires `--from`; it points at the directory the source node runs with (`ckb -C`), which must contain `data/db`. Keeping the source explicit makes large database copies predictable in local scripts and CI.
- Stop the source node first. Use `--dry-run` to validate the source chain, CKB/DB compatibility, migration requirement, and target without replacing the current devnet.
- The source chain is auto-detected from the source `ckb.toml`; pass `--source mainnet|testnet` when it cannot be detected, and `--spec-file <path>` to use a local chain spec (e.g. offline).
- The command copies the chain `data/` (your original data is never modified), imports the matching chain spec, patches it for local mining (Dummy PoW, `cellbase_maturity = 0`), and verifies the genesis hash.
- The first `offckb node` run automatically boots with `--skip-spec-check --overwrite-spec`; later runs are normal.
- The command copies the chain state (your original data is never modified), deliberately excludes peer store/log/tmp data, imports the matching chain spec, patches it for local mining, verifies the genesis hash, and writes a fork receipt.
- Fork networking is outbound-isolated: no bootnodes, persisted peers, peer discovery, or outbound peer slots. `offckb devnet info` displays the observed peer count so this property is visible.
- If `ckb migrate --check` says the database is old, the preflight stops before changing the devnet. Re-run with `--migrate`; only the copied database is migrated.
- The first `offckb node` run automatically boots with `--skip-spec-check --overwrite-spec`; later runs are normal. Daemon startup waits for healthy CKB RPC, miner spawn, and proxy health before reporting success.
- Forking replaces the current devnet; use `--force` to replace an existing devnet/fork, or `offckb clean` to reset back to a pure devnet.

`offckb devnet info` reports RPC readiness, node tip, Indexer tip/lag, peer count, network isolation, and fork metadata. Balance and signing commands warn while the Indexer is unavailable or behind instead of silently presenting incomplete state.

On a forked devnet, `offckb system-scripts`, transfers, deploys and `offckb debug --tx-hash <hash>` work against the real source-chain state, e.g. debugging a failed mainnet transaction fully locally.

> [!CAUTION]
> CKB transactions carry no chain id, so a transaction built on a mainnet fork that spends copied mainnet cells is also valid on mainnet (CKB provides no replay protection). offckb's own flows only use dev keys and fork-mined cells, which cannot replay. Never sign transactions with real mainnet keys against a fork unless you intend to broadcast them yourself.

`offckb transfer` fails closed on a Mainnet fork: non-built-in keys require `--allow-mainnet-replay-risk`, and inputs copied from Mainnet are rejected even with that override.

## Config Setting

### List All Settings
Expand Down Expand Up @@ -455,12 +477,21 @@ LOG_LEVEL=debug offckb node

## Accounts

OffCKB comes with 20 pre-funded accounts, each initialized with `42_000_000_00000000` capacity in the genesis block.
On a pure OffCKB devnet, OffCKB comes with 20 pre-funded accounts, each initialized with `42_000_000_00000000` capacity in the genesis block. A fork keeps the source chain genesis and therefore has no OffCKB genesis allocation; built-in dev accounts are funded by locally mined cellbase cells instead.

```sh
offckb accounts
offckb accounts --show-private-keys # trusted local terminals only
```

On a Mainnet fork, `accounts` re-encodes the same dev lock scripts with the `ckb` address prefix. Once the Indexer is caught up it also reports each account's spendable pure-CKB balance; until then the field is omitted with a warning. Private keys are hidden by default so JSON and agent logs do not collect them.

- All private keys are stored in the `account/keys` file.
- Detailed information for each account is recorded in `account/account.json`.
- When deploying contracts, the deployment cost are automatically deducted from these pre-funded accounts. This allows you to test deployments without faucets or manual funding.

For commands that accept a private key, prefer `--privkey-file <path>` or `OFFCKB_PRIVATE_KEY` over `--privkey`, which is visible in shell history and process listings.

:warning: **DO NOT SEND REAL ASSETS TO THESE ACCOUNTS. THE KEYS ARE PUBLIC, AND YOU MAY LOSE YOUR MONEY** :warning:

## About CCC
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@offckb/cli",
"version": "0.4.8",
"version": "0.4.9",
"description": "ckb development network for your first try",
"author": "CKB EcoFund",
"license": "MIT",
Expand Down
Loading
Loading