@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
@@ -2,13 +2,14 @@ import { createHash } from "node:crypto";
2
2
  import { mkdir, readFile } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
4
  import { COG_PREFIX } from "../cogop/constants.js";
5
- import { writeJsonFileAtomic } from "../fs/atomic.js";
5
+ import { writeFileAtomic } from "../fs/atomic.js";
6
6
  import { extractOpReturnPayloadFromScriptHex } from "../tx/register.js";
7
7
  const MINING_MEMPOOL_INDEX_SCHEMA_VERSION = 1;
8
8
  const MINING_MEMPOOL_INDEX_RAW_TX_FETCH_CONCURRENCY = 8;
9
9
  const MINING_MEMPOOL_INDEX_PROGRESS_REPORT_EVERY = 25;
10
10
  const indexStates = new Map();
11
11
  const rawTxSubscribers = new Map();
12
+ const RAW_TX_SUBSCRIBER_SAVE_DEBOUNCE_MS = 1_000;
12
13
  export function resolveMiningMempoolIndexCachePath(paths) {
13
14
  return join(paths.miningRoot, "mempool-index.json");
14
15
  }
@@ -101,6 +102,8 @@ function getOrCreateState(options) {
101
102
  negativeTxids: new Set(),
102
103
  loaded: false,
103
104
  savePromise: Promise.resolve(),
105
+ saveScheduled: null,
106
+ saveDirty: false,
104
107
  };
105
108
  indexStates.set(key, created);
106
109
  return created;
@@ -117,10 +120,30 @@ async function saveState(state) {
117
120
  };
118
121
  state.savePromise = state.savePromise.catch(() => undefined).then(async () => {
119
122
  await mkdir(dirname(state.cachePath), { recursive: true });
120
- await writeJsonFileAtomic(state.cachePath, payload, { mode: 0o600 });
123
+ await writeFileAtomic(state.cachePath, `${JSON.stringify(payload)}\n`, { mode: 0o600 });
121
124
  });
122
125
  await state.savePromise;
123
126
  }
127
+ function scheduleStateSave(state) {
128
+ state.saveDirty = true;
129
+ if (state.saveScheduled !== null) {
130
+ return;
131
+ }
132
+ state.saveScheduled = setTimeout(() => {
133
+ state.saveScheduled = null;
134
+ if (!state.saveDirty) {
135
+ return;
136
+ }
137
+ state.saveDirty = false;
138
+ void saveState(state)
139
+ .catch(() => undefined)
140
+ .finally(() => {
141
+ if (state.saveDirty) {
142
+ scheduleStateSave(state);
143
+ }
144
+ });
145
+ }, RAW_TX_SUBSCRIBER_SAVE_DEBOUNCE_MS);
146
+ }
124
147
  function pruneStateToVisibleTxids(state, visibleTxids) {
125
148
  const visibleSet = new Set(visibleTxids);
126
149
  let changed = false;
@@ -426,8 +449,11 @@ export async function ensureMiningMempoolRawTxSubscriber(options) {
426
449
  if (parsed === null || isCogPayload(parsed.payload)) {
427
450
  continue;
428
451
  }
452
+ const previousSize = state.negativeTxids.size;
429
453
  state.negativeTxids.add(parsed.txid);
430
- void saveState(state).catch(() => undefined);
454
+ if (state.negativeTxids.size !== previousSize) {
455
+ scheduleStateSave(state);
456
+ }
431
457
  }
432
458
  }
433
459
  catch {
@@ -54,6 +54,15 @@ async function attachNodeStatus(options, dependencies) {
54
54
  startupTimeoutMs: options.startupTimeoutMs,
55
55
  });
56
56
  const decision = resolveManagedBitcoindProbeDecision(probe);
57
+ if (decision.action === "wait") {
58
+ return {
59
+ handle: null,
60
+ rpc: null,
61
+ status: null,
62
+ observedStatus: probe.status,
63
+ error: null,
64
+ };
65
+ }
57
66
  if (decision.action === "reject") {
58
67
  return {
59
68
  handle: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cogcoin/client",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "Store-backed Cogcoin client with wallet flows, SQLite persistence, and managed Bitcoin Core integration.",
5
5
  "license": "MIT",
6
6
  "type": "module",