@cogcoin/client 1.2.3 → 1.2.5

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.
Files changed (36) hide show
  1. package/README.md +12 -2
  2. package/dist/bitcoind/managed-bitcoind-service-config.d.ts +5 -1
  3. package/dist/bitcoind/managed-bitcoind-service-config.js +27 -18
  4. package/dist/bitcoind/managed-bitcoind-service-lifecycle.js +46 -3
  5. package/dist/bitcoind/managed-bitcoind-service-status.d.ts +9 -2
  6. package/dist/bitcoind/managed-bitcoind-service-status.js +65 -9
  7. package/dist/bitcoind/managed-bitcoind-service-types.d.ts +8 -0
  8. package/dist/bitcoind/managed-runtime/bitcoind-policy.js +27 -0
  9. package/dist/bitcoind/managed-runtime/bitcoind-runtime.js +6 -0
  10. package/dist/bitcoind/managed-runtime/types.d.ts +2 -2
  11. package/dist/bitcoind/retryable-rpc.d.ts +1 -0
  12. package/dist/bitcoind/retryable-rpc.js +19 -2
  13. package/dist/cli/command-registry.js +2 -2
  14. package/dist/cli/commands/service-runtime.js +22 -2
  15. package/dist/cli/commands/status.js +7 -1
  16. package/dist/cli/commands/wallet-admin.js +8 -2
  17. package/dist/cli/context.js +2 -0
  18. package/dist/cli/output/rules/cli-surface.js +7 -0
  19. package/dist/cli/output/rules/services.js +7 -0
  20. package/dist/cli/parse.js +9 -0
  21. package/dist/cli/status-format.d.ts +2 -2
  22. package/dist/cli/status-format.js +167 -28
  23. package/dist/cli/types.d.ts +3 -0
  24. package/dist/passive-status.d.ts +49 -1
  25. package/dist/passive-status.js +208 -2
  26. package/dist/wallet/lifecycle/context.js +1 -0
  27. package/dist/wallet/lifecycle/repair-bitcoind.js +44 -1
  28. package/dist/wallet/lifecycle/repair-runtime.d.ts +3 -1
  29. package/dist/wallet/lifecycle/repair-runtime.js +12 -0
  30. package/dist/wallet/lifecycle/repair.js +31 -9
  31. package/dist/wallet/lifecycle/types.d.ts +7 -0
  32. package/dist/wallet/mining/competitiveness.js +2 -2
  33. package/dist/wallet/mining/lifecycle.js +4 -0
  34. package/dist/wallet/mining/mempool-index.js +29 -3
  35. package/dist/wallet/read/managed-bitcoind.js +9 -0
  36. package/package.json +1 -1
@@ -38,7 +38,10 @@ function getResetNextSteps(result) {
38
38
  ? ["Run `cogcoin init` to create or restore a wallet."]
39
39
  : ["Run `cogcoin sync` to bootstrap assumeutxo and the managed Bitcoin/indexer state."];
40
40
  }
