CKB local development network for your first try.
- One-line command to start a devnet, no docker required
- Pre-funded test accounts
- Built-in scripts like CKB-JS-VM and Spore-contract
- Create boilerplate to build CKB Smart Contract in Typescript
- Proxy RPC that automatically dumps failed transactions for easier debugging
Migrate from v0.3.x to v0.4.x:
There are BREAKING CHANGES between v0.3.x and v0.4.x, make sure to read the migration guide before upgrading.
- OffCKB
- Install
- Usage
- Get started
- Config Setting
- Log-Level
- Built-in scripts
- Accounts
- About CCC
- FAQ
- Contributing
npm install -g @offckb/clior use pnpm to install:
pnpm install -g @offckb/cliRequire Node version >= v20.0.0. We recommend using latest LTS version of Node to run offckb
Note for Windows users: If installation fails due to native module compilation issues, the CLI will still work but may use portable binaries instead of optimized ones. For better performance, consider installing Visual Studio Build Tools.
Usage: offckb [options] [command]
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:
node [CKB-Version] Use the CKB to start devnet
node stop Stop the running CKB devnet daemon
create [options] [project-name] Create a new CKB Smart Contract project in JavaScript.
deploy [options] Deploy contracts to different networks, only supports devnet and testnet
debug [options] Quickly debug transaction with tx-hash
system-scripts [options] Print/Output system scripts of the CKB blockchain
clean Clean the devnet data, need to stop running the chain first
accounts Print account list info
deposit [options] [toAddress] [amountInCKB] Deposit CKB tokens to address, only devnet and testnet
transfer [options] [toAddress] [amountInCKB] Transfer CKB tokens to address, only devnet and testnet
transfer-all [options] [toAddress] Transfer All CKB tokens to address, only devnet and testnet
balance [options] [toAddress] Check account balance, only devnet and testnet
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 commandUse offckb [command] -h to learn more about a specific command.
Start a local blockchain with one command:
offckb nodeSpecify a CKB version:
offckb node 0.201.0Or set a default version globally:
offckb config set ckb-version 0.201.0
offckb nodeOr specify the path to your locally compiled CKB binary:
offckb node --binary-path /path/to/your/ckb/binaryWhen using --binary-path, it will ignore the specified version and network, and only work for devnet.
Run in Daemon Mode
Start the devnet in the background so your terminal stays free:
offckb node --daemonThe daemon writes its logs and PID to the devnet data folder, for example:
- Logs:
~/Library/Application Support/offckb-nodejs/devnet/data/logs/daemon.log - PID file:
~/Library/Application Support/offckb-nodejs/devnet/data/logs/daemon.pid
Stop the daemon later with:
offckb node stopAgent-Friendly JSON Output
For programmatic consumption or agent integration, add --json before or after the command:
offckb --json balance ckt1...
offckb devnet info --jsonIn 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:
{ "ok": true, "command": "balance", "network": "devnet", "address": "ckt1...", "ckb": "4200", "udt": [] }RPC & Proxy RPC
When the Devnet starts:
- The RPC server runs at http://127.0.0.1:8114
- The proxy RPC server runs at http://127.0.0.1:28114
The proxy RPC server forwards all requests to the RPC server and record every requests while automatically dumping failed transactions for easier debugging.
You can also start a proxy RPC server for public networks:
offckb node --network <testnet or mainnet>Using a proxy RPC server for Testnet/Mainnet is especially helpful for debugging transactions, since failed transactions are dumped automatically.
Watch Network with TUI
Once you start the CKB Node, launch the interactive CKB-TUI for one network:
offckb status --network devnet
offckb status --network testnet
offckb status --network mainnetstatus performs a JSON-RPC health check through the proxy before opening the TUI and requires an interactive terminal.
Generate a ready-to-use smart-contract project in JS/TS using templates:
offckb create <your-project-name> -c <your-contract-name>- The
-coption is optional, if not provided, the contract name defaults tohello-world.
Note for Windows Users:
To run mock tests in the generated project, you need to manually install ckb-debugger until this upstream fix about ckb-testtool wasm is applied.
Installation Steps:
- Download the latest
ckb-debuggerrelease for Windows from the releases page - Extract the downloaded archive (e.g.,
ckb-debugger-win64.zip) - Add the extracted binary to your system PATH:
- Open "System Properties" → "Environment Variables"
- Under "System variables" or "User variables", find and edit the
Pathvariable - Click "New" and add the full path to the folder containing
ckb-debugger.exe - Click "OK" to save
- Verify installation by opening a new terminal and running:
ckb-debugger --version
- Disable WASM debugger in your mock test file:
- Open the mock test file (e.g.,
<your-contract-name>.mock.test.ts) - Comment out or delete the
verifier.setWasmDebuggerEnabled(true)line:
// When using native ckb-debugger, comment out or delete the following line: // verifier.setWasmDebuggerEnabled(true);
- Open the mock test file (e.g.,
After completing these steps, npm run test should pass without mock test failures.
offckb deploy --network <devnet/testnet> --target <path-to-your-contract-binary-file-or-folder> --output <output-folder-path>- Deployment info is written to the
output-folder-pathyou specify.
Upgradable Scripts with --type-id
Pass the --type-id option if you want your Scripts to be upgradable:
offckb deploy --type-id --network <devnet/testnet>- Important: Upgrades are keyed by the contract‘s artifact name.
- If you plan to upgrade with
--type-id, do not rename your contract artifact (e.g. keephello-world.bc). - Renaming it makes the offckb unable to find the previous Type ID info from the
output-folder-pathand will create a new Type ID.
- If you plan to upgrade with
When you interact with the CKB Devnet through the Proxy RPC server (localhost:28114), any failed transactions are automatically dumped and recorded for debugging.
Debug a Transaction:
offckb debug --tx-hash <transaction-hash> --network <devnet/testnet>output example:
offckb debug --tx-hash 0x64c936ee78107450d49e57b7453dce9031ce68b056b2f1cdad5c2218ab7232ad
Dump transaction successfully
******************************
****** Input[0].Lock ******
hello, this is new add!
Hashed 1148 bytes in sighash_all
sighash_all = 5d9b2340738ee28729fc74eba35e6ef969878354fe556bd89d5b6f62642f6e50
event = {"pubkey":"45c41f21e1cf715fa6d9ca20b8e002a574db7bb49e96ee89834c66dac5446b7a","tags":[["ckb_sighash_all","5d9b2340738ee28729fc74eba35e6ef969878354fe556bd89d5b6f62642f6e50"]],"created_at":1725339769,"kind":23334,"content":"Signing a CKB transaction\n\nIMPORTANT: Please verify the integrity and authenticity of connected Nostr client before signing this message\n","id":"90af298075ac878901282e23ce35b24e584b7727bc545e149fc259875a23a7aa","sig":"b505e7d5b643d2e6b1f0e5581221bbfe3c37f17534715e51eecf5ff97a2e1b828a3d767eb712555c78a8736e9085b4960458014fa171d5d169a1b267b186d2f3"}
verify_signature costs 3654 k cycles
Run result: 0
Total cycles consumed: 4013717(3.8M)
Transfer cycles: 44947(43.9K), running cycles: 3968770(3.8M)
******************************
****** Output[0].Type ******
verify_signature costs 3654 k cycles
Run result: 0
Total cycles consumed: 3916670(3.7M)
Transfer cycles: 43162(42.2K), running cycles: 3873508(3.7M)Debug a Single Cell Script:
offckb debug <transaction-hash> --single-script <single-cell-script-option>The single-cell-script-option format is <cell-type>[<cell-index>].<script-type>
cell-type→inputoroutputcell-index→ index of the Cell in the transactionscript-type→lockortype
Example:
offckb debug --tx-hash <tx-hash> --single-script input[0].lockAll debug utilities are powered by ckb-debugger.
Print all the predefined Scripts for the local blockchain:
offckb system-scripts --listExport options:
- Lumos format
offckb system-scripts --export-style lumos- CCC format:
offckb system-scripts --export-style ccc- Save to a JSON file:
offckb system-scripts --output <output-file-path>By default, OffCKB use a fixed Devnet config. You can customize it, for example by modifying the default log level (warn,ckb-script=debug).
- Open the interactive Devnet config editor:
offckb devnet configThe editor uses a three-column layout: first-column file switcher (ckb.toml / ckb-miner.toml), a middle primary editing pane, and a smaller right read-only reference pane that shows the full built-in template for the currently selected file.
The left editing pane supports full key browsing/editing, including primitive value edits, object key add, array append/insert/move, search filter, and path delete.
Common shortcuts: Enter edit primitive, a add key/item, i insert array item, m move array item, d delete path, / search filter, n/N next/previous search match, c add custom value in fixed-array dialog (when allowed), s save, q quit.
Note: saving rewrites ckb.toml / ckb-miner.toml into canonical TOML format; upstream comments and original formatting are not preserved after save.
You can also update the same fields non-interactively (useful for scripts/CI):
offckb devnet config --set ckb.logger.filter=info
offckb devnet config --set ckb.rpc.enable_deprecated_rpc=true --set miner.client.poll_interval=1500If your terminal is non-interactive (no TTY, e.g. CI/remote pipeline), use --set mode directly instead of the full-screen editor.
- Save changes and restart devnet:
offckb clean -d
offckb node- (Advanced) Locate your Devnet config folder for manual edits:
offckb config listExample result:
{
"devnet": {
"rpcUrl": "http://127.0.0.1:8114",
"configPath": "~/Library/Application Support/offckb-nodejs/devnet",
"dataPath": "~/Library/Application Support/offckb-nodejs/devnet/data"
}
}Pay attention to the devnet.configPath and devnet.dataPath.
cdinto thedevnet.configPath. Modify the config files as needed. See Custom Devnet Setup and Configure CKB for details.- After modifications, run
offckb clean -dto remove the chain data if needed while keeping the updated config files. - Restart local blockchain by running
offckb node
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.
# 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 --daemon
offckb devnet info- Database fork mode requires
--from; it points at the directory the source node runs with (ckb -C), which must containdata/db. Keeping the source explicit makes large database copies predictable in local scripts and CI. - Stop the source node first. Use
--dry-runto 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|testnetwhen it cannot be detected, and--spec-file <path>to use a local chain spec (e.g. offline). - 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 infodisplays the observed peer count so this property is visible. - If
ckb migrate --checksays the database is old, the preflight stops before changing the devnet. Re-run with--migrate; only the copied database is migrated. - The first
offckb noderun 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
--forceto replace an existing devnet/fork, oroffckb cleanto 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.
offckb config listoffckb config get ckb-version
> 0.113.0
offckb config set ckb-version 0.117.0
offckb config get ckb-version
> 0.117.0offckb config set proxy http://127.0.0.1:1086
> save new settings
offckb config get proxy
> http://127.0.0.1:1086
offckb config rm proxy
> save new settings
offckb config get proxy
> No Proxy.You can tweak env LOG_LEVEL to control the offckb log level.
For example, set LOG_LEVEL=debug gives you more outputs of offckb proxy RPC.
LOG_LEVEL=debug offckb node- xUDT nervosnetwork/rfcs#428
- commit id: 410b16c
- Omnilock https://github.com/cryptape/omnilock
- commit id: cd764d7
- AnyoneCanPay https://github.com/cryptape/anyone-can-pay
- commit id: b845b3b
- AlwaysSuccess https://github.com/nervosnetwork/ckb-production-scripts/blob/master/c/always_success.c
- commit id: 410b16c
- Spore https://github.com/sporeprotocol/spore-contract
- version: 0.2.2-beta.1
- CKB-JS-VM https://github.com/nervosnetwork/ckb-js-vm
- version: 1.0.0
- Nostr-Lock https://github.com/cryptape/nostr-binding/tree/main/contracts/nostr-lock
- version: 25dd59d
- Type ID built-in
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.
offckb accounts
offckb accounts --show-private-keys # trusted local terminals onlyOn 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/keysfile. - 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.
offckb uses CCC as the development framework to build the CKB dApp template projects.
Sometimes you might encounter sudo permission problems. Granting the current user write access to the node_modules directory can resolve the problem.
sudo chown -R $(whoami) /usr/local/lib/node_modules
npm install -g @offckb/clicheck development doc