@bitsocial/bitsocial-cli 0.19.42 → 0.19.43

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
@@ -32,7 +32,7 @@ Bitsocial is p2p and decentralized social media protocol built completely with I
32
32
 
33
33
  ## Install
34
34
 
35
- Requires [Node.js 22](https://nodejs.org/) or later.
35
+ Requires Node.js 22 or later. We recommend using [nvm](https://github.com/nvm-sh/nvm) to install and manage Node.js versions.
36
36
 
37
37
  ```sh-session
38
38
  npm install -g @bitsocial/bitsocial-cli
@@ -344,7 +344,7 @@ EXAMPLES
344
344
  $ bitsocial challenge install ./my-local-challenge
345
345
  ```
346
346
 
347
- _See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/challenge/install.ts)_
347
+ _See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/challenge/install.ts)_
348
348
 
349
349
  ## `bitsocial challenge list`
350
350
 
@@ -367,7 +367,7 @@ EXAMPLES
367
367
  $ bitsocial challenge list -q
368
368
  ```
369
369
 
370
- _See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/challenge/list.ts)_
370
+ _See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/challenge/list.ts)_
371
371
 
372
372
  ## `bitsocial challenge remove NAME`
373
373
 
@@ -392,7 +392,7 @@ EXAMPLES
392
392
  $ bitsocial challenge remove @scope/my-challenge
393
393
  ```
394
394
 
395
- _See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/challenge/remove.ts)_
395
+ _See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/challenge/remove.ts)_
396
396
 
397
397
  ## `bitsocial community create`
398
398
 
@@ -417,7 +417,7 @@ EXAMPLES
417
417
  $ bitsocial community create --title 'Hello Plebs' --description 'Welcome'
418
418
  ```
419
419
 
420
- _See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/create.ts)_
420
+ _See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/create.ts)_
421
421
 
422
422
  ## `bitsocial community delete ADDRESSES`
423
423
 
@@ -442,7 +442,7 @@ EXAMPLES
442
442
  $ bitsocial community delete 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
443
443
  ```
444
444
 
445
- _See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/delete.ts)_
445
+ _See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/delete.ts)_
446
446
 
447
447
  ## `bitsocial community edit ADDRESS`
448
448
 
@@ -494,7 +494,7 @@ EXAMPLES
494
494
  $ bitsocial community edit plebbit.bso --settings.fetchThumbnailUrls=false
495
495
  ```
496
496
 
497
- _See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/edit.ts)_
497
+ _See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/edit.ts)_
498
498
 
499
499
  ## `bitsocial community get [ADDRESS]`
500
500
 
@@ -525,7 +525,7 @@ EXAMPLES
525
525
  $ bitsocial community get --publicKey 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
526
526
  ```
527
527
 
528
- _See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/get.ts)_
528
+ _See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/get.ts)_
529
529
 
530
530
  ## `bitsocial community list`
531
531
 
@@ -548,7 +548,7 @@ EXAMPLES
548
548
  $ bitsocial community list
549
549
  ```
550
550
 
551
- _See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/list.ts)_
551
+ _See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/list.ts)_
552
552
 
553
553
  ## `bitsocial community start ADDRESSES`
554
554
 
@@ -577,7 +577,7 @@ EXAMPLES
577
577
  $ bitsocial community start $(bitsocial community list -q)
578
578
  ```
579
579
 
580
- _See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/start.ts)_
580
+ _See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/start.ts)_
581
581
 
582
582
  ## `bitsocial community stop ADDRESSES`
583
583
 
@@ -602,7 +602,7 @@ EXAMPLES
602
602
  $ bitsocial community stop Qmb99crTbSUfKXamXwZBe829Vf6w5w5TktPkb6WstC9RFW
