@cogcoin/client 1.1.4 → 1.1.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 (83) hide show
  1. package/README.md +4 -5
  2. package/dist/bitcoind/progress/tty-renderer.js +3 -2
  3. package/dist/bitcoind/service.js +1 -1
  4. package/dist/cli/command-registry.d.ts +39 -0
  5. package/dist/cli/command-registry.js +1132 -0
  6. package/dist/cli/commands/client-admin.js +6 -56
  7. package/dist/cli/commands/mining-admin.js +9 -32
  8. package/dist/cli/commands/mining-read.js +15 -56
  9. package/dist/cli/commands/mining-runtime.js +258 -57
  10. package/dist/cli/commands/service-runtime.js +1 -64
  11. package/dist/cli/commands/status.js +2 -15
  12. package/dist/cli/commands/update.js +6 -21
  13. package/dist/cli/commands/wallet-admin.js +18 -120
  14. package/dist/cli/commands/wallet-mutation.js +4 -7
  15. package/dist/cli/commands/wallet-read.js +31 -138
  16. package/dist/cli/context.js +2 -4
  17. package/dist/cli/mining-format.js +8 -2
  18. package/dist/cli/mutation-command-groups.d.ts +11 -11
  19. package/dist/cli/mutation-command-groups.js +9 -18
  20. package/dist/cli/mutation-json.d.ts +1 -17
  21. package/dist/cli/mutation-json.js +1 -28
  22. package/dist/cli/mutation-success.d.ts +0 -1
  23. package/dist/cli/mutation-success.js +0 -19
  24. package/dist/cli/output.d.ts +1 -10
  25. package/dist/cli/output.js +52 -481
  26. package/dist/cli/parse.d.ts +1 -1
  27. package/dist/cli/parse.js +38 -695
  28. package/dist/cli/runner.js +28 -113
  29. package/dist/cli/types.d.ts +7 -8
  30. package/dist/cli/update-notifier.js +1 -1
  31. package/dist/cli/wallet-format.js +1 -1
  32. package/dist/wallet/lifecycle/managed-core.d.ts +23 -0
  33. package/dist/wallet/lifecycle/managed-core.js +257 -0
  34. package/dist/wallet/lifecycle/repair-mining.d.ts +49 -0
  35. package/dist/wallet/lifecycle/repair-mining.js +304 -0
  36. package/dist/wallet/lifecycle/repair-runtime.d.ts +36 -0
  37. package/dist/wallet/lifecycle/repair-runtime.js +206 -0
  38. package/dist/wallet/lifecycle/repair.d.ts +11 -0
  39. package/dist/wallet/lifecycle/repair.js +368 -0
  40. package/dist/wallet/lifecycle/setup.d.ts +16 -0
  41. package/dist/wallet/lifecycle/setup.js +430 -0
  42. package/dist/wallet/lifecycle/types.d.ts +125 -0
  43. package/dist/wallet/lifecycle/types.js +1 -0
  44. package/dist/wallet/lifecycle.d.ts +4 -165
  45. package/dist/wallet/lifecycle.js +3 -1656
  46. package/dist/wallet/mining/candidate.d.ts +60 -0
  47. package/dist/wallet/mining/candidate.js +290 -0
  48. package/dist/wallet/mining/competitiveness.d.ts +22 -0
  49. package/dist/wallet/mining/competitiveness.js +640 -0
  50. package/dist/wallet/mining/control.js +7 -251
  51. package/dist/wallet/mining/cycle.d.ts +39 -0
  52. package/dist/wallet/mining/cycle.js +542 -0
  53. package/dist/wallet/mining/engine-state.d.ts +66 -0
  54. package/dist/wallet/mining/engine-state.js +211 -0
  55. package/dist/wallet/mining/engine-types.d.ts +173 -0
  56. package/dist/wallet/mining/engine-types.js +1 -0
  57. package/dist/wallet/mining/engine-utils.d.ts +7 -0
  58. package/dist/wallet/mining/engine-utils.js +75 -0
  59. package/dist/wallet/mining/events.d.ts +2 -0
  60. package/dist/wallet/mining/events.js +19 -0
  61. package/dist/wallet/mining/lifecycle.d.ts +71 -0
  62. package/dist/wallet/mining/lifecycle.js +355 -0
  63. package/dist/wallet/mining/projection.d.ts +61 -0
  64. package/dist/wallet/mining/projection.js +319 -0
  65. package/dist/wallet/mining/publish.d.ts +79 -0
  66. package/dist/wallet/mining/publish.js +614 -0
  67. package/dist/wallet/mining/runner.d.ts +12 -418
  68. package/dist/wallet/mining/runner.js +274 -3433
  69. package/dist/wallet/mining/supervisor.d.ts +134 -0
  70. package/dist/wallet/mining/supervisor.js +558 -0
  71. package/dist/wallet/mining/visualizer-sync.d.ts +42 -0
  72. package/dist/wallet/mining/visualizer-sync.js +166 -0
  73. package/dist/wallet/mining/visualizer.d.ts +1 -0
  74. package/dist/wallet/mining/visualizer.js +33 -18
  75. package/dist/wallet/reset.d.ts +1 -1
  76. package/dist/wallet/reset.js +35 -11
  77. package/dist/wallet/runtime.d.ts +0 -6
  78. package/dist/wallet/runtime.js +2 -38
  79. package/dist/wallet/tx/common.d.ts +18 -0
  80. package/dist/wallet/tx/common.js +40 -26
  81. package/package.json +1 -1
  82. package/dist/wallet/state/seed-index.d.ts +0 -43
  83. package/dist/wallet/state/seed-index.js +0 -151
