@cogcoin/client 0.5.14 → 1.0.0
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 +80 -25
- package/dist/app-paths.d.ts +5 -6
- package/dist/app-paths.js +8 -16
- package/dist/art/balance.txt +10 -0
- package/dist/art/welcome.txt +16 -0
- package/dist/bitcoind/bootstrap/controller.d.ts +1 -0
- package/dist/bitcoind/bootstrap/controller.js +53 -1
- package/dist/bitcoind/client/follow-block-times.d.ts +1 -0
- package/dist/bitcoind/client/follow-block-times.js +1 -1
- package/dist/bitcoind/client/internal-types.d.ts +7 -3
- package/dist/bitcoind/client/managed-client.d.ts +4 -2
- package/dist/bitcoind/client/managed-client.js +14 -0
- package/dist/bitcoind/client/sync-engine.js +72 -11
- package/dist/bitcoind/hash-order.d.ts +4 -0
- package/dist/bitcoind/hash-order.js +13 -0
- package/dist/bitcoind/indexer-daemon-main.js +11 -3
- package/dist/bitcoind/normalize.js +3 -2
- package/dist/bitcoind/processing-start-height.d.ts +5 -0
- package/dist/bitcoind/processing-start-height.js +7 -0
- package/dist/bitcoind/progress/constants.d.ts +4 -0
- package/dist/bitcoind/progress/constants.js +4 -0
- package/dist/bitcoind/progress/controller.d.ts +2 -1
- package/dist/bitcoind/progress/controller.js +3 -3
- package/dist/bitcoind/progress/follow-scene.d.ts +6 -2
- package/dist/bitcoind/progress/follow-scene.js +29 -6
- package/dist/bitcoind/progress/formatting.d.ts +1 -0
- package/dist/bitcoind/progress/formatting.js +6 -0
- package/dist/bitcoind/progress/train-scene.js +37 -18
- package/dist/bitcoind/progress/tty-renderer.d.ts +6 -1
- package/dist/bitcoind/progress/tty-renderer.js +8 -4
- package/dist/bitcoind/rpc.d.ts +2 -1
- package/dist/bitcoind/rpc.js +3 -0
- package/dist/bitcoind/types.d.ts +16 -0
- package/dist/bytes.d.ts +1 -0
- package/dist/bytes.js +3 -0
- package/dist/cli/art.d.ts +2 -0
- package/dist/cli/art.js +37 -0
- package/dist/cli/commands/client-admin.d.ts +2 -0
- package/dist/cli/commands/client-admin.js +91 -0
- package/dist/cli/commands/follow.js +0 -2
- package/dist/cli/commands/mining-admin.js +6 -47
- package/dist/cli/commands/mining-read.js +11 -50
- package/dist/cli/commands/mining-runtime.js +38 -3
- package/dist/cli/commands/service-runtime.js +0 -2
- package/dist/cli/commands/status.js +8 -2
- package/dist/cli/commands/sync.js +51 -4
- package/dist/cli/commands/wallet-admin.js +142 -136
- package/dist/cli/commands/wallet-mutation.js +91 -79
- package/dist/cli/commands/wallet-read.js +15 -18
- package/dist/cli/context.js +4 -14
- package/dist/cli/mining-format.d.ts +0 -1
- package/dist/cli/mining-format.js +5 -37
- package/dist/cli/mining-json.d.ts +0 -18
- package/dist/cli/mining-json.js +0 -35
- package/dist/cli/mutation-command-groups.d.ts +1 -2
- package/dist/cli/mutation-command-groups.js +0 -5
- package/dist/cli/mutation-json.d.ts +24 -145
- package/dist/cli/mutation-json.js +30 -136
- package/dist/cli/mutation-resolved-json.d.ts +0 -7
- package/dist/cli/mutation-resolved-json.js +4 -10
- package/dist/cli/mutation-success.d.ts +2 -0
- package/dist/cli/mutation-success.js +11 -1
- package/dist/cli/mutation-text-format.js +1 -3
- package/dist/cli/output.d.ts +1 -1
- package/dist/cli/output.js +254 -231
- package/dist/cli/parse.d.ts +1 -1
- package/dist/cli/parse.js +93 -122
- package/dist/cli/preview-json.d.ts +17 -120
- package/dist/cli/preview-json.js +14 -97
- package/dist/cli/prompt.js +8 -13
- package/dist/cli/read-json.d.ts +15 -37
- package/dist/cli/read-json.js +44 -140
- package/dist/cli/runner.js +10 -13
- package/dist/cli/types.d.ts +8 -17
- package/dist/cli/types.js +0 -2
- package/dist/cli/wallet-format.d.ts +1 -0
- package/dist/cli/wallet-format.js +205 -144
- package/dist/cli/workflow-hints.d.ts +3 -3
- package/dist/cli/workflow-hints.js +11 -8
- package/dist/client/default-client.d.ts +3 -1
- package/dist/client/default-client.js +45 -2
- package/dist/client/factory.js +1 -1
- package/dist/client/initialization.js +23 -0
- package/dist/client/persistence.js +5 -5
- package/dist/client/store-adapter.js +1 -0
- package/dist/sqlite/checkpoints.d.ts +1 -0
- package/dist/sqlite/checkpoints.js +7 -0
- package/dist/sqlite/store.js +14 -1
- package/dist/types.d.ts +1 -0
- package/dist/wallet/coin-control.d.ts +41 -11
- package/dist/wallet/coin-control.js +100 -357
- package/dist/wallet/descriptor-normalization.d.ts +1 -3
- package/dist/wallet/descriptor-normalization.js +0 -16
- package/dist/wallet/lifecycle.d.ts +7 -99
- package/dist/wallet/lifecycle.js +513 -968
- package/dist/wallet/managed-core-wallet.d.ts +13 -0
- package/dist/wallet/managed-core-wallet.js +20 -0
- package/dist/wallet/mining/constants.d.ts +5 -12
- package/dist/wallet/mining/constants.js +5 -12
- package/dist/wallet/mining/control.d.ts +1 -13
- package/dist/wallet/mining/control.js +45 -349
- package/dist/wallet/mining/index.d.ts +3 -4
- package/dist/wallet/mining/index.js +1 -2
- package/dist/wallet/mining/runner.d.ts +179 -6
- package/dist/wallet/mining/runner.js +891 -501
- package/dist/wallet/mining/runtime-artifacts.js +23 -3
- package/dist/wallet/mining/sentence-protocol.d.ts +44 -0
- package/dist/wallet/mining/sentence-protocol.js +123 -0
- package/dist/wallet/mining/sentences.d.ts +4 -8
- package/dist/wallet/mining/sentences.js +3 -52
- package/dist/wallet/mining/state.d.ts +11 -6
- package/dist/wallet/mining/state.js +7 -6
- package/dist/wallet/mining/types.d.ts +2 -30
- package/dist/wallet/mining/visualizer.d.ts +31 -3
- package/dist/wallet/mining/visualizer.js +135 -13
- package/dist/wallet/read/context.d.ts +0 -2
- package/dist/wallet/read/context.js +119 -140
- package/dist/wallet/read/filter.js +2 -11
- package/dist/wallet/read/index.d.ts +1 -1
- package/dist/wallet/read/project.js +24 -77
- package/dist/wallet/read/types.d.ts +10 -25
- package/dist/wallet/reset.d.ts +0 -1
- package/dist/wallet/reset.js +60 -138
- package/dist/wallet/root-resolution.d.ts +1 -5
- package/dist/wallet/root-resolution.js +0 -18
- package/dist/wallet/runtime.d.ts +0 -6
- package/dist/wallet/runtime.js +0 -8
- package/dist/wallet/state/client-password-agent.js +208 -0
- package/dist/wallet/state/client-password.d.ts +65 -0
- package/dist/wallet/state/client-password.js +952 -0
- package/dist/wallet/state/crypto.d.ts +1 -20
- package/dist/wallet/state/crypto.js +0 -63
- package/dist/wallet/state/provider.d.ts +23 -11
- package/dist/wallet/state/provider.js +248 -290
- package/dist/wallet/state/storage.d.ts +2 -2
- package/dist/wallet/state/storage.js +48 -16
- package/dist/wallet/tx/anchor.d.ts +3 -28
- package/dist/wallet/tx/anchor.js +349 -1240
- package/dist/wallet/tx/bitcoin-transfer.d.ts +35 -0
- package/dist/wallet/tx/bitcoin-transfer.js +200 -0
- package/dist/wallet/tx/cog.d.ts +5 -1
- package/dist/wallet/tx/cog.js +149 -185
- package/dist/wallet/tx/common.d.ts +74 -10
- package/dist/wallet/tx/common.js +315 -138
- package/dist/wallet/tx/domain-admin.d.ts +3 -1
- package/dist/wallet/tx/domain-admin.js +61 -99
- package/dist/wallet/tx/domain-market.d.ts +5 -1
- package/dist/wallet/tx/domain-market.js +221 -228
- package/dist/wallet/tx/field.d.ts +4 -10
- package/dist/wallet/tx/field.js +84 -914
- package/dist/wallet/tx/identity-selector.d.ts +9 -3
- package/dist/wallet/tx/identity-selector.js +17 -35
- package/dist/wallet/tx/index.d.ts +3 -1
- package/dist/wallet/tx/index.js +2 -1
- package/dist/wallet/tx/register.d.ts +3 -1
- package/dist/wallet/tx/register.js +62 -220
- package/dist/wallet/tx/reputation.d.ts +3 -1
- package/dist/wallet/tx/reputation.js +58 -95
- package/dist/wallet/types.d.ts +8 -122
- package/package.json +5 -5
- package/dist/wallet/archive.d.ts +0 -4
- package/dist/wallet/archive.js +0 -41
- package/dist/wallet/mining/hook-protocol.d.ts +0 -47
- package/dist/wallet/mining/hook-protocol.js +0 -161
- package/dist/wallet/mining/hook-runner.js +0 -52
- package/dist/wallet/mining/hooks.d.ts +0 -38
- package/dist/wallet/mining/hooks.js +0 -520
- package/dist/wallet/state/explicit-lock.d.ts +0 -4
- package/dist/wallet/state/explicit-lock.js +0 -19
- package/dist/wallet/state/session.d.ts +0 -12
- package/dist/wallet/state/session.js +0 -23
- /package/dist/wallet/{mining/hook-runner.d.ts → state/client-password-agent.d.ts} +0 -0
|
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { writeRuntimeStatusFile } from "../fs/status-file.js";
|
|
5
|
-
import {
|
|
5
|
+
import { normalizeMiningLifecycleStatus, normalizeMiningPublishState } from "./state.js";
|
|
6
6
|
const MAX_EVENT_LOG_BYTES = 10 * 1024 * 1024;
|
|
7
7
|
const MAX_EVENT_LOG_ROTATIONS = 4;
|
|
8
8
|
export function resolveRotatedMiningEventsPath(eventsPath) {
|
|
@@ -11,14 +11,31 @@ export function resolveRotatedMiningEventsPath(eventsPath) {
|
|
|
11
11
|
function resolveIndexedRotatedMiningEventsPath(eventsPath, index) {
|
|
12
12
|
return `${eventsPath}.${index}`;
|
|
13
13
|
}
|
|
14
|
+
function normalizeLegacyMiningProviderState(raw) {
|
|
15
|
+
switch (raw) {
|
|
16
|
+
case "ready":
|
|
17
|
+
case "backoff":
|
|
18
|
+
case "unavailable":
|
|
19
|
+
case "rate-limited":
|
|
20
|
+
case "auth-error":
|
|
21
|
+
return raw;
|
|
22
|
+
case "hook-error":
|
|
23
|
+
case "n/a":
|
|
24
|
+
return "unavailable";
|
|
25
|
+
default:
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
14
29
|
export async function loadMiningRuntimeStatus(statusPath) {
|
|
15
30
|
try {
|
|
16
31
|
const raw = await readFile(statusPath, "utf8");
|
|
17
32
|
const parsed = JSON.parse(raw);
|
|
18
33
|
return {
|
|
19
34
|
...parsed,
|
|
20
|
-
miningState:
|
|
35
|
+
miningState: normalizeMiningLifecycleStatus(parsed.miningState),
|
|
36
|
+
providerState: normalizeLegacyMiningProviderState(parsed.providerState),
|
|
21
37
|
currentPublishState: normalizeMiningPublishState(parsed.currentPublishState),
|
|
38
|
+
livePublishInMempool: parsed.livePublishInMempool ?? parsed.liveMiningFamilyInMempool ?? null,
|
|
22
39
|
indexerReorgDepth: parsed.indexerReorgDepth ?? null,
|
|
23
40
|
sameDomainCompetitorSuppressed: parsed.sameDomainCompetitorSuppressed ?? null,
|
|
24
41
|
dedupedCompetitorDomainCount: parsed.dedupedCompetitorDomainCount ?? null,
|
|
@@ -34,7 +51,10 @@ export async function loadMiningRuntimeStatus(statusPath) {
|
|
|
34
51
|
}
|
|
35
52
|
}
|
|
36
53
|
export async function saveMiningRuntimeStatus(statusPath, snapshot) {
|
|
37
|
-
await writeRuntimeStatusFile(statusPath,
|
|
54
|
+
await writeRuntimeStatusFile(statusPath, {
|
|
55
|
+
...snapshot,
|
|
56
|
+
providerState: normalizeLegacyMiningProviderState(snapshot.providerState),
|
|
57
|
+
});
|
|
38
58
|
}
|
|
39
59
|
async function rotateMiningEventsIfNeeded(eventsPath, nextEntryBytes) {
|
|
40
60
|
try {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MINING_SENTENCE_SCHEMA_VERSION } from "./constants.js";
|
|
2
|
+
export interface MiningSentenceGenerationRequestV1 {
|
|
3
|
+
schemaVersion: typeof MINING_SENTENCE_SCHEMA_VERSION;
|
|
4
|
+
requestId: string;
|
|
5
|
+
targetBlockHeight: number;
|
|
6
|
+
referencedBlockHashDisplay: string;
|
|
7
|
+
generatedAtUnixMs: number;
|
|
8
|
+
extraPrompt: string | null;
|
|
9
|
+
limits: {
|
|
10
|
+
maxCandidatesPerRootDomain: number;
|
|
11
|
+
maxCandidatesTotal: number;
|
|
12
|
+
timeoutMs: number;
|
|
13
|
+
maxCandidateSentenceUtf8Bytes: number;
|
|
14
|
+
};
|
|
15
|
+
rootDomains: Array<{
|
|
16
|
+
domainId: number;
|
|
17
|
+
domainName: string;
|
|
18
|
+
requiredWords: [string, string, string, string, string];
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
export interface MiningSentenceCandidateV1 {
|
|
22
|
+
domainId: number;
|
|
23
|
+
sentence: string;
|
|
24
|
+
attribution?: {
|
|
25
|
+
provider?: string;
|
|
26
|
+
model?: string;
|
|
27
|
+
promptLabel?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface MiningSentenceGenerationResponseV1 {
|
|
31
|
+
schemaVersion: typeof MINING_SENTENCE_SCHEMA_VERSION;
|
|
32
|
+
requestId: string;
|
|
33
|
+
candidates: MiningSentenceCandidateV1[];
|
|
34
|
+
}
|
|
35
|
+
export declare function createMiningSentenceRequestLimits(): MiningSentenceGenerationRequestV1["limits"];
|
|
36
|
+
export declare function parseStrictJsonValue(raw: string, invalidMessage: string): unknown;
|
|
37
|
+
export declare function stripMarkdownCodeFence(raw: string): string;
|
|
38
|
+
export declare function normalizeMiningSentenceResponse(options: {
|
|
39
|
+
request: MiningSentenceGenerationRequestV1;
|
|
40
|
+
response: unknown;
|
|
41
|
+
}): {
|
|
42
|
+
response: MiningSentenceGenerationResponseV1;
|
|
43
|
+
candidates: MiningSentenceCandidateV1[];
|
|
44
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { MINING_SENTENCE_MAX_CANDIDATES_PER_ROOT_DOMAIN, MINING_SENTENCE_MAX_CANDIDATES_TOTAL, MINING_SENTENCE_MAX_CANDIDATE_SENTENCE_UTF8_BYTES, MINING_SENTENCE_SCHEMA_VERSION, MINING_SENTENCE_TIMEOUT_MS, } from "./constants.js";
|
|
2
|
+
export function createMiningSentenceRequestLimits() {
|
|
3
|
+
return {
|
|
4
|
+
maxCandidateSentenceUtf8Bytes: MINING_SENTENCE_MAX_CANDIDATE_SENTENCE_UTF8_BYTES,
|
|
5
|
+
maxCandidatesPerRootDomain: MINING_SENTENCE_MAX_CANDIDATES_PER_ROOT_DOMAIN,
|
|
6
|
+
maxCandidatesTotal: MINING_SENTENCE_MAX_CANDIDATES_TOTAL,
|
|
7
|
+
timeoutMs: MINING_SENTENCE_TIMEOUT_MS,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function normalizeAttribution(raw) {
|
|
11
|
+
if (raw === null || typeof raw !== "object") {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
const attribution = raw;
|
|
15
|
+
const normalized = {};
|
|
16
|
+
for (const key of ["provider", "model", "promptLabel"]) {
|
|
17
|
+
const value = attribution[key];
|
|
18
|
+
if (typeof value === "string" && value.length > 0) {
|
|
19
|
+
normalized[key] = value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return Object.keys(normalized).length === 0
|
|
23
|
+
? undefined
|
|
24
|
+
: normalized;
|
|
25
|
+
}
|
|
26
|
+
export function parseStrictJsonValue(raw, invalidMessage) {
|
|
27
|
+
const trimmed = raw.trim();
|
|
28
|
+
if (trimmed.length === 0) {
|
|
29
|
+
throw new Error(invalidMessage);
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(trimmed);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw new Error(invalidMessage);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function stripMarkdownCodeFence(raw) {
|
|
39
|
+
const trimmed = raw.trim();
|
|
40
|
+
if (!trimmed.startsWith("```")) {
|
|
41
|
+
return raw;
|
|
42
|
+
}
|
|
43
|
+
const lines = trimmed.split(/\r?\n/);
|
|
44
|
+
if (lines.length < 3) {
|
|
45
|
+
return raw;
|
|
46
|
+
}
|
|
47
|
+
const first = lines[0].trim();
|
|
48
|
+
const last = lines.at(-1)?.trim();
|
|
49
|
+
if (!first.startsWith("```") || last !== "```") {
|
|
50
|
+
return raw;
|
|
51
|
+
}
|
|
52
|
+
return lines.slice(1, -1).join("\n");
|
|
53
|
+
}
|
|
54
|
+
export function normalizeMiningSentenceResponse(options) {
|
|
55
|
+
const raw = options.response;
|
|
56
|
+
if (raw === null || typeof raw !== "object") {
|
|
57
|
+
throw new Error("Mining sentence generation returned an invalid JSON response.");
|
|
58
|
+
}
|
|
59
|
+
const response = raw;
|
|
60
|
+
if (response.schemaVersion !== MINING_SENTENCE_SCHEMA_VERSION) {
|
|
61
|
+
throw new Error("Mining sentence generation returned an unsupported schema version.");
|
|
62
|
+
}
|
|
63
|
+
if (response.requestId !== options.request.requestId) {
|
|
64
|
+
throw new Error("Mining sentence generation returned a mismatched requestId.");
|
|
65
|
+
}
|
|
66
|
+
if (!Array.isArray(response.candidates)) {
|
|
67
|
+
throw new Error("Mining sentence generation response must include a candidates array.");
|
|
68
|
+
}
|
|
69
|
+
if (response.candidates.length > options.request.limits.maxCandidatesTotal) {
|
|
70
|
+
throw new Error("Mining sentence generation returned too many total candidates.");
|
|
71
|
+
}
|
|
72
|
+
const allowedDomainIds = new Set(options.request.rootDomains.map((domain) => domain.domainId));
|
|
73
|
+
const perDomainCounts = new Map();
|
|
74
|
+
const dedupe = new Set();
|
|
75
|
+
const candidates = [];
|
|
76
|
+
for (const rawCandidate of response.candidates) {
|
|
77
|
+
if (rawCandidate === null || typeof rawCandidate !== "object") {
|
|
78
|
+
throw new Error("Mining sentence generation returned an invalid candidate entry.");
|
|
79
|
+
}
|
|
80
|
+
const candidate = rawCandidate;
|
|
81
|
+
const domainId = candidate.domainId;
|
|
82
|
+
const sentence = candidate.sentence;
|
|
83
|
+
if (!Number.isInteger(domainId)) {
|
|
84
|
+
throw new Error("Mining sentence generation candidate is missing a valid domainId.");
|
|
85
|
+
}
|
|
86
|
+
if (!allowedDomainIds.has(domainId)) {
|
|
87
|
+
throw new Error("Mining sentence generation candidate referenced an unknown domainId.");
|
|
88
|
+
}
|
|
89
|
+
if (typeof sentence !== "string") {
|
|
90
|
+
throw new Error("Mining sentence generation candidate is missing a valid sentence.");
|
|
91
|
+
}
|
|
92
|
+
const trimmedSentence = sentence.trim();
|
|
93
|
+
if (trimmedSentence.length === 0) {
|
|
94
|
+
throw new Error("Mining sentence generation candidate sentence was empty after trimming.");
|
|
95
|
+
}
|
|
96
|
+
if (Buffer.byteLength(trimmedSentence, "utf8") > options.request.limits.maxCandidateSentenceUtf8Bytes) {
|
|
97
|
+
throw new Error("Mining sentence generation candidate sentence exceeded the UTF-8 byte limit.");
|
|
98
|
+
}
|
|
99
|
+
const nextCount = (perDomainCounts.get(domainId) ?? 0) + 1;
|
|
100
|
+
perDomainCounts.set(domainId, nextCount);
|
|
101
|
+
if (nextCount > options.request.limits.maxCandidatesPerRootDomain) {
|
|
102
|
+
throw new Error("Mining sentence generation returned too many candidates for one domain.");
|
|
103
|
+
}
|
|
104
|
+
const dedupeKey = `${domainId}:${trimmedSentence}`;
|
|
105
|
+
if (dedupe.has(dedupeKey)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
dedupe.add(dedupeKey);
|
|
109
|
+
candidates.push({
|
|
110
|
+
domainId: domainId,
|
|
111
|
+
sentence: trimmedSentence,
|
|
112
|
+
attribution: normalizeAttribution(candidate.attribution),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
response: {
|
|
117
|
+
schemaVersion: MINING_SENTENCE_SCHEMA_VERSION,
|
|
118
|
+
requestId: options.request.requestId,
|
|
119
|
+
candidates,
|
|
120
|
+
},
|
|
121
|
+
candidates,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MiningSentenceCandidateV1, MiningSentenceGenerationRequestV1 } from "./sentence-protocol.js";
|
|
2
2
|
import type { WalletRuntimePaths } from "../runtime.js";
|
|
3
|
-
import type { HookClientStateRecord } from "../types.js";
|
|
4
3
|
import type { WalletSecretProvider } from "../state/provider.js";
|
|
5
|
-
export type MiningSentenceGenerationRequest =
|
|
6
|
-
export type MiningSentenceGenerationCandidate =
|
|
4
|
+
export type MiningSentenceGenerationRequest = MiningSentenceGenerationRequestV1;
|
|
5
|
+
export type MiningSentenceGenerationCandidate = MiningSentenceCandidateV1;
|
|
7
6
|
export interface MiningSentenceSourceOptions {
|
|
8
7
|
paths: WalletRuntimePaths;
|
|
9
8
|
provider: WalletSecretProvider;
|
|
10
|
-
hookState: HookClientStateRecord | null;
|
|
11
9
|
signal?: AbortSignal;
|
|
12
10
|
fetchImpl?: typeof fetch;
|
|
13
11
|
}
|
|
@@ -16,8 +14,6 @@ declare class MiningProviderRequestError extends Error {
|
|
|
16
14
|
constructor(providerState: "unavailable" | "rate-limited" | "auth-error", message: string);
|
|
17
15
|
}
|
|
18
16
|
export declare function generateMiningSentences(request: MiningSentenceGenerationRequest, options: MiningSentenceSourceOptions): Promise<{
|
|
19
|
-
|
|
20
|
-
candidates: GenerateSentencesHookCandidateV1[];
|
|
21
|
-
providerState: "ready" | "n/a";
|
|
17
|
+
candidates: MiningSentenceCandidateV1[];
|
|
22
18
|
}>;
|
|
23
19
|
export { MiningProviderRequestError, };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { loadClientConfig } from "./config.js";
|
|
2
|
-
import { inspectMiningHookState, runGenerateSentencesHookRequest } from "./hooks.js";
|
|
3
2
|
import { MINING_BUILTIN_TIMEOUT_MS, } from "./constants.js";
|
|
4
|
-
import {
|
|
3
|
+
import { normalizeMiningSentenceResponse, parseStrictJsonValue, stripMarkdownCodeFence, } from "./sentence-protocol.js";
|
|
5
4
|
class MiningProviderRequestError extends Error {
|
|
6
5
|
providerState;
|
|
7
6
|
constructor(providerState, message) {
|
|
@@ -48,15 +47,13 @@ function annotateProviderCandidates(options) {
|
|
|
48
47
|
function parseProviderJsonResponse(options) {
|
|
49
48
|
const response = parseStrictJsonValue(stripMarkdownCodeFence(options.raw), `${options.providerLabel} returned invalid JSON.`);
|
|
50
49
|
try {
|
|
51
|
-
return
|
|
50
|
+
return normalizeMiningSentenceResponse({
|
|
52
51
|
request: options.request,
|
|
53
52
|
response,
|
|
54
53
|
}).candidates;
|
|
55
54
|
}
|
|
56
55
|
catch (error) {
|
|
57
|
-
throw new Error(error instanceof Error
|
|
58
|
-
? error.message.replace(/^Custom mining hook /, `${options.providerLabel} `)
|
|
59
|
-
: `${options.providerLabel} returned an invalid response.`);
|
|
56
|
+
throw new Error(error instanceof Error ? error.message : `${options.providerLabel} returned an invalid response.`);
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
function createProviderSignal(signal, timeoutMs) {
|
|
@@ -211,51 +208,7 @@ function extractAnthropicText(payload) {
|
|
|
211
208
|
}
|
|
212
209
|
throw new Error("The built-in Anthropic mining provider returned an empty response.");
|
|
213
210
|
}
|
|
214
|
-
async function requestCustomHookSentences(options) {
|
|
215
|
-
const inspection = await inspectMiningHookState({
|
|
216
|
-
hookRootPath: options.paths.hooksMiningDir,
|
|
217
|
-
entrypointPath: options.paths.hooksMiningEntrypointPath,
|
|
218
|
-
packagePath: options.paths.hooksMiningPackageJsonPath,
|
|
219
|
-
localState: options.hookState,
|
|
220
|
-
verify: false,
|
|
221
|
-
nowUnixMs: Date.now(),
|
|
222
|
-
});
|
|
223
|
-
if (inspection.mode !== "custom") {
|
|
224
|
-
throw new Error("Custom mining hooks are not enabled.");
|
|
225
|
-
}
|
|
226
|
-
if (inspection.cooldownActive) {
|
|
227
|
-
throw new Error("Custom mining hook is cooling down after repeated failures. Wait for the cooldown to expire or rerun `cogcoin hooks enable mining`.");
|
|
228
|
-
}
|
|
229
|
-
if (inspection.operatorValidationState === "failed"
|
|
230
|
-
|| inspection.operatorValidationState === "stale"
|
|
231
|
-
|| inspection.operatorValidationState === "never") {
|
|
232
|
-
throw new Error("Custom mining hook validation is stale or failed. Rerun `cogcoin hooks enable mining`.");
|
|
233
|
-
}
|
|
234
|
-
if (inspection.trustStatus !== "trusted") {
|
|
235
|
-
throw new Error(inspection.trustMessage ?? "Custom mining hook trust checks failed.");
|
|
236
|
-
}
|
|
237
|
-
return runGenerateSentencesHookRequest({
|
|
238
|
-
hookRootPath: options.paths.hooksMiningDir,
|
|
239
|
-
entrypointPath: options.paths.hooksMiningEntrypointPath,
|
|
240
|
-
request: options.request,
|
|
241
|
-
signal: options.signal,
|
|
242
|
-
timeoutMs: options.request.limits.timeoutMs,
|
|
243
|
-
}).then((result) => result.candidates);
|
|
244
|
-
}
|
|
245
211
|
export async function generateMiningSentences(request, options) {
|
|
246
|
-
const hookMode = options.hookState?.mode === "custom" ? "custom" : "builtin";
|
|
247
|
-
if (hookMode === "custom") {
|
|
248
|
-
return {
|
|
249
|
-
hookMode,
|
|
250
|
-
candidates: await requestCustomHookSentences({
|
|
251
|
-
paths: options.paths,
|
|
252
|
-
hookState: options.hookState,
|
|
253
|
-
request,
|
|
254
|
-
signal: options.signal,
|
|
255
|
-
}),
|
|
256
|
-
providerState: "n/a",
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
212
|
const config = await loadClientConfig({
|
|
260
213
|
path: options.paths.clientConfigPath,
|
|
261
214
|
provider: options.provider,
|
|
@@ -265,7 +218,6 @@ export async function generateMiningSentences(request, options) {
|
|
|
265
218
|
throw new MiningProviderRequestError("unavailable", "Mining is not configured. Run `cogcoin mine setup`.");
|
|
266
219
|
}
|
|
267
220
|
return {
|
|
268
|
-
hookMode,
|
|
269
221
|
candidates: await requestBuiltInSentences({
|
|
270
222
|
provider: builtIn.provider,
|
|
271
223
|
apiKey: builtIn.apiKey,
|
|
@@ -275,7 +227,6 @@ export async function generateMiningSentences(request, options) {
|
|
|
275
227
|
fetchImpl: options.fetchImpl,
|
|
276
228
|
signal: options.signal,
|
|
277
229
|
}),
|
|
278
|
-
providerState: "ready",
|
|
279
230
|
};
|
|
280
231
|
}
|
|
281
232
|
export { MiningProviderRequestError, };
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { MiningStateRecord } from "../types.js";
|
|
2
|
-
|
|
2
|
+
type LegacyMiningStateRecord = MiningStateRecord & {
|
|
3
|
+
livePublishInMempool?: boolean | null;
|
|
4
|
+
liveMiningFamilyInMempool?: boolean | null;
|
|
5
|
+
};
|
|
6
|
+
export type MiningLifecycleStatus = MiningStateRecord["state"];
|
|
3
7
|
export type MiningPublishState = MiningStateRecord["currentPublishState"];
|
|
4
|
-
export declare function
|
|
8
|
+
export declare function normalizeMiningLifecycleStatus(raw: string | null | undefined): MiningLifecycleStatus;
|
|
5
9
|
export declare function normalizeMiningPublishState(raw: string | null | undefined): MiningPublishState;
|
|
6
|
-
export declare function normalizeMiningStateRecord(state:
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
10
|
+
export declare function normalizeMiningStateRecord(state: LegacyMiningStateRecord): MiningStateRecord;
|
|
11
|
+
export declare function clearMiningPublishState(state: MiningStateRecord): MiningStateRecord;
|
|
12
|
+
export declare function miningPublishMayStillExist(state: MiningStateRecord): boolean;
|
|
13
|
+
export declare function miningPublishIsInMempool(state: MiningStateRecord): boolean;
|
|
14
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function
|
|
1
|
+
export function normalizeMiningLifecycleStatus(raw) {
|
|
2
2
|
switch (raw) {
|
|
3
3
|
case "live":
|
|
4
4
|
case "paused":
|
|
@@ -33,11 +33,12 @@ export function normalizeMiningPublishState(raw) {
|
|
|
33
33
|
export function normalizeMiningStateRecord(state) {
|
|
34
34
|
return {
|
|
35
35
|
...state,
|
|
36
|
-
state:
|
|
36
|
+
state: normalizeMiningLifecycleStatus(state.state),
|
|
37
37
|
currentPublishState: normalizeMiningPublishState(state.currentPublishState),
|
|
38
|
+
livePublishInMempool: state.livePublishInMempool ?? state.liveMiningFamilyInMempool ?? false,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
export function
|
|
41
|
+
export function clearMiningPublishState(state) {
|
|
41
42
|
return {
|
|
42
43
|
...normalizeMiningStateRecord(state),
|
|
43
44
|
state: "idle",
|
|
@@ -59,17 +60,17 @@ export function clearMiningFamilyState(state) {
|
|
|
59
60
|
currentBlockTargetHeight: null,
|
|
60
61
|
currentReferencedBlockHashDisplay: null,
|
|
61
62
|
currentIntentFingerprintHex: null,
|
|
62
|
-
|
|
63
|
+
livePublishInMempool: false,
|
|
63
64
|
currentPublishDecision: null,
|
|
64
65
|
replacementCount: 0,
|
|
65
66
|
sharedMiningConflictOutpoint: null,
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
|
-
export function
|
|
69
|
+
export function miningPublishMayStillExist(state) {
|
|
69
70
|
const normalized = normalizeMiningStateRecord(state);
|
|
70
71
|
return normalized.currentTxid !== null
|
|
71
72
|
&& normalized.currentPublishState !== "none";
|
|
72
73
|
}
|
|
73
|
-
export function
|
|
74
|
+
export function miningPublishIsInMempool(state) {
|
|
74
75
|
return normalizeMiningStateRecord(state).currentPublishState === "in-mempool";
|
|
75
76
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ManagedBitcoindHealth, ManagedIndexerTruthSource } from "../../bitcoind/types.js";
|
|
2
|
-
import type { MiningHookOperatorValidationState } from "./hook-protocol.js";
|
|
3
2
|
export type MiningServiceHealth = "synced" | "catching-up" | "reorging" | "starting" | "stale-heartbeat" | "failed" | "schema-mismatch" | "service-version-mismatch" | "wallet-root-mismatch" | "unavailable";
|
|
4
3
|
export type MiningProviderKind = "openai" | "anthropic";
|
|
5
4
|
export interface MiningProviderConfigRecord {
|
|
@@ -57,7 +56,7 @@ export interface MiningRuntimeStatusV1 {
|
|
|
57
56
|
indexerReorgDepth: number | null;
|
|
58
57
|
indexerTipAligned: boolean | null;
|
|
59
58
|
corePublishState: "unknown" | "network-inactive" | "no-outbound-peers" | "ibd" | "mempool-loading" | "healthy" | null;
|
|
60
|
-
providerState: "
|
|
59
|
+
providerState: "ready" | "backoff" | "unavailable" | "rate-limited" | "auth-error" | null;
|
|
61
60
|
lastSuspendDetectedAtUnixMs: number | null;
|
|
62
61
|
reconnectSettledUntilUnixMs: number | null;
|
|
63
62
|
tipSettledUntilUnixMs: number | null;
|
|
@@ -72,7 +71,7 @@ export interface MiningRuntimeStatusV1 {
|
|
|
72
71
|
currentCanonicalBlend: string | null;
|
|
73
72
|
currentTxid: string | null;
|
|
74
73
|
currentWtxid: string | null;
|
|
75
|
-
|
|
74
|
+
livePublishInMempool: boolean | null;
|
|
76
75
|
currentFeeRateSatVb: number | null;
|
|
77
76
|
currentAbsoluteFeeSats: number | null;
|
|
78
77
|
currentBlockFeeSpentSats: string;
|
|
@@ -87,7 +86,6 @@ export interface MiningRuntimeStatusV1 {
|
|
|
87
86
|
lastMempoolSequence: string | null;
|
|
88
87
|
lastCompetitivenessGateAtUnixMs: number | null;
|
|
89
88
|
pauseReason: string | null;
|
|
90
|
-
hookMode: "builtin" | "custom";
|
|
91
89
|
providerConfigured: boolean;
|
|
92
90
|
providerKind: MiningProviderKind | null;
|
|
93
91
|
bitcoindHealth: ManagedBitcoindHealth;
|
|
@@ -96,35 +94,10 @@ export interface MiningRuntimeStatusV1 {
|
|
|
96
94
|
nodeHealth: MiningServiceHealth;
|
|
97
95
|
indexerHealth: MiningServiceHealth;
|
|
98
96
|
tipsAligned: boolean | null;
|
|
99
|
-
lastValidationState: "unknown" | "validated" | "stale" | "failed" | null;
|
|
100
|
-
lastOperatorValidationState: MiningHookOperatorValidationState | null;
|
|
101
|
-
lastValidationAtUnixMs: number | null;
|
|
102
97
|
lastEventAtUnixMs: number | null;
|
|
103
98
|
lastError: string | null;
|
|
104
99
|
note: string | null;
|
|
105
100
|
}
|
|
106
|
-
export interface MiningHookInspection {
|
|
107
|
-
mode: "builtin" | "custom" | "disabled" | "unavailable";
|
|
108
|
-
entrypointPath: string;
|
|
109
|
-
packagePath: string;
|
|
110
|
-
entrypointExists: boolean;
|
|
111
|
-
packageStatus: "valid" | "missing" | "invalid";
|
|
112
|
-
packageMessage: string | null;
|
|
113
|
-
trustStatus: "trusted" | "untrusted" | "missing";
|
|
114
|
-
trustMessage: string | null;
|
|
115
|
-
validationState: "unknown" | "validated" | "stale" | "failed" | "unavailable";
|
|
116
|
-
operatorValidationState: MiningHookOperatorValidationState;
|
|
117
|
-
validationError: string | null;
|
|
118
|
-
validatedAtUnixMs: number | null;
|
|
119
|
-
validatedLaunchFingerprint: string | null;
|
|
120
|
-
validatedFullFingerprint: string | null;
|
|
121
|
-
currentLaunchFingerprint: string | null;
|
|
122
|
-
currentFullFingerprint: string | null;
|
|
123
|
-
verifyUsed: boolean;
|
|
124
|
-
cooldownUntilUnixMs: number | null;
|
|
125
|
-
cooldownActive: boolean;
|
|
126
|
-
consecutiveFailureCount: number;
|
|
127
|
-
}
|
|
128
101
|
export interface MiningProviderInspection {
|
|
129
102
|
configured: boolean;
|
|
130
103
|
provider: MiningProviderKind | null;
|
|
@@ -135,7 +108,6 @@ export interface MiningProviderInspection {
|
|
|
135
108
|
}
|
|
136
109
|
export interface MiningControlPlaneView {
|
|
137
110
|
runtime: MiningRuntimeStatusV1;
|
|
138
|
-
hook: MiningHookInspection;
|
|
139
111
|
provider: MiningProviderInspection;
|
|
140
112
|
lastEventAtUnixMs: number | null;
|
|
141
113
|
}
|
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
import type { BootstrapProgress, ProgressOutputMode } from "../../bitcoind/types.js";
|
|
2
2
|
import { createFollowSceneState } from "../../bitcoind/progress/follow-scene.js";
|
|
3
3
|
import { type RenderClock, type TtyRenderStream } from "../../bitcoind/progress/render-policy.js";
|
|
4
|
+
import { type FollowSceneRenderOptions } from "../../bitcoind/progress/tty-renderer.js";
|
|
4
5
|
import type { MiningRuntimeStatusV1 } from "./types.js";
|
|
5
6
|
interface VisualizerRendererLike {
|
|
6
|
-
renderFollowScene(progress: BootstrapProgress, cogcoinSyncHeight: number | null, cogcoinSyncTargetHeight: number | null, followScene: ReturnType<typeof createFollowSceneState>, statusFieldText?: string): void;
|
|
7
|
+
renderFollowScene(progress: BootstrapProgress, cogcoinSyncHeight: number | null, cogcoinSyncTargetHeight: number | null, followScene: ReturnType<typeof createFollowSceneState>, statusFieldText?: string, renderOptions?: FollowSceneRenderOptions): void;
|
|
7
8
|
close(): void;
|
|
8
9
|
}
|
|
9
|
-
export
|
|
10
|
+
export interface MiningSentenceBoardEntry {
|
|
11
|
+
rank: number;
|
|
12
|
+
domainName: string;
|
|
13
|
+
sentence: string;
|
|
14
|
+
}
|
|
15
|
+
export interface MiningProvisionalSentenceEntry {
|
|
16
|
+
domainName: string | null;
|
|
17
|
+
sentence: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface MiningRecentWinSummary {
|
|
20
|
+
rank: number;
|
|
21
|
+
rewardCogtoshi: bigint;
|
|
22
|
+
blockHeight: number;
|
|
23
|
+
}
|
|
24
|
+
export interface MiningFollowVisualizerState {
|
|
25
|
+
balanceCogtoshi: bigint | null;
|
|
26
|
+
balanceSats: bigint | null;
|
|
27
|
+
visibleBlockTimesByHeight: Record<number, number>;
|
|
28
|
+
settledBlockHeight: number | null;
|
|
29
|
+
settledBoardEntries: MiningSentenceBoardEntry[];
|
|
30
|
+
provisionalRequiredWords: readonly string[];
|
|
31
|
+
provisionalEntry: MiningProvisionalSentenceEntry;
|
|
32
|
+
latestSentence: string | null;
|
|
33
|
+
latestTxid: string | null;
|
|
34
|
+
recentWin: MiningRecentWinSummary | null;
|
|
35
|
+
}
|
|
36
|
+
export declare function createEmptyMiningFollowVisualizerState(): MiningFollowVisualizerState;
|
|
37
|
+
export declare function describeMiningVisualizerStatus(snapshot: MiningRuntimeStatusV1, ui?: MiningFollowVisualizerState): string;
|
|
10
38
|
export declare function describeMiningVisualizerProgress(snapshot: MiningRuntimeStatusV1): string;
|
|
11
39
|
export declare class MiningFollowVisualizer {
|
|
12
40
|
#private;
|
|
@@ -18,7 +46,7 @@ export declare class MiningFollowVisualizer {
|
|
|
18
46
|
clock?: RenderClock;
|
|
19
47
|
rendererFactory?: (stream: TtyRenderStream) => VisualizerRendererLike;
|
|
20
48
|
});
|
|
21
|
-
update(snapshot: MiningRuntimeStatusV1): void;
|
|
49
|
+
update(snapshot: MiningRuntimeStatusV1, uiState?: MiningFollowVisualizerState): void;
|
|
22
50
|
close(): void;
|
|
23
51
|
}
|
|
24
52
|
export {};
|