@cogcoin/client 1.1.3 → 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 (88) hide show
  1. package/README.md +4 -5
  2. package/dist/bitcoind/node.js +2 -1
  3. package/dist/bitcoind/progress/tty-renderer.js +3 -2
  4. package/dist/bitcoind/service.js +6 -24
  5. package/dist/bitcoind/types.d.ts +1 -0
  6. package/dist/bitcoind/types.js +1 -0
  7. package/dist/cli/command-registry.d.ts +39 -0
  8. package/dist/cli/command-registry.js +1132 -0
  9. package/dist/cli/commands/client-admin.js +6 -56
  10. package/dist/cli/commands/mining-admin.js +9 -32
  11. package/dist/cli/commands/mining-read.js +15 -56
  12. package/dist/cli/commands/mining-runtime.js +258 -57
  13. package/dist/cli/commands/service-runtime.js +1 -64
  14. package/dist/cli/commands/status.js +2 -15
  15. package/dist/cli/commands/update.js +6 -21
  16. package/dist/cli/commands/wallet-admin.js +18 -120
  17. package/dist/cli/commands/wallet-mutation.js +4 -7
  18. package/dist/cli/commands/wallet-read.js +31 -138
  19. package/dist/cli/context.js +2 -4
  20. package/dist/cli/mining-format.js +8 -2
  21. package/dist/cli/mutation-command-groups.d.ts +11 -11
  22. package/dist/cli/mutation-command-groups.js +9 -18
  23. package/dist/cli/mutation-json.d.ts +1 -17
  24. package/dist/cli/mutation-json.js +1 -28
  25. package/dist/cli/mutation-success.d.ts +0 -1
  26. package/dist/cli/mutation-success.js +0 -19
  27. package/dist/cli/output.d.ts +1 -10
  28. package/dist/cli/output.js +52 -481
  29. package/dist/cli/parse.d.ts +1 -1
  30. package/dist/cli/parse.js +38 -695
  31. package/dist/cli/runner.js +28 -113
  32. package/dist/cli/types.d.ts +7 -8
  33. package/dist/cli/update-notifier.js +1 -1
  34. package/dist/cli/wallet-format.js +1 -1
  35. package/dist/wallet/lifecycle/managed-core.d.ts +23 -0
  36. package/dist/wallet/lifecycle/managed-core.js +257 -0
  37. package/dist/wallet/lifecycle/repair-mining.d.ts +49 -0
  38. package/dist/wallet/lifecycle/repair-mining.js +304 -0
  39. package/dist/wallet/lifecycle/repair-runtime.d.ts +36 -0
  40. package/dist/wallet/lifecycle/repair-runtime.js +206 -0
  41. package/dist/wallet/lifecycle/repair.d.ts +11 -0
  42. package/dist/wallet/lifecycle/repair.js +368 -0
  43. package/dist/wallet/lifecycle/setup.d.ts +16 -0
  44. package/dist/wallet/lifecycle/setup.js +430 -0
  45. package/dist/wallet/lifecycle/types.d.ts +125 -0
  46. package/dist/wallet/lifecycle/types.js +1 -0
  47. package/dist/wallet/lifecycle.d.ts +4 -165
  48. package/dist/wallet/lifecycle.js +3 -1656
  49. package/dist/wallet/mining/candidate.d.ts +60 -0
  50. package/dist/wallet/mining/candidate.js +290 -0
  51. package/dist/wallet/mining/competitiveness.d.ts +22 -0
  52. package/dist/wallet/mining/competitiveness.js +640 -0
  53. package/dist/wallet/mining/control.js +7 -251
  54. package/dist/wallet/mining/cycle.d.ts +39 -0
  55. package/dist/wallet/mining/cycle.js +542 -0
  56. package/dist/wallet/mining/engine-state.d.ts +66 -0
  57. package/dist/wallet/mining/engine-state.js +211 -0
  58. package/dist/wallet/mining/engine-types.d.ts +173 -0
  59. package/dist/wallet/mining/engine-types.js +1 -0
  60. package/dist/wallet/mining/engine-utils.d.ts +7 -0
  61. package/dist/wallet/mining/engine-utils.js +75 -0
  62. package/dist/wallet/mining/events.d.ts +2 -0
  63. package/dist/wallet/mining/events.js +19 -0
  64. package/dist/wallet/mining/lifecycle.d.ts +71 -0
  65. package/dist/wallet/mining/lifecycle.js +355 -0
  66. package/dist/wallet/mining/projection.d.ts +61 -0
  67. package/dist/wallet/mining/projection.js +319 -0
  68. package/dist/wallet/mining/publish.d.ts +79 -0
  69. package/dist/wallet/mining/publish.js +614 -0
  70. package/dist/wallet/mining/runner.d.ts +12 -418
  71. package/dist/wallet/mining/runner.js +274 -3433
  72. package/dist/wallet/mining/supervisor.d.ts +134 -0
  73. package/dist/wallet/mining/supervisor.js +558 -0
  74. package/dist/wallet/mining/visualizer-sync.d.ts +42 -0
  75. package/dist/wallet/mining/visualizer-sync.js +166 -0
  76. package/dist/wallet/mining/visualizer.d.ts +1 -0
  77. package/dist/wallet/mining/visualizer.js +33 -18
  78. package/dist/wallet/read/context.d.ts +5 -1
  79. package/dist/wallet/read/context.js +19 -4
  80. package/dist/wallet/reset.d.ts +1 -1
  81. package/dist/wallet/reset.js +35 -11
  82. package/dist/wallet/runtime.d.ts +0 -6
  83. package/dist/wallet/runtime.js +2 -38
  84. package/dist/wallet/tx/common.d.ts +18 -0
  85. package/dist/wallet/tx/common.js +40 -26
  86. package/package.json +1 -1
  87. package/dist/wallet/state/seed-index.d.ts +0 -43
  88. package/dist/wallet/state/seed-index.js +0 -151