41
- function getRepairNextSteps() {
41
+ function getRepairNextSteps(result) {
42
+ if (result.bitcoindPostRepairHealth === "starting") {
43
+ return ["Wait for Bitcoin Core to finish loading, then run `cogcoin status` or rerun `cogcoin mine`."];
44
+ }
42
45
  return ["Run `cogcoin status` to review the repaired local state."];
43
46
  }
44
47
  function formatResetBitcoinDataDirStatus(result) {
@@ -116,7 +119,7 @@ function buildRepairWarningEntries(result) {
116
119
  return entries;
117
120
  }
118
121
  function formatRepairResultText(result) {
119
- const nextStep = getRepairNextSteps()[0] ?? null;
122
+ const nextStep = getRepairNextSteps(result)[0] ?? null;
120
123
  const warningEntries = buildRepairWarningEntries(result);
121
124
  const sections = [
122
125
  formatAdminSection("Wallet", [
@@ -244,6 +247,9 @@ export async function runWalletAdminCommand(parsed, context) {
244
247
  provider: repairProvider,
245
248
  assumeYes: parsed.assumeYes,
246
249
  paths: runtimePaths,
250
+ progress: async (event) => {
251
+ writeLine(context.stdout, event.message);
252
+ },
247
253
  });
248
254
  writeLine(context.stdout, formatRepairResultText(result));
249
255
  return 0;
@@ -3,6 +3,7 @@ import { mkdir } from "node:fs/promises";
3
3
  import { attachOrStartIndexerDaemon, probeIndexerDaemon, readObservedIndexerDaemonStatus, stopIndexerDaemonService, } from "../bitcoind/indexer-daemon.js";
4
4
  import { createRpcClient } from "../bitcoind/node.js";
5
5
  import { attachOrStartManagedBitcoindService, probeManagedBitcoindService, stopManagedBitcoindService, } from "../bitcoind/service.js";
6
+ import { refreshManagedBitcoindStatus } from "../bitcoind/managed-bitcoind-service-status.js";
6
7
  import { resolveDefaultBitcoindDataDirForTesting, resolveDefaultClientDatabasePathForTesting, resolveDefaultUpdateCheckStatePathForTesting, } from "../app-paths.js";
7
8
  import { openManagedBitcoindClient } from "../bitcoind/index.js";
8
9
  import { openManagedIndexerMonitor } from "../bitcoind/indexer-monitor.js";
@@ -106,6 +107,7 @@ export function createDefaultContext(overrides = {}) {
106
107
  }),
107
108
  attachManagedBitcoindService: overrides.attachManagedBitcoindService ?? attachOrStartManagedBitcoindService,
108
109
  probeManagedBitcoindService: overrides.probeManagedBitcoindService ?? probeManagedBitcoindService,
110
+ refreshManagedBitcoindServiceStatus: overrides.refreshManagedBitcoindServiceStatus ?? refreshManagedBitcoindStatus,
109
111
  stopManagedBitcoindService: overrides.stopManagedBitcoindService ?? stopManagedBitcoindService,
110
112
  createBitcoinRpcClient: overrides.createBitcoinRpcClient ?? createRpcClient,
111
113
  attachIndexerDaemon: overrides.attachIndexerDaemon ?? attachOrStartIndexerDaemon,
@@ -77,6 +77,13 @@ export const cliSurfaceErrorRules = [
77
77
  next: "Drop `--satvb` for this command, or use it with a wallet mutation command like `cogcoin register` or `cogcoin send`.",
78
78
  };
79
79
  }
80
+ if (errorCode === "cli_live_not_supported_for_command") {
81
+ return {
82
+ what: "This command does not support `--live`.",
83
+ why: "`--live` only applies to `cogcoin status`, where it opts into RPC-backed wallet and service checks.",
84
+ next: "Drop `--live`, or run `cogcoin status --live`.",
85
+ };
86
+ }
80
87
  if (errorCode === "cli_anchor_clear_removed") {
81
88
  return {
82
89
  what: "`anchor clear` is no longer available.",
@@ -21,6 +21,13 @@ export const serviceErrorRules = [
21
21
  next: "Rerun the command in an interactive terminal.",
22
22
  };
23
23
  }
24
+ if (errorCode === "managed_bitcoind_service_starting" || /^bitcoind_rpc_[^_]+_-28(?:_|$)/.test(errorCode)) {
25
+ return {
26
+ what: "Bitcoin Core is still loading.",
27
+ why: "The managed Bitcoin RPC service is alive, but Bitcoin Core is still warming up and returned its normal startup -28 response.",
28
+ next: "Wait for the node to finish loading, then rerun the command. Use `cogcoin status` to check readiness.",
29
+ };
30
+ }
24
31
  if (errorCode.includes("tip_mismatch") || errorCode.includes("stale") || errorCode.includes("catching_up") || errorCode.includes("starting")) {
25
32
  return {
26
33
  what: "Trusted service state is not ready.",
package/dist/cli/parse.js CHANGED
@@ -37,6 +37,7 @@ export function parseCliArgs(argv) {
37
37
  let listLimit = null;
38
38
  let listAll = false;
39
39
  let follow = false;
40
+ let statusLive = false;
40
41
  for (let index = 0; index < argv.length; index += 1) {
41
42
  const token = argv[index];
42
43
  if (token === "--help") {
@@ -238,6 +239,10 @@ export function parseCliArgs(argv) {
238
239
  follow = true;
239
240
  continue;
240
241
  }
242
+ if (token === "--live") {
243
+ statusLive = true;
244
+ continue;
245
+ }
241
246
  if (token === "--yes") {
242
247
  assumeYes = true;
243
248
  continue;
@@ -448,6 +453,9 @@ export function parseCliArgs(argv) {
448
453
  if (follow && command !== "mine-log") {
449
454
  throw new Error("cli_follow_not_supported_for_command");
450
455
  }
456
+ if (statusLive && command !== "status") {
457
+ throw new Error("cli_live_not_supported_for_command");
458
+ }
451
459
  if (command === "mine-log" && follow && (listAll || listLimit !== null)) {
452
460
  throw new Error("cli_follow_limit_not_supported");
453
461
  }
@@ -502,5 +510,6 @@ export function parseCliArgs(argv) {
502
510
  listLimit,
503
511
  listAll,
504
512
  follow,
513
+ statusLive,
505
514
  };
506
515
  }
@@ -1,2 +1,2 @@
1
- import type { inspectPassiveClientStatus } from "../passive-status.js";
2
- export declare function formatStatusReport(status: Awaited<ReturnType<typeof inspectPassiveClientStatus>>): string;
1
+ import type { PassiveClientStatus } from "../passive-status.js";
2
+ export declare function formatStatusReport(status: PassiveClientStatus, version: string): string;
@@ -1,48 +1,187 @@
1
+ function row(ok, text) {
2
+ return { ok, text };
3
+ }
4
+ function formatMarker(ok) {
5
+ return ok ? "✓" : "✗";
6
+ }
7
+ function formatValue(value) {
8
+ return value === null || value === undefined || value === "" ? "none" : String(value);
9
+ }
10
+ function formatYesNo(value) {
11
+ return value ? "yes" : "no";
12
+ }
1
13
  function formatBootstrapPercent(current, total) {
2
14
  if (total <= 0) {
3
15
  return "0.00";
4
16
  }
5
17
  return ((current / total) * 100).toFixed(2);
6
18
  }
7
- export function formatStatusReport(status) {
8
- const lines = [
9
- "Cogcoin Client Status",
10
- `DB path: ${status.dbPath}`,
11
- `Bitcoin datadir: ${status.bitcoinDataDir}`,
12
- `Store exists: ${status.storeExists ? "yes" : "no"}`,
13
- `Store initialized: ${status.storeInitialized ? "yes" : "no"}`,
19
+ function formatSignedDelta(value) {
20
+ if (value > 0) {
21
+ return `+${value}`;
22
+ }
23
+ return String(value);
24
+ }
25
+ function formatSection(title, rows) {
26
+ return [
27
+ title,
28
+ ...rows.map((entry) => `${formatMarker(entry.ok)} ${entry.text}`),
29
+ ].join("\n");
30
+ }
31
+ function buildPathsRows(status) {
32
+ return [
33
+ row(true, `DB path: ${status.dbPath}`),
34
+ row(true, `Bitcoin datadir: ${status.bitcoinDataDir}`),
35
+ ];
36
+ }
37
+ function buildWalletRows(status) {
38
+ const rows = [
39
+ row(status.wallet.walletRootId !== null && status.wallet.error === null, `Wallet root: ${status.wallet.walletRootId ?? "unknown"} (${status.wallet.source})`),
40
+ ];
41
+ if (status.wallet.error !== null) {
42
+ rows.push(row(false, `Wallet root error: ${status.wallet.error}`));
43
+ }
44
+ return rows;
45
+ }
46
+ function buildLocalStoreRows(status) {
47
+ const rows = [
48
+ row(status.storeExists, `Store exists: ${formatYesNo(status.storeExists)}`),
49
+ row(status.storeInitialized, `Store initialized: ${formatYesNo(status.storeInitialized)}`),
14
50
  ];
15
51
  if (status.storeError !== null) {
16
- lines.push(`Store error: ${status.storeError}`);
52
+ rows.push(row(false, `Store error: ${status.storeError}`));
17
53
  }
18
54
  if (status.indexedTip === null) {
19
- lines.push("Indexed tip: none");
55
+ rows.push(row(false, "Indexed tip: none"));
20
56
  }
21
57
  else {
22
- lines.push(`Indexed tip height: ${status.indexedTip.height}`);
23
- lines.push(`Indexed tip hash: ${status.indexedTip.blockHashHex}`);
24
- lines.push(`Indexed tip state hash: ${status.indexedTip.stateHashHex ?? "none"}`);
58
+ rows.push(row(true, `Indexed tip height: ${status.indexedTip.height}`));
59
+ rows.push(row(true, `Indexed tip hash: ${status.indexedTip.blockHashHex}`));
60
+ rows.push(row(status.indexedTip.stateHashHex !== null, `Indexed tip state hash: ${formatValue(status.indexedTip.stateHashHex)}`));
25
61
  }
26
62
  if (status.latestCheckpoint === null) {
27
- lines.push("Latest checkpoint: none");
63
+ rows.push(row(false, "Latest checkpoint: none"));
28
64
  }
29
65
  else {
30
- lines.push(`Latest checkpoint height: ${status.latestCheckpoint.height}`);
31
- lines.push(`Latest checkpoint hash: ${status.latestCheckpoint.blockHashHex}`);
66
+ rows.push(row(true, `Latest checkpoint height: ${status.latestCheckpoint.height}`));
67
+ rows.push(row(true, `Latest checkpoint hash: ${status.latestCheckpoint.blockHashHex}`));
68
+ }
69
+ if (status.indexedTip !== null && status.indexer.appliedTipHeight !== null) {
70
+ const delta = status.indexedTip.height - status.indexer.appliedTipHeight;
71
+ rows.push(row(Math.abs(delta) <= 1, `Store/indexer height delta: ${formatSignedDelta(delta)}`));
32
72
  }
73
+ return rows;
74
+ }
75
+ function buildBootstrapRows(status) {
33
76
  if (status.bootstrap === null) {
34
- lines.push("Bootstrap state: none");
77
+ return [row(false, "Bootstrap state: none")];
35
78
  }
36
- else {
37
- lines.push(`Bootstrap phase: ${status.bootstrap.phase}`);
38
- lines.push(`Bootstrap download: ${status.bootstrap.downloadedBytes} / ${status.bootstrap.totalBytes} bytes (${formatBootstrapPercent(status.bootstrap.downloadedBytes, status.bootstrap.totalBytes)}%)`);
39
- lines.push(`Bootstrap validated: ${status.bootstrap.validated ? "yes" : "no"}`);
40
- lines.push(`Bootstrap loaded: ${status.bootstrap.loadTxOutSetComplete ? "yes" : "no"}`);
41
- lines.push(`Bootstrap base height: ${status.bootstrap.baseHeight ?? "none"}`);
42
- lines.push(`Bootstrap tip hash: ${status.bootstrap.tipHashHex ?? "none"}`);
43
- lines.push(`Bootstrap snapshot height: ${status.bootstrap.snapshotHeight ?? "none"}`);
44
- lines.push(`Bootstrap last error: ${status.bootstrap.lastError ?? "none"}`);
45
- }
46
- lines.push("Live node: not checked (passive status)");
47
- return lines.join("\n");
79
+ return [
80
+ row(status.bootstrap.lastError === null, `Bootstrap phase: ${status.bootstrap.phase}`),
81
+ row(status.bootstrap.lastError === null, `Bootstrap download: ${status.bootstrap.downloadedBytes} / ${status.bootstrap.totalBytes} bytes (${formatBootstrapPercent(status.bootstrap.downloadedBytes, status.bootstrap.totalBytes)}%)`),
82
+ row(status.bootstrap.validated, `Bootstrap validated: ${formatYesNo(status.bootstrap.validated)}`),
83
+ row(status.bootstrap.loadTxOutSetComplete, `Bootstrap loaded: ${formatYesNo(status.bootstrap.loadTxOutSetComplete)}`),
84
+ row(status.bootstrap.baseHeight !== null, `Bootstrap base height: ${formatValue(status.bootstrap.baseHeight)}`),
85
+ row(status.bootstrap.tipHashHex !== null, `Bootstrap tip hash: ${formatValue(status.bootstrap.tipHashHex)}`),
86
+ row(status.bootstrap.snapshotHeight !== null, `Bootstrap snapshot height: ${formatValue(status.bootstrap.snapshotHeight)}`),
87
+ row(status.bootstrap.lastError === null, `Bootstrap last error: ${formatValue(status.bootstrap.lastError)}`),
88
+ ];
89
+ }
90
+ function buildManagedBitcoindRows(status) {
91
+ if (status.managedBitcoind.error !== null) {
92
+ return [
93
+ row(false, "Managed bitcoind: corrupt"),
94
+ row(false, `Managed bitcoind status path: ${formatValue(status.managedBitcoind.statusPath)}`),
95
+ row(false, `Managed bitcoind status error: ${status.managedBitcoind.error}`),
96
+ ];
97
+ }
98
+ if (!status.managedBitcoind.present) {
99
+ return [row(false, "Managed bitcoind: unavailable")];
100
+ }
101
+ return [
102
+ row(status.managedBitcoind.state === "ready", `Managed bitcoind: ${formatValue(status.managedBitcoind.state)}`),
103
+ row(status.managedBitcoind.processId !== null, `Managed bitcoind pid: ${formatValue(status.managedBitcoind.processId)}`),
104
+ row(status.managedBitcoind.walletRootId !== null, `Managed bitcoind wallet root: ${formatValue(status.managedBitcoind.walletRootId)}`),
105
+ row(status.managedBitcoind.heartbeatAtUnixMs !== null, `Managed bitcoind heartbeat: ${formatValue(status.managedBitcoind.heartbeatAtUnixMs)}`),
106
+ row(status.managedBitcoind.updatedAtUnixMs !== null, `Managed bitcoind updated: ${formatValue(status.managedBitcoind.updatedAtUnixMs)}`),
107
+ row(status.managedBitcoind.lastError === null, `Managed bitcoind last error: ${formatValue(status.managedBitcoind.lastError)}`),
108
+ ];
109
+ }
110
+ function buildIndexerRows(status) {
111
+ if (status.indexer.error !== null) {
112
+ return [
113
+ row(false, "Indexer: corrupt"),
114
+ row(false, `Indexer status path: ${formatValue(status.indexer.statusPath)}`),
115
+ row(false, `Indexer status error: ${status.indexer.error}`),
116
+ ];
117
+ }
118
+ if (!status.indexer.present) {
119
+ return [row(false, "Indexer: unavailable")];
120
+ }
121
+ const rows = [
122
+ row(status.indexer.state === "synced", `Indexer: ${formatValue(status.indexer.state)}`),
123
+ row(status.indexer.processId !== null, `Indexer pid: ${formatValue(status.indexer.processId)}`),
124
+ row(status.indexer.walletRootId !== null, `Indexer wallet root: ${formatValue(status.indexer.walletRootId)}`),
125
+ row(status.indexer.coreBestHeight !== null, `Indexer core best height: ${formatValue(status.indexer.coreBestHeight)}`),
126
+ row(status.indexer.appliedTipHeight !== null, `Indexer applied tip height: ${formatValue(status.indexer.appliedTipHeight)}`),
127
+ row(status.indexer.appliedTipHash !== null, `Indexer applied tip hash: ${formatValue(status.indexer.appliedTipHash)}`),
128
+ row(status.indexer.heartbeatAtUnixMs !== null, `Indexer heartbeat: ${formatValue(status.indexer.heartbeatAtUnixMs)}`),
129
+ row(status.indexer.updatedAtUnixMs !== null, `Indexer updated: ${formatValue(status.indexer.updatedAtUnixMs)}`),
130
+ row(status.indexer.lastError === null, `Indexer last error: ${formatValue(status.indexer.lastError)}`),
131
+ ];
132
+ if (status.indexer.coreBestHeight !== null && status.indexer.appliedTipHeight !== null) {
133
+ const lag = Math.max(0, status.indexer.coreBestHeight - status.indexer.appliedTipHeight);
134
+ rows.push(row(lag === 0, `Indexer lag: ${lag} blocks`));
135
+ }
136
+ return rows;
137
+ }
138
+ function buildManagedServicesRows(status) {
139
+ return [
140
+ ...buildManagedBitcoindRows(status),
141
+ ...buildIndexerRows(status),
142
+ ];
143
+ }
144
+ function buildMiningRows(status) {
145
+ if (status.mining.error !== null) {
146
+ return [
147
+ row(false, "Mining state: corrupt"),
148
+ row(false, `Mining status path: ${formatValue(status.mining.statusPath)}`),
149
+ row(false, `Mining status error: ${status.mining.error}`),
150
+ ];
151
+ }
152
+ if (!status.mining.present) {
153
+ return [row(false, "Mining state: unavailable")];
154
+ }
155
+ const miningHasError = status.mining.lastError !== null;
156
+ const needsBackgroundWorker = status.mining.runMode === "background";
157
+ return [
158
+ row(!miningHasError, `Mining run mode: ${formatValue(status.mining.runMode)}`),
159
+ row(!miningHasError, `Mining state: ${formatValue(status.mining.miningState)}`),
160
+ row(!miningHasError, `Mining phase: ${formatValue(status.mining.currentPhase)}`),
161
+ row(!needsBackgroundWorker || status.mining.backgroundWorkerPid !== null, `Mining background worker pid: ${formatValue(status.mining.backgroundWorkerPid)}`),
162
+ row(!needsBackgroundWorker || status.mining.backgroundWorkerHealth !== null, `Mining background worker health: ${formatValue(status.mining.backgroundWorkerHealth)}`),
163
+ row(status.mining.updatedAtUnixMs !== null, `Mining updated: ${formatValue(status.mining.updatedAtUnixMs)}`),
164
+ row(!miningHasError, `Mining last error: ${formatValue(status.mining.lastError)}`),
165
+ row(status.mining.note === null, `Mining note: ${formatValue(status.mining.note)}`),
166
+ ];
167
+ }
168
+ function buildPassiveModeRows() {
169
+ return [
170
+ row(true, "Live node: not checked"),
171
+ row(true, "Password prompt: not required"),
172
+ row(true, "RPC-backed balance: not checked"),
173
+ ];
174
+ }
175
+ export function formatStatusReport(status, version) {
176
+ return [
177
+ `⛭ Cogcoin Status v${version} (passive) ⛭`,
178
+ formatSection("Paths", buildPathsRows(status)),
179
+ formatSection("Wallet", buildWalletRows(status)),
180
+ formatSection("Local Store", buildLocalStoreRows(status)),
181
+ formatSection("Bootstrap", buildBootstrapRows(status)),
182
+ formatSection("Managed Services", buildManagedServicesRows(status)),
183
+ formatSection("Mining", buildMiningRows(status)),
184
+ formatSection("Passive Mode", buildPassiveModeRows()),
185
+ "Run cogcoin status --live for RPC-backed balance and full service verification.",
186
+ ].join("\n\n");
48
187
  }
@@ -4,6 +4,7 @@ import { createRpcClient } from "../bitcoind/node.js";
4
4
  import type { ManagedBitcoindProgressEvent } from "../bitcoind/types.js";
5
5
  import { attachOrStartIndexerDaemon, probeIndexerDaemon, readObservedIndexerDaemonStatus, stopIndexerDaemonService } from "../bitcoind/indexer-daemon.js";
6
6
  import { attachOrStartManagedBitcoindService, probeManagedBitcoindService, stopManagedBitcoindService } from "../bitcoind/service.js";
7
+ import type { refreshManagedBitcoindStatus } from "../bitcoind/managed-bitcoind-service-status.js";
7
8
  import { openSqliteStore } from "../sqlite/index.js";
8
9
  import type { ClientStoreAdapter } from "../types.js";
9
10
  import type { WalletRuntimePaths } from "../wallet/runtime.js";
@@ -64,6 +65,7 @@ export interface ParsedCliArgs {
64
65
  listLimit: number | null;
65
66
  listAll: boolean;
66
67
  follow: boolean;
68
+ statusLive: boolean;
67
69
  }
68
70
  export interface ManagedClientLike {
69
71
  syncToTip(): Promise<{
@@ -115,6 +117,7 @@ export interface CliRunnerContext {
115
117
  openManagedIndexerMonitor?: typeof openManagedIndexerMonitor;
116
118
  attachManagedBitcoindService?: typeof attachOrStartManagedBitcoindService;
117
119
  probeManagedBitcoindService?: typeof probeManagedBitcoindService;
120
+ refreshManagedBitcoindServiceStatus?: typeof refreshManagedBitcoindStatus;
118
121
  stopManagedBitcoindService?: typeof stopManagedBitcoindService;
119
122
  createBitcoinRpcClient?: typeof createRpcClient;
120
123
  attachIndexerDaemon?: typeof attachOrStartIndexerDaemon;
@@ -1,3 +1,4 @@
1
+ import type { WalletRuntimePaths } from "./wallet/runtime.js";
1
2
  interface PassiveTipStatus {
2
3
  height: number;
3
4
  blockHashHex: string;
@@ -22,15 +23,62 @@ interface PassiveBootstrapStatus {
22
23
  snapshotHeight: number | null;
23
24
  updatedAt: number | null;
24
25
  }
26
+ export interface PassiveWalletStatus {
27
+ walletRootId: string | null;
28
+ source: "wallet-state" | "none" | "unreadable";
29
+ error: string | null;
30
+ }
31
+ export interface PassiveManagedBitcoindStatus {
32
+ statusPath: string | null;
33
+ present: boolean;
34
+ state: string | null;
35
+ processId: number | null;
36
+ walletRootId: string | null;
37
+ heartbeatAtUnixMs: number | null;
38
+ updatedAtUnixMs: number | null;
39
+ lastError: string | null;
40
+ error: string | null;
41
+ }
42
+ export interface PassiveIndexerStatus {
43
+ statusPath: string | null;
44
+ present: boolean;
45
+ state: string | null;
46
+ processId: number | null;
47
+ walletRootId: string | null;
48
+ coreBestHeight: number | null;
49
+ appliedTipHeight: number | null;
50
+ appliedTipHash: string | null;
51
+ heartbeatAtUnixMs: number | null;
52
+ updatedAtUnixMs: number | null;
53
+ lastError: string | null;
54
+ error: string | null;
55
+ }
56
+ export interface PassiveMiningStatus {
57
+ statusPath: string | null;
58
+ present: boolean;
59
+ runMode: string | null;
60
+ miningState: string | null;
61
+ currentPhase: string | null;
62
+ backgroundWorkerPid: number | null;
63
+ backgroundWorkerHealth: string | null;
64
+ updatedAtUnixMs: number | null;
65
+ lastError: string | null;
66
+ note: string | null;
67
+ error: string | null;
68
+ }
25
69
  export interface PassiveClientStatus {
26
70
  dbPath: string;
27
71
  bitcoinDataDir: string;
72
+ wallet: PassiveWalletStatus;
28
73
  storeInitialized: boolean;
29
74
  storeExists: boolean;
30
75
  indexedTip: PassiveTipStatus | null;
31
76
  latestCheckpoint: PassiveCheckpointStatus | null;
32
77
  bootstrap: PassiveBootstrapStatus | null;
78
+ managedBitcoind: PassiveManagedBitcoindStatus;
79
+ indexer: PassiveIndexerStatus;
80
+ mining: PassiveMiningStatus;
33
81
  storeError: string | null;
34
82
  }
35
- export declare function inspectPassiveClientStatus(dbPath: string, bitcoinDataDir: string): Promise<PassiveClientStatus>;
83
+ export declare function inspectPassiveClientStatus(dbPath: string, bitcoinDataDir: string, runtimePaths?: WalletRuntimePaths): Promise<PassiveClientStatus>;
36
84
  export {};