@clawlabz/clawnetwork 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,33 +6,58 @@ Official ClawNetwork plugin for OpenClaw Gateway.
6
6
 
7
7
  ## Install
8
8
 
9
+ ### Quick Install (Recommended)
10
+
9
11
  ```bash
10
- openclaw plugins install @clawlabz/clawnetwork@latest --dangerously-force-unsafe-install
12
+ curl -sSf https://raw.githubusercontent.com/clawlabz/claw-network/main/clawnetwork-openclaw/install.sh | bash
11
13
  ```
12
14
 
13
- If you get a `Rate limit exceeded` error from ClawHub, install via npm instead:
15
+ Downloads from npm, installs the plugin, and configures your Gateway automatically. No rate limits, no extra flags.
16
+
17
+ Then restart your Gateway: `openclaw gateway restart`
18
+
19
+ ### OpenClaw CLI
14
20
 
15
21
  ```bash
16
- npm pack @clawlabz/clawnetwork@latest && openclaw plugins install ./clawlabz-clawnetwork-*.tgz --dangerously-force-unsafe-install && rm -f clawlabz-clawnetwork-*.tgz
22
+ openclaw plugins install @clawlabz/clawnetwork@latest --dangerously-force-unsafe-install
17
23
  ```
18
24
 
19
25
  > **Why the flag?** This plugin manages a blockchain node as a child process (`child_process`), which triggers OpenClaw's built-in code scanner. The flag confirms you trust this package. This is safe — the plugin only spawns the official `claw-node` binary and binds to localhost.
20
26
 
27
+ > **Tip:** If you hit a `Rate limit exceeded` error from ClawHub, use the Quick Install method above.
28
+
21
29
  Restart your Gateway and a light node starts automatically, joining the mainnet.
22
30
 
23
31
  ## Update
24
32
 
33
+ Re-run the install script — it detects the existing installation and updates in place:
34
+
35
+ ```bash
36
+ curl -sSf https://raw.githubusercontent.com/clawlabz/claw-network/main/clawnetwork-openclaw/install.sh | bash
37
+ ```
38
+
39
+ Or via OpenClaw CLI (uninstall + reinstall):
40
+
25
41
  ```bash
26
42
  openclaw plugins uninstall clawnetwork
27
43
  openclaw plugins install @clawlabz/clawnetwork@latest --dangerously-force-unsafe-install
28
44
  ```
29
45
 
30
- If ClawHub is rate-limited, use the npm one-liner above.
46
+ Then restart your Gateway: `openclaw gateway restart`
47
+
48
+ > **Your wallet and node data are safe.** Both methods only touch the plugin code. Your wallet, chain data, and node config are untouched.
49
+
50
+ ## Uninstall
51
+
52
+ ```bash
53
+ curl -sSf https://raw.githubusercontent.com/clawlabz/claw-network/main/clawnetwork-openclaw/uninstall.sh | bash
54
+ ```
55
+
56
+ Or: `openclaw plugins uninstall clawnetwork`
57
+
58
+ Then restart your Gateway: `openclaw gateway restart`
31
59
 
