Skill: ngplateform/coc-node (version 1.2.0)

--- name: coc-node description: Operate COC (ChainOfClaw) blockchain nodes — install, start, stop, monitor, and remove validator, fullnode, archive, gateway, and dev nodes. Use when the user wants to run a COC node, inspect the status of a running node (block height, peer count, BFT state), view node logs, edit node-config.json, or probe RPC endpoints. Also covers preparing a machine to provide ≥ 256 MiB of P2P storage to the COC network. **Smooth out-of-box experience (1.2.0+):** read-only commands (list / status / coc-rpc-query against an installed node) work immediately after `openclaw plugins install` with zero config; the activation banner reports `data dir`, `storage quota`, `tracked nodes`, and `coc repo` status so the operator sees at a glance what works now and what (if anything) needs config to unlock install/start. Data dir auto-resolves to a writable path along the same chain @chainofclaw/claw-mem and @chainofclaw/soul use (`config.dataDir → $COC_NODE_DATA_DIR → $CLAW_MEM_DATA_DIR/coc-node → $OPENCLAW_STATE_DIR/coc-node → ~/.claw-mem/coc-node`); legacy `~/.chainofclaw/nodes.json` from pre-1.2.0 installs is detected as a fallback. Fail-fast actionable EACCES at activation rather than silent breakage mid-command. Starting / installing a node additionally requires a local clone of the COC source repo (set $COC_REPO_PATH or `bootstrap.cocRepoPath`); the activation banner tells you whether one was auto-detected. version: 1.2.0 metadata: openclaw: homepage: https://www.npmjs.com/package/@chainofclaw/node primaryEnv: CLAW_MEM_DATA_DIR requires: bins: - node anyBins: - coc-node - openclaw install: - kind: node package: "@chainofclaw/node" version: "1.2.0" bins: - coc-node --- # coc-node — COC blockchain node lifecycle Operate a COC node on this machine. The skill is backed by the npm package [`@chainofclaw/node`](https://www.npmjs.com/package/@chainofclaw/node) which ships both a standalone `coc-node` CLI and an OpenClaw plugin (skill id `coc-node`). ## What this skill can do - **Install** a new COC node of any type: `validator`, `fullnode`, `archive`, `gateway`, or `dev` - **Start / stop / restart** nodes; follow logs across the node / agent / relayer streams - **Report status** — block height, peer count, BFT activity, process PID, per-service health - **Edit** a node's `node-config.json` in `$EDITOR` - **Probe** any COC RPC endpoint safely (whitelisted methods only: `eth_blockNumber`, `eth_getBlockByNumber`, `net_peerCount`, `coc_chainStats`, `coc_getBftStatus`, `eth_syncing`, `eth_chainId`, …) ## Zero-config on install (1.2.0+) **Everything you can do without a COC source repo works immediately after `openclaw plugins install` — no further setup.** The activation banner makes it explicit: ``` [coc-node] data dir: /home/<you>/.claw-mem/coc-node [coc-node] storage quota: advertised=256 MiB, reserved=256 MiB, enforce=true [coc-node] tracked nodes: 0 [coc-node] coc repo: detected at /home/<you>/COC — install/start commands enabled [coc-node] Loaded — no nodes yet, run `openclaw coc-node node install <name>` to add one [coc-node] CLI is mounted at `openclaw coc-node ...`. ... ``` Or, if no COC repo is on this machine: ``` [coc-node] coc repo: not detected — read-only mode (list / status / coc-rpc-query work; install / start need bootstrap.cocRepoPath or $COC_REPO_PATH pointing at a COC source clone) ``` That second line is the **only** thing you need to read to know whether `node install` / `node start` will work. Everything else (list, status, log inspection, RPC probes against an already-running node) is unconditionally available. ### Data directory Auto-resolves to a writable path along a chain that's intentionally aligned with `@chainofclaw/claw-mem` and `@chainofclaw/soul` so the three plugins share one operator-managed root. Priority (highest first): 1. `config.dataDir` (per-instance plugin config) 2. `$COC_NODE_DATA_DIR` (coc-node-specific operator override) 3. `$CLAW_MEM_DATA_DIR/coc-node` (shared with claw-mem + soul — set this once and all three move together) 4. `$OPENCLAW_STATE_DIR/coc-node` (sandbox-managed state dir) 5. `~/.claw-mem/coc-node` (default — shared root with claw-mem + soul) 6. `~/.chainofclaw` (legacy pre-1.2.0 fallback; only picked when `nodes.json` already exists there) Fails fast at activation with an actionable EACCES error naming each tried path, rather than silently breaking mid-command. `/tmp` is intentionally not a fallback. ### What needs setup to start a node yourself Actually starting a node process requires the COC source repository (it spawns `node/src/index.ts` from there). Tell the skill where the repo is via **one of**: - `COC_REPO_PATH` environment variable (simplest) - `bootstrap.cocRepoPath` in plugin config - Run inside (or anywhere under) the COC repo — auto-discovered via marker files - Place a clone at `~/COC` — also auto-discovered Plus ≥ 256 MiB free disk for the P2P storage reservation (mandatory COC network entry requirement). The activation banner tells you whether the auto-detection succeeded. If `COC_REPO_PATH` is unset and no clone is at `~/COC`, `node install` and `node start` fail with a clear error pointing here — list / status / log / RPC commands keep working. ## Relationship with claw-mem and coc-soul The three `@chainofclaw/*` skills are **fully decoupled** at the npm-dependency level. Each can be installed independently. They cooperate through shared on-disk conventions, not through code coupling: | Skill | Owns | What it adds when paired | |---|---|---| | **coc-node** | Local node lifecycle (install / start / stop / status / RPC probe) | Independent of the other two. | | [claw-mem2db](https://clawhub.ai/ngplateform/claw-mem2db) | Persistent agent memory (chat + tool capture, FTS5 search, hybrid recall) | Pure agent-side; doesn't touch the chain. coc-node doesn't read or write to its DB. | | [coc-soul](https://clawhub.ai/ngplateform/coc-soul) | On-chain DID, IPFS backup, guardian recovery, carrier resurrection | Reads claw-mem's SQLite DB (when present) for semantic snapshots. Also independent of coc-node. | **Shared dataDir convention.** All three default to writing under `~/.claw-mem` (or under `$CLAW_MEM_DATA_DIR` / `$OPENCLAW_STATE_DIR`), each in a scoped subdirectory: - claw-mem → `~/.claw-mem/{claw-mem.db, config.json, ...}` - coc-soul → `~/.claw-mem/keys/agent.key` - coc-node → `~/.claw-mem/coc-node/{nodes.json, <node>/...}` So one [REDACTED_SECRET] env var moves all three. Operators in sandboxed Docker hosts (where `~/.claw-mem` is read-only) only have one knob to turn. ## How to invoke **Inside OpenClaw (recommended — works automatically after `plugins install`):** ```bash openclaw coc-node node install --type fullnode --network testnet openclaw coc-node node list openclaw coc-node node status openclaw coc-node node logs <name> --follow --all ``` **Standalone bin (only if you ran `npm i -g @chainofclaw/node` separately):** ```bash coc-node node install --type dev --network local --name dev-1 --rpc-port 28780 coc-node node list ``` > `openclaw plugins install` does NOT install the standalone `coc-node` binary into your PATH. Use `openclaw coc-node ...` (with the `openclaw` prefix), or install the bin globally via npm if you want the bare command. ## Typical flows 1. **Spin up a dev node against local hardhat** — `coc-node node install --type dev --network local` then `coc-node node start dev-1`. 2. **Join testnet as a fullnode** — `coc-node node install --type fullnode --network testnet --rpc-port 28780` then `coc-node node start`. 3. **Stand up a validator** — `coc-node node install --type validator --network testnet --advertised-bytes 1073741824` (1 GiB storage contribution). 4. **Diagnose a flaky node** — `coc-node node status` (snapshot) → `coc-node node logs --follow` (tail) → `coc-node node config show` (inspect config) → `coc-node node restart` if needed. 5. **Decommission a node** — `coc-node node stop NAME` then `coc-node node remove NAME --yes` (delete data) or `coc-node node remove NAME --yes --keep-data`. ## When NOT to use this skill - Deploying COC smart contracts — that's a `contracts/` hardhat / script task, not node lifecycle. - On-chain identity / backup / recovery — use the [coc-soul](https://clawhub.ai/ngplateform/coc-soul) skill. - Agent memory / session capture — use the [claw-mem2db](https://clawhub.ai/ngplateform/claw-mem2db) skill. ## Reference Detailed references live alongside this file: - `references/cli.md` — every `coc-node` subcommand with flags and examples - `references/config.md` — complete `~/.claw-mem/coc-node/config.json` schema - `references/node-types.md` — validator vs fullnode vs archive vs gateway vs dev tradeoffs - `references/troubleshooting.md` — common failure modes and fixes Source and issue tracker: <https://github.com/NGPlateform/claw-mem/tree/main/packages/node>.