603
603
  ```
604
604
 
605
- _See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/community/stop.ts)_
605
+ _See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/community/stop.ts)_
606
606
 
607
607
  ## `bitsocial daemon`
608
608
 
@@ -613,9 +613,10 @@ USAGE
613
613
  $ bitsocial daemon --pkcRpcUrl <value> --logPath <value> [--chainProviderUrls <value>...]
614
614
 
615
615
  FLAGS
616
- --chainProviderUrls=<value>... [default: viem,https://ethrpc.xyz] Ethereum RPC URL(s) for .bso/.eth name resolution.
617
- Can be specified multiple times. Defaults to viem public transport and
618
- https://ethrpc.xyz
616
+ --chainProviderUrls=<value>... [default:
617
+ https://eth.drpc.org,https://ethereum.publicnode.com,https://ethereum-rpc.publicnode.c
618
+ om,https://rpc.mevblocker.io,https://1rpc.io/eth,https://eth-pokt.nodies.app] RPC
619
+ URL(s) for .bso name resolution. Can be specified multiple times.
619
620
  --logPath=<value> (required) [default: /home/runner/.local/state/bitsocial] Specify a directory which
620
621
  will be used to store logs
621
622
  --pkcRpcUrl=<value> (required) [default: ws://localhost:9138/] Specify PKC RPC URL to listen on
@@ -640,11 +641,9 @@ EXAMPLES
640
641
  $ bitsocial daemon --pkcOptions.kuboRpcClientsOptions[0] https://remoteipfsnode.com
641
642
 
642
643
  $ bitsocial daemon --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY
643
-
644
- $ bitsocial daemon --chainProviderUrls viem --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY
645
644
  ```
646
645
 
647
- _See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/daemon.ts)_
646
+ _See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/daemon.ts)_
648
647
 
649
648
  ## `bitsocial help [COMMAND]`
650
649
 
@@ -701,7 +700,7 @@ EXAMPLES
701
700
  $ bitsocial logs --since 1h -f
702
701
  ```
703
702
 
704
- _See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/logs.ts)_
703
+ _See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/logs.ts)_
705
704
 
706
705
  ## `bitsocial update check`
707
706
 
@@ -718,7 +717,7 @@ EXAMPLES
718
717
  $ bitsocial update check
719
718
  ```
720
719
 
721
- _See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/update/check.ts)_
720
+ _See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/update/check.ts)_
722
721
 
723
722
  ## `bitsocial update install [VERSION]`
724
723
 
@@ -726,13 +725,14 @@ Install a specific version of bitsocial from npm
726
725
 
727
726
  ```
728
727
  USAGE
729
- $ bitsocial update install [VERSION] [--force]
728
+ $ bitsocial update install [VERSION] [--force] [--restart-daemons]
730
729
 
731
730
  ARGUMENTS
732
731
  [VERSION] [default: latest] Version to install (e.g. "0.19.40" or "latest")
733
732
 
734
733
  FLAGS
735
- --force Reinstall even if already on the requested version
734
+ --force Reinstall even if already on the requested version
735
+ --[no-]restart-daemons Stop all running daemons, update, and restart them with the same settings
736
736
 
737
737
  DESCRIPTION
738
738
  Install a specific version of bitsocial from npm
@@ -745,9 +745,11 @@ EXAMPLES
745
745
  $ bitsocial update install 0.19.40
746
746
 
747
747
  $ bitsocial update install --force
748
+
749
+ $ bitsocial update install --no-restart-daemons
748
750
  ```
749
751
 
750
- _See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/update/install.ts)_
752
+ _See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/update/install.ts)_
751
753
 
752
754
  ## `bitsocial update versions`
753
755
 
@@ -769,7 +771,7 @@ EXAMPLES
769
771
  $ bitsocial update versions --limit 5
