@zcloak/ai-agent 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 +5 -0
- package/dist/bind.d.ts +22 -0
- package/dist/bind.js +145 -0
- package/dist/bind.js.map +1 -0
- package/dist/cli.d.ts +31 -0
- package/dist/cli.js +126 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.js +34 -0
- package/dist/config.js.map +1 -0
- package/dist/crypto.d.ts +113 -0
- package/dist/crypto.js +252 -0
- package/dist/crypto.js.map +1 -0
- package/dist/daemon.d.ts +94 -0
- package/dist/daemon.js +271 -0
- package/dist/daemon.js.map +1 -0
- package/dist/delete.d.ts +22 -0
- package/dist/delete.js +231 -0
- package/dist/delete.js.map +1 -0
- package/dist/doc.d.ts +23 -0
- package/dist/doc.js +180 -0
- package/dist/doc.js.map +1 -0
- package/dist/error.d.ts +45 -0
- package/dist/error.js +79 -0
- package/dist/error.js.map +1 -0
- package/dist/feed.d.ts +20 -0
- package/dist/feed.js +83 -0
- package/dist/feed.js.map +1 -0
- package/dist/identity.d.ts +50 -0
- package/dist/identity.js +99 -0
- package/dist/identity.js.map +1 -0
- package/dist/identity_cmd.d.ts +23 -0
- package/dist/identity_cmd.js +136 -0
- package/dist/identity_cmd.js.map +1 -0
- package/dist/idl.d.ts +99 -0
- package/dist/idl.js +213 -0
- package/dist/idl.js.map +1 -0
- package/dist/key-store.d.ts +88 -0
- package/dist/key-store.js +171 -0
- package/dist/key-store.js.map +1 -0
- package/dist/pow.d.ts +24 -0
- package/dist/pow.js +86 -0
- package/dist/pow.js.map +1 -0
- package/dist/register.d.ts +24 -0
- package/dist/register.js +191 -0
- package/dist/register.js.map +1 -0
- package/dist/rpc.d.ts +107 -0
- package/dist/rpc.js +60 -0
- package/dist/rpc.js.map +1 -0
- package/dist/serve.d.ts +55 -0
- package/dist/serve.js +455 -0
- package/dist/serve.js.map +1 -0
- package/dist/session.d.ts +104 -0
- package/dist/session.js +189 -0
- package/dist/session.js.map +1 -0
- package/dist/sign.d.ts +33 -0
- package/dist/sign.js +355 -0
- package/dist/sign.js.map +1 -0
- package/dist/types/common.d.ts +63 -0
- package/dist/types/common.js +8 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/config.d.ts +28 -0
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/registry.d.ts +72 -0
- package/dist/types/registry.js +13 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/types/sign-event.d.ts +134 -0
- package/dist/types/sign-event.js +13 -0
- package/dist/types/sign-event.js.map +1 -0
- package/dist/utils.d.ts +113 -0
- package/dist/utils.js +382 -0
- package/dist/utils.js.map +1 -0
- package/dist/verify.d.ts +23 -0
- package/dist/verify.js +207 -0
- package/dist/verify.js.map +1 -0
- package/dist/vetkey.d.ts +27 -0
- package/dist/vetkey.js +507 -0
- package/dist/vetkey.js.map +1 -0
- package/package.json +55 -0
package/dist/serve.js
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Daemon Serve — JSON-RPC over Unix Domain Socket or stdin/stdout
|
|
4
|
+
*
|
|
5
|
+
* Two operational modes:
|
|
6
|
+
*
|
|
7
|
+
* 1. UDS mode (default): Unix Domain Socket listener, supports concurrent clients.
|
|
8
|
+
* The daemon creates a socket file and listens for connections. Each client
|
|
9
|
+
* connection is handled independently. "quit" closes the connection;
|
|
10
|
+
* "shutdown" stops the entire daemon.
|
|
11
|
+
*
|
|
12
|
+
* 2. Stdio mode (--stdio): Legacy stdin/stdout mode, single client.
|
|
13
|
+
* Backwards-compatible with the Rust implementation. Reads JSON-RPC from
|
|
14
|
+
* stdin and writes responses to stdout. "quit" stops the daemon.
|
|
15
|
+
*
|
|
16
|
+
* Both modes share the same request handling logic (handleRequest).
|
|
17
|
+
*
|
|
18
|
+
* Trust model:
|
|
19
|
+
* - The daemon trusts its callers (local AI agent processes or socket clients).
|
|
20
|
+
* - File paths in encrypt/decrypt requests are not sandboxed — the daemon
|
|
21
|
+
* operates with the same filesystem permissions as the calling process.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.runDaemonUds = runDaemonUds;
|
|
25
|
+
exports.runDaemonStdio = runDaemonStdio;
|
|
26
|
+
const net_1 = require("net");
|
|
27
|
+
const readline_1 = require("readline");
|
|
28
|
+
const fs_1 = require("fs");
|
|
29
|
+
const daemon_1 = require("./daemon");
|
|
30
|
+
const rpc_1 = require("./rpc");
|
|
31
|
+
/** Maximum data size for encrypt/decrypt operations (1 GB) */
|
|
32
|
+
const MAX_DATA_SIZE = 1024 * 1024 * 1024;
|
|
33
|
+
/**
|
|
34
|
+
* Handle a single JSON-RPC request line.
|
|
35
|
+
*
|
|
36
|
+
* Dispatches to the appropriate handler based on the method name.
|
|
37
|
+
* Returns a response and an action indicating what to do next.
|
|
38
|
+
*/
|
|
39
|
+
function handleRequest(req, keyStore, principal, startedAt, mode, sockPath) {
|
|
40
|
+
const { id, method } = req;
|
|
41
|
+
switch (method) {
|
|
42
|
+
case "encrypt": {
|
|
43
|
+
const result = handleEncrypt(req.params, keyStore);
|
|
44
|
+
if ("error" in result) {
|
|
45
|
+
return { response: (0, rpc_1.errorResponse)(id, result.error), action: "continue" };
|
|
46
|
+
}
|
|
47
|
+
return { response: (0, rpc_1.successResponse)(id, result), action: "continue" };
|
|
48
|
+
}
|
|
49
|
+
case "decrypt": {
|
|
50
|
+
const result = handleDecrypt(req.params, keyStore);
|
|
51
|
+
if ("error" in result) {
|
|
52
|
+
return { response: (0, rpc_1.errorResponse)(id, result.error), action: "continue" };
|
|
53
|
+
}
|
|
54
|
+
return { response: (0, rpc_1.successResponse)(id, result), action: "continue" };
|
|
55
|
+
}
|
|
56
|
+
case "status": {
|
|
57
|
+
const status = {
|
|
58
|
+
status: "running",
|
|
59
|
+
derivation_id: keyStore.derivationId,
|
|
60
|
+
principal,
|
|
61
|
+
started_at: startedAt,
|
|
62
|
+
mode,
|
|
63
|
+
socket_path: sockPath,
|
|
64
|
+
};
|
|
65
|
+
return { response: (0, rpc_1.successResponse)(id, status), action: "continue" };
|
|
66
|
+
}
|
|
67
|
+
case "quit":
|
|
68
|
+
// In stdio mode: quit stops the daemon. In UDS mode: quit closes the connection.
|
|
69
|
+
return {
|
|
70
|
+
response: (0, rpc_1.successResponse)(id, { message: mode === "stdio" ? "Shutting down, key zeroized" : "Connection closed" }),
|
|
71
|
+
action: mode === "stdio" ? "shutdown" : "quit",
|
|
72
|
+
};
|
|
73
|
+
case "shutdown":
|
|
74
|
+
// Stop the entire daemon (both modes)
|
|
75
|
+
return {
|
|
76
|
+
response: (0, rpc_1.successResponse)(id, { message: "Shutting down, key zeroized" }),
|
|
77
|
+
action: "shutdown",
|
|
78
|
+
};
|
|
79
|
+
default:
|
|
80
|
+
return {
|
|
81
|
+
response: (0, rpc_1.errorResponse)(id, `Unknown method '${method}'. Supported: encrypt, decrypt, status, quit, shutdown`),
|
|
82
|
+
action: "continue",
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Encrypt / Decrypt Handlers
|
|
88
|
+
// ============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Handle the "encrypt" method.
|
|
91
|
+
* Supports file mode (input_file + output_file) and inline mode (data_base64).
|
|
92
|
+
*/
|
|
93
|
+
function handleEncrypt(params, keyStore) {
|
|
94
|
+
if (!params)
|
|
95
|
+
return { error: "Missing encrypt params" };
|
|
96
|
+
if (params.input_file && params.data_base64) {
|
|
97
|
+
return { error: "Cannot specify both input_file and data_base64" };
|
|
98
|
+
}
|
|
99
|
+
if (params.input_file) {
|
|
100
|
+
// File mode
|
|
101
|
+
if (!params.output_file) {
|
|
102
|
+
return { error: "output_file is required in file mode" };
|
|
103
|
+
}
|
|
104
|
+
const readResult = readFileChecked(params.input_file);
|
|
105
|
+
if ("error" in readResult)
|
|
106
|
+
return readResult;
|
|
107
|
+
const plaintext = readResult;
|
|
108
|
+
const plaintextSize = plaintext.length;
|
|
109
|
+
let ciphertext;
|
|
110
|
+
try {
|
|
111
|
+
ciphertext = keyStore.encrypt(plaintext);
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
return { error: `Encryption failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
(0, fs_1.writeFileSync)(params.output_file, ciphertext);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
return { error: `Failed to write '${params.output_file}': ${e instanceof Error ? e.message : String(e)}` };
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
output_file: params.output_file,
|
|
124
|
+
plaintext_size: plaintextSize,
|
|
125
|
+
ciphertext_size: ciphertext.length,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (params.data_base64) {
|
|
129
|
+
// Inline mode — check size before decoding
|
|
130
|
+
if (params.data_base64.length > MAX_DATA_SIZE * 4 / 3 + 4) {
|
|
131
|
+
return {
|
|
132
|
+
error: `data_base64 too large: ${params.data_base64.length} chars (decoded would exceed ${MAX_DATA_SIZE} byte limit)`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
let plaintext;
|
|
136
|
+
try {
|
|
137
|
+
plaintext = Buffer.from(params.data_base64, "base64");
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
return { error: `Invalid base64 input: ${e instanceof Error ? e.message : String(e)}` };
|
|
141
|
+
}
|
|
142
|
+
const plaintextSize = plaintext.length;
|
|
143
|
+
let ciphertext;
|
|
144
|
+
try {
|
|
145
|
+
ciphertext = keyStore.encrypt(plaintext);
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
return { error: `Encryption failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
data_base64: ciphertext.toString("base64"),
|
|
152
|
+
plaintext_size: plaintextSize,
|
|
153
|
+
ciphertext_size: ciphertext.length,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return { error: "Either input_file or data_base64 must be provided" };
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Handle the "decrypt" method.
|
|
160
|
+
* Supports file mode (input_file + output_file) and inline mode (data_base64).
|
|
161
|
+
*/
|
|
162
|
+
function handleDecrypt(params, keyStore) {
|
|
163
|
+
if (!params)
|
|
164
|
+
return { error: "Missing decrypt params" };
|
|
165
|
+
if (params.input_file && params.data_base64) {
|
|
166
|
+
return { error: "Cannot specify both input_file and data_base64" };
|
|
167
|
+
}
|
|
168
|
+
if (params.input_file) {
|
|
169
|
+
// File mode
|
|
170
|
+
if (!params.output_file) {
|
|
171
|
+
return { error: "output_file is required in file mode" };
|
|
172
|
+
}
|
|
173
|
+
const readResult = readFileChecked(params.input_file);
|
|
174
|
+
if ("error" in readResult)
|
|
175
|
+
return readResult;
|
|
176
|
+
const ciphertext = readResult;
|
|
177
|
+
let plaintext;
|
|
178
|
+
try {
|
|
179
|
+
plaintext = keyStore.decrypt(ciphertext);
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
return { error: `Decryption failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
(0, fs_1.writeFileSync)(params.output_file, plaintext);
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
return { error: `Failed to write '${params.output_file}': ${e instanceof Error ? e.message : String(e)}` };
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
output_file: params.output_file,
|
|
192
|
+
plaintext_size: plaintext.length,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (params.data_base64) {
|
|
196
|
+
// Inline mode
|
|
197
|
+
if (params.data_base64.length > MAX_DATA_SIZE * 4 / 3 + 4) {
|
|
198
|
+
return {
|
|
199
|
+
error: `data_base64 too large: ${params.data_base64.length} chars (decoded would exceed ${MAX_DATA_SIZE} byte limit)`,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
let ciphertext;
|
|
203
|
+
try {
|
|
204
|
+
ciphertext = Buffer.from(params.data_base64, "base64");
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
return { error: `Invalid base64 input: ${e instanceof Error ? e.message : String(e)}` };
|
|
208
|
+
}
|
|
209
|
+
let plaintext;
|
|
210
|
+
try {
|
|
211
|
+
plaintext = keyStore.decrypt(ciphertext);
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
return { error: `Decryption failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
data_base64: plaintext.toString("base64"),
|
|
218
|
+
plaintext_size: plaintext.length,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return { error: "Either input_file or data_base64 must be provided" };
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Read a file with size validation to limit memory usage.
|
|
225
|
+
* Rejects files larger than MAX_DATA_SIZE and non-regular files.
|
|
226
|
+
*/
|
|
227
|
+
function readFileChecked(filePath) {
|
|
228
|
+
try {
|
|
229
|
+
const stat = (0, fs_1.statSync)(filePath);
|
|
230
|
+
if (!stat.isFile()) {
|
|
231
|
+
return { error: `'${filePath}' is not a regular file (refusing to read devices/pipes/sockets)` };
|
|
232
|
+
}
|
|
233
|
+
if (stat.size > MAX_DATA_SIZE) {
|
|
234
|
+
return { error: `File '${filePath}' is too large: ${stat.size} bytes (max ${MAX_DATA_SIZE} bytes)` };
|
|
235
|
+
}
|
|
236
|
+
return (0, fs_1.readFileSync)(filePath);
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
return { error: `Cannot read '${filePath}': ${e instanceof Error ? e.message : String(e)}` };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// ============================================================================
|
|
243
|
+
// UDS Mode (Default)
|
|
244
|
+
// ============================================================================
|
|
245
|
+
/**
|
|
246
|
+
* Run the JSON-RPC daemon over a Unix Domain Socket.
|
|
247
|
+
*
|
|
248
|
+
* Lifecycle:
|
|
249
|
+
* 1. Create DaemonRuntime (PID file, socket path)
|
|
250
|
+
* 2. Create server and listen on socket
|
|
251
|
+
* 3. Emit ready info to stderr
|
|
252
|
+
* 4. Accept connections, handle requests concurrently
|
|
253
|
+
* 5. On shutdown signal: stop accepting, close connections, cleanup
|
|
254
|
+
*
|
|
255
|
+
* @param keyStore - AES-256 key holder
|
|
256
|
+
* @param principal - Authenticated principal text
|
|
257
|
+
* @param derivationId - Derivation ID used for the key
|
|
258
|
+
*/
|
|
259
|
+
function runDaemonUds(keyStore, principal, derivationId) {
|
|
260
|
+
return new Promise((resolve, reject) => {
|
|
261
|
+
// Step 1: Create daemon runtime (PID file, socket setup)
|
|
262
|
+
const runtime = daemon_1.DaemonRuntime.create(derivationId);
|
|
263
|
+
const startedAt = new Date().toISOString();
|
|
264
|
+
const sockPath = runtime.socketFilePath;
|
|
265
|
+
// Track active connections for graceful shutdown
|
|
266
|
+
const activeConnections = new Set();
|
|
267
|
+
// Step 2: Create server
|
|
268
|
+
const server = (0, net_1.createServer)((conn) => {
|
|
269
|
+
activeConnections.add(conn);
|
|
270
|
+
conn.on("close", () => {
|
|
271
|
+
activeConnections.delete(conn);
|
|
272
|
+
});
|
|
273
|
+
// Handle each connection with line-based JSON-RPC
|
|
274
|
+
const rl = (0, readline_1.createInterface)({ input: conn });
|
|
275
|
+
rl.on("line", (line) => {
|
|
276
|
+
if (!line.trim())
|
|
277
|
+
return; // Skip blank lines
|
|
278
|
+
// Parse the request
|
|
279
|
+
const parsed = (0, rpc_1.parseRpcRequest)(line);
|
|
280
|
+
if ((0, rpc_1.isErrorResponse)(parsed)) {
|
|
281
|
+
// Parse error — send error response
|
|
282
|
+
writeLine(conn, JSON.stringify(parsed));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
// Handle the request
|
|
286
|
+
const { response, action } = handleRequest(parsed, keyStore, principal, startedAt, "uds", sockPath);
|
|
287
|
+
writeLine(conn, JSON.stringify(response));
|
|
288
|
+
if (action === "quit") {
|
|
289
|
+
// Close this connection only
|
|
290
|
+
conn.end();
|
|
291
|
+
}
|
|
292
|
+
else if (action === "shutdown") {
|
|
293
|
+
// Stop the entire daemon
|
|
294
|
+
initiateShutdown();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
rl.on("close", () => {
|
|
298
|
+
conn.end();
|
|
299
|
+
});
|
|
300
|
+
conn.on("error", () => {
|
|
301
|
+
// Client disconnected unexpectedly — just clean up
|
|
302
|
+
activeConnections.delete(conn);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
// Step 3: Listen on socket
|
|
306
|
+
server.listen(sockPath, () => {
|
|
307
|
+
// Emit ready info to stderr
|
|
308
|
+
console.error(`Daemon ready. Socket: ${sockPath}`);
|
|
309
|
+
console.error(`Derivation ID: ${derivationId}`);
|
|
310
|
+
console.error(`Principal: ${principal}`);
|
|
311
|
+
});
|
|
312
|
+
server.on("error", (err) => {
|
|
313
|
+
runtime.destroy();
|
|
314
|
+
reject(err);
|
|
315
|
+
});
|
|
316
|
+
// Step 4: Signal handling — store references for cleanup in finishShutdown()
|
|
317
|
+
const onSigterm = () => { console.error("Received SIGTERM, initiating graceful shutdown..."); initiateShutdown(); };
|
|
318
|
+
const onSigint = () => { console.error("Received SIGINT, initiating graceful shutdown..."); initiateShutdown(); };
|
|
319
|
+
// SIGHUP: terminal hangup — gracefully shut down instead of crashing
|
|
320
|
+
const onSighup = () => { console.error("Received SIGHUP, initiating graceful shutdown..."); initiateShutdown(); };
|
|
321
|
+
process.on("SIGTERM", onSigterm);
|
|
322
|
+
process.on("SIGINT", onSigint);
|
|
323
|
+
process.on("SIGHUP", onSighup);
|
|
324
|
+
// Catch uncaught exceptions / unhandled rejections to ensure key zeroization
|
|
325
|
+
// and PID file cleanup even on unexpected errors.
|
|
326
|
+
const onUncaughtException = (err) => {
|
|
327
|
+
console.error(`Uncaught exception in daemon: ${err.message}`);
|
|
328
|
+
console.error(err.stack);
|
|
329
|
+
initiateShutdown();
|
|
330
|
+
};
|
|
331
|
+
const onUnhandledRejection = (reason) => {
|
|
332
|
+
console.error(`Unhandled rejection in daemon: ${reason}`);
|
|
333
|
+
initiateShutdown();
|
|
334
|
+
};
|
|
335
|
+
process.on("uncaughtException", onUncaughtException);
|
|
336
|
+
process.on("unhandledRejection", onUnhandledRejection);
|
|
337
|
+
// Shutdown procedure
|
|
338
|
+
let shuttingDown = false;
|
|
339
|
+
function initiateShutdown() {
|
|
340
|
+
if (shuttingDown)
|
|
341
|
+
return;
|
|
342
|
+
shuttingDown = true;
|
|
343
|
+
// Stop accepting new connections
|
|
344
|
+
server.close();
|
|
345
|
+
// Close all active connections
|
|
346
|
+
for (const conn of activeConnections) {
|
|
347
|
+
conn.end();
|
|
348
|
+
}
|
|
349
|
+
// Wait a moment for connections to close, then force cleanup
|
|
350
|
+
const forceTimer = setTimeout(() => {
|
|
351
|
+
for (const conn of activeConnections) {
|
|
352
|
+
conn.destroy();
|
|
353
|
+
}
|
|
354
|
+
finishShutdown();
|
|
355
|
+
}, 3000); // 3 second grace period
|
|
356
|
+
// If all connections close before timeout, finish immediately
|
|
357
|
+
const checkDone = setInterval(() => {
|
|
358
|
+
if (activeConnections.size === 0) {
|
|
359
|
+
clearInterval(checkDone);
|
|
360
|
+
clearTimeout(forceTimer);
|
|
361
|
+
finishShutdown();
|
|
362
|
+
}
|
|
363
|
+
}, 100);
|
|
364
|
+
}
|
|
365
|
+
let finished = false;
|
|
366
|
+
function finishShutdown() {
|
|
367
|
+
if (finished)
|
|
368
|
+
return;
|
|
369
|
+
finished = true;
|
|
370
|
+
// Remove all process-level event listeners to prevent leaks
|
|
371
|
+
process.removeListener("SIGTERM", onSigterm);
|
|
372
|
+
process.removeListener("SIGINT", onSigint);
|
|
373
|
+
process.removeListener("SIGHUP", onSighup);
|
|
374
|
+
process.removeListener("uncaughtException", onUncaughtException);
|
|
375
|
+
process.removeListener("unhandledRejection", onUnhandledRejection);
|
|
376
|
+
// Cleanup: destroy key, remove files
|
|
377
|
+
keyStore.destroy();
|
|
378
|
+
runtime.destroy();
|
|
379
|
+
console.error("Daemon stopped. Key has been zeroized.");
|
|
380
|
+
resolve();
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
// ============================================================================
|
|
385
|
+
// Stdio Mode (Legacy, --stdio)
|
|
386
|
+
// ============================================================================
|
|
387
|
+
/**
|
|
388
|
+
* Run the JSON-RPC daemon over stdin/stdout (legacy mode).
|
|
389
|
+
*
|
|
390
|
+
* Reads one JSON-RPC request per line from stdin, processes it,
|
|
391
|
+
* and writes the response to stdout. Exits on "quit" or stdin EOF.
|
|
392
|
+
*
|
|
393
|
+
* This mode is backwards-compatible with the Rust vetkey-tool implementation.
|
|
394
|
+
* No PID file or socket file is created.
|
|
395
|
+
*
|
|
396
|
+
* @param keyStore - AES-256 key holder (consumed; destroyed on exit)
|
|
397
|
+
* @param principal - Authenticated principal text
|
|
398
|
+
* @param derivationId - Derivation ID used for the key
|
|
399
|
+
* @param input - Optional input stream (defaults to process.stdin, override for testing)
|
|
400
|
+
* @param output - Optional output stream (defaults to process.stdout, override for testing)
|
|
401
|
+
*/
|
|
402
|
+
function runDaemonStdio(keyStore, principal, derivationId, input, output) {
|
|
403
|
+
return new Promise((resolve) => {
|
|
404
|
+
const stdin = input ?? process.stdin;
|
|
405
|
+
const stdout = output ?? process.stdout;
|
|
406
|
+
const startedAt = new Date().toISOString();
|
|
407
|
+
// Emit ready signal to stdout (same format as Rust version)
|
|
408
|
+
const readyMsg = JSON.stringify({
|
|
409
|
+
ready: true,
|
|
410
|
+
derivation_id: derivationId,
|
|
411
|
+
principal,
|
|
412
|
+
started_at: startedAt,
|
|
413
|
+
});
|
|
414
|
+
stdout.write(readyMsg + "\n");
|
|
415
|
+
// Read input line by line
|
|
416
|
+
const rl = (0, readline_1.createInterface)({ input: stdin });
|
|
417
|
+
rl.on("line", (line) => {
|
|
418
|
+
if (!line.trim())
|
|
419
|
+
return; // Skip blank lines
|
|
420
|
+
// Parse the request
|
|
421
|
+
const parsed = (0, rpc_1.parseRpcRequest)(line);
|
|
422
|
+
if ((0, rpc_1.isErrorResponse)(parsed)) {
|
|
423
|
+
stdout.write(JSON.stringify(parsed) + "\n");
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
// Handle the request
|
|
427
|
+
const { response, action } = handleRequest(parsed, keyStore, principal, startedAt, "stdio");
|
|
428
|
+
stdout.write(JSON.stringify(response) + "\n");
|
|
429
|
+
if (action === "shutdown" || action === "quit") {
|
|
430
|
+
// In stdio mode, both quit and shutdown stop the daemon
|
|
431
|
+
rl.close();
|
|
432
|
+
keyStore.destroy();
|
|
433
|
+
resolve();
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
// stdin EOF — daemon exits
|
|
437
|
+
rl.on("close", () => {
|
|
438
|
+
keyStore.destroy();
|
|
439
|
+
resolve();
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
// ============================================================================
|
|
444
|
+
// Helpers
|
|
445
|
+
// ============================================================================
|
|
446
|
+
/** Write a line to a socket, handling write errors gracefully */
|
|
447
|
+
function writeLine(socket, line) {
|
|
448
|
+
try {
|
|
449
|
+
socket.write(line + "\n");
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
// Socket may have been closed — ignore write errors
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session — Single CLI Invocation Context
|
|
3
|
+
*
|
|
4
|
+
* Replaces global mutable state (process.argv rewriting, module-level caches)
|
|
5
|
+
* with an explicit, per-invocation context object. All sub-scripts receive a
|
|
6
|
+
* Session instance instead of reading process.argv or relying on module singletons.
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle:
|
|
9
|
+
* 1. cli.ts (or standalone script) creates a Session from argv
|
|
10
|
+
* 2. Session is passed to the sub-script's run() function
|
|
11
|
+
* 3. Sub-script uses session.getSignActor(), session.autoPoW(), etc.
|
|
12
|
+
* 4. Session is garbage-collected when the process exits
|
|
13
|
+
*
|
|
14
|
+
* Lazy initialization:
|
|
15
|
+
* Identity, HttpAgent, and Actor instances are created on first use and cached
|
|
16
|
+
* within the Session. This avoids unnecessary PEM reads or HTTP connections
|
|
17
|
+
* for commands that don't need them (e.g. `doc hash`).
|
|
18
|
+
*/
|
|
19
|
+
import { HttpAgent, type ActorSubclass } from '@dfinity/agent';
|
|
20
|
+
import type { Secp256k1KeyIdentity } from '@dfinity/identity-secp256k1';
|
|
21
|
+
import type { Principal } from '@dfinity/principal';
|
|
22
|
+
import type { SignService } from './types/sign-event';
|
|
23
|
+
import type { RegistryService } from './types/registry';
|
|
24
|
+
import type { ParsedArgs, AutoPowResult } from './types/common';
|
|
25
|
+
import type { CanisterIds } from './types/config';
|
|
26
|
+
/**
|
|
27
|
+
* Session encapsulates all state for a single CLI command invocation.
|
|
28
|
+
*
|
|
29
|
+
* It holds:
|
|
30
|
+
* - Parsed arguments and configuration (immutable after construction)
|
|
31
|
+
* - Lazy-loaded identity, HTTP agents, and canister actors (cached per session)
|
|
32
|
+
*
|
|
33
|
+
* This design eliminates:
|
|
34
|
+
* - process.argv rewriting in cli.ts
|
|
35
|
+
* - Module-level singleton caches (_identity, _authenticatedAgent, _anonymousAgent)
|
|
36
|
+
* - Implicit global state reads in domain functions
|
|
37
|
+
*/
|
|
38
|
+
export declare class Session {
|
|
39
|
+
/** Raw argv array (preserved for functions that need it, like getPemPath) */
|
|
40
|
+
private readonly _argv;
|
|
41
|
+
/** Parsed command-line arguments */
|
|
42
|
+
readonly args: ParsedArgs;
|
|
43
|
+
/** Canister IDs */
|
|
44
|
+
readonly canisterIds: CanisterIds;
|
|
45
|
+
private _identity;
|
|
46
|
+
private _authenticatedAgent;
|
|
47
|
+
private _anonymousAgent;
|
|
48
|
+
/**
|
|
49
|
+
* Create a new Session from a raw argv array.
|
|
50
|
+
*
|
|
51
|
+
* @param argv - Full argument array (same format as process.argv).
|
|
52
|
+
* The first two elements (node binary, script path) are skipped
|
|
53
|
+
* by parseArgs. Global options (--identity) are extracted
|
|
54
|
+
* by getPemPath.
|
|
55
|
+
*/
|
|
56
|
+
constructor(argv: string[]);
|
|
57
|
+
/**
|
|
58
|
+
* Get the resolved PEM file path for this session.
|
|
59
|
+
* Uses the same resolution priority as getIdentity():
|
|
60
|
+
* --identity=<path> > ZCLOAK_IDENTITY env > dfx default location
|
|
61
|
+
*/
|
|
62
|
+
getPemPath(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Get the ECDSA secp256k1 identity for this session.
|
|
65
|
+
* Loaded from PEM file on first call, then cached.
|
|
66
|
+
*
|
|
67
|
+
* PEM path resolution: --identity=<path> > ZCLOAK_IDENTITY env > dfx default location
|
|
68
|
+
*/
|
|
69
|
+
getIdentity(): Secp256k1KeyIdentity;
|
|
70
|
+
/** Get the current identity's Principal ID as text */
|
|
71
|
+
getPrincipal(): string;
|
|
72
|
+
/** Get the current identity's Principal object */
|
|
73
|
+
getPrincipalObj(): Principal;
|
|
74
|
+
/**
|
|
75
|
+
* Get an authenticated HttpAgent (with identity, for update calls).
|
|
76
|
+
* Created on first call, then cached for the session duration.
|
|
77
|
+
*/
|
|
78
|
+
getAuthenticatedAgent(): Promise<HttpAgent>;
|
|
79
|
+
/**
|
|
80
|
+
* Get an anonymous HttpAgent (no identity, for query calls).
|
|
81
|
+
* Created on first call, then cached for the session duration.
|
|
82
|
+
*/
|
|
83
|
+
getAnonymousAgent(): Promise<HttpAgent>;
|
|
84
|
+
/** Get authenticated signatures canister Actor (supports update calls) */
|
|
85
|
+
getSignActor(): Promise<ActorSubclass<SignService>>;
|
|
86
|
+
/** Get authenticated registry canister Actor (supports update calls) */
|
|
87
|
+
getRegistryActor(): Promise<ActorSubclass<RegistryService>>;
|
|
88
|
+
/** Get anonymous signatures canister Actor (query only) */
|
|
89
|
+
getAnonymousSignActor(): Promise<ActorSubclass<SignService>>;
|
|
90
|
+
/** Get anonymous registry canister Actor (query only) */
|
|
91
|
+
getAnonymousRegistryActor(): Promise<ActorSubclass<RegistryService>>;
|
|
92
|
+
/**
|
|
93
|
+
* Automatically fetch PoW base and compute nonce.
|
|
94
|
+
* Complete PoW flow: get latest sign event ID → compute nonce.
|
|
95
|
+
*/
|
|
96
|
+
autoPoW(): Promise<AutoPowResult>;
|
|
97
|
+
/** Get the bind URL */
|
|
98
|
+
getBindUrl(): string;
|
|
99
|
+
/** Get the profile URL prefix */
|
|
100
|
+
getProfileUrl(): string;
|
|
101
|
+
/** Get the 2FA verification URL */
|
|
102
|
+
getTwoFAUrl(): string;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=session.d.ts.map
|