path: references/cli.md
content: # `coc-node` CLI reference

All commands live under `coc-node node`. Every subcommand prints `--help` with full flag detail.

## `node install` (alias: `node init`)

Create a new node — generates `node-config.json`, writes to the registry, does **not** start the process.

| Flag | Meaning | Default |
|---|---|---|
| `-t, --type <type>` | `validator` / `fullnode` / `archive` / `gateway` / `dev` | `dev` |
| `-n, --network <net>` | `testnet` / `mainnet` / `local` / `custom` | `local` |
| `--name <name>` | Unique node name | auto-generated |
| `--data-dir <dir>` | Override data directory | `~/.chainofclaw/nodes/<name>` |
| `--rpc-port <n>` | JSON-RPC port | 18780 (local) / 28780 (testnet) |
| `--advertised-bytes <n>` | Storage to advertise to the P2P network | 268435456 (256 MiB min) |

## `node list`

Table of every node tracked by the registry. `--json` for machine-readable output.

## `node start [name]` / `node stop [name]` / `node restart [name]`

Omit `name` to apply to all registered nodes.

## `node status [name]`

Live status. Without `name`: prints each registered node. With `--json`: structured output including:

- `running` (bool), `pid`, `dataDir`
- `blockHeight`, `peerCount`, `bftActive` (only if RPC is reachable)
- `services.{node,agent,relayer}.{running, pid}`

