@cogcoin/client 1.1.5 → 1.1.7

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 (132) hide show
  1. package/README.md +2 -2
  2. package/dist/bitcoind/indexer-daemon.d.ts +3 -7
  3. package/dist/bitcoind/indexer-daemon.js +39 -204
  4. package/dist/bitcoind/managed-runtime/bitcoind-policy.d.ts +16 -0
  5. package/dist/bitcoind/managed-runtime/bitcoind-policy.js +177 -0
  6. package/dist/bitcoind/managed-runtime/bitcoind-runtime.d.ts +20 -0
  7. package/dist/bitcoind/managed-runtime/bitcoind-runtime.js +74 -0
  8. package/dist/bitcoind/managed-runtime/bitcoind-status.d.ts +11 -0
  9. package/dist/bitcoind/managed-runtime/bitcoind-status.js +44 -0
  10. package/dist/bitcoind/managed-runtime/indexer-policy.d.ts +34 -0
  11. package/dist/bitcoind/managed-runtime/indexer-policy.js +200 -0
  12. package/dist/bitcoind/managed-runtime/indexer-runtime.d.ts +15 -0
  13. package/dist/bitcoind/managed-runtime/indexer-runtime.js +82 -0
  14. package/dist/bitcoind/managed-runtime/status.d.ts +11 -0
  15. package/dist/bitcoind/managed-runtime/status.js +59 -0
  16. package/dist/bitcoind/managed-runtime/types.d.ts +77 -0
  17. package/dist/bitcoind/node.d.ts +2 -2
  18. package/dist/bitcoind/node.js +2 -2
  19. package/dist/bitcoind/rpc.d.ts +2 -1
  20. package/dist/bitcoind/rpc.js +53 -3
  21. package/dist/bitcoind/service.d.ts +2 -7
  22. package/dist/bitcoind/service.js +79 -207
  23. package/dist/cli/command-registry.d.ts +1 -1
  24. package/dist/cli/command-registry.js +2 -64
  25. package/dist/cli/commands/client-admin.js +3 -18
  26. package/dist/cli/commands/mining-runtime.js +4 -60
  27. package/dist/cli/commands/wallet-admin.js +6 -6
  28. package/dist/cli/context.js +1 -3
  29. package/dist/cli/mining-json.d.ts +1 -22
  30. package/dist/cli/mining-json.js +0 -23
  31. package/dist/cli/output.js +16 -2
  32. package/dist/cli/parse.js +0 -2
  33. package/dist/cli/preview-json.d.ts +1 -22
  34. package/dist/cli/preview-json.js +0 -19
  35. package/dist/cli/types.d.ts +1 -3
  36. package/dist/cli/wallet-format.js +1 -1
  37. package/dist/cli/workflow-hints.d.ts +1 -2
  38. package/dist/cli/workflow-hints.js +5 -8
  39. package/dist/wallet/lifecycle/access.d.ts +5 -0
  40. package/dist/wallet/lifecycle/access.js +79 -0
  41. package/dist/wallet/lifecycle/context.d.ts +26 -0
  42. package/dist/wallet/lifecycle/context.js +57 -0
  43. package/dist/wallet/lifecycle/managed-core.d.ts +1 -9
  44. package/dist/wallet/lifecycle/managed-core.js +3 -63
  45. package/dist/wallet/lifecycle/repair-bitcoind.d.ts +10 -0
  46. package/dist/wallet/lifecycle/repair-bitcoind.js +142 -0
  47. package/dist/wallet/lifecycle/repair-indexer.d.ts +8 -0
  48. package/dist/wallet/lifecycle/repair-indexer.js +117 -0
  49. package/dist/wallet/lifecycle/repair-mining.d.ts +1 -5
  50. package/dist/wallet/lifecycle/repair-mining.js +5 -39
  51. package/dist/wallet/lifecycle/repair.d.ts +2 -4
  52. package/dist/wallet/lifecycle/repair.js +74 -318
  53. package/dist/wallet/lifecycle/setup-prompts.d.ts +7 -0
  54. package/dist/wallet/lifecycle/setup-prompts.js +88 -0
  55. package/dist/wallet/lifecycle/setup-state.d.ts +26 -0
  56. package/dist/wallet/lifecycle/setup-state.js +159 -0
  57. package/dist/wallet/lifecycle/setup.d.ts +3 -4
  58. package/dist/wallet/lifecycle/setup.js +47 -351
  59. package/dist/wallet/lifecycle/types.d.ts +33 -5
  60. package/dist/wallet/managed-core-wallet.d.ts +2 -0
  61. package/dist/wallet/managed-core-wallet.js +27 -1
  62. package/dist/wallet/mining/candidate.d.ts +1 -0
  63. package/dist/wallet/mining/candidate.js +38 -6
  64. package/dist/wallet/mining/competitiveness.d.ts +1 -0
  65. package/dist/wallet/mining/competitiveness.js +6 -0
  66. package/dist/wallet/mining/cycle.d.ts +2 -0
  67. package/dist/wallet/mining/cycle.js +14 -4
  68. package/dist/wallet/mining/engine-types.d.ts +1 -0
  69. package/dist/wallet/mining/index.d.ts +1 -1
  70. package/dist/wallet/mining/index.js +1 -1
  71. package/dist/wallet/mining/publish.d.ts +3 -0
  72. package/dist/wallet/mining/publish.js +78 -6
  73. package/dist/wallet/mining/runner.d.ts +0 -32
  74. package/dist/wallet/mining/runner.js +59 -104
  75. package/dist/wallet/mining/stop.d.ts +7 -0
  76. package/dist/wallet/mining/stop.js +23 -0
  77. package/dist/wallet/mining/supervisor.d.ts +2 -36
  78. package/dist/wallet/mining/supervisor.js +139 -246
  79. package/dist/wallet/read/context.d.ts +1 -5
  80. package/dist/wallet/read/context.js +20 -379
  81. package/dist/wallet/read/managed-services.d.ts +33 -0
  82. package/dist/wallet/read/managed-services.js +222 -0
  83. package/dist/wallet/state/client-password/bootstrap.d.ts +2 -0
  84. package/dist/wallet/state/client-password/bootstrap.js +3 -0
  85. package/dist/wallet/state/client-password/context.d.ts +10 -0
  86. package/dist/wallet/state/client-password/context.js +46 -0
  87. package/dist/wallet/state/client-password/crypto.d.ts +34 -0
  88. package/dist/wallet/state/client-password/crypto.js +117 -0
  89. package/dist/wallet/state/client-password/files.d.ts +10 -0
  90. package/dist/wallet/state/client-password/files.js +109 -0
  91. package/dist/wallet/state/client-password/legacy-cleanup.d.ts +11 -0
  92. package/dist/wallet/state/client-password/legacy-cleanup.js +338 -0
  93. package/dist/wallet/state/client-password/messages.d.ts +3 -0
  94. package/dist/wallet/state/client-password/messages.js +9 -0
  95. package/dist/wallet/state/client-password/migration.d.ts +4 -0
  96. package/dist/wallet/state/client-password/migration.js +32 -0
  97. package/dist/wallet/state/client-password/prompts.d.ts +12 -0
  98. package/dist/wallet/state/client-password/prompts.js +79 -0
  99. package/dist/wallet/state/client-password/protected-secrets.d.ts +13 -0
  100. package/dist/wallet/state/client-password/protected-secrets.js +90 -0
  101. package/dist/wallet/state/client-password/readiness.d.ts +4 -0
  102. package/dist/wallet/state/client-password/readiness.js +48 -0
  103. package/dist/wallet/state/client-password/references.d.ts +1 -0
  104. package/dist/wallet/state/client-password/references.js +56 -0
  105. package/dist/wallet/state/client-password/rotation.d.ts +6 -0
  106. package/dist/wallet/state/client-password/rotation.js +98 -0
  107. package/dist/wallet/state/client-password/session-policy.d.ts +6 -0
  108. package/dist/wallet/state/client-password/session-policy.js +28 -0
  109. package/dist/wallet/state/client-password/session.d.ts +19 -0
  110. package/dist/wallet/state/client-password/session.js +170 -0
  111. package/dist/wallet/state/client-password/setup.d.ts +8 -0
  112. package/dist/wallet/state/client-password/setup.js +49 -0
  113. package/dist/wallet/state/client-password/types.d.ts +82 -0
  114. package/dist/wallet/state/client-password/types.js +5 -0
  115. package/dist/wallet/state/client-password.d.ts +7 -38
  116. package/dist/wallet/state/client-password.js +52 -937
  117. package/dist/wallet/tx/anchor.js +123 -216
  118. package/dist/wallet/tx/cog.js +294 -489
  119. package/dist/wallet/tx/common.d.ts +2 -0
  120. package/dist/wallet/tx/common.js +2 -0
  121. package/dist/wallet/tx/domain-admin.js +111 -220
  122. package/dist/wallet/tx/domain-market.js +401 -681
  123. package/dist/wallet/tx/executor.d.ts +176 -0
  124. package/dist/wallet/tx/executor.js +302 -0
  125. package/dist/wallet/tx/field.js +109 -215
  126. package/dist/wallet/tx/register.js +158 -269
  127. package/dist/wallet/tx/reputation.js +120 -227
  128. package/package.json +1 -1
  129. package/dist/wallet/mining/worker-main.js +0 -17
  130. package/dist/wallet/state/client-password-agent.d.ts +0 -1
  131. package/dist/wallet/state/client-password-agent.js +0 -211
  132. /package/dist/{wallet/mining/worker-main.d.ts → bitcoind/managed-runtime/types.js} +0 -0
