@otskit/mcp 0.1.2 → 0.1.4
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/dist/chunk-45GR42GV.js +115 -0
- package/dist/{chunk-6IPLIM6I.js → chunk-ASPLCXMC.js} +9 -108
- package/dist/{cli-GQMURR5I.js → cli-67APZKT6.js} +7 -5
- package/dist/index.js +23 -10
- package/dist/install-claude-UKSS65BW.js +44 -0
- package/dist/{server-NCO7JIUI.js → server-2YEI77IT.js} +6 -4
- package/dist/watch-JWDMAZWS.js +47 -0
- package/package.json +1 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDataDir,
|
|
3
|
+
getStamp,
|
|
4
|
+
insertStamp,
|
|
5
|
+
listStamps,
|
|
6
|
+
logOperation
|
|
7
|
+
} from "./chunk-ASPLCXMC.js";
|
|
8
|
+
import {
|
|
9
|
+
writeAtomic
|
|
10
|
+
} from "./chunk-YFSUDT24.js";
|
|
11
|
+
|
|
12
|
+
// src/tools/create-timestamp.ts
|
|
13
|
+
import { mkdirSync } from "fs";
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
import { randomUUID } from "crypto";
|
|
16
|
+
import { OpenTimestampsClient } from "@otskit/client";
|
|
17
|
+
var HEX64 = /^[0-9a-f]{64}$/i;
|
|
18
|
+
async function createTimestamp(input, db, config) {
|
|
19
|
+
if (!HEX64.test(input.hash)) {
|
|
20
|
+
return { error: "invalid_hash", details: "hash must be 64 hex characters (SHA-256)" };
|
|
21
|
+
}
|
|
22
|
+
const normalizedHash = input.hash.toLowerCase();
|
|
23
|
+
const client = new OpenTimestampsClient({
|
|
24
|
+
calendars: config.calendars,
|
|
25
|
+
resilience: { timeout: config.calendar_timeout_ms }
|
|
26
|
+
});
|
|
27
|
+
const t0 = Date.now();
|
|
28
|
+
let proofBuffer;
|
|
29
|
+
try {
|
|
30
|
+
proofBuffer = await client.stamp(normalizedHash);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return { error: "calendar_error", details: String(e) };
|
|
33
|
+
}
|
|
34
|
+
const responseTimeMs = Date.now() - t0;
|
|
35
|
+
const id = randomUUID();
|
|
36
|
+
const proofDir = join(getDataDir(), "proofs");
|
|
37
|
+
mkdirSync(proofDir, { recursive: true });
|
|
38
|
+
const proofPath = join(proofDir, `${id}.ots`);
|
|
39
|
+
try {
|
|
40
|
+
writeAtomic(proofPath, proofBuffer);
|
|
41
|
+
} catch (e) {
|
|
42
|
+
return { error: "storage_error", details: String(e) };
|
|
43
|
+
}
|
|
44
|
+
const record = insertStamp(db, { id, hash: normalizedHash, proof_path: proofPath });
|
|
45
|
+
logOperation(db, { stamp_id: id, action: "stamp", result: "success", response_time_ms: responseTimeMs });
|
|
46
|
+
return {
|
|
47
|
+
id: record.id,
|
|
48
|
+
hash: record.hash,
|
|
49
|
+
status: "pending",
|
|
50
|
+
calendars: config.calendars,
|
|
51
|
+
created_at: record.created_at,
|
|
52
|
+
proof_path: proofPath
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/tools/verify-timestamp.ts
|
|
57
|
+
import { readFileSync } from "fs";
|
|
58
|
+
import { OpenTimestampsClient as OpenTimestampsClient2 } from "@otskit/client";
|
|
59
|
+
async function verifyTimestamp(input, db, config) {
|
|
60
|
+
const record = getStamp(db, input.id);
|
|
61
|
+
if (!record) return { error: "not_found", details: `No stamp with id ${input.id}` };
|
|
62
|
+
if (!record.proof_path) return { error: "storage_error", details: "No proof_path on record" };
|
|
63
|
+
let proofBytes;
|
|
64
|
+
try {
|
|
65
|
+
proofBytes = readFileSync(record.proof_path);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return { error: "storage_error", details: String(e) };
|
|
68
|
+
}
|
|
69
|
+
const client = new OpenTimestampsClient2({
|
|
70
|
+
calendars: config.calendars,
|
|
71
|
+
resilience: { timeout: config.calendar_timeout_ms }
|
|
72
|
+
});
|
|
73
|
+
let result;
|
|
74
|
+
try {
|
|
75
|
+
result = await client.verify(proofBytes, record.hash);
|
|
76
|
+
} catch (e) {
|
|
77
|
+
logOperation(db, { stamp_id: input.id, action: "verify", result: "failed", error_msg: String(e) });
|
|
78
|
+
return { status: "network_error", hash: record.hash, details: String(e) };
|
|
79
|
+
}
|
|
80
|
+
if (!result.valid) {
|
|
81
|
+
if (result.error?.includes("No Bitcoin attestation")) {
|
|
82
|
+
logOperation(db, { stamp_id: input.id, action: "verify", result: "pending" });
|
|
83
|
+
return { status: "pending", hash: record.hash, calendars: config.calendars };
|
|
84
|
+
}
|
|
85
|
+
if (result.error?.toLowerCase().includes("invalid") || result.error?.toLowerCase().includes("corrupt")) {
|
|
86
|
+
logOperation(db, { stamp_id: input.id, action: "verify", result: "failed", error_msg: result.error });
|
|
87
|
+
return { status: "invalid", hash: record.hash, reason: result.error ?? "unknown" };
|
|
88
|
+
}
|
|
89
|
+
logOperation(db, { stamp_id: input.id, action: "verify", result: "failed", error_msg: result.error });
|
|
90
|
+
return { status: "unknown", hash: record.hash };
|
|
91
|
+
}
|
|
92
|
+
logOperation(db, { stamp_id: input.id, action: "verify", result: "success" });
|
|
93
|
+
return {
|
|
94
|
+
status: "confirmed",
|
|
95
|
+
hash: record.hash,
|
|
96
|
+
bitcoin_block: result.blockHeight,
|
|
97
|
+
bitcoin_time: new Date(result.timestamp * 1e3).toISOString()
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/tools/list-pending.ts
|
|
102
|
+
function listPending(input, db, _config) {
|
|
103
|
+
return listStamps(db, {
|
|
104
|
+
status: input.status ?? "pending",
|
|
105
|
+
limit: Math.min(input.limit ?? 50, 200),
|
|
106
|
+
offset: input.offset ?? 0,
|
|
107
|
+
older_than_hours: input.older_than_hours
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
createTimestamp,
|
|
113
|
+
verifyTimestamp,
|
|
114
|
+
listPending
|
|
115
|
+
};
|
|
@@ -119,11 +119,10 @@ function reconcileOrphans(db) {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
// src/tools/
|
|
123
|
-
import {
|
|
124
|
-
import {
|
|
125
|
-
import {
|
|
126
|
-
import { OpenTimestampsClient } from "@otskit/client";
|
|
122
|
+
// src/tools/upgrade-timestamp.ts
|
|
123
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
124
|
+
import { OpenTimestampsClient, UpgradeError } from "@otskit/client";
|
|
125
|
+
import { DetachedTimestampFile } from "@otskit/core";
|
|
127
126
|
|
|
128
127
|
// src/db/stamps.ts
|
|
129
128
|
function insertStamp(db, params) {
|
|
@@ -192,50 +191,7 @@ function logOperation(db, params) {
|
|
|
192
191
|
);
|
|
193
192
|
}
|
|
194
193
|
|
|
195
|
-
// src/tools/create-timestamp.ts
|
|
196
|
-
var HEX64 = /^[0-9a-f]{64}$/i;
|
|
197
|
-
async function createTimestamp(input, db, config) {
|
|
198
|
-
if (!HEX64.test(input.hash)) {
|
|
199
|
-
return { error: "invalid_hash", details: "hash must be 64 hex characters (SHA-256)" };
|
|
200
|
-
}
|
|
201
|
-
const normalizedHash = input.hash.toLowerCase();
|
|
202
|
-
const client = new OpenTimestampsClient({
|
|
203
|
-
calendars: config.calendars,
|
|
204
|
-
resilience: { timeout: config.calendar_timeout_ms }
|
|
205
|
-
});
|
|
206
|
-
const t0 = Date.now();
|
|
207
|
-
let proofBuffer;
|
|
208
|
-
try {
|
|
209
|
-
proofBuffer = await client.stamp(normalizedHash);
|
|
210
|
-
} catch (e) {
|
|
211
|
-
return { error: "calendar_error", details: String(e) };
|
|
212
|
-
}
|
|
213
|
-
const responseTimeMs = Date.now() - t0;
|
|
214
|
-
const id = randomUUID();
|
|
215
|
-
const proofDir = join3(getDataDir(), "proofs");
|
|
216
|
-
mkdirSync3(proofDir, { recursive: true });
|
|
217
|
-
const proofPath = join3(proofDir, `${id}.ots`);
|
|
218
|
-
try {
|
|
219
|
-
writeAtomic(proofPath, proofBuffer);
|
|
220
|
-
} catch (e) {
|
|
221
|
-
return { error: "storage_error", details: String(e) };
|
|
222
|
-
}
|
|
223
|
-
const record = insertStamp(db, { id, hash: normalizedHash, proof_path: proofPath });
|
|
224
|
-
logOperation(db, { stamp_id: id, action: "stamp", result: "success", response_time_ms: responseTimeMs });
|
|
225
|
-
return {
|
|
226
|
-
id: record.id,
|
|
227
|
-
hash: record.hash,
|
|
228
|
-
status: "pending",
|
|
229
|
-
calendars: config.calendars,
|
|
230
|
-
created_at: record.created_at,
|
|
231
|
-
proof_path: proofPath
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
194
|
// src/tools/upgrade-timestamp.ts
|
|
236
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
237
|
-
import { OpenTimestampsClient as OpenTimestampsClient2, UpgradeError } from "@otskit/client";
|
|
238
|
-
import { DetachedTimestampFile } from "@otskit/core";
|
|
239
195
|
function checkBitcoinConfirmation(bytes) {
|
|
240
196
|
try {
|
|
241
197
|
const proof = DetachedTimestampFile.deserialize(new Uint8Array(bytes));
|
|
@@ -260,7 +216,7 @@ async function upgradeTimestamp(input, db, config) {
|
|
|
260
216
|
if (!record) return { error: "not_found", details: `No stamp with id ${input.id}` };
|
|
261
217
|
if (!record.proof_path) return { error: "storage_error", details: "No proof_path on record" };
|
|
262
218
|
const proofBefore = readFileSync2(record.proof_path);
|
|
263
|
-
const client = new
|
|
219
|
+
const client = new OpenTimestampsClient({
|
|
264
220
|
calendars: config.calendars,
|
|
265
221
|
resilience: { timeout: config.calendar_timeout_ms }
|
|
266
222
|
});
|
|
@@ -300,69 +256,14 @@ async function upgradeTimestamp(input, db, config) {
|
|
|
300
256
|
return { id: input.id, status: "pending", attempt_count: newAttemptCount, last_attempt_at: now, next_retry_at: next };
|
|
301
257
|
}
|
|
302
258
|
|
|
303
|
-
// src/tools/verify-timestamp.ts
|
|
304
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
305
|
-
import { OpenTimestampsClient as OpenTimestampsClient3 } from "@otskit/client";
|
|
306
|
-
async function verifyTimestamp(input, db, config) {
|
|
307
|
-
const record = getStamp(db, input.id);
|
|
308
|
-
if (!record) return { error: "not_found", details: `No stamp with id ${input.id}` };
|
|
309
|
-
if (!record.proof_path) return { error: "storage_error", details: "No proof_path on record" };
|
|
310
|
-
let proofBytes;
|
|
311
|
-
try {
|
|
312
|
-
proofBytes = readFileSync3(record.proof_path);
|
|
313
|
-
} catch (e) {
|
|
314
|
-
return { error: "storage_error", details: String(e) };
|
|
315
|
-
}
|
|
316
|
-
const client = new OpenTimestampsClient3({
|
|
317
|
-
calendars: config.calendars,
|
|
318
|
-
resilience: { timeout: config.calendar_timeout_ms }
|
|
319
|
-
});
|
|
320
|
-
let result;
|
|
321
|
-
try {
|
|
322
|
-
result = await client.verify(proofBytes, record.hash);
|
|
323
|
-
} catch (e) {
|
|
324
|
-
logOperation(db, { stamp_id: input.id, action: "verify", result: "failed", error_msg: String(e) });
|
|
325
|
-
return { status: "network_error", hash: record.hash, details: String(e) };
|
|
326
|
-
}
|
|
327
|
-
if (!result.valid) {
|
|
328
|
-
if (result.error?.includes("No Bitcoin attestation")) {
|
|
329
|
-
logOperation(db, { stamp_id: input.id, action: "verify", result: "pending" });
|
|
330
|
-
return { status: "pending", hash: record.hash, calendars: config.calendars };
|
|
331
|
-
}
|
|
332
|
-
if (result.error?.toLowerCase().includes("invalid") || result.error?.toLowerCase().includes("corrupt")) {
|
|
333
|
-
logOperation(db, { stamp_id: input.id, action: "verify", result: "failed", error_msg: result.error });
|
|
334
|
-
return { status: "invalid", hash: record.hash, reason: result.error ?? "unknown" };
|
|
335
|
-
}
|
|
336
|
-
logOperation(db, { stamp_id: input.id, action: "verify", result: "failed", error_msg: result.error });
|
|
337
|
-
return { status: "unknown", hash: record.hash };
|
|
338
|
-
}
|
|
339
|
-
logOperation(db, { stamp_id: input.id, action: "verify", result: "success" });
|
|
340
|
-
return {
|
|
341
|
-
status: "confirmed",
|
|
342
|
-
hash: record.hash,
|
|
343
|
-
bitcoin_block: result.blockHeight,
|
|
344
|
-
bitcoin_time: new Date(result.timestamp * 1e3).toISOString()
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// src/tools/list-pending.ts
|
|
349
|
-
function listPending(input, db, _config) {
|
|
350
|
-
return listStamps(db, {
|
|
351
|
-
status: input.status ?? "pending",
|
|
352
|
-
limit: Math.min(input.limit ?? 50, 200),
|
|
353
|
-
offset: input.offset ?? 0,
|
|
354
|
-
older_than_hours: input.older_than_hours
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
259
|
export {
|
|
359
260
|
getDataDir,
|
|
360
261
|
loadConfig,
|
|
361
262
|
getDb,
|
|
362
263
|
backupDb,
|
|
264
|
+
insertStamp,
|
|
363
265
|
getStamp,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
listPending
|
|
266
|
+
listStamps,
|
|
267
|
+
logOperation,
|
|
268
|
+
upgradeTimestamp
|
|
368
269
|
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
backupDb,
|
|
3
2
|
createTimestamp,
|
|
4
|
-
getDb,
|
|
5
3
|
listPending,
|
|
6
|
-
loadConfig,
|
|
7
|
-
upgradeTimestamp,
|
|
8
4
|
verifyTimestamp
|
|
9
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-45GR42GV.js";
|
|
6
|
+
import {
|
|
7
|
+
backupDb,
|
|
8
|
+
getDb,
|
|
9
|
+
loadConfig,
|
|
10
|
+
upgradeTimestamp
|
|
11
|
+
} from "./chunk-ASPLCXMC.js";
|
|
10
12
|
import "./chunk-YFSUDT24.js";
|
|
11
13
|
|
|
12
14
|
// src/cli.ts
|
package/dist/index.js
CHANGED
|
@@ -5,23 +5,36 @@ var [, , command, ...args] = process.argv;
|
|
|
5
5
|
if (!command || command === "--help" || command === "help") {
|
|
6
6
|
process.stderr.write(`Usage: ots-mcp <command>
|
|
7
7
|
Commands:
|
|
8
|
-
serve
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
serve Start MCP server (stdio transport)
|
|
9
|
+
install-claude Install MCP in Claude Desktop config (auto-setup)
|
|
10
|
+
watch [interval] Watch pending stamps in real-time (default: 5 min)
|
|
11
|
+
stamp <hash> Stamp a SHA-256 hash
|
|
12
|
+
upgrade <id> Upgrade a pending stamp
|
|
13
|
+
verify <id> Verify a stamp
|
|
14
|
+
list [status] List stamps (default: pending)
|
|
15
|
+
check-pending Run pending upgrades (for scheduler)
|
|
16
|
+
backup [dest] Backup the SQLite database
|
|
17
|
+
scheduler Manage OS scheduler (install|remove|status)
|
|
16
18
|
`);
|
|
17
19
|
process.exit(command ? 0 : 1);
|
|
18
20
|
}
|
|
19
21
|
switch (command) {
|
|
20
22
|
case "serve": {
|
|
21
|
-
const { runServer } = await import("./server-
|
|
23
|
+
const { runServer } = await import("./server-2YEI77IT.js");
|
|
22
24
|
await runServer();
|
|
23
25
|
break;
|
|
24
26
|
}
|
|
27
|
+
case "install-claude": {
|
|
28
|
+
const { installClaude } = await import("./install-claude-UKSS65BW.js");
|
|
29
|
+
installClaude();
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
case "watch": {
|
|
33
|
+
const { watchPending } = await import("./watch-JWDMAZWS.js");
|
|
34
|
+
const interval = args[0] ? parseInt(args[0]) : 5;
|
|
35
|
+
await watchPending(interval);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
25
38
|
case "stamp":
|
|
26
39
|
case "upgrade":
|
|
27
40
|
case "verify":
|
|
@@ -29,7 +42,7 @@ switch (command) {
|
|
|
29
42
|
case "check-pending":
|
|
30
43
|
case "backup":
|
|
31
44
|
case "scheduler": {
|
|
32
|
-
const { runCli } = await import("./cli-
|
|
45
|
+
const { runCli } = await import("./cli-67APZKT6.js");
|
|
33
46
|
await runCli(command, args);
|
|
34
47
|
break;
|
|
35
48
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/install-claude.ts
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
function getConfigPath() {
|
|
5
|
+
if (process.platform === "win32") {
|
|
6
|
+
return join(process.env.APPDATA ?? "", "Claude", "claude_desktop_config.json");
|
|
7
|
+
} else if (process.platform === "darwin") {
|
|
8
|
+
return join(process.env.HOME ?? "", "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
9
|
+
} else {
|
|
10
|
+
return join(process.env.HOME ?? "", ".config", "Claude", "claude_desktop_config.json");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function installClaude() {
|
|
14
|
+
const configPath = getConfigPath();
|
|
15
|
+
const configDir = join(configPath, "..");
|
|
16
|
+
if (!existsSync(configDir)) {
|
|
17
|
+
mkdirSync(configDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
let config = {};
|
|
20
|
+
if (existsSync(configPath)) {
|
|
21
|
+
try {
|
|
22
|
+
config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
23
|
+
} catch {
|
|
24
|
+
process.stderr.write(`Warning: could not parse existing config, creating new one
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const mcpServers = config.mcpServers ?? {};
|
|
29
|
+
mcpServers["otskit"] = {
|
|
30
|
+
command: "npx",
|
|
31
|
+
args: ["-y", "@otskit/mcp", "serve"]
|
|
32
|
+
};
|
|
33
|
+
config.mcpServers = mcpServers;
|
|
34
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
|
|
35
|
+
process.stdout.write(`\u2713 OTSkit MCP installed in Claude Desktop
|
|
36
|
+
`);
|
|
37
|
+
process.stdout.write(` Config: ${configPath}
|
|
38
|
+
`);
|
|
39
|
+
process.stdout.write(` Restart Claude Desktop to apply changes.
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
installClaude
|
|
44
|
+
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createTimestamp,
|
|
3
|
+
listPending,
|
|
4
|
+
verifyTimestamp
|
|
5
|
+
} from "./chunk-45GR42GV.js";
|
|
6
|
+
import {
|
|
3
7
|
getDataDir,
|
|
4
8
|
getDb,
|
|
5
9
|
getStamp,
|
|
6
|
-
listPending,
|
|
7
10
|
loadConfig,
|
|
8
|
-
upgradeTimestamp
|
|
9
|
-
|
|
10
|
-
} from "./chunk-6IPLIM6I.js";
|
|
11
|
+
upgradeTimestamp
|
|
12
|
+
} from "./chunk-ASPLCXMC.js";
|
|
11
13
|
import "./chunk-YFSUDT24.js";
|
|
12
14
|
|
|
13
15
|
// src/server.ts
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDb,
|
|
3
|
+
loadConfig,
|
|
4
|
+
upgradeTimestamp
|
|
5
|
+
} from "./chunk-ASPLCXMC.js";
|
|
6
|
+
import "./chunk-YFSUDT24.js";
|
|
7
|
+
|
|
8
|
+
// src/tools/watch.ts
|
|
9
|
+
async function watchPending(intervalMinutes = 5) {
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const db = getDb(config);
|
|
12
|
+
process.stdout.write(`Watching pending stamps every ${intervalMinutes} min. Ctrl+C to stop.
|
|
13
|
+
|
|
14
|
+
`);
|
|
15
|
+
async function tick() {
|
|
16
|
+
const rows = db.prepare(`SELECT id, hash, status FROM stamps WHERE status = 'pending'`).all();
|
|
17
|
+
if (rows.length === 0) {
|
|
18
|
+
process.stdout.write(`${now()} All stamps confirmed.
|
|
19
|
+
`);
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
process.stdout.write(`${now()} Checking ${rows.length} pending stamps...
|
|
23
|
+
`);
|
|
24
|
+
for (const row of rows) {
|
|
25
|
+
const result = await upgradeTimestamp({ id: row.id }, db, config);
|
|
26
|
+
if ("error" in result) {
|
|
27
|
+
process.stdout.write(` ${row.id.slice(0, 8)}... ERROR: ${result.error}
|
|
28
|
+
`);
|
|
29
|
+
} else if (result.status === "confirmed") {
|
|
30
|
+
process.stdout.write(` ${row.id.slice(0, 8)}... CONFIRMED block #${result.bitcoin_block}
|
|
31
|
+
`);
|
|
32
|
+
} else {
|
|
33
|
+
process.stdout.write(` ${row.id.slice(0, 8)}... pending (attempt ${result.attempt_count})
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
process.stdout.write("\n");
|
|
38
|
+
}
|
|
39
|
+
function now() {
|
|
40
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
41
|
+
}
|
|
42
|
+
await tick();
|
|
43
|
+
setInterval(tick, intervalMinutes * 60 * 1e3);
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
watchPending
|
|
47
|
+
};
|