770
772
  ```
771
773
 
772
- _See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.42/src/cli/commands/update/versions.ts)_
774
+ _See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.43/src/cli/commands/update/versions.ts)_
773
775
  <!-- commandsstop -->
774
776
 
775
777
  ## Contribution
@@ -8,7 +8,8 @@ import { startDaemonServer } from "../../webui/daemon-server.js";
8
8
  import { printBanner } from "../ascii-banner.js";
9
9
  import { loadChallengesIntoPKC } from "../../challenge-packages/challenge-utils.js";
10
10
  import { migrateDataDirectory } from "../../common-utils/data-migration.js";
11
- import { createBsoResolvers } from "../../common-utils/resolvers.js";
11
+ import { createBsoResolvers, DEFAULT_PROVIDERS } from "../../common-utils/resolvers.js";
12
+ import { pruneStaleStates, writeDaemonState, deleteDaemonState } from "../../common-utils/daemon-state.js";
12
13
  import fs from "fs";
13
14
  import fsPromise from "fs/promises";
14
15
  /** Replace wildcard bind addresses with loopback for connectivity checks (macOS rejects connect to 0.0.0.0 with EINVAL) */
@@ -48,9 +49,9 @@ export default class Daemon extends Command {
48
49
  default: defaults.PKC_LOG_PATH
49
50
  }),
50
51
  chainProviderUrls: Flags.string({
51
- description: 'Ethereum RPC URL(s) for .bso/.eth name resolution. Can be specified multiple times. Defaults to viem public transport and https://ethrpc.xyz',
52
+ description: "RPC URL(s) for .bso name resolution. Can be specified multiple times.",
52
53
  multiple: true,
53
- default: ["viem", "https://ethrpc.xyz"]
54
+ default: DEFAULT_PROVIDERS
54
55
  })
55
56
  };
56
57
  static examples = [
@@ -59,7 +60,6 @@ export default class Daemon extends Command {
59
60
  "bitsocial daemon --pkcOptions.dataPath /tmp/bitsocial-datapath/",
60
61
  "bitsocial daemon --pkcOptions.kuboRpcClientsOptions[0] https://remoteipfsnode.com",
61
62
  "bitsocial daemon --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY",
62
- "bitsocial daemon --chainProviderUrls viem --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY"
63
63
  ];
64
64
  _setupLogger(Logger) {
65
65
  setupDebugLogger(Logger, { enableDefaultNamespace: true });
@@ -84,7 +84,11 @@ export default class Daemon extends Command {
84
84
  deletedLogFile = logFileToDelete;
85
85
  await fsPromise.rm(path.join(logPath, logFileToDelete));
86
86
  }
87
- return { logFilePath: path.join(logPath, `bitsocial_cli_daemon_${new Date().toISOString().replace(/:/g, "-")}.log`), deletedLogFile, logfilesCapacity };
87
+ return {
88
+ logFilePath: path.join(logPath, `bitsocial_cli_daemon_${new Date().toISOString().replace(/:/g, "-")}.log`),
89
+ deletedLogFile,
90
+ logfilesCapacity
91
+ };
88
92
  }
89
93
  async _pipeDebugLogsToLogFile(logPath, Logger) {
90
94
  const { logFilePath, deletedLogFile, logfilesCapacity } = await this._getNewLogfileByEvacuatingOldLogsIfNeeded(logPath);
@@ -202,11 +206,24 @@ export default class Daemon extends Command {
202
206
  defaultPkcOptions.kuboRpcClientsOptions = [kuboRpcEndpoint.toString()];
203
207
  const mergedPkcOptions = { ...defaultPkcOptions, ...pkcOptionsFromFlag };
204
208
  log("Merged pkc options that will be used for this node", mergedPkcOptions);
209
+ const { nameResolvers: _nr, ...printablePkcOptions } = mergedPkcOptions;
210
+ console.log("PKC options:", JSON.stringify(printablePkcOptions, null, 2));
205
211
  // Migrate data directory before creating PKC instance
206
212
  migrateDataDirectory(mergedPkcOptions.dataPath);
213
+ // Prune stale daemon state files (dead PIDs from crashed daemons)
214
+ await pruneStaleStates();
215
+ // Persist this daemon's PID and startup args so `bitsocial update install --restart-daemons` can stop and restart it
216
+ const daemonArgv = process.argv.slice(process.argv.indexOf("daemon") + 1);
217
+ await writeDaemonState({
218
+ pid: process.pid,
219
+ startedAt: new Date().toISOString(),
220
+ argv: daemonArgv,
221
+ pkcRpcUrl: pkcRpcUrl.toString()
222
+ });
207
223
  // Create BSO name resolvers for .bso/.eth domain resolution
208
224
  const bsoResolvers = createBsoResolvers(flags.chainProviderUrls, mergedPkcOptions.dataPath);
209
225
  mergedPkcOptions.nameResolvers = [...(mergedPkcOptions.nameResolvers || []), ...bsoResolvers];
226
+ console.log(".bso name resolvers:", bsoResolvers.map((r) => r.provider).join(", "));
210
227
  let mainProcessExited = false;
211
228
  let pendingKuboStart;
212
229
  // Kubo Node may fail randomly, we need to set a listener so when it exits because of an error we restart it
@@ -423,6 +440,8 @@ export default class Daemon extends Command {
423
440
  console.log("\nShutting down Bitsocial daemon, it may take a few seconds to shut down all communities and the IPFS node...");
424
441
  log("Received signal to exit, shutting down both kubo and pkc rpc. Please wait, it may take a few seconds");
425
442
  mainProcessExited = true;
443
+ // Remove daemon state file so update install knows we're gone
444
+ await deleteDaemonState(process.pid).catch(() => { });
426
445
  // Start killing Kubo immediately, in parallel with daemon server destroy.
427
446
  // This way Kubo receives SIGINT right away, even if daemonServer.destroy() hangs.
428
447
  const kuboKillPromise = killKuboProcess();
@@ -6,7 +6,9 @@ export default class Install extends Command {
6
6
  };
7
7
  static flags: {
8
8
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ "restart-daemons": import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
10
  };
10
11
  static examples: string[];
11
12
  run(): Promise<void>;
13
+ private _restartDaemons;
12
14
  }
@@ -1,8 +1,9 @@
1
1
  import { Args, Flags, Command } from "@oclif/core";
2
+ import { spawn } from "child_process";
2
3
  import tcpPortUsed from "tcp-port-used";
3
- import defaults from "../../../common-utils/defaults.js";
4
4
  import { fetchLatestVersion, installGlobal } from "../../../update/npm-registry.js";
5
5
  import { compareVersions } from "../../../update/semver.js";
6
+ import { getAliveDaemonStates } from "../../../common-utils/daemon-state.js";
6
7
  export default class Install extends Command {
7
8
  static description = "Install a specific version of bitsocial from npm";
8
9
  static args = {
@@ -16,21 +17,54 @@ export default class Install extends Command {
16
17
  force: Flags.boolean({
17
18
  description: "Reinstall even if already on the requested version",
18
19
  default: false
20
+ }),
21
+ "restart-daemons": Flags.boolean({
22
+ description: "Stop all running daemons, update, and restart them with the same settings",
23
+ default: true,
24
+ allowNo: true
19
25
  })
20
26
  };
21
27
  static examples = [
22
28
  "bitsocial update install",
23
29
  "bitsocial update install latest",
24
30
  "bitsocial update install 0.19.40",
25
- "bitsocial update install --force"
31
+ "bitsocial update install --force",
32
+ "bitsocial update install --no-restart-daemons"
26
33
  ];
27
34
  async run() {
28
35
  const { args, flags } = await this.parse(Install);
29
- // Check if daemon is running refuse to update while it's active
30
- const rpcPort = Number(defaults.PKC_RPC_URL.port);
31
- const daemonRunning = await tcpPortUsed.check(rpcPort, "127.0.0.1").catch(() => false);
32
- if (daemonRunning) {
33
- this.error(`Daemon is running on port ${rpcPort}. Stop it first with Ctrl-C, then run 'bitsocial update install'.`, { exit: 1 });
36
+ // Check for running daemons via state files
37
+ const aliveDaemons = await getAliveDaemonStates();
38
+ if (aliveDaemons.length > 0) {
39
+ if (!flags["restart-daemons"]) {
40
+ this.error(`${aliveDaemons.length} daemon(s) running. Stop them first, then retry.`, { exit: 1 });
41
+ }
42
+ // Stop all running daemons
43
+ for (const d of aliveDaemons) {
44
+ this.log(`Stopping daemon (PID ${d.pid})...`);
45
+ try {
46
+ process.kill(d.pid, "SIGINT");
47
+ }
48
+ catch (e) {
49
+ if (e.code === "ESRCH") {
50
+ this.log(` PID ${d.pid} already exited.`);
51
+ continue;
52
+ }
53
+ throw e;
54
+ }
55
+ }
56
+ // Wait for all daemon ports to be free
57
+ for (const d of aliveDaemons) {
58
+ const url = new URL(d.pkcRpcUrl);
59
+ const port = Number(url.port);
60
+ const host = url.hostname;
61
+ this.log(`Waiting for port ${port} to be free...`);
62
+ const freed = await tcpPortUsed.waitUntilFree(port, 500, 30000).then(() => true).catch(() => false);
63
+ if (!freed) {
64
+ this.error(`Daemon (PID ${d.pid}) did not shut down within 30 seconds on port ${port}.`, { exit: 1 });
65
+ }
66
+ }
67
+ this.log("All daemons stopped.");
34
68
  }
35
69
  // Resolve the target version
36
70
  let targetVersion;
@@ -49,6 +83,10 @@ export default class Install extends Command {
49
83
  // Skip if already on this version (unless --force)
50
84
  if (compareVersions(current, targetVersion) === 0 && !flags.force) {
51
85
  this.log(`Already on v${current}. Use --force to reinstall.`);
86
+ if (aliveDaemons.length > 0 && flags["restart-daemons"]) {
87
+ // We stopped daemons but don't need to update — restart them
88
+ await this._restartDaemons(aliveDaemons);
89
+ }
52
90
  return;
53
91
  }
54
92
  this.log(`Installing bitsocial-cli@${targetVersion}...`);
@@ -59,5 +97,35 @@ export default class Install extends Command {
59
97
  this.error(`Update failed: ${err.message}`, { exit: 1 });
60
98
  }
61
99
  this.log(`Installed bitsocial v${targetVersion} (was v${current}).`);
100
+ // Restart daemons with the new binary
101
+ if (aliveDaemons.length > 0 && flags["restart-daemons"]) {
102
+ await this._restartDaemons(aliveDaemons);
103
+ }
104
+ }
105
+ async _restartDaemons(daemons) {
106
+ this.log(`Restarting ${daemons.length} daemon(s)...`);
107
+ for (const d of daemons) {
108
+ const argStr = d.argv.length > 0 ? d.argv.join(" ") : "(defaults)";
109
+ this.log(` Starting daemon with args: ${argStr}`);
110
+ const child = spawn("bitsocial", ["daemon", ...d.argv], {
111
+ detached: true,
112
+ stdio: "ignore"
113
+ });
114
+ child.unref();
115
+ if (!child.pid) {
116
+ this.warn(`Failed to spawn daemon for args: ${argStr}`);
117
+ continue;
118
+ }
119
+ // Wait briefly for the daemon's RPC port to come up
120
+ const url = new URL(d.pkcRpcUrl);
121
+ const port = Number(url.port);
122
+ const started = await tcpPortUsed.waitUntilUsed(port, 500, 30000).then(() => true).catch(() => false);
123
+ if (started) {
124
+ this.log(` Daemon started (port ${port}).`);
125
+ }
126
+ else {
127
+ this.warn(` Daemon may not have started — port ${port} not responding after 30s. Check logs with: bitsocial logs`);
128
+ }
129
+ }
62
130
  }
63
131
  }
@@ -0,0 +1,16 @@
1
+ export interface DaemonState {
2
+ pid: number;
3
+ startedAt: string;
4
+ argv: string[];
5
+ pkcRpcUrl: string;
6
+ }
7
+ /** Write a daemon state file atomically (write to .tmp then rename). */
8
+ export declare function writeDaemonState(state: DaemonState): Promise<void>;
9
+ /** Read all state files from the daemon states directory. */
10
+ export declare function readAllDaemonStates(): Promise<DaemonState[]>;
11
+ /** Delete a specific daemon's state file. Ignores ENOENT. */
12
+ export declare function deleteDaemonState(pid: number): Promise<void>;
13
+ /** Delete state files for dead PIDs from disk. */
14
+ export declare function pruneStaleStates(): Promise<void>;
15
+ /** Read all states, delete stale files (dead PIDs) from disk, return only alive ones. */
16
+ export declare function getAliveDaemonStates(): Promise<DaemonState[]>;
@@ -0,0 +1,85 @@
1
+ import defaults from "./defaults.js";
2
+ import path from "path";
3
+ import fs from "fs/promises";
4
+ const DAEMON_STATES_DIR = path.join(defaults.PKC_DATA_PATH, ".daemon_states");
5
+ function stateFilePath(pid) {
6
+ return path.join(DAEMON_STATES_DIR, `${pid}-daemon.state`);
7
+ }
8
+ /** Write a daemon state file atomically (write to .tmp then rename). */
9
+ export async function writeDaemonState(state) {
10
+ await fs.mkdir(DAEMON_STATES_DIR, { recursive: true });
11
+ const dest = stateFilePath(state.pid);
12
+ const tmp = dest + ".tmp";
13
+ await fs.writeFile(tmp, JSON.stringify(state, null, 2));
14
+ await fs.rename(tmp, dest);
15
+ }
16
+ /** Read all state files from the daemon states directory. */
17
+ export async function readAllDaemonStates() {
18
+ let entries;
19
+ try {
20
+ entries = await fs.readdir(DAEMON_STATES_DIR);
21
+ }
22
+ catch (e) {
23
+ if (e.code === "ENOENT")
24
+ return [];
25
+ throw e;
26
+ }
27
+ const states = [];
28
+ for (const entry of entries) {
29
+ if (!entry.endsWith("-daemon.state"))
30
+ continue;
31
+ try {
32
+ const content = await fs.readFile(path.join(DAEMON_STATES_DIR, entry), "utf-8");
33
+ states.push(JSON.parse(content));
34
+ }
35
+ catch {
36
+ // Corrupted or partially written — skip
37
+ }
38
+ }
39
+ return states;
40
+ }
41
+ /** Delete a specific daemon's state file. Ignores ENOENT. */
42
+ export async function deleteDaemonState(pid) {
43
+ try {
44
+ await fs.unlink(stateFilePath(pid));
45
+ }
46
+ catch (e) {
47
+ if (e.code !== "ENOENT")
48
+ throw e;
49
+ }
50
+ }
51
+ /** Check whether a PID is alive. */
52
+ function isPidAlive(pid) {
53
+ try {
54
+ process.kill(pid, 0);
55
+ return true;
56
+ }
57
+ catch (e) {
58
+ if (e.code === "EPERM")
59
+ return true; // alive but owned by another user
60
+ return false; // ESRCH — no such process
61
+ }
62
+ }
63
+ /** Delete state files for dead PIDs from disk. */
64
+ export async function pruneStaleStates() {
65
+ const states = await readAllDaemonStates();
66
+ for (const state of states) {
67
+ if (!isPidAlive(state.pid)) {
68
+ await deleteDaemonState(state.pid);
69
+ }
70
+ }
71
+ }
72
+ /** Read all states, delete stale files (dead PIDs) from disk, return only alive ones. */
73
+ export async function getAliveDaemonStates() {
74
+ const states = await readAllDaemonStates();
75
+ const alive = [];
76
+ for (const state of states) {
77
+ if (isPidAlive(state.pid)) {
78
+ alive.push(state);
79
+ }
80
+ else {
81
+ await deleteDaemonState(state.pid);
82
+ }
83
+ }
84
+ return alive;
85
+ }
@@ -1,2 +1,3 @@
1
1
  import { BsoResolver } from "@bitsocial/bso-resolver";
2
+ export declare const DEFAULT_PROVIDERS: string[];
2
3
  export declare function createBsoResolvers(providers?: string[], dataPath?: string): BsoResolver[];
@@ -1,5 +1,12 @@
1
1
  import { BsoResolver } from "@bitsocial/bso-resolver";
2
- const DEFAULT_PROVIDERS = ["viem", "https://ethrpc.xyz"];
2
+ export const DEFAULT_PROVIDERS = [
3
+ "https://eth.drpc.org",
4
+ "https://ethereum.publicnode.com",
5
+ "https://ethereum-rpc.publicnode.com",
6
+ "https://rpc.mevblocker.io",
7
+ "https://1rpc.io/eth",
8
+ "https://eth-pokt.nodies.app"
9
+ ];
3
10
  export function createBsoResolvers(providers, dataPath) {
4
11
  const resolverProviders = providers && providers.length > 0 ? providers : DEFAULT_PROVIDERS;
5
12
  return resolverProviders.map((provider) => new BsoResolver({ key: `bso-${provider}`, provider, dataPath }));
@@ -9,8 +9,7 @@
9
9
  "bitsocial daemon --pkcRpcUrl ws://localhost:53812",
10
10
  "bitsocial daemon --pkcOptions.dataPath /tmp/bitsocial-datapath/",
11
11
  "bitsocial daemon --pkcOptions.kuboRpcClientsOptions[0] https://remoteipfsnode.com",
12
- "bitsocial daemon --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY",
13
- "bitsocial daemon --chainProviderUrls viem --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY"
12
+ "bitsocial daemon --chainProviderUrls https://mainnet.infura.io/v3/YOUR_KEY"
14
13
  ],
15
14
  "flags": {
16
15
  "pkcRpcUrl": {
@@ -32,11 +31,15 @@
32
31
  "type": "option"
33
32
  },
34
33
  "chainProviderUrls": {
35
- "description": "Ethereum RPC URL(s) for .bso/.eth name resolution. Can be specified multiple times. Defaults to viem public transport and https://ethrpc.xyz",
34
+ "description": "RPC URL(s) for .bso name resolution. Can be specified multiple times.",
36
35
  "name": "chainProviderUrls",
37
36
  "default": [
38
- "viem",
39
- "https://ethrpc.xyz"
37
+ "https://eth.drpc.org",
38
+ "https://ethereum.publicnode.com",
39
+ "https://ethereum-rpc.publicnode.com",
40
+ "https://rpc.mevblocker.io",
41
+ "https://1rpc.io/eth",
42
+ "https://eth-pokt.nodies.app"
40
43
  ],
41
44
  "hasDynamicHelp": false,
42
45
  "multiple": true,
@@ -640,7 +643,8 @@
640
643
  "bitsocial update install",
641
644
  "bitsocial update install latest",
642
645
  "bitsocial update install 0.19.40",
643
- "bitsocial update install --force"
646
+ "bitsocial update install --force",
647
+ "bitsocial update install --no-restart-daemons"
644
648
  ],
645
649
  "flags": {
646
650
  "force": {
@@ -648,6 +652,12 @@
648
652
  "name": "force",
649
653
  "allowNo": false,
650
654
  "type": "boolean"
655
+ },
656
+ "restart-daemons": {
657
+ "description": "Stop all running daemons, update, and restart them with the same settings",
658
+ "name": "restart-daemons",
659
+ "allowNo": true,
660
+ "type": "boolean"
651
661
  }
652
662
  },
653
663
  "hasDynamicHelp": false,
@@ -703,5 +713,5 @@
703
713
  ]
704
714
  }
705
715
  },
706
- "version": "0.19.42"
716
+ "version": "0.19.43"
707
717
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitsocial/bitsocial-cli",
3
- "version": "0.19.42",
3
+ "version": "0.19.43",
4
4
  "description": "Command line interface to Bitsocial API",
5
5
  "types": "./dist/index.d.ts",
6
6
  "homepage": "https://github.com/bitsocialnet/bitsocial-cli",
@@ -111,13 +111,13 @@
111
111
  "wait-on": "6.0.1"
112
112
  },
113
113
  "dependencies": {
114
- "@bitsocial/bso-resolver": "0.0.4",
114
+ "@bitsocial/bso-resolver": "0.0.5",
115
115
  "@multiformats/multiaddr": "13.0.1",
116
116
  "@oclif/core": "4.8.0",
117
117
  "@oclif/plugin-help": "6.2.36",
118
118
  "@oclif/plugin-not-found": "3.2.73",
119
119
  "@oclif/table": "0.5.1",
120
- "@pkcprotocol/pkc-js": "0.0.16",
120
+ "@pkcprotocol/pkc-js": "0.0.17",
121
121
  "dataobject-parser": "1.2.22",
122
122
  "decompress": "4.2.1",
123
123
  "env-paths": "2.2.1",