32
- > **Your wallet and node data are safe.** Uninstall only removes the plugin code (`~/.openclaw/extensions/clawnetwork/`). Your wallet (`~/.openclaw/workspace/clawnetwork/wallet.json`), chain data, and node config are untouched.
33
- >
34
- > Once [openclaw#60140](https://github.com/openclaw/openclaw/pull/60140) is merged, a single command will work:
35
- > `openclaw plugins update clawnetwork --dangerously-force-unsafe-install`
60
+ > Your wallet (`~/.openclaw/workspace/clawnetwork/wallet.json`), chain data (`~/.clawnetwork/`), and node binary are preserved. Delete manually for full cleanup.
36
61
 
37
62
  ## What happens on first start
38
63
 
package/index.ts CHANGED
@@ -975,6 +975,7 @@ function buildUiHtml(cfg: PluginConfig): string {
975
975
  </div>
976
976
  <div class="node-controls">
977
977
  <button class="btn primary" id="startBtn" onclick="doAction('start')">&#x25B6; Start Node</button>
978
+ <button class="btn" id="restartBtn" onclick="doRestart()" style="background:var(--accent);color:#000;font-weight:600">&#x21BB; Restart</button>
978
979
  <button class="btn danger" id="stopBtn" onclick="doAction('stop')">&#x25A0; Stop Node</button>
979
980
  </div>
980
981
  </div>
@@ -1413,6 +1414,16 @@ function buildUiHtml(cfg: PluginConfig): string {
1413
1414
  } catch (e) { toast('Error: ' + e.message); }
1414
1415
  }
1415
1416
 
1417
+ async function doRestart() {
1418
+ toast('Restarting node...');
1419
+ try {
1420
+ var res = await fetch(API + '/api/action/restart', { method: 'POST' });
1421
+ var data = await res.json();
1422
+ toast(data.message || data.error || 'Done');
1423
+ setTimeout(fetchStatus, 3000);
1424
+ } catch (e) { toast('Error: ' + e.message); }
1425
+ }
1426
+
1416
1427
  async function refreshLogs() {
1417
1428
  try {
1418
1429
  const res = await fetch(API + '/api/logs');
@@ -1749,12 +1760,65 @@ async function handle(req, res) {
1749
1760
  // Also kill by name (covers orphans)
1750
1761
  try { require('child_process').execFileSync('pkill', ['-f', 'claw-node start'], { timeout: 3000 }); } catch {}
1751
1762
  try { fs.unlinkSync(pidFile); } catch {}
1763
+ // Wait for process to actually exit (max 5s)
1764
+ for (let w = 0; w < 10; w++) {
1765
+ try { require('child_process').execSync("pgrep -f 'claw-node start'", { timeout: 1000 }); } catch { break; }
1766
+ require('child_process').execSync('sleep 0.5', { timeout: 2000 });
1767
+ }
1752
1768
  json(200, { message: 'Node stopped' });
1753
1769
  } catch (e) { json(500, { error: e.message }); }
1754
1770
  return;
1755
1771
  }
1756
1772
  if (a === 'restart') {
1757
- json(200, { message: 'Use Stop then Start to restart the node' });
1773
+ // Stop, wait, start all server-side
1774
+ try {
1775
+ const pidFile = path.join(os.homedir(), '.openclaw/workspace/clawnetwork/node.pid');
1776
+ try {
1777
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
1778
+ if (pid > 0) try { process.kill(pid, 'SIGTERM'); } catch {}
1779
+ } catch {}
1780
+ const stopFile = path.join(os.homedir(), '.openclaw/workspace/clawnetwork/stop.signal');
1781
+ try { fs.writeFileSync(stopFile, String(Date.now())); } catch {}
1782
+ try { require('child_process').execFileSync('pkill', ['-f', 'claw-node start'], { timeout: 3000 }); } catch {}
1783
+ try { fs.unlinkSync(pidFile); } catch {}
1784
+ // Wait for exit
1785
+ for (let w = 0; w < 10; w++) {
1786
+ try { require('child_process').execSync("pgrep -f 'claw-node start'", { timeout: 1000 }); } catch { break; }
1787
+ require('child_process').execSync('sleep 0.5', { timeout: 2000 });
1788
+ }
1789
+ try { fs.unlinkSync(stopFile); } catch {}
1790
+ // Now start (reuse start logic inline)
1791
+ const binDir = path.join(os.homedir(), '.openclaw/bin');
1792
+ const binName = process.platform === 'win32' ? 'claw-node.exe' : 'claw-node';
1793
+ let binary = path.join(binDir, binName);
1794
+ if (!fs.existsSync(binary)) { binary = path.join(os.homedir(), '.clawnetwork/bin/claw-node'); }
1795
+ if (!fs.existsSync(binary)) { json(400, { error: 'claw-node binary not found' }); return; }
1796
+ const cfgPath = path.join(os.homedir(), '.openclaw/workspace/clawnetwork/config.json');
1797
+ let network = 'mainnet', p2pPort = 9711, syncMode = 'light', extraPeers = [];
1798
+ try {
1799
+ const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
1800
+ if (cfg.network) network = cfg.network;
1801
+ if (cfg.p2pPort) p2pPort = cfg.p2pPort;
1802
+ if (cfg.syncMode) syncMode = cfg.syncMode;
1803
+ if (cfg.extraBootstrapPeers) extraPeers = cfg.extraBootstrapPeers;
1804
+ } catch {}
1805
+ const bootstrapPeers = { mainnet: ['/ip4/178.156.162.162/tcp/9711', '/ip4/39.102.144.231/tcp/9711'], testnet: ['/ip4/178.156.162.162/tcp/9721', '/ip4/39.102.144.231/tcp/9721'], devnet: [] };
1806
+ const peers = [...(bootstrapPeers[network] || []), ...extraPeers];
1807
+ const args = ['start', '--network', network, '--rpc-port', String(RPC_PORT), '--p2p-port', String(p2pPort), '--sync-mode', syncMode, '--allow-genesis'];
1808
+ for (const peer of peers) { args.push('--bootstrap', peer); }
1809
+ const logPath = path.join(os.homedir(), '.openclaw/workspace/clawnetwork/node.log');
1810
+ const logFd = fs.openSync(logPath, 'a');
1811
+ const { spawn: nodeSpawn } = require('child_process');
1812
+ const child = nodeSpawn(binary, args, {
1813
+ stdio: ['ignore', logFd, logFd],
1814
+ detached: true,
1815
+ env: { HOME: os.homedir(), PATH: process.env.PATH || '/usr/local/bin:/usr/bin:/bin', RUST_LOG: process.env.RUST_LOG || 'claw=info' },
1816
+ });
1817
+ child.unref();
1818
+ fs.closeSync(logFd);
1819
+ fs.writeFileSync(pidFile, String(child.pid));
1820
+ json(200, { message: 'Node restarted', pid: child.pid });
1821
+ } catch (e) { json(500, { error: e.message }); }
1758
1822
  return;
1759
1823
  }
1760
1824
  if (a === 'upgrade') {
@@ -1811,7 +1875,7 @@ async function handle(req, res) {
1811
1875
  newVersion = require('child_process').execFileSync(path.join(binDir, binName), ['--version'], { encoding: 'utf8', timeout: 5000 }).trim();
1812
1876
  } catch {}
1813
1877
 
1814
- json(200, { message: 'Upgraded to ' + newVersion + '. Restart the node from Dashboard.', newVersion });
1878
+ json(200, { message: 'Upgraded to ' + newVersion + '. Click Restart to apply.', newVersion });
1815
1879
  } catch (e) { json(500, { error: e.message }); }
1816
1880
  return;
1817
1881
  }
@@ -2,7 +2,7 @@
2
2
  "id": "clawnetwork",
3
3
  "name": "ClawNetwork Node",
4
4
  "description": "Run a ClawNetwork blockchain node inside OpenClaw. Every agent is a node.",
5
- "version": "0.1.11",
5
+ "version": "0.1.13",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawlabz/clawnetwork",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Run a ClawNetwork blockchain node inside OpenClaw. Every agent is a blockchain node.",
5
5
  "type": "module",
6
6
  "license": "MIT",