@cogcoin/client 0.5.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.
Files changed (289) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +136 -0
  3. package/dist/app-paths.d.ts +38 -0
  4. package/dist/app-paths.js +121 -0
  5. package/dist/art/banner.txt +13 -0
  6. package/dist/art/scroll.txt +13 -0
  7. package/dist/art/train-car.txt +6 -0
  8. package/dist/art/train-smoke.txt +6 -0
  9. package/dist/art/train.txt +6 -0
  10. package/dist/bitcoind/bootstrap/chainstate.d.ts +4 -0
  11. package/dist/bitcoind/bootstrap/chainstate.js +13 -0
  12. package/dist/bitcoind/bootstrap/constants.d.ts +7 -0
  13. package/dist/bitcoind/bootstrap/constants.js +12 -0
  14. package/dist/bitcoind/bootstrap/controller.d.ts +29 -0
  15. package/dist/bitcoind/bootstrap/controller.js +101 -0
  16. package/dist/bitcoind/bootstrap/download.d.ts +2 -0
  17. package/dist/bitcoind/bootstrap/download.js +196 -0
  18. package/dist/bitcoind/bootstrap/headers.d.ts +13 -0
  19. package/dist/bitcoind/bootstrap/headers.js +61 -0
  20. package/dist/bitcoind/bootstrap/paths.d.ts +4 -0
  21. package/dist/bitcoind/bootstrap/paths.js +15 -0
  22. package/dist/bitcoind/bootstrap/snapshot-file.d.ts +7 -0
  23. package/dist/bitcoind/bootstrap/snapshot-file.js +42 -0
  24. package/dist/bitcoind/bootstrap/state.d.ts +40 -0
  25. package/dist/bitcoind/bootstrap/state.js +70 -0
  26. package/dist/bitcoind/bootstrap/types.d.ts +28 -0
  27. package/dist/bitcoind/bootstrap/types.js +1 -0
  28. package/dist/bitcoind/bootstrap.d.ts +8 -0
  29. package/dist/bitcoind/bootstrap.js +7 -0
  30. package/dist/bitcoind/client/factory.d.ts +3 -0
  31. package/dist/bitcoind/client/factory.js +57 -0
  32. package/dist/bitcoind/client/follow-block-times.d.ts +8 -0
  33. package/dist/bitcoind/client/follow-block-times.js +25 -0
  34. package/dist/bitcoind/client/follow-loop.d.ts +10 -0
  35. package/dist/bitcoind/client/follow-loop.js +57 -0
  36. package/dist/bitcoind/client/internal-types.d.ts +63 -0
  37. package/dist/bitcoind/client/internal-types.js +18 -0
  38. package/dist/bitcoind/client/managed-client.d.ts +20 -0
  39. package/dist/bitcoind/client/managed-client.js +197 -0
  40. package/dist/bitcoind/client/rate-tracker.d.ts +2 -0
  41. package/dist/bitcoind/client/rate-tracker.js +24 -0
  42. package/dist/bitcoind/client/sync-engine.d.ts +3 -0
  43. package/dist/bitcoind/client/sync-engine.js +143 -0
  44. package/dist/bitcoind/client.d.ts +1 -0
  45. package/dist/bitcoind/client.js +1 -0
  46. package/dist/bitcoind/errors.d.ts +1 -0
  47. package/dist/bitcoind/errors.js +49 -0
  48. package/dist/bitcoind/index.d.ts +2 -0
  49. package/dist/bitcoind/index.js +1 -0
  50. package/dist/bitcoind/indexer-daemon-main.d.ts +1 -0
  51. package/dist/bitcoind/indexer-daemon-main.js +472 -0
  52. package/dist/bitcoind/indexer-daemon.d.ts +107 -0
  53. package/dist/bitcoind/indexer-daemon.js +391 -0
  54. package/dist/bitcoind/node.d.ts +8 -0
  55. package/dist/bitcoind/node.js +219 -0
  56. package/dist/bitcoind/normalize.d.ts +3 -0
  57. package/dist/bitcoind/normalize.js +47 -0
  58. package/dist/bitcoind/progress/assets.d.ts +10 -0
  59. package/dist/bitcoind/progress/assets.js +90 -0
  60. package/dist/bitcoind/progress/constants.d.ts +48 -0
  61. package/dist/bitcoind/progress/constants.js +53 -0
  62. package/dist/bitcoind/progress/controller.d.ts +28 -0
  63. package/dist/bitcoind/progress/controller.js +188 -0
  64. package/dist/bitcoind/progress/follow-scene.d.ts +40 -0
  65. package/dist/bitcoind/progress/follow-scene.js +367 -0
  66. package/dist/bitcoind/progress/formatting.d.ts +23 -0
  67. package/dist/bitcoind/progress/formatting.js +227 -0
  68. package/dist/bitcoind/progress/quote-scene.d.ts +4 -0
  69. package/dist/bitcoind/progress/quote-scene.js +137 -0
  70. package/dist/bitcoind/progress/train-scene.d.ts +9 -0
  71. package/dist/bitcoind/progress/train-scene.js +92 -0
  72. package/dist/bitcoind/progress/tty-renderer.d.ts +18 -0
  73. package/dist/bitcoind/progress/tty-renderer.js +150 -0
  74. package/dist/bitcoind/progress.d.ts +7 -0
  75. package/dist/bitcoind/progress.js +7 -0
  76. package/dist/bitcoind/quotes.d.ts +24 -0
  77. package/dist/bitcoind/quotes.js +195 -0
  78. package/dist/bitcoind/rpc.d.ts +71 -0
  79. package/dist/bitcoind/rpc.js +322 -0
  80. package/dist/bitcoind/service-paths.d.ts +19 -0
  81. package/dist/bitcoind/service-paths.js +49 -0
  82. package/dist/bitcoind/service.d.ts +40 -0
  83. package/dist/bitcoind/service.js +735 -0
  84. package/dist/bitcoind/testing.d.ts +9 -0
  85. package/dist/bitcoind/testing.js +9 -0
  86. package/dist/bitcoind/types.d.ts +396 -0
  87. package/dist/bitcoind/types.js +3 -0
  88. package/dist/bytes.d.ts +9 -0
  89. package/dist/bytes.js +36 -0
  90. package/dist/cli/commands/follow.d.ts +2 -0
  91. package/dist/cli/commands/follow.js +43 -0
  92. package/dist/cli/commands/mining-admin.d.ts +2 -0
  93. package/dist/cli/commands/mining-admin.js +92 -0
  94. package/dist/cli/commands/mining-read.d.ts +2 -0
  95. package/dist/cli/commands/mining-read.js +173 -0
  96. package/dist/cli/commands/mining-runtime.d.ts +2 -0
  97. package/dist/cli/commands/mining-runtime.js +108 -0
  98. package/dist/cli/commands/status.d.ts +2 -0
  99. package/dist/cli/commands/status.js +31 -0
  100. package/dist/cli/commands/sync.d.ts +2 -0
  101. package/dist/cli/commands/sync.js +52 -0
  102. package/dist/cli/commands/wallet-admin.d.ts +2 -0
  103. package/dist/cli/commands/wallet-admin.js +175 -0
  104. package/dist/cli/commands/wallet-mutation.d.ts +2 -0
  105. package/dist/cli/commands/wallet-mutation.js +681 -0
  106. package/dist/cli/commands/wallet-read.d.ts +2 -0
  107. package/dist/cli/commands/wallet-read.js +265 -0
  108. package/dist/cli/context.d.ts +3 -0
  109. package/dist/cli/context.js +75 -0
  110. package/dist/cli/io.d.ts +3 -0
  111. package/dist/cli/io.js +12 -0
  112. package/dist/cli/mining-format.d.ts +5 -0
  113. package/dist/cli/mining-format.js +156 -0
  114. package/dist/cli/mining-json.d.ts +49 -0
  115. package/dist/cli/mining-json.js +89 -0
  116. package/dist/cli/mutation-command-groups.d.ts +15 -0
  117. package/dist/cli/mutation-command-groups.js +71 -0
  118. package/dist/cli/mutation-json.d.ts +430 -0
  119. package/dist/cli/mutation-json.js +311 -0
  120. package/dist/cli/mutation-resolved-json.d.ts +124 -0
  121. package/dist/cli/mutation-resolved-json.js +129 -0
  122. package/dist/cli/mutation-success.d.ts +20 -0
  123. package/dist/cli/mutation-success.js +47 -0
  124. package/dist/cli/mutation-text-format.d.ts +22 -0
  125. package/dist/cli/mutation-text-format.js +171 -0
  126. package/dist/cli/mutation-text-write.d.ts +13 -0
  127. package/dist/cli/mutation-text-write.js +16 -0
  128. package/dist/cli/output.d.ts +185 -0
  129. package/dist/cli/output.js +1085 -0
  130. package/dist/cli/parse.d.ts +3 -0
  131. package/dist/cli/parse.js +971 -0
  132. package/dist/cli/preview-json.d.ts +416 -0
  133. package/dist/cli/preview-json.js +293 -0
  134. package/dist/cli/prompt.d.ts +3 -0
  135. package/dist/cli/prompt.js +33 -0
  136. package/dist/cli/read-json.d.ts +187 -0
  137. package/dist/cli/read-json.js +675 -0
  138. package/dist/cli/runner.d.ts +2 -0
  139. package/dist/cli/runner.js +129 -0
  140. package/dist/cli/signals.d.ts +3 -0
  141. package/dist/cli/signals.js +63 -0
  142. package/dist/cli/status-format.d.ts +2 -0
  143. package/dist/cli/status-format.js +48 -0
  144. package/dist/cli/types.d.ts +148 -0
  145. package/dist/cli/types.js +2 -0
  146. package/dist/cli/wallet-format.d.ts +29 -0
  147. package/dist/cli/wallet-format.js +637 -0
  148. package/dist/cli/workflow-hints.d.ts +13 -0
  149. package/dist/cli/workflow-hints.js +94 -0
  150. package/dist/cli-runner.d.ts +3 -0
  151. package/dist/cli-runner.js +3 -0
  152. package/dist/cli.d.ts +2 -0
  153. package/dist/cli.js +6 -0
  154. package/dist/client/default-client.d.ts +11 -0
  155. package/dist/client/default-client.js +118 -0
  156. package/dist/client/factory.d.ts +2 -0
  157. package/dist/client/factory.js +15 -0
  158. package/dist/client/initialization.d.ts +6 -0
  159. package/dist/client/initialization.js +30 -0
  160. package/dist/client/persistence.d.ts +5 -0
  161. package/dist/client/persistence.js +28 -0
  162. package/dist/client/store-adapter.d.ts +3 -0
  163. package/dist/client/store-adapter.js +20 -0
  164. package/dist/client.d.ts +2 -0
  165. package/dist/client.js +2 -0
  166. package/dist/index.d.ts +2 -0
  167. package/dist/index.js +1 -0
  168. package/dist/passive-status.d.ts +36 -0
  169. package/dist/passive-status.js +100 -0
  170. package/dist/sqlite/better-sqlite3.d.ts +26 -0
  171. package/dist/sqlite/better-sqlite3.js +4 -0
  172. package/dist/sqlite/checkpoints.d.ts +11 -0
  173. package/dist/sqlite/checkpoints.js +27 -0
  174. package/dist/sqlite/driver.d.ts +17 -0
  175. package/dist/sqlite/driver.js +98 -0
  176. package/dist/sqlite/index.d.ts +4 -0
  177. package/dist/sqlite/index.js +9 -0
  178. package/dist/sqlite/migrate.d.ts +2 -0
  179. package/dist/sqlite/migrate.js +37 -0
  180. package/dist/sqlite/store.d.ts +3 -0
  181. package/dist/sqlite/store.js +122 -0
  182. package/dist/sqlite/tip-meta.d.ts +26 -0
  183. package/dist/sqlite/tip-meta.js +97 -0
  184. package/dist/sqlite/types.d.ts +10 -0
  185. package/dist/sqlite/types.js +1 -0
  186. package/dist/types.d.ts +55 -0
  187. package/dist/types.js +1 -0
  188. package/dist/wallet/archive.d.ts +4 -0
  189. package/dist/wallet/archive.js +39 -0
  190. package/dist/wallet/cogop/constants.d.ts +32 -0
  191. package/dist/wallet/cogop/constants.js +32 -0
  192. package/dist/wallet/cogop/index.d.ts +32 -0
  193. package/dist/wallet/cogop/index.js +213 -0
  194. package/dist/wallet/cogop/numeric.d.ts +3 -0
  195. package/dist/wallet/cogop/numeric.js +24 -0
  196. package/dist/wallet/cogop/scriptpubkey.d.ts +2 -0
  197. package/dist/wallet/cogop/scriptpubkey.js +13 -0
  198. package/dist/wallet/cogop/validate-name.d.ts +2 -0
  199. package/dist/wallet/cogop/validate-name.js +18 -0
  200. package/dist/wallet/fs/atomic.d.ts +6 -0
  201. package/dist/wallet/fs/atomic.js +46 -0
  202. package/dist/wallet/fs/lock.d.ts +19 -0
  203. package/dist/wallet/fs/lock.js +61 -0
  204. package/dist/wallet/fs/status-file.d.ts +1 -0
  205. package/dist/wallet/fs/status-file.js +4 -0
  206. package/dist/wallet/lifecycle.d.ts +193 -0
  207. package/dist/wallet/lifecycle.js +1475 -0
  208. package/dist/wallet/material.d.ts +45 -0
  209. package/dist/wallet/material.js +118 -0
  210. package/dist/wallet/mining/config.d.ts +18 -0
  211. package/dist/wallet/mining/config.js +44 -0
  212. package/dist/wallet/mining/constants.d.ts +24 -0
  213. package/dist/wallet/mining/constants.js +24 -0
  214. package/dist/wallet/mining/control.d.ts +53 -0
  215. package/dist/wallet/mining/control.js +758 -0
  216. package/dist/wallet/mining/coordination.d.ts +40 -0
  217. package/dist/wallet/mining/coordination.js +121 -0
  218. package/dist/wallet/mining/hook-protocol.d.ts +47 -0
  219. package/dist/wallet/mining/hook-protocol.js +161 -0
  220. package/dist/wallet/mining/hook-runner.d.ts +1 -0
  221. package/dist/wallet/mining/hook-runner.js +52 -0
  222. package/dist/wallet/mining/hooks.d.ts +38 -0
  223. package/dist/wallet/mining/hooks.js +520 -0
  224. package/dist/wallet/mining/index.d.ts +8 -0
  225. package/dist/wallet/mining/index.js +6 -0
  226. package/dist/wallet/mining/runner.d.ts +155 -0
  227. package/dist/wallet/mining/runner.js +2574 -0
  228. package/dist/wallet/mining/runtime-artifacts.d.ts +17 -0
  229. package/dist/wallet/mining/runtime-artifacts.js +166 -0
  230. package/dist/wallet/mining/sentences.d.ts +23 -0
  231. package/dist/wallet/mining/sentences.js +281 -0
  232. package/dist/wallet/mining/state.d.ts +9 -0
  233. package/dist/wallet/mining/state.js +75 -0
  234. package/dist/wallet/mining/types.d.ts +141 -0
  235. package/dist/wallet/mining/types.js +1 -0
  236. package/dist/wallet/mining/visualizer.d.ts +19 -0
  237. package/dist/wallet/mining/visualizer.js +134 -0
  238. package/dist/wallet/mining/worker-main.d.ts +1 -0
  239. package/dist/wallet/mining/worker-main.js +17 -0
  240. package/dist/wallet/read/context.d.ts +20 -0
  241. package/dist/wallet/read/context.js +532 -0
  242. package/dist/wallet/read/filter.d.ts +9 -0
  243. package/dist/wallet/read/filter.js +42 -0
  244. package/dist/wallet/read/index.d.ts +4 -0
  245. package/dist/wallet/read/index.js +3 -0
  246. package/dist/wallet/read/project.d.ts +11 -0
  247. package/dist/wallet/read/project.js +300 -0
  248. package/dist/wallet/read/types.d.ts +144 -0
  249. package/dist/wallet/read/types.js +1 -0
  250. package/dist/wallet/runtime.d.ts +26 -0
  251. package/dist/wallet/runtime.js +28 -0
  252. package/dist/wallet/state/crypto.d.ts +31 -0
  253. package/dist/wallet/state/crypto.js +127 -0
  254. package/dist/wallet/state/provider.d.ts +37 -0
  255. package/dist/wallet/state/provider.js +312 -0
  256. package/dist/wallet/state/session.d.ts +12 -0
  257. package/dist/wallet/state/session.js +23 -0
  258. package/dist/wallet/state/storage.d.ts +19 -0
  259. package/dist/wallet/state/storage.js +55 -0
  260. package/dist/wallet/tx/anchor.d.ts +40 -0
  261. package/dist/wallet/tx/anchor.js +1210 -0
  262. package/dist/wallet/tx/cog.d.ts +92 -0
  263. package/dist/wallet/tx/cog.js +1055 -0
  264. package/dist/wallet/tx/common.d.ts +89 -0
  265. package/dist/wallet/tx/common.js +156 -0
  266. package/dist/wallet/tx/confirm.d.ts +15 -0
  267. package/dist/wallet/tx/confirm.js +24 -0
  268. package/dist/wallet/tx/domain-admin.d.ts +105 -0
  269. package/dist/wallet/tx/domain-admin.js +869 -0
  270. package/dist/wallet/tx/domain-market.d.ts +112 -0
  271. package/dist/wallet/tx/domain-market.js +1365 -0
  272. package/dist/wallet/tx/field.d.ts +101 -0
  273. package/dist/wallet/tx/field.js +1853 -0
  274. package/dist/wallet/tx/identity-selector.d.ts +12 -0
  275. package/dist/wallet/tx/identity-selector.js +52 -0
  276. package/dist/wallet/tx/index.d.ts +7 -0
  277. package/dist/wallet/tx/index.js +7 -0
  278. package/dist/wallet/tx/journal.d.ts +5 -0
  279. package/dist/wallet/tx/journal.js +31 -0
  280. package/dist/wallet/tx/register.d.ts +68 -0
  281. package/dist/wallet/tx/register.js +952 -0
  282. package/dist/wallet/tx/reputation.d.ts +72 -0
  283. package/dist/wallet/tx/reputation.js +693 -0
  284. package/dist/wallet/tx/targets.d.ts +7 -0
  285. package/dist/wallet/tx/targets.js +122 -0
  286. package/dist/wallet/types.d.ts +249 -0
  287. package/dist/wallet/types.js +1 -0
  288. package/dist/writing_quotes.json +1654 -0
  289. package/package.json +78 -0