## `node remove <name>`

Deregister a node.

- `--yes` — skip confirmation prompt
- `--keep-data` — preserve the data directory on disk (default: delete)

## `node config show [name]`

Pretty-print the node's `node-config.json`.

## `node config edit <name>`

Open `node-config.json` in `$EDITOR`.

## `node logs <name>`

Tail / follow logs.

- `--follow` (`-f`) — continuous tail (like `tail -F`)
- `--service <svc>` — `node` (default), `agent`, or `relayer`
- `--all` — interleave all three service logs
- `--lines <n>` — how many lines when not following (default 100)

## RPC probe

A read-only RPC helper is also exported by the underlying library. If you only need to inspect a remote node:

```ts
import { rpcCall, ALLOWED_RPC_METHODS } from "@chainofclaw/node";
const height = await rpcCall("http://remote:28780", "eth_blockNumber", []);
```

`ALLOWED_RPC_METHODS` is the allowlist — anything else fails at the client side (defense-in-depth against accidental exposure of mutating methods).


path: references/troubleshooting.md
content: # Troubleshooting

## `node start` fails with "COC repo not located"

The skill can't find the COC source repo. Either:

- Set env var: `export COC_REPO_PATH=/absolute/path/to/COC`
- Or edit config: `coc-node config set bootstrap.cocRepoPath /absolute/path/to/COC`
- Or cd into the COC repo before running `coc-node` (auto-discovery walks upward)

Read-only commands (`list`, `status`, `config show`) do not need this.

## Port already in use

Default local port is 18780; default testnet port is 28780. On collision, pass `--rpc-port` explicitly. Other derived ports (`ws`, `p2p`, `wire`, `ipfs`) are offset from `rpcPort`; see `node config show <name>` to see exactly which ports a node uses.

## `storage-reservation` warn

`enforceQuota: false` in config disables the reservation. For production, keep `enforceQuota: true` and mount `dataDir` on a dedicated disk so the reservation file doesn't collide with OS or home-dir files.

## Node shows "STOPPED" after `node start`

- Check `coc-node node logs NAME --follow` — most startup failures print a clear reason
- Verify Node.js version ≥ 22 (`node -v`)
- Verify `COC_REPO_PATH` points at a complete clone (run `ls $COC_REPO_PATH/node/src/index.ts`)

## RPC status empty