@@ -0,0 +1,430 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { access, constants } from "node:fs/promises";
3
+ import { withClaimedUninitializedManagedRuntime } from "../../bitcoind/service.js";
4
+ import { acquireFileLock } from "../fs/lock.js";
5
+ import { createInternalCoreWalletPassphrase, createMnemonicConfirmationChallenge, deriveWalletMaterialFromMnemonic, generateWalletMaterial, isEnglishMnemonicWord, validateEnglishMnemonic, } from "../material.js";
6
+ import { renderWalletMnemonicRevealArt } from "../mnemonic-art.js";
7
+ import { resolveWalletRuntimePathsForTesting } from "../runtime.js";
8
+ import { clearWalletPendingInitializationState, loadWalletPendingInitializationStateOrNull, saveWalletPendingInitializationState, } from "../state/pending-init.js";
9
+ import { createDefaultWalletSecretProvider, createWalletPendingInitSecretReference, createWalletRootId, createWalletSecretReference, ensureClientPasswordConfigured, withInteractiveWalletSecretProvider, } from "../state/provider.js";
10
+ import { clearLegacyWalletLockArtifacts, } from "../managed-core-wallet.js";
11
+ import { loadWalletState, saveWalletState } from "../state/storage.js";
12
+ import { importDescriptorIntoManagedCoreWallet, normalizeLoadedWalletStateIfNeeded, sanitizeWalletName, } from "./managed-core.js";
13
+ function resolvePendingInitializationStoragePaths(paths) {
14
+ return {
15
+ primaryPath: paths.walletInitPendingPath,
16
+ backupPath: paths.walletInitPendingBackupPath,
17
+ };
18
+ }
19
+ async function pathExists(path) {
20
+ try {
21
+ await access(path, constants.F_OK);
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ async function clearPendingInitialization(paths, provider) {
29
+ await clearWalletPendingInitializationState(resolvePendingInitializationStoragePaths(paths), {
30
+ provider,
31
+ secretReference: createWalletPendingInitSecretReference(paths.walletStateRoot),
32
+ });
33
+ }
34
+ async function loadOrCreatePendingInitializationMaterial(options) {
35
+ try {
36
+ const loaded = await loadWalletPendingInitializationStateOrNull(resolvePendingInitializationStoragePaths(options.paths), {
37
+ provider: options.provider,
38
+ });
39
+ if (loaded !== null) {
40
+ return deriveWalletMaterialFromMnemonic(loaded.state.mnemonic.phrase);
41
+ }
42
+ }
43
+ catch {
44
+ await clearPendingInitialization(options.paths, options.provider);
45
+ }
46
+ const material = generateWalletMaterial();
47
+ const secretReference = createWalletPendingInitSecretReference(options.paths.walletStateRoot);
48
+ const pendingState = {
49
+ schemaVersion: 1,
50
+ createdAtUnixMs: options.nowUnixMs,
51
+ mnemonic: {
52
+ phrase: material.mnemonic.phrase,
53
+ language: material.mnemonic.language,
54
+ },
55
+ };
56
+ await options.provider.storeSecret(secretReference.keyId, randomBytes(32));
57
+ try {
58
+ await saveWalletPendingInitializationState(resolvePendingInitializationStoragePaths(options.paths), pendingState, {
59
+ provider: options.provider,
60
+ secretReference,
61
+ });
62
+ }
63
+ catch (error) {
64
+ await options.provider.deleteSecret(secretReference.keyId).catch(() => undefined);
65
+ throw error;
66
+ }
67
+ return material;
68
+ }
69
+ function createInitialWalletState(options) {
70
+ return {
71
+ schemaVersion: 5,
72
+ stateRevision: 1,
73
+ lastWrittenAtUnixMs: options.nowUnixMs,
74
+ walletRootId: options.walletRootId,
75
+ network: "mainnet",
76
+ localScriptPubKeyHexes: [options.material.funding.scriptPubKeyHex],
77
+ mnemonic: {
78
+ phrase: options.material.mnemonic.phrase,
79
+ language: options.material.mnemonic.language,
80
+ },
81
+ keys: {
82
+ masterFingerprintHex: options.material.keys.masterFingerprintHex,
83
+ accountPath: options.material.keys.accountPath,
84
+ accountXprv: options.material.keys.accountXprv,
85
+ accountXpub: options.material.keys.accountXpub,
86
+ },
87
+ descriptor: {
88
+ privateExternal: options.material.descriptor.privateExternal,
89
+ publicExternal: options.material.descriptor.publicExternal,
90
+ checksum: options.material.descriptor.checksum,
91
+ rangeEnd: options.material.descriptor.rangeEnd,
92
+ safetyMargin: options.material.descriptor.safetyMargin,
93
+ },
94
+ funding: {
95
+ address: options.material.funding.address,
96
+ scriptPubKeyHex: options.material.funding.scriptPubKeyHex,
97
+ },
98
+ walletBirthTime: Math.floor(options.nowUnixMs / 1000),
99
+ managedCoreWallet: {
100
+ walletName: sanitizeWalletName(options.walletRootId),
101
+ internalPassphrase: options.internalCoreWalletPassphrase,
102
+ descriptorChecksum: null,
103
+ walletAddress: null,
104
+ walletScriptPubKeyHex: null,
105
+ proofStatus: "not-proven",
106
+ lastImportedAtUnixMs: null,
107
+ lastVerifiedAtUnixMs: null,
108
+ },
109
+ domains: [],
110
+ miningState: {
111
+ runMode: "stopped",
112
+ state: "idle",
113
+ pauseReason: null,
114
+ currentPublishState: "none",
115
+ currentDomain: null,
116
+ currentDomainId: null,
117
+ currentDomainIndex: null,
118
+ currentSenderScriptPubKeyHex: null,
119
+ currentTxid: null,
120
+ currentWtxid: null,
121
+ currentFeeRateSatVb: null,
122
+ currentAbsoluteFeeSats: null,
123
+ currentScore: null,
124
+ currentSentence: null,
125
+ currentEncodedSentenceBytesHex: null,
126
+ currentBip39WordIndices: null,
127
+ currentBlendSeedHex: null,
128
+ currentBlockTargetHeight: null,
129
+ currentReferencedBlockHashDisplay: null,
130
+ currentIntentFingerprintHex: null,
131
+ livePublishInMempool: null,
132
+ currentPublishDecision: null,
133
+ replacementCount: 0,
134
+ currentBlockFeeSpentSats: "0",
135
+ sessionFeeSpentSats: "0",
136
+ lifetimeFeeSpentSats: "0",
137
+ sharedMiningConflictOutpoint: null,
138
+ },
139
+ pendingMutations: [],
140
+ };
141
+ }
142
+ async function promptRequiredValue(prompter, message) {
143
+ const value = (await prompter.prompt(message)).trim();
144
+ if (value === "") {
145
+ throw new Error("wallet_prompt_value_required");
146
+ }
147
+ return value;
148
+ }
149
+ async function promptForRestoreMnemonic(prompter) {
150
+ const words = [];
151
+ for (let index = 0; index < 24; index += 1) {
152
+ const word = (await promptRequiredValue(prompter, `Word ${index + 1} of 24: `)).toLowerCase();
153
+ if (!isEnglishMnemonicWord(word)) {
154
+ throw new Error("wallet_restore_mnemonic_invalid");
155
+ }
156
+ words.push(word);
157
+ }
158
+ const phrase = words.join(" ");
159
+ if (!validateEnglishMnemonic(phrase)) {
160
+ throw new Error("wallet_restore_mnemonic_invalid");
161
+ }
162
+ return phrase;
163
+ }
164
+ async function promptForInitializationMode(prompter) {
165
+ if (prompter.selectOption != null) {
166
+ return await prompter.selectOption({
167
+ message: "How should Cogcoin set up this wallet?",
168
+ options: [
169
+ {
170
+ label: "Create new wallet",
171
+ description: "Generate a fresh 24-word recovery phrase.",
172
+ value: "generated",
173
+ },
174
+ {
175
+ label: "Restore existing wallet",
176
+ description: "Enter an existing 24-word recovery phrase.",
177
+ value: "restored",
178
+ },
179
+ ],
180
+ initialValue: "generated",
181
+ });
182
+ }
183
+ prompter.writeLine("How should Cogcoin set up this wallet?");
184
+ prompter.writeLine("1. Create new wallet");
185
+ prompter.writeLine("2. Restore existing wallet");
186
+ while (true) {
187
+ const answer = (await prompter.prompt("Choice [1-2]: ")).trim();
188
+ if (answer === "1") {
189
+ return "generated";
190
+ }
191
+ if (answer === "2") {
192
+ return "restored";
193
+ }
194
+ prompter.writeLine("Enter 1 or 2.");
195
+ }
196
+ }
197
+ async function confirmTypedAcknowledgement(prompter, expected, message, errorCode = "wallet_typed_confirmation_rejected") {
198
+ const answer = (await prompter.prompt(message)).trim();
199
+ if (answer !== expected) {
200
+ throw new Error(errorCode);
201
+ }
202
+ }
203
+ function isWalletSecretAccessError(error) {
204
+ const message = error instanceof Error ? error.message : String(error);
205
+ return message.startsWith("wallet_secret_missing_")
206
+ || message.startsWith("wallet_secret_provider_");
207
+ }
208
+ async function persistInitializedWallet(options) {
209
+ const walletRootId = createWalletRootId();
210
+ const internalCoreWalletPassphrase = createInternalCoreWalletPassphrase();
211
+ const secretReference = createWalletSecretReference(walletRootId);
212
+ await options.provider.storeSecret(secretReference.keyId, randomBytes(32));
213
+ const initialState = createInitialWalletState({
214
+ walletRootId,
215
+ nowUnixMs: options.nowUnixMs,
216
+ material: options.material,
217
+ internalCoreWalletPassphrase,
218
+ });
219
+ const verifiedState = await withClaimedUninitializedManagedRuntime({
220
+ dataDir: options.dataDir,
221
+ walletRootId,
222
+ }, async () => {
223
+ await saveWalletState({
224
+ primaryPath: options.paths.walletStatePath,
225
+ backupPath: options.paths.walletStateBackupPath,
226
+ }, initialState, {
227
+ provider: options.provider,
228
+ secretReference,
229
+ });
230
+ return importDescriptorIntoManagedCoreWallet(initialState, options.provider, options.paths, options.dataDir, options.nowUnixMs, options.attachService, options.rpcFactory);
231
+ });
232
+ await clearLegacyWalletLockArtifacts(options.paths.walletRuntimeRoot);
233
+ await clearPendingInitialization(options.paths, options.provider);
234
+ return {
235
+ walletRootId,
236
+ state: verifiedState,
237
+ };
238
+ }
239
+ function writeMnemonicReveal(prompter, phrase, introLines) {
240
+ const words = phrase.trim().split(/\s+/);
241
+ for (const line of introLines) {
242
+ prompter.writeLine(line);
243
+ }
244
+ for (const line of renderWalletMnemonicRevealArt(words)) {
245
+ prompter.writeLine(line);
246
+ }
247
+ prompter.writeLine("Single-line copy:");
248
+ prompter.writeLine(phrase);
249
+ }
250
+ async function confirmMnemonic(prompter, words) {
251
+ const challenge = createMnemonicConfirmationChallenge(words);
252
+ for (const entry of challenge) {
253
+ const answer = (await prompter.prompt(`Confirm word #${entry.index + 1}: `)).trim().toLowerCase();
254
+ if (answer !== entry.word) {
255
+ throw new Error(`wallet_init_confirmation_failed_word_${entry.index + 1}`);
256
+ }
257
+ }
258
+ }
259
+ async function loadWalletStateForAccess(options = {}) {
260
+ const provider = options.provider ?? createDefaultWalletSecretProvider();
261
+ const nowUnixMs = options.nowUnixMs ?? Date.now();
262
+ const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
263
+ const loaded = await loadWalletState({
264
+ primaryPath: paths.walletStatePath,
265
+ backupPath: paths.walletStateBackupPath,
266
+ }, {
267
+ provider,
268
+ });
269
+ return normalizeLoadedWalletStateIfNeeded({
270
+ provider,
271
+ state: loaded.state,
272
+ source: loaded.source,
273
+ nowUnixMs,
274
+ paths,
275
+ dataDir: options.dataDir,
276
+ attachService: options.attachService,
277
+ rpcFactory: options.rpcFactory,
278
+ });
279
+ }
280
+ export async function initializeWallet(options) {
281
+ if (!options.prompter.isInteractive) {
282
+ throw new Error("wallet_init_requires_tty");
283
+ }
284
+ const provider = options.provider ?? createDefaultWalletSecretProvider();
285
+ const interactiveProvider = withInteractiveWalletSecretProvider(provider, options.prompter);
286
+ const nowUnixMs = options.nowUnixMs ?? Date.now();
287
+ const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
288
+ const controlLock = await acquireFileLock(paths.walletControlLockPath, {
289
+ purpose: "wallet-init",
290
+ walletRootId: null,
291
+ });
292
+ try {
293
+ const passwordAction = await ensureClientPasswordConfigured(provider, options.prompter);
294
+ const hasWalletState = await pathExists(paths.walletStatePath) || await pathExists(paths.walletStateBackupPath);
295
+ if (hasWalletState) {
296
+ await clearPendingInitialization(paths, interactiveProvider);
297
+ const loaded = await loadWalletStateForAccess({
298
+ provider: interactiveProvider,
299
+ nowUnixMs,
300
+ paths,
301
+ dataDir: options.dataDir,
302
+ attachService: options.attachService,
303
+ rpcFactory: options.rpcFactory,
304
+ });
305
+ return {
306
+ setupMode: "existing",
307
+ passwordAction,
308
+ walletAction: "already-initialized",
309
+ walletRootId: loaded.state.walletRootId,
310
+ fundingAddress: loaded.state.funding.address,
311
+ state: loaded.state,
312
+ };
313
+ }
314
+ const setupMode = await promptForInitializationMode(options.prompter);
315
+ let material;
316
+ if (setupMode === "generated") {
317
+ material = await loadOrCreatePendingInitializationMaterial({
318
+ provider: interactiveProvider,
319
+ paths,
320
+ nowUnixMs,
321
+ });
322
+ let mnemonicRevealed = false;
323
+ writeMnemonicReveal(options.prompter, material.mnemonic.phrase, [
324
+ "Cogcoin Wallet Initialization",
325
+ "Write down this 24-word recovery phrase.",
326
+ "The same phrase will be shown again until confirmation succeeds:",
327
+ "",
328
+ ]);
329
+ mnemonicRevealed = true;
330
+ try {
331
+ await confirmMnemonic(options.prompter, material.mnemonic.words);
332
+ }
333
+ finally {
334
+ if (mnemonicRevealed) {
335
+ await Promise.resolve()
336
+ .then(() => options.prompter.clearSensitiveDisplay?.("mnemonic-reveal"))
337
+ .catch(() => undefined);
338
+ }
339
+ }
340
+ }
341
+ else {
342
+ let promptPhaseStarted = false;
343
+ let mnemonicPhrase;
344
+ try {
345
+ promptPhaseStarted = true;
346
+ mnemonicPhrase = await promptForRestoreMnemonic(options.prompter);
347
+ }
348
+ finally {
349
+ if (promptPhaseStarted) {
350
+ await options.prompter.clearSensitiveDisplay?.("restore-mnemonic-entry");
351
+ }
352
+ }
353
+ await clearPendingInitialization(paths, interactiveProvider);
354
+ material = deriveWalletMaterialFromMnemonic(mnemonicPhrase);
355
+ }
356
+ const initialized = await persistInitializedWallet({
357
+ dataDir: options.dataDir,
358
+ provider: interactiveProvider,
359
+ material,
360
+ nowUnixMs,
361
+ paths,
362
+ attachService: options.attachService,
363
+ rpcFactory: options.rpcFactory,
364
+ });
365
+ return {
366
+ setupMode,
367
+ passwordAction,
368
+ walletAction: "initialized",
369
+ walletRootId: initialized.walletRootId,
370
+ fundingAddress: initialized.state.funding.address,
371
+ state: initialized.state,
372
+ };
373
+ }
374
+ finally {
375
+ await controlLock.release();
376
+ }
377
+ }
378
+ export async function showWalletMnemonic(options) {
379
+ if (!options.prompter.isInteractive) {
380
+ throw new Error("wallet_show_mnemonic_requires_tty");
381
+ }
382
+ const provider = options.provider ?? createDefaultWalletSecretProvider();
383
+ const interactiveProvider = withInteractiveWalletSecretProvider(provider, options.prompter);
384
+ const nowUnixMs = options.nowUnixMs ?? Date.now();
385
+ const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
386
+ const controlLock = await acquireFileLock(paths.walletControlLockPath, {
387
+ purpose: "wallet-show-mnemonic",
388
+ walletRootId: null,
389
+ });
390
+ try {
391
+ const [hasPrimaryStateFile, hasBackupStateFile] = await Promise.all([
392
+ pathExists(paths.walletStatePath),
393
+ pathExists(paths.walletStateBackupPath),
394
+ ]);
395
+ if (!hasPrimaryStateFile && !hasBackupStateFile) {
396
+ throw new Error("wallet_uninitialized");
397
+ }
398
+ const loaded = await loadWalletStateForAccess({
399
+ provider: interactiveProvider,
400
+ nowUnixMs,
401
+ paths,
402
+ }).catch((error) => {
403
+ if (isWalletSecretAccessError(error)) {
404
+ throw new Error("wallet_secret_provider_unavailable");
405
+ }
406
+ throw new Error("local-state-corrupt");
407
+ });
408
+ await confirmTypedAcknowledgement(options.prompter, "show mnemonic", "Type \"show mnemonic\" to continue: ", "wallet_show_mnemonic_typed_ack_required");
409
+ let mnemonicRevealed = false;
410
+ writeMnemonicReveal(options.prompter, loaded.state.mnemonic.phrase, [
411
+ "Cogcoin Wallet Recovery Phrase",
412
+ "This 24-word recovery phrase controls the wallet.",
413
+ "",
414
+ ]);
415
+ mnemonicRevealed = true;
416
+ try {
417
+ await options.prompter.prompt("Press Enter to clear the recovery phrase from the screen: ");
418
+ }
419
+ finally {
420
+ if (mnemonicRevealed) {
421
+ await Promise.resolve()
422
+ .then(() => options.prompter.clearSensitiveDisplay?.("mnemonic-reveal"))
423
+ .catch(() => undefined);
424
+ }
425
+ }
426
+ }
427
+ finally {
428
+ await controlLock.release();
429
+ }
430
+ }
@@ -0,0 +1,125 @@
1
+ import type { attachOrStartIndexerDaemon, probeIndexerDaemon } from "../../bitcoind/indexer-daemon.js";
2
+ import type { createRpcClient } from "../../bitcoind/node.js";
3
+ import type { attachOrStartManagedBitcoindService, probeManagedBitcoindService } from "../../bitcoind/service.js";
4
+ import type { RpcListUnspentEntry } from "../../bitcoind/types.js";
5
+ import type { requestMiningGenerationPreemption } from "../mining/coordination.js";
6
+ import type { startBackgroundMining } from "../mining/runner.js";
7
+ import type { WalletRuntimePaths } from "../runtime.js";
8
+ import type { WalletSecretProvider } from "../state/provider.js";
9
+ import type { WalletStateV1 } from "../types.js";
10
+ export interface WalletPrompter {
11
+ readonly isInteractive: boolean;
12
+ writeLine(message: string): void;
13
+ prompt(message: string): Promise<string>;
14
+ promptHidden?(message: string): Promise<string>;
15
+ selectOption?(options: {
16
+ message: string;
17
+ options: Array<{
18
+ label: string;
19
+ description?: string | null;
20
+ value: string;
21
+ }>;
22
+ initialValue?: string | null;
23
+ footer?: string | null;
24
+ }): Promise<string>;
25
+ clearSensitiveDisplay?(scope: "mnemonic-reveal" | "restore-mnemonic-entry"): void | Promise<void>;
26
+ }
27
+ export interface WalletInitializationResult {
28
+ setupMode: "generated" | "restored" | "existing";
29
+ passwordAction: "created" | "migrated" | "already-configured";
30
+ walletAction: "initialized" | "already-initialized";
31
+ walletRootId: string;
32
+ fundingAddress: string;
33
+ state: WalletStateV1;
34
+ }
35
+ export interface WalletRepairResult {
36
+ walletRootId: string;
37
+ recoveredFromBackup: boolean;
38
+ recreatedManagedCoreWallet: boolean;
39
+ resetIndexerDatabase: boolean;
40
+ bitcoindServiceAction: "none" | "cleared-stale-artifacts" | "stopped-incompatible-service" | "restarted-compatible-service";
41
+ bitcoindCompatibilityIssue: "none" | "service-version-mismatch" | "wallet-root-mismatch" | "runtime-mismatch";
42
+ managedCoreReplicaAction: "none" | "recreated";
43
+ bitcoindPostRepairHealth: "ready" | "catching-up" | "starting" | "failed" | "unavailable";
44
+ indexerDaemonAction: "none" | "cleared-stale-artifacts" | "stopped-incompatible-daemon" | "restarted-compatible-daemon";
45
+ indexerCompatibilityIssue: "none" | "service-version-mismatch" | "wallet-root-mismatch" | "schema-mismatch";
46
+ indexerPostRepairHealth: "starting" | "catching-up" | "synced" | "failed";
47
+ miningPreRepairRunMode: "stopped" | "foreground" | "background";
48
+ miningResumeAction: "none" | "skipped-not-resumable" | "skipped-post-repair-blocked" | "resumed-background" | "resume-failed";
49
+ miningPostRepairRunMode: "stopped" | "background";
50
+ miningResumeError: string | null;
51
+ note: string | null;
52
+ }
53
+ export interface WalletLifecycleRpcClient {
54
+ getDescriptorInfo(descriptor: string): Promise<{
55
+ descriptor: string;
56
+ checksum: string;
57
+ }>;
58
+ createWallet(walletName: string, options: {
59
+ blank: boolean;
60
+ descriptors: boolean;
61
+ disablePrivateKeys: boolean;
62
+ loadOnStartup: boolean;
63
+ passphrase: string;
64
+ }): Promise<unknown>;
65
+ walletPassphrase(walletName: string, passphrase: string, timeoutSeconds: number): Promise<null>;
66
+ importDescriptors(walletName: string, requests: Array<{
67
+ desc: string;
68
+ timestamp: string | number;
69
+ active?: boolean;
70
+ internal?: boolean;
71
+ range?: number | [number, number];
72
+ }>): Promise<Array<{
73
+ success: boolean;
74
+ }>>;
75
+ walletLock(walletName: string): Promise<null>;
76
+ deriveAddresses(descriptor: string, range?: number | [number, number]): Promise<string[]>;
77
+ listDescriptors(walletName: string, privateOnly?: boolean): Promise<{
78
+ descriptors: Array<{
79
+ desc: string;
80
+ }>;
81
+ }>;
82
+ getWalletInfo(walletName: string): Promise<{
83
+ walletname: string;
84
+ private_keys_enabled: boolean;
85
+ descriptors: boolean;
86
+ }>;
87
+ loadWallet(walletName: string, loadOnStartup?: boolean): Promise<{
88
+ name: string;
89
+ warning: string;
90
+ }>;
91
+ unloadWallet?(walletName: string, loadOnStartup?: boolean): Promise<null>;
92
+ listWallets(): Promise<string[]>;
93
+ listUnspent(walletName: string, minConf?: number): Promise<RpcListUnspentEntry[]>;
94
+ getBlockchainInfo(): Promise<{
95
+ blocks: number;
96
+ headers: number;
97
+ }>;
98
+ }
99
+ export interface WalletManagedCoreDependencies {
100
+ attachService?: typeof attachOrStartManagedBitcoindService;
101
+ rpcFactory?: (config: Parameters<typeof createRpcClient>[0]) => WalletLifecycleRpcClient;
102
+ }
103
+ export interface WalletSetupDependencies extends WalletManagedCoreDependencies {
104
+ }
105
+ export interface WalletLifecycleResolvedContext {
106
+ provider: WalletSecretProvider;
107
+ paths: WalletRuntimePaths;
108
+ nowUnixMs: number;
109
+ }
110
+ export interface WalletSetupContext extends WalletLifecycleResolvedContext, WalletSetupDependencies {
111
+ dataDir: string;
112
+ prompter: WalletPrompter;
113
+ }
114
+ export interface WalletRepairDependencies extends WalletManagedCoreDependencies {
115
+ probeBitcoindService?: typeof probeManagedBitcoindService;
116
+ attachIndexerDaemon?: typeof attachOrStartIndexerDaemon;
117
+ probeIndexerDaemon?: typeof probeIndexerDaemon;
118
+ requestMiningPreemption?: typeof requestMiningGenerationPreemption;
119
+ startBackgroundMining?: typeof startBackgroundMining;
120
+ }
121
+ export interface WalletRepairContext extends WalletLifecycleResolvedContext, WalletRepairDependencies {
122
+ dataDir: string;
123
+ databasePath: string;
124
+ assumeYes: boolean;
125
+ }
@@ -0,0 +1 @@
1
+ export {};