@@ -0,0 +1,173 @@
1
+ import { dirname } from "node:path";
2
+ import { stat } from "node:fs/promises";
3
+ import { formatHooksStatusReport, formatMineStatusReport, formatMiningEventRecord } from "../mining-format.js";
4
+ import { writeLine } from "../io.js";
5
+ import { inspectWalletLocalState } from "../../wallet/read/index.js";
6
+ import { createErrorEnvelope, createSuccessEnvelope, describeCanonicalCommand, normalizeListPage, writeJsonValue, } from "../output.js";
7
+ import { buildHooksStatusJson, buildMineLogJson, buildMineStatusJson } from "../read-json.js";
8
+ import { resolveWalletRuntimePathsForTesting } from "../../wallet/runtime.js";
9
+ async function readRotationIndices() {
10
+ const paths = resolveWalletRuntimePathsForTesting();
11
+ const rotation = [];
12
+ for (let index = 1; index <= 4; index += 1) {
13
+ try {
14
+ await stat(`${paths.miningEventsPath}.${index}`);
15
+ rotation.push(index);
16
+ }
17
+ catch (error) {
18
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
19
+ throw error;
20
+ }
21
+ }
22
+ }
23
+ return rotation;
24
+ }
25
+ export async function runMiningReadCommand(parsed, context) {
26
+ try {
27
+ const dbPath = parsed.dbPath ?? context.resolveDefaultClientDatabasePath();
28
+ const dataDir = parsed.dataDir ?? context.resolveDefaultBitcoindDataDir();
29
+ await context.ensureDirectory(dirname(dbPath));
30
+ if (parsed.command === "hooks-mining-status") {
31
+ const localState = await inspectWalletLocalState({
32
+ secretProvider: context.walletSecretProvider,
33
+ });
34
+ const view = await context.inspectMiningControlPlane({
35
+ provider: context.walletSecretProvider,
36
+ localState,
37
+ bitcoind: {
38
+ health: "unavailable",
39
+ status: null,
40
+ message: "Managed bitcoind status unavailable during hook inspection.",
41
+ },
42
+ nodeStatus: null,
43
+ nodeHealth: "unavailable",
44
+ indexer: {
45
+ health: "unavailable",
46
+ status: null,
47
+ message: null,
48
+ snapshotTip: null,
49
+ source: "none",
50
+ daemonInstanceId: null,
51
+ snapshotSeq: null,
52
+ openedAtUnixMs: null,
53
+ },
54
+ verify: parsed.verify,
55
+ });
56
+ if (parsed.outputMode === "json") {
57
+ const result = buildHooksStatusJson(view);
58
+ writeJsonValue(context.stdout, createSuccessEnvelope("cogcoin/hooks-status/v1", describeCanonicalCommand(parsed), result.data, {
59
+ warnings: result.warnings,
60
+ explanations: result.explanations,
61
+ nextSteps: result.nextSteps,
62
+ }));
63
+ return 0;
64
+ }
65
+ writeLine(context.stdout, formatHooksStatusReport(view));
66
+ return 0;
67
+ }
68
+ if (parsed.command === "mine-log") {
69
+ if (!parsed.follow) {
70
+ const allEvents = await context.readMiningLog({
71
+ all: true,
72
+ });
73
+ const defaultLimit = 50;
74
+ const normalized = normalizeListPage(allEvents.slice().reverse(), {
75
+ limit: parsed.listLimit,
76
+ all: parsed.listAll,
77
+ defaultLimit,
78
+ });
79
+ const events = normalized.items.slice().reverse();
80
+ if (events.length === 0) {
81
+ if (parsed.outputMode === "json") {
82
+ const result = buildMineLogJson(events, normalized.page, await readRotationIndices());
83
+ writeJsonValue(context.stdout, createSuccessEnvelope("cogcoin/mine-log/v1", describeCanonicalCommand(parsed), result.data, {
84
+ warnings: result.warnings,
85
+ explanations: result.explanations,
86
+ nextSteps: result.nextSteps,
87
+ }));
88
+ return 0;
89
+ }
90
+ writeLine(context.stdout, "No mining events recorded yet.");
91
+ return 0;
92
+ }
93
+ if (parsed.outputMode === "json") {
94
+ const result = buildMineLogJson(events, normalized.page, await readRotationIndices());
95
+ writeJsonValue(context.stdout, createSuccessEnvelope("cogcoin/mine-log/v1", describeCanonicalCommand(parsed), result.data, {
96
+ warnings: result.warnings,
97
+ explanations: result.explanations,
98
+ nextSteps: result.nextSteps,
99
+ }));
100
+ return 0;
101
+ }
102
+ for (const event of events) {
103
+ writeLine(context.stdout, formatMiningEventRecord(event));
104
+ }
105
+ if (normalized.page.truncated && normalized.page.limit !== null && normalized.page.totalKnown !== null) {
106
+ writeLine(context.stdout, `Showing latest ${normalized.page.returned} of ${normalized.page.totalKnown}. Use --limit <n> or --all for more.`);
107
+ }
108
+ return 0;
109
+ }
110
+ const abortController = new AbortController();
111
+ const onStop = () => {
112
+ abortController.abort();
113
+ };
114
+ context.signalSource.on("SIGINT", onStop);
115
+ context.signalSource.on("SIGTERM", onStop);
116
+ try {
117
+ await context.followMiningLog({
118
+ signal: abortController.signal,
119
+ onEvent: (event) => {
120
+ writeLine(context.stdout, formatMiningEventRecord(event));
121
+ },
122
+ });
123
+ }
124
+ finally {
125
+ context.signalSource.off("SIGINT", onStop);
126
+ context.signalSource.off("SIGTERM", onStop);
127
+ }
128
+ return 0;
129
+ }
130
+ const readContext = await context.openWalletReadContext({
131
+ dataDir,
132
+ databasePath: dbPath,
133
+ secretProvider: context.walletSecretProvider,
134
+ });
135
+ try {
136
+ const mining = readContext.mining ?? await context.inspectMiningControlPlane({
137
+ provider: context.walletSecretProvider,
138
+ localState: readContext.localState,
139
+ bitcoind: readContext.bitcoind,
140
+ nodeStatus: readContext.nodeStatus,
141
+ nodeHealth: readContext.nodeHealth,
142
+ indexer: readContext.indexer,
143
+ });
144
+ if (parsed.outputMode === "json") {
145
+ const result = buildMineStatusJson(mining);
146
+ writeJsonValue(context.stdout, createSuccessEnvelope("cogcoin/mine-status/v1", describeCanonicalCommand(parsed), result.data, {
147
+ warnings: result.warnings,
148
+ explanations: result.explanations,
149
+ nextSteps: result.nextSteps,
150
+ }));
151
+ return 0;
152
+ }
153
+ writeLine(context.stdout, formatMineStatusReport(mining));
154
+ return 0;
155
+ }
156
+ finally {
157
+ await readContext.close();
158
+ }
159
+ }
160
+ catch (error) {
161
+ const message = error instanceof Error ? error.message : String(error);
162
+ if (parsed.outputMode === "json") {
163
+ writeJsonValue(context.stdout, createErrorEnvelope(parsed.command === "hooks-mining-status"
164
+ ? "cogcoin/hooks-status/v1"
165
+ : parsed.command === "mine-log"
166
+ ? "cogcoin/mine-log/v1"
167
+ : "cogcoin/mine-status/v1", describeCanonicalCommand(parsed), message, message));
168
+ return 5;
169
+ }
170
+ writeLine(context.stderr, message);
171
+ return 5;
172
+ }
173
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedCliArgs, RequiredCliRunnerContext } from "../types.js";
2
+ export declare function runMiningRuntimeCommand(parsed: ParsedCliArgs, context: RequiredCliRunnerContext): Promise<number>;
@@ -0,0 +1,108 @@
1
+ import { dirname } from "node:path";
2
+ import { buildMineStartData, buildMineStopData, } from "../mining-json.js";
3
+ import { buildMineStartPreviewData, buildMineStopPreviewData, } from "../preview-json.js";
4
+ import { writeLine } from "../io.js";
5
+ import { createTerminalPrompter } from "../prompt.js";
6
+ import { createPreviewSuccessEnvelope, createMutationSuccessEnvelope, describeCanonicalCommand, resolvePreviewJsonSchema, resolveStableMiningControlJsonSchema, writeHandledCliError, writeJsonValue, } from "../output.js";
7
+ import { formatNextStepLines, getMineStopNextSteps, } from "../workflow-hints.js";
8
+ function createCommandPrompter(parsed, context) {
9
+ return parsed.outputMode !== "text"
10
+ ? createTerminalPrompter(context.stdin, context.stderr)
11
+ : context.createPrompter();
12
+ }
13
+ export async function runMiningRuntimeCommand(parsed, context) {
14
+ try {
15
+ const dbPath = parsed.dbPath ?? context.resolveDefaultClientDatabasePath();
16
+ const dataDir = parsed.dataDir ?? context.resolveDefaultBitcoindDataDir();
17
+ const provider = context.walletSecretProvider;
18
+ await context.ensureDirectory(dirname(dbPath));
19
+ if (parsed.command === "mine") {
20
+ const abortController = new AbortController();
21
+ const onStop = () => {
22
+ abortController.abort();
23
+ };
24
+ context.signalSource.on("SIGINT", onStop);
25
+ context.signalSource.on("SIGTERM", onStop);
26
+ try {
27
+ await context.runForegroundMining({
28
+ dataDir,
29
+ databasePath: dbPath,
30
+ provider,
31
+ prompter: context.createPrompter(),
32
+ signal: abortController.signal,
33
+ stdout: context.stdout,
34
+ stderr: context.stderr,
35
+ progressOutput: parsed.progressOutput,
36
+ });
37
+ }
38
+ finally {
39
+ context.signalSource.off("SIGINT", onStop);
40
+ context.signalSource.off("SIGTERM", onStop);
41
+ }
42
+ return 0;
43
+ }
44
+ if (parsed.command === "mine-start") {
45
+ const result = await context.startBackgroundMining({
46
+ dataDir,
47
+ databasePath: dbPath,
48
+ provider,
49
+ prompter: createCommandPrompter(parsed, context),
50
+ });
51
+ if (parsed.outputMode === "preview-json") {
52
+ writeJsonValue(context.stdout, createPreviewSuccessEnvelope(resolvePreviewJsonSchema(parsed), describeCanonicalCommand(parsed), result.started ? "started" : "already-active", buildMineStartPreviewData(result)));
53
+ return 0;
54
+ }
55
+ if (parsed.outputMode === "json") {
56
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMiningControlJsonSchema(parsed), "cogcoin mine start", result.started ? "started" : "already-active", buildMineStartData(result)));
57
+ return 0;
58
+ }
59
+ if (!result.started) {
60
+ writeLine(context.stdout, "Background mining is already active.");
61
+ if (result.snapshot?.backgroundWorkerPid !== null && result.snapshot?.backgroundWorkerPid !== undefined) {
62
+ writeLine(context.stdout, `Worker pid: ${result.snapshot.backgroundWorkerPid}`);
63
+ }
64
+ return 0;
65
+ }
66
+ writeLine(context.stdout, "Started background mining.");
67
+ if (result.snapshot?.backgroundWorkerPid !== null && result.snapshot?.backgroundWorkerPid !== undefined) {
68
+ writeLine(context.stdout, `Worker pid: ${result.snapshot.backgroundWorkerPid}`);
69
+ }
70
+ return 0;
71
+ }
72
+ if (parsed.command === "mine-stop") {
73
+ const snapshot = await context.stopBackgroundMining({
74
+ dataDir,
75
+ databasePath: dbPath,
76
+ provider,
77
+ });
78
+ const nextSteps = getMineStopNextSteps();
79
+ if (parsed.outputMode === "preview-json") {
80
+ writeJsonValue(context.stdout, createPreviewSuccessEnvelope(resolvePreviewJsonSchema(parsed), describeCanonicalCommand(parsed), snapshot === null ? "not-active" : "stopped", buildMineStopPreviewData(snapshot), {
81
+ nextSteps,
82
+ }));
83
+ return 0;
84
+ }
85
+ if (parsed.outputMode === "json") {
86
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMiningControlJsonSchema(parsed), "cogcoin mine stop", snapshot === null ? "not-active" : "stopped", buildMineStopData(snapshot), {
87
+ nextSteps,
88
+ }));
89
+ return 0;
90
+ }
91
+ writeLine(context.stdout, snapshot?.note ?? "Background mining was not active.");
92
+ for (const line of formatNextStepLines(nextSteps)) {
93
+ writeLine(context.stdout, line);
94
+ }
95
+ return 0;
96
+ }
97
+ writeLine(context.stderr, `mining runtime command not implemented: ${parsed.command}`);
98
+ return 1;
99
+ }
100
+ catch (error) {
101
+ return writeHandledCliError({
102
+ parsed,
103
+ stdout: context.stdout,
104
+ stderr: context.stderr,
105
+ error,
106
+ });
107
+ }
108
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedCliArgs, RequiredCliRunnerContext } from "../types.js";
2
+ export declare function runStatusCommand(parsed: ParsedCliArgs, context: RequiredCliRunnerContext): Promise<number>;
@@ -0,0 +1,31 @@
1
+ import { dirname } from "node:path";
2
+ import { buildStatusJson } from "../read-json.js";
3
+ import { formatWalletOverviewReport } from "../wallet-format.js";
4
+ import { writeLine } from "../io.js";
5
+ import { createSuccessEnvelope, describeCanonicalCommand, writeJsonValue } from "../output.js";
6
+ export async function runStatusCommand(parsed, context) {
7
+ const dbPath = parsed.dbPath ?? context.resolveDefaultClientDatabasePath();
8
+ const dataDir = parsed.dataDir ?? context.resolveDefaultBitcoindDataDir();
9
+ await context.ensureDirectory(dirname(dbPath));
10
+ const readContext = await context.openWalletReadContext({
11
+ dataDir,
12
+ databasePath: dbPath,
13
+ secretProvider: context.walletSecretProvider,
14
+ });
15
+ try {
16
+ if (parsed.outputMode === "json") {
17
+ const result = buildStatusJson(readContext);
18
+ writeJsonValue(context.stdout, createSuccessEnvelope("cogcoin/status/v1", describeCanonicalCommand(parsed), result.data, {
19
+ warnings: result.warnings,
20
+ explanations: result.explanations,
21
+ nextSteps: result.nextSteps,
22
+ }));
23
+ return 0;
24
+ }
25
+ writeLine(context.stdout, formatWalletOverviewReport(readContext));
26
+ return 0;
27
+ }
28
+ finally {
29
+ await readContext.close();
30
+ }
31
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedCliArgs, RequiredCliRunnerContext } from "../types.js";
2
+ export declare function runSyncCommand(parsed: ParsedCliArgs, context: RequiredCliRunnerContext): Promise<number>;
@@ -0,0 +1,52 @@
1
+ import { dirname } from "node:path";
2
+ import { formatManagedSyncErrorMessage } from "../../bitcoind/errors.js";
3
+ import { writeLine } from "../io.js";
4
+ import { classifyCliError } from "../output.js";
5
+ import { createStopSignalWatcher, waitForCompletionOrStop } from "../signals.js";
6
+ export async function runSyncCommand(parsed, context) {
7
+ const dbPath = parsed.dbPath ?? context.resolveDefaultClientDatabasePath();
8
+ const dataDir = parsed.dataDir ?? context.resolveDefaultBitcoindDataDir();
9
+ await context.ensureDirectory(dirname(dbPath));
10
+ const store = await context.openSqliteStore({ filename: dbPath });
11
+ let storeOwned = true;
12
+ try {
13
+ const client = await context.openManagedBitcoindClient({
14
+ store,
15
+ databasePath: dbPath,
16
+ dataDir,
17
+ progressOutput: parsed.progressOutput,
18
+ });
19
+ storeOwned = false;
20
+ const stopWatcher = createStopSignalWatcher(context.signalSource, context.stderr, client, context.forceExit);
21
+ try {
22
+ const syncOutcome = await waitForCompletionOrStop(client.syncToTip(), stopWatcher);
23
+ if (syncOutcome.kind === "stopped") {
24
+ return syncOutcome.code;
25
+ }
26
+ const result = syncOutcome.value;
27
+ if (typeof client.playSyncCompletionScene === "function") {
28
+ const completionOutcome = await waitForCompletionOrStop(client.playSyncCompletionScene().catch(() => undefined), stopWatcher);
29
+ if (completionOutcome.kind === "stopped") {
30
+ return completionOutcome.code;
31
+ }
32
+ }
33
+ writeLine(context.stdout, `Applied blocks: ${result.appliedBlocks}`);
34
+ writeLine(context.stdout, `Rewound blocks: ${result.rewoundBlocks}`);
35
+ writeLine(context.stdout, `Indexed ending height: ${result.endingHeight ?? "none"}`);
36
+ writeLine(context.stdout, `Node best height: ${result.bestHeight}`);
37
+ return 0;
38
+ }
39
+ finally {
40
+ stopWatcher.cleanup();
41
+ await client.close();
42
+ }
43
+ }
44
+ catch (error) {
45
+ const message = formatManagedSyncErrorMessage(error instanceof Error ? error.message : String(error));
46
+ writeLine(context.stderr, `sync failed: ${message}`);
47
+ if (storeOwned) {
48
+ await store.close().catch(() => undefined);
49
+ }
50
+ return classifyCliError(error).exitCode;
51
+ }
52
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedCliArgs, RequiredCliRunnerContext } from "../types.js";
2
+ export declare function runWalletAdminCommand(parsed: ParsedCliArgs, context: RequiredCliRunnerContext): Promise<number>;
@@ -0,0 +1,175 @@
1
+ import { parseUnlockDurationToMs } from "../../wallet/lifecycle.js";
2
+ import { buildInitMutationData, buildUnlockMutationData, buildRepairMutationData, buildWalletExportMutationData, buildWalletImportMutationData, buildWalletLockMutationData, } from "../mutation-json.js";
3
+ import { buildRepairPreviewData, buildWalletLockPreviewData, } from "../preview-json.js";
4
+ import { writeLine } from "../io.js";
5
+ import { createTerminalPrompter } from "../prompt.js";
6
+ import { createPreviewSuccessEnvelope, createMutationSuccessEnvelope, describeCanonicalCommand, resolvePreviewJsonSchema, resolveStableMutationJsonSchema, writeHandledCliError, writeJsonValue, } from "../output.js";
7
+ import { formatNextStepLines, getFundingQuickstartGuidance, getInitNextSteps, } from "../workflow-hints.js";
8
+ function createCommandPrompter(parsed, context) {
9
+ return parsed.outputMode !== "text"
10
+ ? createTerminalPrompter(context.stdin, context.stderr)
11
+ : context.createPrompter();
12
+ }
13
+ function getRepairWarnings(result) {
14
+ return result.miningResumeAction === "resume-failed"
15
+ ? [`Wallet repair succeeded, but background mining did not resume automatically: ${result.miningResumeError ?? "unknown error"}`]
16
+ : [];
17
+ }
18
+ export async function runWalletAdminCommand(parsed, context) {
19
+ try {
20
+ const dataDir = parsed.dataDir ?? context.resolveDefaultBitcoindDataDir();
21
+ const dbPath = parsed.dbPath ?? context.resolveDefaultClientDatabasePath();
22
+ const provider = context.walletSecretProvider;
23
+ if (parsed.command === "init" || parsed.command === "wallet-init") {
24
+ const prompter = createCommandPrompter(parsed, context);
25
+ const result = await context.initializeWallet({
26
+ dataDir,
27
+ provider,
28
+ prompter,
29
+ });
30
+ const nextSteps = getInitNextSteps();
31
+ if (parsed.outputMode === "json") {
32
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMutationJsonSchema(parsed), describeCanonicalCommand(parsed), "initialized", buildInitMutationData(result), {
33
+ explanations: [getFundingQuickstartGuidance()],
34
+ nextSteps,
35
+ }));
36
+ return 0;
37
+ }
38
+ writeLine(context.stdout, `Wallet initialized.`);
39
+ writeLine(context.stdout, `Wallet root: ${result.walletRootId}`);
40
+ writeLine(context.stdout, `Funding address: ${result.fundingAddress}`);
41
+ writeLine(context.stdout, `Unlocked until: ${new Date(result.unlockUntilUnixMs).toISOString()}`);
42
+ writeLine(context.stdout, `Quickstart: ${getFundingQuickstartGuidance()}`);
43
+ for (const line of formatNextStepLines(nextSteps)) {
44
+ writeLine(context.stdout, line);
45
+ }
46
+ return 0;
47
+ }
48
+ if (parsed.command === "unlock" || parsed.command === "wallet-unlock") {
49
+ const durationMs = parseUnlockDurationToMs(parsed.unlockFor);
50
+ const result = await context.unlockWallet({
51
+ provider,
52
+ unlockDurationMs: durationMs,
53
+ });
54
+ if (parsed.outputMode === "json") {
55
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMutationJsonSchema(parsed), describeCanonicalCommand(parsed), "unlocked", buildUnlockMutationData(result)));
56
+ return 0;
57
+ }
58
+ writeLine(context.stdout, `Wallet unlocked.`);
59
+ writeLine(context.stdout, `Wallet root: ${result.state.walletRootId}`);
60
+ writeLine(context.stdout, `Unlocked until: ${new Date(result.unlockUntilUnixMs).toISOString()}`);
61
+ return 0;
62
+ }
63
+ if (parsed.command === "wallet-export") {
64
+ const prompter = createCommandPrompter(parsed, context);
65
+ const result = await context.exportWallet({
66
+ archivePath: parsed.args[0],
67
+ dataDir,
68
+ databasePath: dbPath,
69
+ provider,
70
+ prompter,
71
+ });
72
+ if (parsed.outputMode === "json") {
73
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMutationJsonSchema(parsed), describeCanonicalCommand(parsed), "exported", buildWalletExportMutationData(result)));
74
+ return 0;
75
+ }
76
+ writeLine(context.stdout, `Wallet exported.`);
77
+ writeLine(context.stdout, `Wallet root: ${result.walletRootId}`);
78
+ writeLine(context.stdout, `Archive path: ${result.archivePath}`);
79
+ return 0;
80
+ }
81
+ if (parsed.command === "wallet-import") {
82
+ const prompter = createCommandPrompter(parsed, context);
83
+ const result = await context.importWallet({
84
+ archivePath: parsed.args[0],
85
+ dataDir,
86
+ databasePath: dbPath,
87
+ provider,
88
+ prompter,
89
+ });
90
+ if (parsed.outputMode === "json") {
91
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMutationJsonSchema(parsed), describeCanonicalCommand(parsed), "imported", buildWalletImportMutationData(result)));
92
+ return 0;
93
+ }
94
+ writeLine(context.stdout, `Wallet imported.`);
95
+ writeLine(context.stdout, `Wallet root: ${result.walletRootId}`);
96
+ writeLine(context.stdout, `Funding address: ${result.fundingAddress}`);
97
+ writeLine(context.stdout, `Unlocked until: ${new Date(result.unlockUntilUnixMs).toISOString()}`);
98
+ return 0;
99
+ }
100
+ if (parsed.command === "wallet-lock") {
101
+ const result = await context.lockWallet({
102
+ dataDir,
103
+ provider,
104
+ });
105
+ if (parsed.outputMode === "preview-json") {
106
+ writeJsonValue(context.stdout, createPreviewSuccessEnvelope(resolvePreviewJsonSchema(parsed), describeCanonicalCommand(parsed), "locked", buildWalletLockPreviewData(result)));
107
+ return 0;
108
+ }
109
+ if (parsed.outputMode === "json") {
110
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMutationJsonSchema(parsed), "cogcoin wallet lock", "locked", buildWalletLockMutationData(result)));
111
+ return 0;
112
+ }
113
+ writeLine(context.stdout, `Wallet locked.`);
114
+ writeLine(context.stdout, `Wallet root: ${result.walletRootId ?? "none"}`);
115
+ return 0;
116
+ }
117
+ if (parsed.command === "repair") {
118
+ const result = await context.repairWallet({
119
+ dataDir,
120
+ databasePath: dbPath,
121
+ provider,
122
+ assumeYes: parsed.assumeYes,
123
+ });
124
+ if (parsed.outputMode === "preview-json") {
125
+ writeJsonValue(context.stdout, createPreviewSuccessEnvelope(resolvePreviewJsonSchema(parsed), describeCanonicalCommand(parsed), "completed", buildRepairPreviewData(result), {
126
+ nextSteps: ["Run `cogcoin status` to review the repaired local state."],
127
+ warnings: getRepairWarnings(result),
128
+ }));
129
+ return 0;
130
+ }
131
+ if (parsed.outputMode === "json") {
132
+ writeJsonValue(context.stdout, createMutationSuccessEnvelope(resolveStableMutationJsonSchema(parsed), "cogcoin repair", "completed", buildRepairMutationData(result), {
133
+ nextSteps: ["Run `cogcoin status` to review the repaired local state."],
134
+ warnings: getRepairWarnings(result),
135
+ }));
136
+ return 0;
137
+ }
138
+ writeLine(context.stdout, `Wallet repair completed.`);
139
+ writeLine(context.stdout, `Wallet root: ${result.walletRootId}`);
140
+ writeLine(context.stdout, `Recovered from backup: ${result.recoveredFromBackup ? "yes" : "no"}`);
141
+ writeLine(context.stdout, `Managed Core wallet recreated: ${result.recreatedManagedCoreWallet ? "yes" : "no"}`);
142
+ writeLine(context.stdout, `Managed bitcoind action: ${result.bitcoindServiceAction}`);
143
+ writeLine(context.stdout, `Managed bitcoind compatibility issue: ${result.bitcoindCompatibilityIssue}`);
144
+ writeLine(context.stdout, `Managed Core replica action: ${result.managedCoreReplicaAction}`);
145
+ writeLine(context.stdout, `Managed bitcoind post-repair health: ${result.bitcoindPostRepairHealth}`);
146
+ writeLine(context.stdout, `Indexer database reset: ${result.resetIndexerDatabase ? "yes" : "no"}`);
147
+ writeLine(context.stdout, `Indexer daemon action: ${result.indexerDaemonAction}`);
148
+ writeLine(context.stdout, `Indexer compatibility issue: ${result.indexerCompatibilityIssue}`);
149
+ writeLine(context.stdout, `Indexer post-repair health: ${result.indexerPostRepairHealth}`);
150
+ writeLine(context.stdout, `Mining mode before repair: ${result.miningPreRepairRunMode}`);
151
+ writeLine(context.stdout, `Mining resume action: ${result.miningResumeAction}`);
152
+ writeLine(context.stdout, `Mining mode after repair: ${result.miningPostRepairRunMode}`);
153
+ if (result.miningResumeError !== null) {
154
+ writeLine(context.stdout, `Mining resume error: ${result.miningResumeError}`);
155
+ }
156
+ if (result.note !== null) {
157
+ writeLine(context.stdout, `Note: ${result.note}`);
158
+ }
159
+ for (const warning of getRepairWarnings(result)) {
160
+ writeLine(context.stdout, `Warning: ${warning}`);
161
+ }
162
+ return 0;
163
+ }
164
+ writeLine(context.stderr, `wallet admin command not implemented: ${parsed.command}`);
165
+ return 1;
166
+ }
167
+ catch (error) {
168
+ return writeHandledCliError({
169
+ parsed,
170
+ stdout: context.stdout,
171
+ stderr: context.stderr,
172
+ error,
173
+ });
174
+ }
175
+ }
@@ -0,0 +1,2 @@
1
+ import type { ParsedCliArgs, RequiredCliRunnerContext } from "../types.js";
2
+ export declare function runWalletMutationCommand(parsed: ParsedCliArgs, context: RequiredCliRunnerContext): Promise<number>;