@@ -1,5 +1,4 @@
1
1
  import { createHash } from "node:crypto";
2
- import { spawn } from "node:child_process";
3
2
  import { getBalance, getBlockWinners, lookupDomain, lookupDomainById, } from "@cogcoin/indexer/queries";
4
3
  import { assaySentences, deriveBlendSeed, displayToInternalBlockhash, getWords, settleBlock, } from "@cogcoin/scoring";
5
4
  import { probeIndexerDaemon } from "../../bitcoind/indexer-daemon.js";
@@ -12,7 +11,8 @@ import { extractOpReturnPayloadFromScriptHex } from "../tx/register.js";
12
11
  import { assertFixedInputPrefixMatches, buildWalletMutationTransaction, fundAndValidateWalletMutationDraft, isInsufficientFundsError, outpointKey as walletMutationOutpointKey, isAlreadyAcceptedError, isBroadcastUnknownError, reconcilePersistentPolicyLocks, resolveWalletMutationFeeSelection, saveWalletStatePreservingUnlock, } from "../tx/common.js";
13
12
  import { isMineableWalletDomain, openWalletReadContext, } from "../read/index.js";
14
13
  import { resolveWalletRuntimePathsForTesting } from "../runtime.js";
15
- import { createDefaultWalletSecretProvider, } from "../state/provider.js";
14
+ import { createDefaultWalletSecretProvider, unlockClientPassword, withInteractiveWalletSecretProvider, } from "../state/provider.js";
15
+ import { bindClientPasswordPromptSessionPolicy } from "../state/client-password/session-policy.js";
16
16
  import { serializeMine } from "../cogop/index.js";