If `coc-node node status NAME` shows `RUNNING` but no `blockHeight`/`peerCount`:

- The node is up but RPC hasn't finished starting — retry in a few seconds
- Or RPC bind is non-localhost and can't be reached from the calling process — inspect `rpcBind` / `rpcPort` in `config show`

## Removing stale registry entries

If a node process died without being removed from the registry:

```bash
coc-node node remove NAME --yes --keep-data  # deregister without touching data
```

Then `coc-node node install --name NAME` will create a fresh registry entry.


path: references/config.md
content: # `~/.chainofclaw/config.json` schema

`coc-node` reads `$COC_NODE_CONFIG` if set, otherwise `~/.chainofclaw/config.json`. Missing keys fall back to defaults baked into the package.

```json
{
  "dataDir": "~/.chainofclaw",
  "node": {
    "enabled": true,
    "defaultType": "dev",
    "defaultNetwork": "local",
    "port": 18780,
    "bind": "127.0.0.1",
    "autoAdvertiseStorage": true
  },
  "storage": {
    "quotaBytes": 268435456,
    "advertisedBytes": 268435456,
    "reservedBytes": 268435456,
    "enforceQuota": true,
    "reserveFile": ".quota.reserved"
  },
  "bootstrap": {
    "cocRepoPath": "/path/to/COC"
  }
}
```

## Field reference

### `dataDir` (string)

Where node registry and per-node data directories live. `~` is expanded.

### `node.*`

| Key | Type | Default | Notes |
|---|---|---|---|
| `enabled` | bool | `true` | Gate for the whole skill; set `false` to disable plugin activation |
| `runtimeDir` | string | (COC repo's `runtime/`) | Where to find `coc-agent.ts` / `coc-relayer.ts` |
| `defaultType` | enum | `dev` | Used when `--type` is omitted |
| `defaultNetwork` | enum | `local` | Used when `--network` is omitted |
| `port` | number | `18780` | RPC port default |
| `bind` | string | `127.0.0.1` | Bind address |
| `autoAdvertiseStorage` | bool | `true` | Auto-pick `advertisedBytes` when omitted |

### `storage.*`

| Key | Type | Default | Notes |
|---|---|---|---|
| `quotaBytes` | number | `268435456` | Hard cap for this process's disk usage |
| `advertisedBytes` | number | `268435456` | P2P network claim (min 256 MiB) |
| `reservedBytes` | number | `268435456` | Pre-allocate via `fallocate` to prevent over-commit |
| `enforceQuota` | bool | `true` | When `false`, skip the reservation check |
| `reserveFile` | string | `.quota.reserved` | Name of the placeholder file |

### `bootstrap.cocRepoPath` (string)

Absolute path to your COC source-repo clone. Required for `node start` (spawn needs `node/src/index.ts` etc.). Read-only commands tolerate this being unset.


path: references/node-types.md
content: # Node types — when to choose which

`--type` at install time.

| Type | Role | Services | Rewards | Storage footprint |
|---|---|---|---|---|
| `dev` | Local development | node only; hardhat fake L1 | none | minimal, everything in memory |
| `fullnode` | Verifier + relay | node + agent | marginal (relay fees) | 256 MiB – several GiB |
| `validator` | BFT block production + verification | node + agent | high (block rewards + fees) | 256 MiB – TB (archive-grade optional) |
| `archive` | Historical state serving | node + agent + archive mode | moderate (PoSe service fees) | TB-scale |
| `gateway` | JSON-RPC / IPFS fan-out for clients | node + relayer | moderate (gateway fees) | 256 MiB – GiB |

## Choosing

- **First time, just want to poke around** → `dev` + `--network local` (hardhat). No chain identity, no gas.
- **Run a node that contributes storage to testnet** → `fullnode` + `--network testnet`. Minimum viable participant.
- **Become a validator** → requires stake + peer approval. `--type validator` installs the role; staking happens on-chain afterward.
- **Mirror full history** → `archive`. Expensive disk-wise; appropriate for block explorers and analytics.
- **Edge ingress for end-users** → `gateway`. Accepts RPC / IPFS from clients; no block production.

Validator selection is stake-weighted and rotates deterministically. See the [COC whitepaper §XII](https://github.com/NGPlateform/COC/blob/main/docs/COC_whitepaper.en.md) for the consensus model.


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)