@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.
- package/README.md +4 -5
- package/dist/bitcoind/node.js +2 -1
- package/dist/bitcoind/progress/tty-renderer.js +3 -2
- package/dist/bitcoind/service.js +6 -24
- package/dist/bitcoind/types.d.ts +1 -0
- package/dist/bitcoind/types.js +1 -0
- package/dist/cli/command-registry.d.ts +39 -0
- package/dist/cli/command-registry.js +1132 -0
- package/dist/cli/commands/client-admin.js +6 -56
- package/dist/cli/commands/mining-admin.js +9 -32
- package/dist/cli/commands/mining-read.js +15 -56
- package/dist/cli/commands/mining-runtime.js +258 -57
- package/dist/cli/commands/service-runtime.js +1 -64
- package/dist/cli/commands/status.js +2 -15
- package/dist/cli/commands/update.js +6 -21
- package/dist/cli/commands/wallet-admin.js +18 -120
- package/dist/cli/commands/wallet-mutation.js +4 -7
- package/dist/cli/commands/wallet-read.js +31 -138
- package/dist/cli/context.js +2 -4
- package/dist/cli/mining-format.js +8 -2
- package/dist/cli/mutation-command-groups.d.ts +11 -11
- package/dist/cli/mutation-command-groups.js +9 -18
- package/dist/cli/mutation-json.d.ts +1 -17
- package/dist/cli/mutation-json.js +1 -28
- package/dist/cli/mutation-success.d.ts +0 -1
- package/dist/cli/mutation-success.js +0 -19
- package/dist/cli/output.d.ts +1 -10
- package/dist/cli/output.js +52 -481
- package/dist/cli/parse.d.ts +1 -1
- package/dist/cli/parse.js +38 -695
- package/dist/cli/runner.js +28 -113
- package/dist/cli/types.d.ts +7 -8
- package/dist/cli/update-notifier.js +1 -1
- package/dist/cli/wallet-format.js +1 -1
- package/dist/wallet/lifecycle/managed-core.d.ts +23 -0
- package/dist/wallet/lifecycle/managed-core.js +257 -0
- package/dist/wallet/lifecycle/repair-mining.d.ts +49 -0
- package/dist/wallet/lifecycle/repair-mining.js +304 -0
- package/dist/wallet/lifecycle/repair-runtime.d.ts +36 -0
- package/dist/wallet/lifecycle/repair-runtime.js +206 -0
- package/dist/wallet/lifecycle/repair.d.ts +11 -0
- package/dist/wallet/lifecycle/repair.js +368 -0
- package/dist/wallet/lifecycle/setup.d.ts +16 -0
- package/dist/wallet/lifecycle/setup.js +430 -0
- package/dist/wallet/lifecycle/types.d.ts +125 -0
- package/dist/wallet/lifecycle/types.js +1 -0
- package/dist/wallet/lifecycle.d.ts +4 -165
- package/dist/wallet/lifecycle.js +3 -1656
- package/dist/wallet/mining/candidate.d.ts +60 -0
- package/dist/wallet/mining/candidate.js +290 -0
- package/dist/wallet/mining/competitiveness.d.ts +22 -0
- package/dist/wallet/mining/competitiveness.js +640 -0
- package/dist/wallet/mining/control.js +7 -251
- package/dist/wallet/mining/cycle.d.ts +39 -0
- package/dist/wallet/mining/cycle.js +542 -0
- package/dist/wallet/mining/engine-state.d.ts +66 -0
- package/dist/wallet/mining/engine-state.js +211 -0
- package/dist/wallet/mining/engine-types.d.ts +173 -0
- package/dist/wallet/mining/engine-types.js +1 -0
- package/dist/wallet/mining/engine-utils.d.ts +7 -0
- package/dist/wallet/mining/engine-utils.js +75 -0
- package/dist/wallet/mining/events.d.ts +2 -0
- package/dist/wallet/mining/events.js +19 -0
- package/dist/wallet/mining/lifecycle.d.ts +71 -0
- package/dist/wallet/mining/lifecycle.js +355 -0
- package/dist/wallet/mining/projection.d.ts +61 -0
- package/dist/wallet/mining/projection.js +319 -0
- package/dist/wallet/mining/publish.d.ts +79 -0
- package/dist/wallet/mining/publish.js +614 -0
- package/dist/wallet/mining/runner.d.ts +12 -418
- package/dist/wallet/mining/runner.js +274 -3433
- package/dist/wallet/mining/supervisor.d.ts +134 -0
- package/dist/wallet/mining/supervisor.js +558 -0
- package/dist/wallet/mining/visualizer-sync.d.ts +42 -0
- package/dist/wallet/mining/visualizer-sync.js +166 -0
- package/dist/wallet/mining/visualizer.d.ts +1 -0
- package/dist/wallet/mining/visualizer.js +33 -18
- package/dist/wallet/read/context.d.ts +5 -1
- package/dist/wallet/read/context.js +19 -4
- package/dist/wallet/reset.d.ts +1 -1
- package/dist/wallet/reset.js +35 -11
- package/dist/wallet/runtime.d.ts +0 -6
- package/dist/wallet/runtime.js +2 -38
- package/dist/wallet/tx/common.d.ts +18 -0
- package/dist/wallet/tx/common.js +40 -26
- package/package.json +1 -1
- package/dist/wallet/state/seed-index.d.ts +0 -43
- package/dist/wallet/state/seed-index.js +0 -151
package/dist/wallet/tx/common.js
CHANGED
|
@@ -416,35 +416,16 @@ export async function pauseMiningForWalletMutation(options) {
|
|
|
416
416
|
});
|
|
417
417
|
}
|
|
418
418
|
export async function buildWalletMutationTransaction(options) {
|
|
419
|
-
const availableFundingMinConf = options.availableFundingMinConf ?? 1;
|
|
420
|
-
const availableFundingUtxos = (await options.rpc.listUnspent(options.walletName, availableFundingMinConf))
|
|
421
|
-
.filter((entry) => isSpendableFundingUtxo(entry, options.plan.allowedFundingScriptPubKeyHex, availableFundingMinConf));
|
|
422
|
-
const availableFundingValueByKey = new Map(availableFundingUtxos.map((entry) => [
|
|
423
|
-
outpointKey({ txid: entry.txid, vout: entry.vout }),
|
|
424
|
-
btcNumberToSats(entry.amount),
|
|
425
|
-
]));
|
|
426
|
-
const validationPlan = {
|
|
427
|
-
...options.plan,
|
|
428
|
-
eligibleFundingOutpointKeys: new Set([
|
|
429
|
-
...options.plan.eligibleFundingOutpointKeys,
|
|
430
|
-
...availableFundingUtxos.map((entry) => outpointKey({ txid: entry.txid, vout: entry.vout })),
|
|
431
|
-
]),
|
|
432
|
-
};
|
|
433
419
|
const temporaryBuilderLockedOutpoints = [];
|
|
434
420
|
try {
|
|
435
|
-
const funded = await
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
fee_rate: options.feeRate ?? DEFAULT_WALLET_MUTATION_FEE_RATE_SAT_VB,
|
|
443
|
-
replaceable: true,
|
|
444
|
-
subtractFeeFromOutputs: [],
|
|
421
|
+
const { funded, decoded } = await fundAndValidateWalletMutationDraft({
|
|
422
|
+
rpc: options.rpc,
|
|
423
|
+
walletName: options.walletName,
|
|
424
|
+
plan: options.plan,
|
|
425
|
+
validateFundedDraft: options.validateFundedDraft,
|
|
426
|
+
feeRate: options.feeRate,
|
|
427
|
+
availableFundingMinConf: options.availableFundingMinConf,
|
|
445
428
|
});
|
|
446
|
-
const decoded = await options.rpc.decodePsbt(funded.psbt);
|
|
447
|
-
options.validateFundedDraft(decoded, funded, validationPlan);
|
|
448
429
|
let signed;
|
|
449
430
|
let finalized;
|
|
450
431
|
let rawHex;
|
|
@@ -490,6 +471,39 @@ export async function buildWalletMutationTransaction(options) {
|
|
|
490
471
|
throw error;
|
|
491
472
|
}
|
|
492
473
|
}
|
|
474
|
+
export async function fundAndValidateWalletMutationDraft(options) {
|
|
475
|
+
const availableFundingMinConf = options.availableFundingMinConf ?? 1;
|
|
476
|
+
const availableFundingUtxos = (await options.rpc.listUnspent(options.walletName, availableFundingMinConf))
|
|
477
|
+
.filter((entry) => isSpendableFundingUtxo(entry, options.plan.allowedFundingScriptPubKeyHex, availableFundingMinConf));
|
|
478
|
+
const availableFundingValueByKey = new Map(availableFundingUtxos.map((entry) => [
|
|
479
|
+
outpointKey({ txid: entry.txid, vout: entry.vout }),
|
|
480
|
+
btcNumberToSats(entry.amount),
|
|
481
|
+
]));
|
|
482
|
+
const validationPlan = {
|
|
483
|
+
...options.plan,
|
|
484
|
+
eligibleFundingOutpointKeys: new Set([
|
|
485
|
+
...options.plan.eligibleFundingOutpointKeys,
|
|
486
|
+
...availableFundingUtxos.map((entry) => outpointKey({ txid: entry.txid, vout: entry.vout })),
|
|
487
|
+
]),
|
|
488
|
+
};
|
|
489
|
+
const funded = await options.rpc.walletCreateFundedPsbt(options.walletName, options.plan.fixedInputs, options.plan.outputs, 0, {
|
|
490
|
+
add_inputs: true,
|
|
491
|
+
include_unsafe: false,
|
|
492
|
+
minconf: availableFundingMinConf,
|
|
493
|
+
changeAddress: options.plan.changeAddress,
|
|
494
|
+
...(options.plan.changePosition == null ? {} : { changePosition: options.plan.changePosition }),
|
|
495
|
+
lockUnspents: false,
|
|
496
|
+
fee_rate: options.feeRate ?? DEFAULT_WALLET_MUTATION_FEE_RATE_SAT_VB,
|
|
497
|
+
replaceable: true,
|
|
498
|
+
subtractFeeFromOutputs: [],
|
|
499
|
+
});
|
|
500
|
+
const decoded = await options.rpc.decodePsbt(funded.psbt);
|
|
501
|
+
options.validateFundedDraft(decoded, funded, validationPlan);
|
|
502
|
+
return {
|
|
503
|
+
funded,
|
|
504
|
+
decoded,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
493
507
|
export async function buildWalletMutationTransactionWithReserveFallback(options) {
|
|
494
508
|
return buildWalletMutationTransaction({
|
|
495
509
|
rpc: options.rpc,
|
package/package.json
CHANGED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { WalletSeedKind, WalletRuntimePaths } from "../runtime.js";
|
|
2
|
-
import { type RawWalletStateEnvelope } from "./storage.js";
|
|
3
|
-
export interface WalletSeedRecord {
|
|
4
|
-
name: string;
|
|
5
|
-
kind: WalletSeedKind;
|
|
6
|
-
walletRootId: string;
|
|
7
|
-
createdAtUnixMs: number;
|
|
8
|
-
restoredAtUnixMs: number | null;
|
|
9
|
-
}
|
|
10
|
-
export interface WalletSeedIndexV1 {
|
|
11
|
-
schemaVersion: 1;
|
|
12
|
-
lastWrittenAtUnixMs: number;
|
|
13
|
-
seeds: WalletSeedRecord[];
|
|
14
|
-
}
|
|
15
|
-
export declare function normalizeWalletSeedName(name: string): string;
|
|
16
|
-
export declare function isValidWalletSeedName(name: string): boolean;
|
|
17
|
-
export declare function assertValidImportedWalletSeedName(name: string): string;
|
|
18
|
-
export declare function findWalletSeedRecord(index: WalletSeedIndexV1, seedName: string): WalletSeedRecord | null;
|
|
19
|
-
export declare function loadWalletSeedIndex(options: {
|
|
20
|
-
paths: Pick<WalletRuntimePaths, "seedRegistryPath" | "walletStatePath" | "walletStateBackupPath">;
|
|
21
|
-
nowUnixMs?: number;
|
|
22
|
-
loadRawWalletStateEnvelope?: (paths: {
|
|
23
|
-
primaryPath: string;
|
|
24
|
-
backupPath: string;
|
|
25
|
-
}) => Promise<RawWalletStateEnvelope | null>;
|
|
26
|
-
}): Promise<WalletSeedIndexV1>;
|
|
27
|
-
export declare function saveWalletSeedIndex(paths: Pick<WalletRuntimePaths, "seedRegistryPath">, index: WalletSeedIndexV1): Promise<void>;
|
|
28
|
-
export declare function ensureMainWalletSeedIndexRecord(options: {
|
|
29
|
-
paths: Pick<WalletRuntimePaths, "seedRegistryPath" | "walletStatePath" | "walletStateBackupPath">;
|
|
30
|
-
walletRootId: string;
|
|
31
|
-
nowUnixMs?: number;
|
|
32
|
-
}): Promise<WalletSeedIndexV1>;
|
|
33
|
-
export declare function addImportedWalletSeedRecord(options: {
|
|
34
|
-
paths: Pick<WalletRuntimePaths, "seedRegistryPath" | "walletStatePath" | "walletStateBackupPath">;
|
|
35
|
-
seedName: string;
|
|
36
|
-
walletRootId: string;
|
|
37
|
-
nowUnixMs?: number;
|
|
38
|
-
}): Promise<WalletSeedIndexV1>;
|
|
39
|
-
export declare function removeWalletSeedRecord(options: {
|
|
40
|
-
paths: Pick<WalletRuntimePaths, "seedRegistryPath" | "walletStatePath" | "walletStateBackupPath">;
|
|
41
|
-
seedName: string;
|
|
42
|
-
nowUnixMs?: number;
|
|
43
|
-
}): Promise<WalletSeedIndexV1>;
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { mkdir, readFile } from "node:fs/promises";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
import { writeFileAtomic } from "../fs/atomic.js";
|
|
4
|
-
import { extractWalletRootIdHintFromWalletStateEnvelope, loadRawWalletStateEnvelope, } from "./storage.js";
|
|
5
|
-
function createEmptySeedIndex(nowUnixMs) {
|
|
6
|
-
return {
|
|
7
|
-
schemaVersion: 1,
|
|
8
|
-
lastWrittenAtUnixMs: nowUnixMs,
|
|
9
|
-
seeds: [],
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
function sortSeedRecords(seeds) {
|
|
13
|
-
return [...seeds].sort((left, right) => left.name.localeCompare(right.name));
|
|
14
|
-
}
|
|
15
|
-
async function readSeedIndexFile(path) {
|
|
16
|
-
try {
|
|
17
|
-
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
18
|
-
if (parsed?.schemaVersion !== 1 || !Array.isArray(parsed.seeds)) {
|
|
19
|
-
throw new Error("wallet_seed_index_invalid");
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
schemaVersion: 1,
|
|
23
|
-
lastWrittenAtUnixMs: typeof parsed.lastWrittenAtUnixMs === "number" ? parsed.lastWrittenAtUnixMs : 0,
|
|
24
|
-
seeds: sortSeedRecords(parsed.seeds),
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
throw new Error("wallet_seed_index_invalid");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export function normalizeWalletSeedName(name) {
|
|
35
|
-
return name.trim().toLowerCase();
|
|
36
|
-
}
|
|
37
|
-
export function isValidWalletSeedName(name) {
|
|
38
|
-
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name);
|
|
39
|
-
}
|
|
40
|
-
export function assertValidImportedWalletSeedName(name) {
|
|
41
|
-
const normalized = normalizeWalletSeedName(name);
|
|
42
|
-
if (!isValidWalletSeedName(normalized)) {
|
|
43
|
-
throw new Error("wallet_seed_name_invalid");
|
|
44
|
-
}
|
|
45
|
-
if (normalized === "main") {
|
|
46
|
-
throw new Error("wallet_seed_name_reserved");
|
|
47
|
-
}
|
|
48
|
-
return normalized;
|
|
49
|
-
}
|
|
50
|
-
export function findWalletSeedRecord(index, seedName) {
|
|
51
|
-
const normalized = normalizeWalletSeedName(seedName);
|
|
52
|
-
return index.seeds.find((seed) => seed.name === normalized) ?? null;
|
|
53
|
-
}
|
|
54
|
-
export async function loadWalletSeedIndex(options) {
|
|
55
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
56
|
-
const stored = await readSeedIndexFile(options.paths.seedRegistryPath);
|
|
57
|
-
if (stored !== null) {
|
|
58
|
-
return stored;
|
|
59
|
-
}
|
|
60
|
-
const rawEnvelope = await (options.loadRawWalletStateEnvelope ?? loadRawWalletStateEnvelope)({
|
|
61
|
-
primaryPath: options.paths.walletStatePath,
|
|
62
|
-
backupPath: options.paths.walletStateBackupPath,
|
|
63
|
-
}).catch(() => null);
|
|
64
|
-
const mainWalletRootId = extractWalletRootIdHintFromWalletStateEnvelope(rawEnvelope?.envelope ?? null);
|
|
65
|
-
if (mainWalletRootId === null) {
|
|
66
|
-
return createEmptySeedIndex(nowUnixMs);
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
schemaVersion: 1,
|
|
70
|
-
lastWrittenAtUnixMs: nowUnixMs,
|
|
71
|
-
seeds: [{
|
|
72
|
-
name: "main",
|
|
73
|
-
kind: "main",
|
|
74
|
-
walletRootId: mainWalletRootId,
|
|
75
|
-
createdAtUnixMs: nowUnixMs,
|
|
76
|
-
restoredAtUnixMs: null,
|
|
77
|
-
}],
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
export async function saveWalletSeedIndex(paths, index) {
|
|
81
|
-
await mkdir(dirname(paths.seedRegistryPath), { recursive: true });
|
|
82
|
-
await writeFileAtomic(paths.seedRegistryPath, `${JSON.stringify({
|
|
83
|
-
...index,
|
|
84
|
-
seeds: sortSeedRecords(index.seeds),
|
|
85
|
-
}, null, 2)}\n`, { mode: 0o600 });
|
|
86
|
-
}
|
|
87
|
-
export async function ensureMainWalletSeedIndexRecord(options) {
|
|
88
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
89
|
-
const index = await loadWalletSeedIndex({
|
|
90
|
-
paths: options.paths,
|
|
91
|
-
nowUnixMs,
|
|
92
|
-
});
|
|
93
|
-
const existing = findWalletSeedRecord(index, "main");
|
|
94
|
-
const seeds = index.seeds.filter((seed) => seed.name !== "main");
|
|
95
|
-
seeds.push({
|
|
96
|
-
name: "main",
|
|
97
|
-
kind: "main",
|
|
98
|
-
walletRootId: options.walletRootId,
|
|
99
|
-
createdAtUnixMs: existing?.createdAtUnixMs ?? nowUnixMs,
|
|
100
|
-
restoredAtUnixMs: existing?.restoredAtUnixMs ?? null,
|
|
101
|
-
});
|
|
102
|
-
const nextIndex = {
|
|
103
|
-
schemaVersion: 1,
|
|
104
|
-
lastWrittenAtUnixMs: nowUnixMs,
|
|
105
|
-
seeds: sortSeedRecords(seeds),
|
|
106
|
-
};
|
|
107
|
-
await saveWalletSeedIndex(options.paths, nextIndex);
|
|
108
|
-
return nextIndex;
|
|
109
|
-
}
|
|
110
|
-
export async function addImportedWalletSeedRecord(options) {
|
|
111
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
112
|
-
const seedName = assertValidImportedWalletSeedName(options.seedName);
|
|
113
|
-
const index = await loadWalletSeedIndex({
|
|
114
|
-
paths: options.paths,
|
|
115
|
-
nowUnixMs,
|
|
116
|
-
});
|
|
117
|
-
if (findWalletSeedRecord(index, seedName) !== null) {
|
|
118
|
-
throw new Error("wallet_seed_name_exists");
|
|
119
|
-
}
|
|
120
|
-
const nextIndex = {
|
|
121
|
-
schemaVersion: 1,
|
|
122
|
-
lastWrittenAtUnixMs: nowUnixMs,
|
|
123
|
-
seeds: sortSeedRecords([
|
|
124
|
-
...index.seeds,
|
|
125
|
-
{
|
|
126
|
-
name: seedName,
|
|
127
|
-
kind: "imported",
|
|
128
|
-
walletRootId: options.walletRootId,
|
|
129
|
-
createdAtUnixMs: nowUnixMs,
|
|
130
|
-
restoredAtUnixMs: nowUnixMs,
|
|
131
|
-
},
|
|
132
|
-
]),
|
|
133
|
-
};
|
|
134
|
-
await saveWalletSeedIndex(options.paths, nextIndex);
|
|
135
|
-
return nextIndex;
|
|
136
|
-
}
|
|
137
|
-
export async function removeWalletSeedRecord(options) {
|
|
138
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
139
|
-
const seedName = normalizeWalletSeedName(options.seedName);
|
|
140
|
-
const index = await loadWalletSeedIndex({
|
|
141
|
-
paths: options.paths,
|
|
142
|
-
nowUnixMs,
|
|
143
|
-
});
|
|
144
|
-
const nextIndex = {
|
|
145
|
-
schemaVersion: 1,
|
|
146
|
-
lastWrittenAtUnixMs: nowUnixMs,
|
|
147
|
-
seeds: sortSeedRecords(index.seeds.filter((seed) => seed.name !== seedName)),
|
|
148
|
-
};
|
|
149
|
-
await saveWalletSeedIndex(options.paths, nextIndex);
|
|
150
|
-
return nextIndex;
|
|
151
|
-
}
|