@@ -0,0 +1,355 @@
1
+ import { createRpcClient } from "../../bitcoind/node.js";
2
+ import { attachOrStartManagedBitcoindService, probeManagedBitcoindService, stopManagedBitcoindService, } from "../../bitcoind/service.js";
3
+ import { isRetryableManagedRpcError } from "../../bitcoind/retryable-rpc.js";
4
+ import { openWalletReadContext } from "../read/index.js";
5
+ import { saveWalletStatePreservingUnlock } from "../tx/common.js";
6
+ import { appendMiningEvent, saveMiningRuntimeStatus } from "./runtime-artifacts.js";
7
+ import { inspectMiningControlPlane } from "./control.js";
8
+ import { applyMiningRuntimeStatusOverrides, } from "./projection.js";
9
+ import { buildMiningSettleWindowStatusOverrides, defaultMiningStatePatch, discardMiningLoopTransientWork, setMiningReconnectSettleWindow, } from "./engine-state.js";
10
+ import { createIndexedMiningFollowVisualizerState } from "./visualizer-sync.js";
11
+ import { createMiningEventRecord } from "./events.js";
12
+ import { reconcileLiveMiningState } from "./publish.js";
13
+ import { clearMiningGateCache } from "./competitiveness.js";
14
+ const MINING_BITCOIN_RECOVERY_GRACE_MS = 15_000;
15
+ const MINING_BITCOIN_RECOVERY_RESTART_COOLDOWN_MS = 60_000;
16
+ const MINING_BITCOIN_RECOVERY_NOTE = "Mining lost contact with the local Bitcoin RPC service and is waiting for it to recover.";
17
+ export async function refreshAndSaveMiningRuntimeStatus(options) {
18
+ const view = await inspectMiningControlPlane({
19
+ provider: options.provider,
20
+ localState: options.readContext.localState,
21
+ bitcoind: options.readContext.bitcoind,
22
+ nodeStatus: options.readContext.nodeStatus,
23
+ nodeHealth: options.readContext.nodeHealth,
24
+ indexer: options.readContext.indexer,
25
+ paths: options.paths,
26
+ });
27
+ const snapshot = applyMiningRuntimeStatusOverrides({
28
+ runtime: view.runtime,
29
+ provider: view.provider,
30
+ overrides: options.overrides,
31
+ });
32
+ await saveMiningRuntimeStatus(options.paths.miningStatusPath, snapshot);
33
+ options.visualizer?.update(snapshot, options.visualizerState);
34
+ return snapshot;
35
+ }
36
+ function resolveMiningBitcoindRecoveryIdentity(value) {
37
+ const raw = (value ?? {});
38
+ return {
39
+ serviceInstanceId: raw.serviceInstanceId ?? null,
40
+ processId: raw.processId ?? raw.pid ?? null,
41
+ };
42
+ }
43
+ function miningBitcoindRecoveryIdentityMatches(left, right) {
44
+ if (left.serviceInstanceId !== null && right.serviceInstanceId !== null) {
45
+ return left.serviceInstanceId === right.serviceInstanceId;
46
+ }
47
+ if (left.processId !== null && right.processId !== null) {
48
+ return left.processId === right.processId;
49
+ }
50
+ return false;
51
+ }
52
+ function rememberMiningBitcoindRecoveryIdentity(loopState, value) {
53
+ const next = resolveMiningBitcoindRecoveryIdentity(value);
54
+ if (next.serviceInstanceId === null && next.processId === null) {
55
+ return false;
56
+ }
57
+ const previous = {
58
+ serviceInstanceId: loopState.bitcoinRecoveryServiceInstanceId,
59
+ processId: loopState.bitcoinRecoveryProcessId,
60
+ };
61
+ const changed = (previous.serviceInstanceId !== null
62
+ || previous.processId !== null) && !miningBitcoindRecoveryIdentityMatches(previous, next);
63
+ loopState.bitcoinRecoveryServiceInstanceId = next.serviceInstanceId ?? (next.processId !== null && previous.processId === next.processId
64
+ ? previous.serviceInstanceId
65
+ : null);
66
+ loopState.bitcoinRecoveryProcessId = next.processId ?? (next.serviceInstanceId !== null && previous.serviceInstanceId === next.serviceInstanceId
67
+ ? previous.processId
68
+ : null);
69
+ return changed;
70
+ }
71
+ export function resetMiningBitcoindRecoveryState(loopState, value) {
72
+ const hadRecovery = loopState.bitcoinRecoveryFirstFailureAtUnixMs !== null;
73
+ loopState.bitcoinRecoveryFirstFailureAtUnixMs = null;
74
+ loopState.bitcoinRecoveryFirstUnreachableAtUnixMs = null;
75
+ loopState.bitcoinRecoveryLastRestartAttemptAtUnixMs = null;
76
+ if (value !== undefined) {
77
+ rememberMiningBitcoindRecoveryIdentity(loopState, value);
78
+ }
79
+ return hadRecovery;
80
+ }
81
+ function isMiningBitcoindRecoveryPidAlive(pid) {
82
+ if (pid === null || pid === undefined || !Number.isInteger(pid) || pid <= 0) {
83
+ return false;
84
+ }
85
+ try {
86
+ process.kill(pid, 0);
87
+ return true;
88
+ }
89
+ catch (error) {
90
+ if (error instanceof Error && "code" in error && error.code === "EPERM") {
91
+ return true;
92
+ }
93
+ return false;
94
+ }
95
+ }
96
+ function describeRecoverableMiningBitcoindError(error) {
97
+ return error instanceof Error ? error.message : String(error);
98
+ }
99
+ export function isRecoverableMiningBitcoindError(error) {
100
+ if (isRetryableManagedRpcError(error)) {
101
+ return true;
102
+ }
103
+ if (!(error instanceof Error)) {
104
+ return false;
105
+ }
106
+ if ("code" in error) {
107
+ const code = error.code;
108
+ if (code === "ENOENT" || code === "ECONNREFUSED" || code === "ECONNRESET") {
109
+ return true;
110
+ }
111
+ }
112
+ return error.message === "managed_bitcoind_service_start_timeout"
113
+ || error.message === "bitcoind_cookie_timeout"
114
+ || error.message.includes("cookie file is unavailable")
115
+ || error.message.includes("cookie file could not be read")
116
+ || error.message.includes("ECONNREFUSED")
117
+ || error.message.includes("ECONNRESET")
118
+ || error.message.includes("socket hang up");
119
+ }
120
+ async function attachManagedBitcoindForRecovery(options) {
121
+ try {
122
+ const service = await options.attachService({
123
+ dataDir: options.dataDir,
124
+ chain: "main",
125
+ startHeight: 0,
126
+ walletRootId: options.walletRootId,
127
+ });
128
+ const serviceStatus = await service.refreshServiceStatus?.().catch(() => null);
129
+ rememberMiningBitcoindRecoveryIdentity(options.loopState, serviceStatus ?? { pid: service.pid });
130
+ return true;
131
+ }
132
+ catch (error) {
133
+ if (!isRecoverableMiningBitcoindError(error)) {
134
+ throw error;
135
+ }
136
+ return false;
137
+ }
138
+ }
139
+ export async function handleRecoverableMiningBitcoindFailure(options) {
140
+ const failureMessage = describeRecoverableMiningBitcoindError(options.error);
141
+ const walletRootId = options.readContext.localState.walletRootId ?? undefined;
142
+ if (options.loopState.bitcoinRecoveryFirstFailureAtUnixMs === null) {
143
+ options.loopState.bitcoinRecoveryFirstFailureAtUnixMs = options.nowUnixMs;
144
+ }
145
+ let restartedService = false;
146
+ const probe = await options.probeService({
147
+ dataDir: options.dataDir,
148
+ chain: "main",
149
+ startHeight: 0,
150
+ walletRootId,
151
+ }).catch((probeError) => {
152
+ if (!isRecoverableMiningBitcoindError(probeError)) {
153
+ throw probeError;
154
+ }
155
+ return null;
156
+ });
157
+ if (probe !== null) {
158
+ if (probe.compatibility === "compatible") {
159
+ rememberMiningBitcoindRecoveryIdentity(options.loopState, probe.status);
160
+ options.loopState.bitcoinRecoveryFirstUnreachableAtUnixMs = null;
161
+ }
162
+ else if (probe.compatibility === "unreachable") {
163
+ const identityChanged = rememberMiningBitcoindRecoveryIdentity(options.loopState, probe.status);
164
+ const livePid = isMiningBitcoindRecoveryPidAlive(probe.status?.processId ?? null);
165
+ if (identityChanged || options.loopState.bitcoinRecoveryFirstUnreachableAtUnixMs === null) {
166
+ options.loopState.bitcoinRecoveryFirstUnreachableAtUnixMs = options.nowUnixMs;
167
+ }
168
+ if (!livePid) {
169
+ restartedService = await attachManagedBitcoindForRecovery({
170
+ dataDir: options.dataDir,
171
+ walletRootId,
172
+ attachService: options.attachService,
173
+ loopState: options.loopState,
174
+ });
175
+ }
176
+ else {
177
+ const graceElapsed = (options.loopState.bitcoinRecoveryFirstUnreachableAtUnixMs !== null
178
+ && options.nowUnixMs - options.loopState.bitcoinRecoveryFirstUnreachableAtUnixMs
179
+ >= MINING_BITCOIN_RECOVERY_GRACE_MS);
180
+ const cooldownElapsed = (options.loopState.bitcoinRecoveryLastRestartAttemptAtUnixMs === null
181
+ || options.nowUnixMs - options.loopState.bitcoinRecoveryLastRestartAttemptAtUnixMs
182
+ >= MINING_BITCOIN_RECOVERY_RESTART_COOLDOWN_MS);
183
+ if (graceElapsed && cooldownElapsed) {
184
+ options.loopState.bitcoinRecoveryLastRestartAttemptAtUnixMs = options.nowUnixMs;
185
+ await options.stopService({
186
+ dataDir: options.dataDir,
187
+ walletRootId,
188
+ }).catch((stopError) => {
189
+ if (!isRecoverableMiningBitcoindError(stopError)) {
190
+ throw stopError;
191
+ }
192
+ });
193
+ await attachManagedBitcoindForRecovery({
194
+ dataDir: options.dataDir,
195
+ walletRootId,
196
+ attachService: options.attachService,
197
+ loopState: options.loopState,
198
+ });
199
+ restartedService = true;
200
+ }
201
+ }
202
+ }
203
+ else {
204
+ throw new Error(probe.error ?? "managed_bitcoind_protocol_error");
205
+ }
206
+ }
207
+ if (restartedService) {
208
+ discardMiningLoopTransientWork(options.loopState, walletRootId);
209
+ setMiningReconnectSettleWindow(options.loopState, options.nowUnixMs);
210
+ }
211
+ await refreshAndSaveMiningRuntimeStatus({
212
+ paths: options.paths,
213
+ provider: options.provider,
214
+ readContext: options.readContext,
215
+ overrides: {
216
+ runMode: options.runMode,
217
+ currentPhase: "waiting-bitcoin-network",
218
+ lastError: failureMessage,
219
+ note: MINING_BITCOIN_RECOVERY_NOTE,
220
+ ...buildMiningSettleWindowStatusOverrides(options.loopState, options.nowUnixMs),
221
+ },
222
+ visualizer: options.visualizer,
223
+ visualizerState: options.loopState.ui,
224
+ });
225
+ }
226
+ export async function handleDetectedMiningRuntimeResume(options) {
227
+ const readContext = await (options.openReadContext ?? openWalletReadContext)({
228
+ dataDir: options.dataDir,
229
+ databasePath: options.databasePath,
230
+ secretProvider: options.provider,
231
+ paths: options.paths,
232
+ });
233
+ try {
234
+ clearMiningGateCache(readContext.localState.walletRootId);
235
+ setMiningReconnectSettleWindow(options.loopState, options.detectedAtUnixMs);
236
+ await refreshAndSaveMiningRuntimeStatus({
237
+ paths: options.paths,
238
+ provider: options.provider,
239
+ readContext,
240
+ overrides: {
241
+ runMode: options.runMode,
242
+ backgroundWorkerPid: options.backgroundWorkerPid,
243
+ backgroundWorkerRunId: options.backgroundWorkerRunId,
244
+ backgroundWorkerHeartbeatAtUnixMs: options.runMode === "background" ? Date.now() : null,
245
+ currentPhase: "resuming",
246
+ lastSuspendDetectedAtUnixMs: options.detectedAtUnixMs,
247
+ note: "Mining discarded stale in-flight work after a large local runtime gap and is rechecking health.",
248
+ ...buildMiningSettleWindowStatusOverrides(options.loopState, options.detectedAtUnixMs),
249
+ },
250
+ visualizer: options.visualizer,
251
+ visualizerState: createIndexedMiningFollowVisualizerState(readContext),
252
+ });
253
+ }
254
+ finally {
255
+ await readContext.close();
256
+ }
257
+ await appendMiningEvent(options.paths.miningEventsPath, createMiningEventRecord("system-resumed", "Detected a large local runtime gap, discarded stale in-flight mining work, and resumed health checks from scratch.", {
258
+ level: "warn",
259
+ runId: options.backgroundWorkerRunId,
260
+ timestampUnixMs: options.detectedAtUnixMs,
261
+ }));
262
+ }
263
+ export async function saveStopSnapshot(options) {
264
+ const openReadContextImpl = options.openReadContext ?? openWalletReadContext;
265
+ const attachServiceImpl = options.attachService ?? attachOrStartManagedBitcoindService;
266
+ const rpcFactory = options.rpcFactory ?? createRpcClient;
267
+ const readContext = await openReadContextImpl({
268
+ dataDir: options.dataDir,
269
+ databasePath: options.databasePath,
270
+ secretProvider: options.provider,
271
+ paths: options.paths,
272
+ });
273
+ try {
274
+ let localState = readContext.localState;
275
+ if (localState.availability === "ready" && localState.state !== null) {
276
+ const service = await attachServiceImpl({
277
+ dataDir: options.dataDir,
278
+ chain: "main",
279
+ startHeight: 0,
280
+ walletRootId: localState.state.walletRootId,
281
+ }).catch(() => null);
282
+ if (service !== null) {
283
+ const rpc = rpcFactory(service.rpc);
284
+ const reconciledState = (await reconcileLiveMiningState({
285
+ state: localState.state,
286
+ rpc,
287
+ nodeBestHash: readContext.nodeStatus?.nodeBestHashHex ?? null,
288
+ nodeBestHeight: readContext.nodeStatus?.nodeBestHeight ?? null,
289
+ snapshotState: readContext.snapshot?.state ?? null,
290
+ })).state;
291
+ const stopState = defaultMiningStopState(reconciledState);
292
+ await saveWalletStatePreservingUnlock({
293
+ state: stopState,
294
+ provider: options.provider,
295
+ paths: options.paths,
296
+ });
297
+ localState = {
298
+ ...localState,
299
+ state: stopState,
300
+ };
301
+ }
302
+ }
303
+ await refreshAndSaveMiningRuntimeStatus({
304
+ paths: options.paths,
305
+ provider: options.provider,
306
+ readContext: {
307
+ ...readContext,
308
+ localState,
309
+ },
310
+ overrides: {
311
+ runMode: "stopped",
312
+ backgroundWorkerPid: options.runMode === "background" ? null : options.backgroundWorkerPid,
313
+ backgroundWorkerRunId: options.runMode === "background" ? null : options.backgroundWorkerRunId,
314
+ backgroundWorkerHeartbeatAtUnixMs: options.runMode === "background" ? null : Date.now(),
315
+ currentPhase: "idle",
316
+ note: options.note,
317
+ },
318
+ });
319
+ }
320
+ finally {
321
+ await readContext.close();
322
+ }
323
+ }
324
+ function defaultMiningStopState(state) {
325
+ return defaultMiningStatePatch(state, {
326
+ runMode: "stopped",
327
+ state: state.miningState.livePublishInMempool
328
+ ? state.miningState.state === "paused-stale"
329
+ ? "paused-stale"
330
+ : "paused"
331
+ : state.miningState.state === "repair-required"
332
+ ? "repair-required"
333
+ : "idle",
334
+ pauseReason: state.miningState.livePublishInMempool
335
+ ? state.miningState.state === "paused-stale"
336
+ ? "stale-block-context"
337
+ : "user-stopped"
338
+ : state.miningState.state === "repair-required"
339
+ ? state.miningState.pauseReason
340
+ : null,
341
+ });
342
+ }
343
+ export async function attemptSaveMempool(options) {
344
+ try {
345
+ await options.rpc.saveMempool?.();
346
+ }
347
+ catch {
348
+ // ignore
349
+ }
350
+ finally {
351
+ await appendMiningEvent(options.paths.miningEventsPath, createMiningEventRecord("savemempool-attempted", "Attempted to persist the local mempool before stopping mining.", {
352
+ runId: options.runId,
353
+ }));
354
+ }
355
+ }
@@ -0,0 +1,61 @@
1
+ import type { WalletBitcoindStatus, WalletIndexerStatus, WalletLocalStateStatus, WalletNodeStatus } from "../read/types.js";
2
+ import type { WalletStateV1 } from "../types.js";
3
+ import type { MiningCandidate } from "./engine-types.js";
4
+ import type { MiningProviderInspection, MiningRuntimeStatusV1 } from "./types.js";
5
+ export interface MiningRuntimeStatusOverrides {
6
+ runMode?: MiningRuntimeStatusV1["runMode"];
7
+ backgroundWorkerPid?: number | null;
8
+ backgroundWorkerRunId?: string | null;
9
+ backgroundWorkerHeartbeatAtUnixMs?: number | null;
10
+ currentPhase?: MiningRuntimeStatusV1["currentPhase"];
11
+ currentPublishState?: MiningRuntimeStatusV1["currentPublishState"];
12
+ targetBlockHeight?: number | null;
13
+ referencedBlockHashDisplay?: string | null;
14
+ currentDomainId?: number | null;
15
+ currentDomainName?: string | null;
16
+ currentSentenceDisplay?: string | null;
17
+ currentCanonicalBlend?: string | null;
18
+ currentTxid?: string | null;
19
+ currentWtxid?: string | null;
20
+ currentFeeRateSatVb?: number | null;
21
+ currentAbsoluteFeeSats?: number | null;
22
+ currentBlockFeeSpentSats?: string;
23
+ lastSuspendDetectedAtUnixMs?: number | null;
24
+ reconnectSettledUntilUnixMs?: number | null;
25
+ tipSettledUntilUnixMs?: number | null;
26
+ providerState?: MiningRuntimeStatusV1["providerState"];
27
+ corePublishState?: MiningRuntimeStatusV1["corePublishState"];
28
+ currentPublishDecision?: string | null;
29
+ sameDomainCompetitorSuppressed?: boolean | null;
30
+ higherRankedCompetitorDomainCount?: number | null;
31
+ dedupedCompetitorDomainCount?: number | null;
32
+ competitivenessGateIndeterminate?: boolean | null;
33
+ mempoolSequenceCacheStatus?: MiningRuntimeStatusV1["mempoolSequenceCacheStatus"];
34
+ lastMempoolSequence?: string | null;
35
+ lastCompetitivenessGateAtUnixMs?: number | null;
36
+ lastError?: string | null;
37
+ note?: string | null;
38
+ livePublishInMempool?: boolean | null;
39
+ }
40
+ export declare function buildPrePublishStatusOverrides(options: {
41
+ state: WalletStateV1;
42
+ candidate: MiningCandidate;
43
+ }): MiningRuntimeStatusOverrides;
44
+ export declare function buildMiningRuntimeStatusSnapshot(options: {
45
+ nowUnixMs: number;
46
+ localState: WalletLocalStateStatus;
47
+ bitcoind: WalletBitcoindStatus;
48
+ nodeStatus: WalletNodeStatus | null;
49
+ provider: MiningProviderInspection;
50
+ nodeHealth: MiningRuntimeStatusV1["nodeHealth"];
51
+ indexer: WalletIndexerStatus;
52
+ tipsAligned: boolean | null;
53
+ lastEventAtUnixMs: number | null;
54
+ existingRuntime: MiningRuntimeStatusV1 | null;
55
+ }): Promise<MiningRuntimeStatusV1>;
56
+ export declare function applyMiningRuntimeStatusOverrides(options: {
57
+ runtime: MiningRuntimeStatusV1;
58
+ provider: MiningProviderInspection;
59
+ overrides?: MiningRuntimeStatusOverrides;
60
+ nowUnixMs?: number;
61
+ }): MiningRuntimeStatusV1;