17
17
  import { appendMiningEvent } from "./runtime-artifacts.js";
18
18
  import { loadClientConfig } from "./config.js";
@@ -29,7 +29,8 @@ import { attemptSaveMempool, handleDetectedMiningRuntimeResume, handleRecoverabl
29
29
  import { compareLexicographically, deriveMiningWordIndices, getBlockRewardCogtoshi, numberToSats, resolveBip39WordsFromIndices, rootDomain, tieBreakHash, } from "./engine-utils.js";
30
30
  import { isMiningGenerationAbortRequested, markMiningGenerationActive, markMiningGenerationInactive, readMiningGenerationActivity, readMiningPreemptionRequest, requestMiningGenerationPreemption, } from "./coordination.js";
31
31
  import { clearMiningPublishState, miningPublishIsInMempool, miningPublishMayStillExist, normalizeMiningPublishState, normalizeMiningStateRecord, } from "./state.js";
32
- import { runBackgroundMiningWorker as runBackgroundMiningWorkerSupervisor, runForegroundMining as runForegroundMiningSupervisor, startBackgroundMining as startBackgroundMiningSupervisor, stopBackgroundMining as stopBackgroundMiningSupervisor, waitForBackgroundHealthy as waitForBackgroundHealthySupervisor, } from "./supervisor.js";
32
+ import { runForegroundMining as runForegroundMiningSupervisor, } from "./supervisor.js";
33
+ import { isMiningStopRequestedError, throwIfMiningStopRequested, } from "./stop.js";
33
34
  import { createMiningSentenceRequestLimits } from "./sentence-protocol.js";
34
35
  import { generateMiningSentences, MiningProviderRequestError } from "./sentences.js";
35
36
  import { MiningFollowVisualizer, } from "./visualizer.js";
@@ -106,6 +107,10 @@ function clearMiningGateCache(walletRootId) {
106
107
  }
107
108
  function sleep(ms, signal) {
108
109
  return new Promise((resolve) => {
110
+ if (signal?.aborted) {
111
+ resolve();
112
+ return;
113
+ }
109
114
  const timer = setTimeout(resolve, ms);
110
115
  signal?.addEventListener("abort", () => {
111
116
  clearTimeout(timer);
@@ -171,6 +176,9 @@ async function performMiningCycle(options) {
171
176
  const now = options.nowImpl ?? Date.now;
172
177
  const generateCandidatesForDomainsImpl = options.generateCandidatesForDomainsImpl ?? generateCandidatesForDomains;
173
178
  const runCompetitivenessGateImpl = options.runCompetitivenessGateImpl ?? runCompetitivenessGate;
179
+ const throwIfStopping = () => {
180
+ throwIfMiningStopRequested(options.signal);
181
+ };
174
182
  let readContext = await options.openReadContext({
175
183
  dataDir: options.dataDir,
176
184
  databasePath: options.databasePath,
@@ -179,6 +187,7 @@ async function performMiningCycle(options) {
179
187
  });
180
188
  let readContextClosed = false;
181
189
  try {
190
+ throwIfStopping();
182
191
  throwIfMiningSuspendDetected(options.suspendDetector);
183
192
  let clearRecoveredBitcoindError = false;
184
193
  const saveCycleStatus = async (readContext, overrides, includeVisualizer = true) => {
@@ -223,6 +232,7 @@ async function performMiningCycle(options) {
223
232
  startHeight: 0,
224
233
  walletRootId: readContext.localState.state.walletRootId,
225
234
  });
235
+ throwIfStopping();
226
236
  throwIfMiningSuspendDetected(options.suspendDetector);
227
237
  const rpc = options.rpcFactory(service.rpc);
228
238
  const reconciliation = await reconcileLiveMiningState({
@@ -232,6 +242,7 @@ async function performMiningCycle(options) {
232
242
  nodeBestHeight: readContext.nodeStatus?.nodeBestHeight ?? null,
233
243
  snapshotState: readContext.snapshot?.state ?? null,
234
244
  });
245
+ throwIfStopping();
235
246
  const reconciledState = reconciliation.state;
236
247
  throwIfMiningSuspendDetected(options.suspendDetector);
237
248
  let effectiveReadContext = readContext;
@@ -262,6 +273,7 @@ async function performMiningCycle(options) {
262
273
  indexedTipHeight: indexedTip?.height ?? null,
263
274
  indexedTipHashHex: indexedTip?.blockHashHex ?? null,
264
275
  }).catch(() => ({}));
276
+ throwIfStopping();
265
277
  syncMiningVisualizerBlockTimes(options.loopState, visibleBlockTimes);
266
278
  const { targetBlockHeight, tipKey, tipChanged } = syncMiningUiForCurrentTip({
267
279
  loopState: options.loopState,
@@ -351,6 +363,7 @@ async function performMiningCycle(options) {
351
363
  rpc.getNetworkInfo(),
352
364
  rpc.getMempoolInfo(),
353
365
  ]);
366
+ throwIfStopping();
354
367
  throwIfMiningSuspendDetected(options.suspendDetector);
355
368
  const corePublishState = determineCorePublishState({
356
369
  blockchain: blockchainInfo,
@@ -414,12 +427,17 @@ async function performMiningCycle(options) {
414
427
  nowImpl: now,
415
428
  saveCycleStatus: async (context, overrides) => await saveCycleStatus(context, overrides),
416
429
  appendEvent: async (event) => await appendEvent(options.paths, event),
430
+ stopSignal: options.signal,
431
+ throwIfStopping,
417
432
  throwIfSuspendDetected: () => {
418
433
  throwIfMiningSuspendDetected(options.suspendDetector);
419
434
  },
420
435
  });
421
436
  }
422
437
  catch (error) {
438
+ if (isMiningStopRequestedError(error)) {
439
+ return;
440
+ }
423
441
  if (error instanceof MiningSuspendDetectedError) {
424
442
  discardMiningLoopTransientWork(options.loopState, readContext?.localState.walletRootId ?? undefined);
425
443
  if (readContext !== null && !readContextClosed) {
@@ -482,9 +500,13 @@ async function runMiningLoop(options) {
482
500
  }));
483
501
  while (!options.signal?.aborted) {
484
502
  try {
503
+ throwIfMiningStopRequested(options.signal);
485
504
  throwIfMiningSuspendDetected(suspendDetector);
486
505
  }
487
506
  catch (error) {
507
+ if (isMiningStopRequestedError(error)) {
508
+ break;
509
+ }
488
510
  if (!(error instanceof MiningSuspendDetectedError)) {
489
511
  throw error;
490
512
  }
@@ -504,18 +526,35 @@ async function runMiningLoop(options) {
504
526
  });
505
527
  continue;
506
528
  }
507
- await performMiningCycle({
508
- ...options,
509
- suspendDetector,
510
- assaySentencesImpl: options.assaySentencesImpl,
511
- cooperativeYieldImpl: options.cooperativeYieldImpl,
512
- cooperativeYieldEvery: options.cooperativeYieldEvery,
513
- loopState,
514
- probeService,
515
- stopService,
516
- });
529
+ try {
530
+ await performMiningCycle({
531
+ ...options,
532
+ suspendDetector,
533
+ assaySentencesImpl: options.assaySentencesImpl,
534
+ cooperativeYieldImpl: options.cooperativeYieldImpl,
535
+ cooperativeYieldEvery: options.cooperativeYieldEvery,
536
+ loopState,
537
+ probeService,
538
+ stopService,
539
+ });
540
+ }
541
+ catch (error) {
542
+ if (isMiningStopRequestedError(error)) {
543
+ break;
544
+ }
545
+ throw error;
546
+ }
547
+ if (options.signal?.aborted) {
548
+ break;
549
+ }
517
550
  await sleepImpl(Math.min(MINING_LOOP_INTERVAL_MS, MINING_STATUS_HEARTBEAT_INTERVAL_MS), options.signal);
518
551
  }
552
+ if (options.signal?.aborted) {
553
+ await appendEvent(options.paths, createEvent("runtime-stop", `Stopped ${options.runMode} mining runtime.`, {
554
+ runId: options.backgroundWorkerRunId,
555
+ }));
556
+ return;
557
+ }
519
558
  const service = await options.attachService({
520
559
  dataDir: options.dataDir,
521
560
  chain: "main",
@@ -537,29 +576,30 @@ async function runMiningLoop(options) {
537
576
  stopMiningSuspendDetector(suspendDetector);
538
577
  }
539
578
  }
540
- async function waitForBackgroundHealthy(paths) {
541
- return await waitForBackgroundHealthySupervisor(paths);
542
- }
543
579
  export async function runForegroundMining(options) {
544
580
  if (!options.prompter.isInteractive) {
545
581
  throw new Error("mine_requires_tty");
546
582
  }
547
- const provider = options.provider ?? createDefaultWalletSecretProvider();
583
+ const miningPrompter = bindClientPasswordPromptSessionPolicy(options.prompter, "mining-indefinite");
584
+ const provider = withInteractiveWalletSecretProvider(options.provider ?? createDefaultWalletSecretProvider(), miningPrompter);
548
585
  const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
549
586
  const openReadContext = options.openReadContext ?? openWalletReadContext;
550
587
  const attachService = options.attachService ?? attachOrStartManagedBitcoindService;
551
- const rpcFactory = options.rpcFactory ?? createRpcClient;
588
+ const rpcFactory = options.rpcFactory ?? ((config) => createRpcClient(config, {
589
+ abortSignal: options.signal,
590
+ }));
552
591
  const requestMiningPreemption = options.requestMiningPreemption ?? requestMiningGenerationPreemption;
553
592
  const setupReady = options.builtInSetupEnsured === true
554
593
  ? true
555
594
  : await ensureBuiltInMiningSetupIfNeeded({
556
595
  provider,
557
- prompter: options.prompter,
596
+ prompter: miningPrompter,
558
597
  paths,
559
598
  });
560
599
  if (!setupReady) {
561
600
  throw new Error("Built-in mining provider is not configured. Run `cogcoin mine setup`.");
562
601
  }
602
+ await unlockClientPassword(provider, miningPrompter);
563
603
  await runForegroundMiningSupervisor({
564
604
  dataDir: options.dataDir,
565
605
  databasePath: options.databasePath,
@@ -587,91 +627,6 @@ export async function runForegroundMining(options) {
587
627
  },
588
628
  });
589
629
  }
590
- export async function startBackgroundMining(options) {
591
- const provider = options.provider ?? createDefaultWalletSecretProvider();
592
- const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
593
- const requestMiningPreemption = options.requestMiningPreemption ?? requestMiningGenerationPreemption;
594
- const waitForBackgroundHealthyImpl = options.waitForBackgroundHealthyImpl ?? waitForBackgroundHealthy;
595
- const openReadContext = options.openReadContext ?? openWalletReadContext;
596
- const attachService = options.attachService ?? attachOrStartManagedBitcoindService;
597
- const rpcFactory = options.rpcFactory ?? createRpcClient;
598
- const setupReady = options.builtInSetupEnsured === true
599
- ? true
600
- : await ensureBuiltInMiningSetupIfNeeded({
601
- provider,
602
- prompter: options.prompter,
603
- paths,
604
- });
605
- if (!setupReady) {
606
- throw new Error("Built-in mining provider is not configured. Run `cogcoin mine setup`.");
607
- }
608
- return await startBackgroundMiningSupervisor({
609
- dataDir: options.dataDir,
610
- databasePath: options.databasePath,
611
- shutdownGraceMs: options.shutdownGraceMs,
612
- waitForBackgroundHealthy: waitForBackgroundHealthyImpl,
613
- runtime: {
614
- provider,
615
- paths,
616
- openReadContext,
617
- attachService,
618
- rpcFactory,
619
- },
620
- deps: {
621
- requestMiningPreemption,
622
- spawnWorkerProcess: options.spawnWorkerProcess,
623
- sleep: options.sleepImpl,
624
- },
625
- });
626
- }
627
- export async function stopBackgroundMining(options) {
628
- const provider = options.provider ?? createDefaultWalletSecretProvider();
629
- const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
630
- const openReadContext = options.openReadContext ?? openWalletReadContext;
631
- const attachService = options.attachService ?? attachOrStartManagedBitcoindService;
632
- const rpcFactory = options.rpcFactory ?? createRpcClient;
633
- return await stopBackgroundMiningSupervisor({
634
- dataDir: options.dataDir,
635
- databasePath: options.databasePath,
636
- shutdownGraceMs: options.shutdownGraceMs,
637
- runtime: {
638
- provider,
639
- paths,
640
- openReadContext,
641
- attachService,
642
- rpcFactory,
643
- },
644
- deps: {
645
- requestMiningPreemption: options.requestMiningPreemption,
646
- saveStopSnapshot: options.saveStopSnapshotImpl,
647
- sleep: options.sleepImpl,
648
- },
649
- });
650
- }
651
- export async function runBackgroundMiningWorker(options) {
652
- const provider = options.provider ?? createDefaultWalletSecretProvider();
653
- const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
654
- const openReadContext = options.openReadContext ?? openWalletReadContext;
655
- const attachService = options.attachService ?? attachOrStartManagedBitcoindService;
656
- const rpcFactory = options.rpcFactory ?? createRpcClient;
657
- await runBackgroundMiningWorkerSupervisor({
658
- dataDir: options.dataDir,
659
- databasePath: options.databasePath,
660
- runId: options.runId,
661
- fetchImpl: options.fetchImpl,
662
- runtime: {
663
- provider,
664
- paths,
665
- openReadContext,
666
- attachService,
667
- rpcFactory,
668
- },
669
- deps: {
670
- runMiningLoop: options.runMiningLoopImpl ?? runMiningLoop,
671
- saveStopSnapshot: options.saveStopSnapshotImpl,
672
- },
673
- });
674
- }
675
630
  export async function performMiningCycleForTesting(options) {
676
631
  await performMiningCycle({
677
632
  ...options,
@@ -0,0 +1,7 @@
1
+ export declare const MINING_STOP_REQUESTED_ERROR_CODE = "mining_runtime_stop_requested";
2
+ export declare class MiningStopRequestedError extends Error {
3
+ constructor();
4
+ }
5
+ export declare function isMiningStopRequestedError(error: unknown): error is Error;
6
+ export declare function createMiningStopRequestedError(): MiningStopRequestedError;
7
+ export declare function throwIfMiningStopRequested(signal: AbortSignal | undefined): void;
@@ -0,0 +1,23 @@
1
+ export const MINING_STOP_REQUESTED_ERROR_CODE = "mining_runtime_stop_requested";
2
+ export class MiningStopRequestedError extends Error {
3
+ constructor() {
4
+ super(MINING_STOP_REQUESTED_ERROR_CODE);
5
+ this.name = "MiningStopRequestedError";
6
+ }
7
+ }
8
+ export function isMiningStopRequestedError(error) {
9
+ return error instanceof Error && error.message === MINING_STOP_REQUESTED_ERROR_CODE;
10
+ }
11
+ export function createMiningStopRequestedError() {
12
+ return new MiningStopRequestedError();
13
+ }
14
+ export function throwIfMiningStopRequested(signal) {
15
+ if (!signal?.aborted) {
16
+ return;
17
+ }
18
+ const reason = signal.reason;
19
+ if (reason instanceof Error) {
20
+ throw reason;
21
+ }
22
+ throw createMiningStopRequestedError();
23
+ }
@@ -1,4 +1,3 @@
1
- import { spawn } from "node:child_process";
2
1
  import { rm } from "node:fs/promises";
3
2
  import { createRpcClient } from "../../bitcoind/node.js";
4
3
  import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
@@ -8,7 +7,6 @@ import { openWalletReadContext } from "../read/index.js";
8
7
  import type { WalletRuntimePaths } from "../runtime.js";
9
8
  import type { WalletSecretProvider } from "../state/provider.js";
10
9
  import { requestMiningGenerationPreemption } from "./coordination.js";
11
- import { inspectMiningControlPlane } from "./control.js";
12
10
  import { saveStopSnapshot } from "./lifecycle.js";
13
11
  import type { MiningRpcClient } from "./engine-types.js";
14
12
  import { loadMiningRuntimeStatus, saveMiningRuntimeStatus } from "./runtime-artifacts.js";
@@ -19,9 +17,8 @@ type AttachService = typeof attachOrStartManagedBitcoindService;
19
17
  type RpcFactory = (config: Parameters<typeof createRpcClient>[0]) => MiningRpcClient;
20
18
  type RequestMiningPreemption = typeof requestMiningGenerationPreemption;
21
19
  type SaveStopSnapshot = typeof saveStopSnapshot;
22
- type SpawnWorkerProcess = typeof spawn;
23
20
  type ProcessKill = typeof process.kill;
24
- type InspectMiningControlPlane = typeof inspectMiningControlPlane;
21
+ type ForceExit = (code: number) => never | void;
25
22
  interface MiningLoopRunnerOptions {
26
23
  dataDir: string;
27
24
  databasePath: string;
@@ -51,9 +48,7 @@ export interface MiningSupervisorRuntimeContext {
51
48
  interface MiningSupervisorDependencies {
52
49
  requestMiningPreemption: RequestMiningPreemption;
53
50
  saveStopSnapshot: SaveStopSnapshot;
54
- spawnWorkerProcess: SpawnWorkerProcess;
55
51
  runMiningLoop: RunMiningLoop;
56
- inspectMiningControlPlane: InspectMiningControlPlane;
57
52
  loadRuntimeStatus: typeof loadMiningRuntimeStatus;
58
53
  saveRuntimeStatus: typeof saveMiningRuntimeStatus;
59
54
  acquireLock: typeof acquireFileLock;
@@ -64,12 +59,7 @@ interface MiningSupervisorDependencies {
64
59
  nowUnixMs: () => number;
65
60
  processKill: ProcessKill;
66
61
  processPid: number;
67
- processExecPath: string;
68
- resolveWorkerMainPath: () => string;
69
- }
70
- export interface MiningSupervisorStartResult {
71
- started: boolean;
72
- snapshot: MiningRuntimeStatusV1 | null;
62
+ forceExit: ForceExit;
73
63
  }
74
64
  export interface MiningSupervisorTakeoverResult {
75
65
  controlLockCleared: boolean;
@@ -86,7 +76,6 @@ export declare function takeOverMiningRuntime(options: {
86
76
  shutdownGraceMs?: number;
87
77
  deps?: Partial<MiningSupervisorDependencies>;
88
78
  }): Promise<MiningSupervisorTakeoverResult>;
89
- export declare function waitForBackgroundHealthy(paths: WalletRuntimePaths, depsOverrides?: Partial<MiningSupervisorDependencies>): Promise<MiningRuntimeStatusV1 | null>;
90
79
  export declare function runForegroundMining(options: {
91
80
  dataDir: string;
92
81
  databasePath: string;
@@ -108,27 +97,4 @@ export declare function runForegroundMining(options: {
108
97
  runtime: MiningSupervisorRuntimeContext;
109
98
  deps?: Partial<MiningSupervisorDependencies>;
110
99
  }): Promise<void>;
111
- export declare function startBackgroundMining(options: {
112
- dataDir: string;
113
- databasePath: string;
114
- shutdownGraceMs?: number;
115
- waitForBackgroundHealthy?: (paths: WalletRuntimePaths) => Promise<MiningRuntimeStatusV1 | null>;
116
- runtime: MiningSupervisorRuntimeContext;
117
- deps?: Partial<MiningSupervisorDependencies>;
118
- }): Promise<MiningSupervisorStartResult>;
119
- export declare function stopBackgroundMining(options: {
120
- dataDir: string;
121
- databasePath: string;
122
- shutdownGraceMs?: number;
123
- runtime: MiningSupervisorRuntimeContext;
124
- deps?: Partial<MiningSupervisorDependencies>;
125
- }): Promise<MiningRuntimeStatusV1 | null>;
126
- export declare function runBackgroundMiningWorker(options: {
127
- dataDir: string;
128
- databasePath: string;
129
- runId: string;
130
- fetchImpl?: typeof fetch;
131
- runtime: MiningSupervisorRuntimeContext;
132
- deps?: Partial<MiningSupervisorDependencies>;
133
- }): Promise<void>;
134
100
  export {};