@sm-lab/keys 0.2.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 +60 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +718 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.mts +61 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/io-BtF203qz.mjs +275 -0
- package/dist/io-BtF203qz.mjs.map +1 -0
- package/package.json +60 -0
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as writeDepositDataFile, r as makeDepositKeys, s as CHAINS, t as toDepositDataJson } from "./io-BtF203qz.mjs";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { Argument, Command, Option } from "commander";
|
|
5
|
+
import { Readable } from "node:stream";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region ../../node_modules/.pnpm/@hono+node-server@2.0.6_hono@4.12.27/node_modules/@hono/node-server/dist/index.mjs
|
|
8
|
+
const GlobalRequest = global.Request;
|
|
9
|
+
var Request$1 = class extends GlobalRequest {
|
|
10
|
+
constructor(input, options) {
|
|
11
|
+
if (typeof input === "object" && getRequestCache in input) {
|
|
12
|
+
const hasReplacementBody = options !== void 0 && "body" in options && options.body != null;
|
|
13
|
+
if (input[bodyConsumedDirectlyKey] && !hasReplacementBody) throw new TypeError("Cannot construct a Request with a Request object that has already been used.");
|
|
14
|
+
input = input[getRequestCache]();
|
|
15
|
+
}
|
|
16
|
+
if (typeof (options?.body)?.getReader !== "undefined") options.duplex ??= "half";
|
|
17
|
+
super(input, options);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const newHeadersFromIncoming = (incoming) => {
|
|
21
|
+
const headerRecord = [];
|
|
22
|
+
const rawHeaders = incoming.rawHeaders;
|
|
23
|
+
for (let i = 0, len = rawHeaders.length; i < len; i += 2) {
|
|
24
|
+
const key = rawHeaders[i];
|
|
25
|
+
if (key.charCodeAt(0) !== 58) headerRecord.push([key, rawHeaders[i + 1]]);
|
|
26
|
+
}
|
|
27
|
+
return new Headers(headerRecord);
|
|
28
|
+
};
|
|
29
|
+
const wrapBodyStream = Symbol("wrapBodyStream");
|
|
30
|
+
const newRequestFromIncoming = (method, url, headers, incoming, abortController) => {
|
|
31
|
+
const init = {
|
|
32
|
+
method,
|
|
33
|
+
headers,
|
|
34
|
+
signal: abortController.signal
|
|
35
|
+
};
|
|
36
|
+
if (method === "TRACE") {
|
|
37
|
+
init.method = "GET";
|
|
38
|
+
const req = new Request$1(url, init);
|
|
39
|
+
Object.defineProperty(req, "method", { get() {
|
|
40
|
+
return "TRACE";
|
|
41
|
+
} });
|
|
42
|
+
return req;
|
|
43
|
+
}
|
|
44
|
+
if (!(method === "GET" || method === "HEAD")) if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) init.body = new ReadableStream({ start(controller) {
|
|
45
|
+
controller.enqueue(incoming.rawBody);
|
|
46
|
+
controller.close();
|
|
47
|
+
} });
|
|
48
|
+
else if (incoming[wrapBodyStream]) {
|
|
49
|
+
let reader;
|
|
50
|
+
init.body = new ReadableStream({ async pull(controller) {
|
|
51
|
+
try {
|
|
52
|
+
reader ||= Readable.toWeb(incoming).getReader();
|
|
53
|
+
const { done, value } = await reader.read();
|
|
54
|
+
if (done) controller.close();
|
|
55
|
+
else controller.enqueue(value);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
controller.error(error);
|
|
58
|
+
}
|
|
59
|
+
} });
|
|
60
|
+
} else init.body = Readable.toWeb(incoming);
|
|
61
|
+
return new Request$1(url, init);
|
|
62
|
+
};
|
|
63
|
+
const getRequestCache = Symbol("getRequestCache");
|
|
64
|
+
const requestCache = Symbol("requestCache");
|
|
65
|
+
const incomingKey = Symbol("incomingKey");
|
|
66
|
+
const urlKey = Symbol("urlKey");
|
|
67
|
+
const methodKey = Symbol("methodKey");
|
|
68
|
+
const headersKey = Symbol("headersKey");
|
|
69
|
+
const abortControllerKey = Symbol("abortControllerKey");
|
|
70
|
+
const getAbortController = Symbol("getAbortController");
|
|
71
|
+
const abortRequest = Symbol("abortRequest");
|
|
72
|
+
const bodyBufferKey = Symbol("bodyBuffer");
|
|
73
|
+
const bodyReadPromiseKey = Symbol("bodyReadPromise");
|
|
74
|
+
const bodyConsumedDirectlyKey = Symbol("bodyConsumedDirectly");
|
|
75
|
+
const bodyLockReaderKey = Symbol("bodyLockReader");
|
|
76
|
+
const abortReasonKey = Symbol("abortReason");
|
|
77
|
+
const newBodyUnusableError = () => {
|
|
78
|
+
return /* @__PURE__ */ new TypeError("Body is unusable");
|
|
79
|
+
};
|
|
80
|
+
const rejectBodyUnusable = () => {
|
|
81
|
+
return Promise.reject(newBodyUnusableError());
|
|
82
|
+
};
|
|
83
|
+
const textDecoder = new TextDecoder();
|
|
84
|
+
const consumeBodyDirectOnce = (request) => {
|
|
85
|
+
if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
|
|
86
|
+
request[bodyConsumedDirectlyKey] = true;
|
|
87
|
+
};
|
|
88
|
+
const toArrayBuffer = (buf) => {
|
|
89
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
90
|
+
};
|
|
91
|
+
const contentType = (request) => {
|
|
92
|
+
return (request[headersKey] ||= newHeadersFromIncoming(request[incomingKey])).get("content-type") || "";
|
|
93
|
+
};
|
|
94
|
+
const methodTokenRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
95
|
+
const validateDirectReadMethod = (method) => {
|
|
96
|
+
if (!methodTokenRegExp.test(method)) return /* @__PURE__ */ new TypeError(`'${method}' is not a valid HTTP method.`);
|
|
97
|
+
const normalized = method.toUpperCase();
|
|
98
|
+
if (normalized === "CONNECT" || normalized === "TRACK" || normalized === "TRACE" && method !== "TRACE") return /* @__PURE__ */ new TypeError(`'${method}' HTTP method is unsupported.`);
|
|
99
|
+
};
|
|
100
|
+
const readBodyWithFastPath = (request, method, fromBuffer) => {
|
|
101
|
+
if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
|
|
102
|
+
const methodName = request.method;
|
|
103
|
+
if (methodName === "GET" || methodName === "HEAD") return request[getRequestCache]()[method]();
|
|
104
|
+
const methodValidationError = validateDirectReadMethod(methodName);
|
|
105
|
+
if (methodValidationError) return Promise.reject(methodValidationError);
|
|
106
|
+
if (request[requestCache]) {
|
|
107
|
+
if (methodName !== "TRACE") return request[requestCache][method]();
|
|
108
|
+
}
|
|
109
|
+
const alreadyUsedError = consumeBodyDirectOnce(request);
|
|
110
|
+
if (alreadyUsedError) return alreadyUsedError;
|
|
111
|
+
const raw = readRawBodyIfAvailable(request);
|
|
112
|
+
if (raw) {
|
|
113
|
+
const result = Promise.resolve(fromBuffer(raw, request));
|
|
114
|
+
request[bodyBufferKey] = void 0;
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
return readBodyDirect(request).then((buf) => {
|
|
118
|
+
const result = fromBuffer(buf, request);
|
|
119
|
+
request[bodyBufferKey] = void 0;
|
|
120
|
+
return result;
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
const readRawBodyIfAvailable = (request) => {
|
|
124
|
+
const incoming = request[incomingKey];
|
|
125
|
+
if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) return incoming.rawBody;
|
|
126
|
+
};
|
|
127
|
+
const readBodyDirect = (request) => {
|
|
128
|
+
if (request[bodyBufferKey]) return Promise.resolve(request[bodyBufferKey]);
|
|
129
|
+
if (request[bodyReadPromiseKey]) return request[bodyReadPromiseKey];
|
|
130
|
+
const incoming = request[incomingKey];
|
|
131
|
+
if (Readable.isDisturbed(incoming)) return rejectBodyUnusable();
|
|
132
|
+
const promise = new Promise((resolve, reject) => {
|
|
133
|
+
const chunks = [];
|
|
134
|
+
let settled = false;
|
|
135
|
+
const finish = (callback) => {
|
|
136
|
+
if (settled) return;
|
|
137
|
+
settled = true;
|
|
138
|
+
cleanup();
|
|
139
|
+
callback();
|
|
140
|
+
};
|
|
141
|
+
const onData = (chunk) => {
|
|
142
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
143
|
+
};
|
|
144
|
+
const onEnd = () => {
|
|
145
|
+
finish(() => {
|
|
146
|
+
const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
|
|
147
|
+
request[bodyBufferKey] = buffer;
|
|
148
|
+
resolve(buffer);
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const onError = (error) => {
|
|
152
|
+
finish(() => {
|
|
153
|
+
reject(error);
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
const onClose = () => {
|
|
157
|
+
if (incoming.readableEnded) {
|
|
158
|
+
onEnd();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
finish(() => {
|
|
162
|
+
if (incoming.errored) {
|
|
163
|
+
reject(incoming.errored);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const reason = request[abortReasonKey];
|
|
167
|
+
if (reason !== void 0) {
|
|
168
|
+
reject(reason instanceof Error ? reason : new Error(String(reason)));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
reject(/* @__PURE__ */ new Error("Client connection prematurely closed."));
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
const cleanup = () => {
|
|
175
|
+
incoming.off("data", onData);
|
|
176
|
+
incoming.off("end", onEnd);
|
|
177
|
+
incoming.off("error", onError);
|
|
178
|
+
incoming.off("close", onClose);
|
|
179
|
+
request[bodyReadPromiseKey] = void 0;
|
|
180
|
+
};
|
|
181
|
+
incoming.on("data", onData);
|
|
182
|
+
incoming.on("end", onEnd);
|
|
183
|
+
incoming.on("error", onError);
|
|
184
|
+
incoming.on("close", onClose);
|
|
185
|
+
queueMicrotask(() => {
|
|
186
|
+
if (settled) return;
|
|
187
|
+
if (incoming.readableEnded) onEnd();
|
|
188
|
+
else if (incoming.errored) onError(incoming.errored);
|
|
189
|
+
else if (incoming.destroyed) onClose();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
request[bodyReadPromiseKey] = promise;
|
|
193
|
+
return promise;
|
|
194
|
+
};
|
|
195
|
+
const requestPrototype = {
|
|
196
|
+
get method() {
|
|
197
|
+
return this[methodKey];
|
|
198
|
+
},
|
|
199
|
+
get url() {
|
|
200
|
+
return this[urlKey];
|
|
201
|
+
},
|
|
202
|
+
get headers() {
|
|
203
|
+
return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
|
|
204
|
+
},
|
|
205
|
+
[abortRequest](reason) {
|
|
206
|
+
if (this[abortReasonKey] === void 0) this[abortReasonKey] = reason;
|
|
207
|
+
const abortController = this[abortControllerKey];
|
|
208
|
+
if (abortController && !abortController.signal.aborted) abortController.abort(reason);
|
|
209
|
+
},
|
|
210
|
+
[getAbortController]() {
|
|
211
|
+
this[abortControllerKey] ||= new AbortController();
|
|
212
|
+
if (this[abortReasonKey] !== void 0 && !this[abortControllerKey].signal.aborted) this[abortControllerKey].abort(this[abortReasonKey]);
|
|
213
|
+
return this[abortControllerKey];
|
|
214
|
+
},
|
|
215
|
+
[getRequestCache]() {
|
|
216
|
+
const abortController = this[getAbortController]();
|
|
217
|
+
if (this[requestCache]) return this[requestCache];
|
|
218
|
+
const method = this.method;
|
|
219
|
+
if (this[bodyConsumedDirectlyKey] && !(method === "GET" || method === "HEAD")) {
|
|
220
|
+
this[bodyBufferKey] = void 0;
|
|
221
|
+
const init = {
|
|
222
|
+
method: method === "TRACE" ? "GET" : method,
|
|
223
|
+
headers: this.headers,
|
|
224
|
+
signal: abortController.signal
|
|
225
|
+
};
|
|
226
|
+
if (method !== "TRACE") {
|
|
227
|
+
init.body = new ReadableStream({ start(c) {
|
|
228
|
+
c.close();
|
|
229
|
+
} });
|
|
230
|
+
init.duplex = "half";
|
|
231
|
+
}
|
|
232
|
+
const req = new Request$1(this[urlKey], init);
|
|
233
|
+
if (method === "TRACE") Object.defineProperty(req, "method", { get() {
|
|
234
|
+
return "TRACE";
|
|
235
|
+
} });
|
|
236
|
+
return this[requestCache] = req;
|
|
237
|
+
}
|
|
238
|
+
return this[requestCache] = newRequestFromIncoming(this.method, this[urlKey], this.headers, this[incomingKey], abortController);
|
|
239
|
+
},
|
|
240
|
+
get body() {
|
|
241
|
+
if (!this[bodyConsumedDirectlyKey]) return this[getRequestCache]().body;
|
|
242
|
+
const request = this[getRequestCache]();
|
|
243
|
+
if (!this[bodyLockReaderKey] && request.body) this[bodyLockReaderKey] = request.body.getReader();
|
|
244
|
+
return request.body;
|
|
245
|
+
},
|
|
246
|
+
get bodyUsed() {
|
|
247
|
+
if (this[bodyConsumedDirectlyKey]) return true;
|
|
248
|
+
if (this[requestCache]) return this[requestCache].bodyUsed;
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
Object.defineProperty(requestPrototype, "signal", { get() {
|
|
253
|
+
return this[getAbortController]().signal;
|
|
254
|
+
} });
|
|
255
|
+
[
|
|
256
|
+
"cache",
|
|
257
|
+
"credentials",
|
|
258
|
+
"destination",
|
|
259
|
+
"integrity",
|
|
260
|
+
"mode",
|
|
261
|
+
"redirect",
|
|
262
|
+
"referrer",
|
|
263
|
+
"referrerPolicy",
|
|
264
|
+
"keepalive"
|
|
265
|
+
].forEach((k) => {
|
|
266
|
+
Object.defineProperty(requestPrototype, k, { get() {
|
|
267
|
+
return this[getRequestCache]()[k];
|
|
268
|
+
} });
|
|
269
|
+
});
|
|
270
|
+
["clone", "formData"].forEach((k) => {
|
|
271
|
+
Object.defineProperty(requestPrototype, k, { value: function() {
|
|
272
|
+
if (this[bodyConsumedDirectlyKey]) {
|
|
273
|
+
if (k === "clone") throw newBodyUnusableError();
|
|
274
|
+
return rejectBodyUnusable();
|
|
275
|
+
}
|
|
276
|
+
return this[getRequestCache]()[k]();
|
|
277
|
+
} });
|
|
278
|
+
});
|
|
279
|
+
Object.defineProperty(requestPrototype, "text", { value: function() {
|
|
280
|
+
return readBodyWithFastPath(this, "text", (buf) => textDecoder.decode(buf));
|
|
281
|
+
} });
|
|
282
|
+
Object.defineProperty(requestPrototype, "arrayBuffer", { value: function() {
|
|
283
|
+
return readBodyWithFastPath(this, "arrayBuffer", (buf) => toArrayBuffer(buf));
|
|
284
|
+
} });
|
|
285
|
+
Object.defineProperty(requestPrototype, "blob", { value: function() {
|
|
286
|
+
return readBodyWithFastPath(this, "blob", (buf, request) => {
|
|
287
|
+
const type = contentType(request);
|
|
288
|
+
return new Response(buf, type ? { headers: { "content-type": type } } : void 0).blob();
|
|
289
|
+
});
|
|
290
|
+
} });
|
|
291
|
+
Object.defineProperty(requestPrototype, "json", { value: function() {
|
|
292
|
+
if (this[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
|
|
293
|
+
return this.text().then(JSON.parse);
|
|
294
|
+
} });
|
|
295
|
+
Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
|
|
296
|
+
return `Request (lightweight) ${inspectFn({
|
|
297
|
+
method: this.method,
|
|
298
|
+
url: this.url,
|
|
299
|
+
headers: this.headers,
|
|
300
|
+
nativeRequest: this[requestCache]
|
|
301
|
+
}, {
|
|
302
|
+
...options,
|
|
303
|
+
depth: depth == null ? null : depth - 1
|
|
304
|
+
})}`;
|
|
305
|
+
} });
|
|
306
|
+
Object.setPrototypeOf(requestPrototype, Request$1.prototype);
|
|
307
|
+
const defaultContentType = "text/plain; charset=UTF-8";
|
|
308
|
+
const responseCache = Symbol("responseCache");
|
|
309
|
+
const getResponseCache = Symbol("getResponseCache");
|
|
310
|
+
const cacheKey = Symbol("cache");
|
|
311
|
+
const GlobalResponse = global.Response;
|
|
312
|
+
var Response$1 = class Response$1 {
|
|
313
|
+
#body;
|
|
314
|
+
#init;
|
|
315
|
+
[getResponseCache]() {
|
|
316
|
+
const cache = this[cacheKey];
|
|
317
|
+
const liveHeaders = cache && cache[2] instanceof Headers ? cache[2] : void 0;
|
|
318
|
+
delete this[cacheKey];
|
|
319
|
+
return this[responseCache] ||= new GlobalResponse(this.#body, liveHeaders ? {
|
|
320
|
+
status: this.#init?.status,
|
|
321
|
+
statusText: this.#init?.statusText,
|
|
322
|
+
headers: liveHeaders
|
|
323
|
+
} : this.#init);
|
|
324
|
+
}
|
|
325
|
+
constructor(body, init) {
|
|
326
|
+
let headers;
|
|
327
|
+
this.#body = body;
|
|
328
|
+
if (init instanceof Response$1) {
|
|
329
|
+
const cachedGlobalResponse = init[responseCache];
|
|
330
|
+
if (cachedGlobalResponse) {
|
|
331
|
+
this.#init = cachedGlobalResponse;
|
|
332
|
+
this[getResponseCache]();
|
|
333
|
+
return;
|
|
334
|
+
} else {
|
|
335
|
+
this.#init = init.#init;
|
|
336
|
+
headers = new Headers(init.headers);
|
|
337
|
+
}
|
|
338
|
+
} else this.#init = init;
|
|
339
|
+
if (body == null || typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) this[cacheKey] = [
|
|
340
|
+
init?.status || 200,
|
|
341
|
+
body ?? null,
|
|
342
|
+
headers || init?.headers
|
|
343
|
+
];
|
|
344
|
+
}
|
|
345
|
+
get headers() {
|
|
346
|
+
const cache = this[cacheKey];
|
|
347
|
+
if (cache) {
|
|
348
|
+
if (!(cache[2] instanceof Headers)) cache[2] = new Headers(cache[2] || (cache[1] === null ? void 0 : { "content-type": defaultContentType }));
|
|
349
|
+
return cache[2];
|
|
350
|
+
}
|
|
351
|
+
return this[getResponseCache]().headers;
|
|
352
|
+
}
|
|
353
|
+
get status() {
|
|
354
|
+
return this[cacheKey]?.[0] ?? this[getResponseCache]().status;
|
|
355
|
+
}
|
|
356
|
+
get ok() {
|
|
357
|
+
const status = this.status;
|
|
358
|
+
return status >= 200 && status < 300;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
[
|
|
362
|
+
"body",
|
|
363
|
+
"bodyUsed",
|
|
364
|
+
"redirected",
|
|
365
|
+
"statusText",
|
|
366
|
+
"trailers",
|
|
367
|
+
"type",
|
|
368
|
+
"url"
|
|
369
|
+
].forEach((k) => {
|
|
370
|
+
Object.defineProperty(Response$1.prototype, k, { get() {
|
|
371
|
+
return this[getResponseCache]()[k];
|
|
372
|
+
} });
|
|
373
|
+
});
|
|
374
|
+
[
|
|
375
|
+
"arrayBuffer",
|
|
376
|
+
"blob",
|
|
377
|
+
"clone",
|
|
378
|
+
"formData",
|
|
379
|
+
"json",
|
|
380
|
+
"text"
|
|
381
|
+
].forEach((k) => {
|
|
382
|
+
Object.defineProperty(Response$1.prototype, k, { value: function() {
|
|
383
|
+
return this[getResponseCache]()[k]();
|
|
384
|
+
} });
|
|
385
|
+
});
|
|
386
|
+
Object.defineProperty(Response$1.prototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
|
|
387
|
+
return `Response (lightweight) ${inspectFn({
|
|
388
|
+
status: this.status,
|
|
389
|
+
headers: this.headers,
|
|
390
|
+
ok: this.ok,
|
|
391
|
+
nativeResponse: this[responseCache]
|
|
392
|
+
}, {
|
|
393
|
+
...options,
|
|
394
|
+
depth: depth == null ? null : depth - 1
|
|
395
|
+
})}`;
|
|
396
|
+
} });
|
|
397
|
+
Object.setPrototypeOf(Response$1, GlobalResponse);
|
|
398
|
+
Object.setPrototypeOf(Response$1.prototype, GlobalResponse.prototype);
|
|
399
|
+
const validRedirectUrl = /^https?:\/\/[!#-;=?-[\]_a-z~A-Z]+$/;
|
|
400
|
+
const parseRedirectUrl = (url) => {
|
|
401
|
+
if (url instanceof URL) return url.href;
|
|
402
|
+
if (validRedirectUrl.test(url)) return url;
|
|
403
|
+
return new URL(url).href;
|
|
404
|
+
};
|
|
405
|
+
const validRedirectStatuses = /* @__PURE__ */ new Set([
|
|
406
|
+
301,
|
|
407
|
+
302,
|
|
408
|
+
303,
|
|
409
|
+
307,
|
|
410
|
+
308
|
|
411
|
+
]);
|
|
412
|
+
Object.defineProperty(Response$1, "redirect", {
|
|
413
|
+
value: function redirect(url, status = 302) {
|
|
414
|
+
if (!validRedirectStatuses.has(status)) throw new RangeError("Invalid status code");
|
|
415
|
+
return new Response$1(null, {
|
|
416
|
+
status,
|
|
417
|
+
headers: { location: parseRedirectUrl(url) }
|
|
418
|
+
});
|
|
419
|
+
},
|
|
420
|
+
writable: true,
|
|
421
|
+
configurable: true
|
|
422
|
+
});
|
|
423
|
+
Object.defineProperty(Response$1, "json", {
|
|
424
|
+
value: function json(data, init) {
|
|
425
|
+
const body = JSON.stringify(data);
|
|
426
|
+
if (body === void 0) throw new TypeError("The data is not JSON serializable");
|
|
427
|
+
const initHeaders = init?.headers;
|
|
428
|
+
let headers;
|
|
429
|
+
if (initHeaders) {
|
|
430
|
+
headers = new Headers(initHeaders);
|
|
431
|
+
if (!headers.has("content-type")) headers.set("content-type", "application/json");
|
|
432
|
+
} else headers = { "content-type": "application/json" };
|
|
433
|
+
return new Response$1(body, {
|
|
434
|
+
status: init?.status ?? 200,
|
|
435
|
+
statusText: init?.statusText,
|
|
436
|
+
headers
|
|
437
|
+
});
|
|
438
|
+
},
|
|
439
|
+
writable: true,
|
|
440
|
+
configurable: true
|
|
441
|
+
});
|
|
442
|
+
globalThis.CloseEvent;
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region ../../packages/core/src/admin.ts
|
|
445
|
+
/**
|
|
446
|
+
* Read the consuming package's version from its package.json at runtime.
|
|
447
|
+
*
|
|
448
|
+
* Pass `import.meta.url` from the CONSUMER module. core is bundled into each consumer, so
|
|
449
|
+
* after the build this code runs from the consumer's `dist/` and package.json sits one
|
|
450
|
+
* level up (`../package.json`). Never throws — returns 'unknown' on any failure.
|
|
451
|
+
*/
|
|
452
|
+
function readPackageVersion(metaUrl) {
|
|
453
|
+
try {
|
|
454
|
+
return JSON.parse(readFileSync(new URL("../package.json", metaUrl), "utf8")).version ?? "unknown";
|
|
455
|
+
} catch {
|
|
456
|
+
return "unknown";
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region ../../packages/core/src/cli.ts
|
|
461
|
+
/** Climb to the root program so commands at any nesting depth can read root-level options (e.g. --url). */
|
|
462
|
+
function findRoot(cmd) {
|
|
463
|
+
let c = cmd;
|
|
464
|
+
while (c.parent) c = c.parent;
|
|
465
|
+
return c;
|
|
466
|
+
}
|
|
467
|
+
//#endregion
|
|
468
|
+
//#region ../../packages/core/src/completion.ts
|
|
469
|
+
const SHELLS = [
|
|
470
|
+
"bash",
|
|
471
|
+
"zsh",
|
|
472
|
+
"fish"
|
|
473
|
+
];
|
|
474
|
+
function firstLine(text) {
|
|
475
|
+
return (text.split("\n")[0] ?? "").trim();
|
|
476
|
+
}
|
|
477
|
+
function toNode(cmd, path) {
|
|
478
|
+
return {
|
|
479
|
+
name: cmd.name(),
|
|
480
|
+
aliases: [...cmd.aliases()],
|
|
481
|
+
description: firstLine(cmd.description()),
|
|
482
|
+
path,
|
|
483
|
+
options: cmd.options.filter((o) => !o.hidden).map((o) => ({
|
|
484
|
+
short: o.short,
|
|
485
|
+
long: o.long,
|
|
486
|
+
description: firstLine(o.description),
|
|
487
|
+
takesValue: o.required || o.optional,
|
|
488
|
+
choices: o.argChoices ? [...o.argChoices] : void 0
|
|
489
|
+
})),
|
|
490
|
+
args: cmd.registeredArguments.map((a) => ({
|
|
491
|
+
name: a.name(),
|
|
492
|
+
description: firstLine(a.description),
|
|
493
|
+
variadic: a.variadic,
|
|
494
|
+
choices: a.argChoices ? [...a.argChoices] : void 0
|
|
495
|
+
})),
|
|
496
|
+
children: cmd.commands.map((c) => toNode(c, [...path, c.name()]))
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
/** Flatten in registration order — the emitters iterate this, so output is deterministic. */
|
|
500
|
+
function walk(node) {
|
|
501
|
+
return [node, ...node.children.flatMap(walk)];
|
|
502
|
+
}
|
|
503
|
+
function namesOf(node) {
|
|
504
|
+
return [node.name, ...node.aliases];
|
|
505
|
+
}
|
|
506
|
+
function fishQuote(s) {
|
|
507
|
+
return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
508
|
+
}
|
|
509
|
+
function emitFish(bin, root) {
|
|
510
|
+
const lines = [
|
|
511
|
+
`# fish completion for ${bin}`,
|
|
512
|
+
`# Load with: ${bin} completion fish | source`,
|
|
513
|
+
`# Or install: ${bin} completion fish > ~/.config/fish/completions/${bin}.fish`
|
|
514
|
+
];
|
|
515
|
+
for (const node of walk(root)) {
|
|
516
|
+
const seen = node.path.map((p) => `__fish_seen_subcommand_from ${p}`);
|
|
517
|
+
const childNames = node.children.flatMap(namesOf);
|
|
518
|
+
const hereParts = [...seen];
|
|
519
|
+
if (childNames.length > 0) hereParts.push(`not __fish_seen_subcommand_from ${childNames.join(" ")}`);
|
|
520
|
+
const here = hereParts.length > 0 ? ` -n ${fishQuote(hereParts.join("; and "))}` : "";
|
|
521
|
+
for (const child of node.children) for (const name of namesOf(child)) lines.push(`complete -c ${bin}${here} -f -a ${name} -d ${fishQuote(child.description)}`);
|
|
522
|
+
for (const opt of node.options) {
|
|
523
|
+
let line = `complete -c ${bin}${here}`;
|
|
524
|
+
if (opt.short) line += ` -s ${opt.short.replace(/^-+/, "")}`;
|
|
525
|
+
if (opt.long) line += ` -l ${opt.long.replace(/^-+/, "")}`;
|
|
526
|
+
if (opt.takesValue) line += opt.choices ? ` -x -a ${fishQuote(opt.choices.join(" "))}` : " -r";
|
|
527
|
+
line += ` -d ${fishQuote(opt.description)}`;
|
|
528
|
+
lines.push(line);
|
|
529
|
+
}
|
|
530
|
+
const atArgs = seen.length > 0 ? ` -n ${fishQuote(seen.join("; and "))}` : "";
|
|
531
|
+
for (const arg of node.args) if (arg.choices) {
|
|
532
|
+
const desc = arg.description || arg.name;
|
|
533
|
+
lines.push(`complete -c ${bin}${atArgs} -f -a ${fishQuote(arg.choices.join(" "))} -d ${fishQuote(desc)}`);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return `${lines.join("\n")}\n`;
|
|
537
|
+
}
|
|
538
|
+
function sanitizeIdent(bin) {
|
|
539
|
+
return bin.replace(/[^A-Za-z0-9_]/g, "_");
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Case arms that descend the known subcommand tree token by token, normalising
|
|
543
|
+
* aliases to the canonical path so a single lookup table serves both spellings.
|
|
544
|
+
*/
|
|
545
|
+
function descentCases(root, indent) {
|
|
546
|
+
return walk(root).filter((node) => node.path.length > 0).map((node) => {
|
|
547
|
+
const parent = node.path.slice(0, -1).join(" ");
|
|
548
|
+
return `${indent}${namesOf(node).map((name) => `"${parent ? `${parent} ${name}` : name}"`).join("|")}) path="${node.path.join(" ")}" ;;`;
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
function emitBash(bin, root) {
|
|
552
|
+
const fn = `_${sanitizeIdent(bin)}_completions`;
|
|
553
|
+
const optCases = walk(root).map((node) => {
|
|
554
|
+
const subs = node.children.flatMap(namesOf).join(" ");
|
|
555
|
+
const flags = node.options.flatMap((o) => [o.short, o.long]).filter((f) => f !== void 0).join(" ");
|
|
556
|
+
const args = node.args.flatMap((a) => a.choices ?? []).join(" ");
|
|
557
|
+
return ` "${node.path.join(" ")}") subs="${subs}"; flags="${flags}"; args="${args}" ;;`;
|
|
558
|
+
});
|
|
559
|
+
return [
|
|
560
|
+
`# bash completion for ${bin}`,
|
|
561
|
+
`# Load with: source <(${bin} completion bash)`,
|
|
562
|
+
`${fn}() {`,
|
|
563
|
+
" local cur path try w i subs flags args",
|
|
564
|
+
" cur=\"${COMP_WORDS[COMP_CWORD]}\"",
|
|
565
|
+
" path=\"\"",
|
|
566
|
+
" for ((i = 1; i < COMP_CWORD; i++)); do",
|
|
567
|
+
" w=\"${COMP_WORDS[i]}\"",
|
|
568
|
+
" [[ \"$w\" == -* ]] && continue",
|
|
569
|
+
" try=\"${path:+$path }$w\"",
|
|
570
|
+
" case \"$try\" in",
|
|
571
|
+
...descentCases(root, " "),
|
|
572
|
+
" *) ;;",
|
|
573
|
+
" esac",
|
|
574
|
+
" done",
|
|
575
|
+
" subs=\"\"; flags=\"\"; args=\"\"",
|
|
576
|
+
" case \"$path\" in",
|
|
577
|
+
...optCases,
|
|
578
|
+
" esac",
|
|
579
|
+
" if [[ \"$cur\" == -* ]]; then",
|
|
580
|
+
" COMPREPLY=($(compgen -W \"$flags\" -- \"$cur\"))",
|
|
581
|
+
" elif [[ -n \"$subs\" ]]; then",
|
|
582
|
+
" COMPREPLY=($(compgen -W \"$subs\" -- \"$cur\"))",
|
|
583
|
+
" elif [[ -n \"$args\" ]]; then",
|
|
584
|
+
" COMPREPLY=($(compgen -W \"$args\" -- \"$cur\"))",
|
|
585
|
+
" else",
|
|
586
|
+
" COMPREPLY=($(compgen -f -- \"$cur\"))",
|
|
587
|
+
" fi",
|
|
588
|
+
"}",
|
|
589
|
+
`complete -F ${fn} ${bin}`,
|
|
590
|
+
""
|
|
591
|
+
].join("\n");
|
|
592
|
+
}
|
|
593
|
+
function zshItem(name, description) {
|
|
594
|
+
return `'${`${name}:${description}`.replace(/'/g, `'\\''`)}'`;
|
|
595
|
+
}
|
|
596
|
+
function emitZsh(bin, root) {
|
|
597
|
+
const fn = `_${sanitizeIdent(bin)}`;
|
|
598
|
+
const optCases = walk(root).map((node) => {
|
|
599
|
+
const subs = node.children.flatMap((child) => namesOf(child).map((name) => zshItem(name, child.description))).join(" ");
|
|
600
|
+
const flags = node.options.flatMap((o) => [o.short, o.long].filter((f) => f !== void 0).map((f) => zshItem(f, o.description))).join(" ");
|
|
601
|
+
const args = node.args.flatMap((a) => (a.choices ?? []).map((c) => zshItem(c, a.description || a.name))).join(" ");
|
|
602
|
+
const body = [
|
|
603
|
+
subs ? `subs=(${subs})` : void 0,
|
|
604
|
+
flags ? `flags=(${flags})` : void 0,
|
|
605
|
+
args ? `argwords=(${args})` : void 0
|
|
606
|
+
].filter((p) => p !== void 0).join("; ");
|
|
607
|
+
return ` "${node.path.join(" ")}") ${body ? `${body} ` : ""};;`;
|
|
608
|
+
});
|
|
609
|
+
return [
|
|
610
|
+
`#compdef ${bin}`,
|
|
611
|
+
`# zsh completion for ${bin}`,
|
|
612
|
+
`# Install: ${bin} completion zsh > "\${fpath[1]}/_${bin}" (then restart zsh)`,
|
|
613
|
+
`${fn}() {`,
|
|
614
|
+
" local -a subs flags argwords",
|
|
615
|
+
" local path=\"\" try w",
|
|
616
|
+
" for w in \"${(@)words[2,CURRENT-1]}\"; do",
|
|
617
|
+
" [[ \"$w\" == -* ]] && continue",
|
|
618
|
+
" try=\"${path:+$path }$w\"",
|
|
619
|
+
" case \"$try\" in",
|
|
620
|
+
...descentCases(root, " "),
|
|
621
|
+
" *) ;;",
|
|
622
|
+
" esac",
|
|
623
|
+
" done",
|
|
624
|
+
" case \"$path\" in",
|
|
625
|
+
...optCases,
|
|
626
|
+
" esac",
|
|
627
|
+
" if [[ \"$PREFIX\" == -* ]]; then",
|
|
628
|
+
" (( ${#flags[@]} )) && _describe -t options 'option' flags",
|
|
629
|
+
" elif (( ${#subs[@]} )); then",
|
|
630
|
+
" _describe -t commands 'command' subs",
|
|
631
|
+
" elif (( ${#argwords[@]} )); then",
|
|
632
|
+
" _describe -t values 'value' argwords",
|
|
633
|
+
" else",
|
|
634
|
+
" _files",
|
|
635
|
+
" fi",
|
|
636
|
+
"}",
|
|
637
|
+
`if [[ "\${funcstack[1]}" == "${fn}" ]]; then`,
|
|
638
|
+
` ${fn} "$@"`,
|
|
639
|
+
"else",
|
|
640
|
+
` compdef ${fn} ${bin}`,
|
|
641
|
+
"fi",
|
|
642
|
+
""
|
|
643
|
+
].join("\n");
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Build a fully static, self-contained shell-completion script for `root`'s command
|
|
647
|
+
* tree (subcommands at any depth, aliases, flags, option/argument choices). Pure:
|
|
648
|
+
* output depends only on the tree, iterated in registration order.
|
|
649
|
+
*/
|
|
650
|
+
function buildCompletionScript(root, shell) {
|
|
651
|
+
const bin = root.name();
|
|
652
|
+
const tree = toNode(root, []);
|
|
653
|
+
switch (shell) {
|
|
654
|
+
case "fish": return emitFish(bin, tree);
|
|
655
|
+
case "bash": return emitBash(bin, tree);
|
|
656
|
+
case "zsh": return emitZsh(bin, tree);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Build a `completion <shell>` subcommand that prints the static completion script
|
|
661
|
+
* for the ROOT program (resolved by walking `.parent`) to stdout.
|
|
662
|
+
*/
|
|
663
|
+
function createCompletionCommand() {
|
|
664
|
+
return new Command("completion").description("Print a static shell-completion script for bash, zsh or fish. Load it in your shell, e.g. fish: `sm-cl completion fish | source`").addArgument(new Argument("<shell>", "target shell").choices(SHELLS)).action((shell, _opts, cmd) => {
|
|
665
|
+
process.stdout.write(buildCompletionScript(findRoot(cmd), shell));
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region src/cli/program.ts
|
|
670
|
+
const CHAIN_CHOICES = Object.keys(CHAINS);
|
|
671
|
+
const WC_TYPE_CHOICES = ["0x01", "0x02"];
|
|
672
|
+
/** Serialize bigint values to decimal strings; all other values pass through. */
|
|
673
|
+
const bigintReplacer = (_k, v) => typeof v === "bigint" ? v.toString() : v;
|
|
674
|
+
/** Run an async action; print thrown errors to stderr and exit 1. */
|
|
675
|
+
function run(fn) {
|
|
676
|
+
fn().catch((err) => {
|
|
677
|
+
console.error("Error:", err instanceof Error ? err.message : String(err));
|
|
678
|
+
process.exit(1);
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
function buildProgram(deps = { makeDepositKeys }) {
|
|
682
|
+
return new Command().name("sm-keys").description("Generate real BLS validator deposit data for Lido SM (mainnet/hoodi); human mode: deposit_data.json to stdout (or --out), mnemonic to stderr").version(readPackageVersion(import.meta.url)).addOption(new Option("--chain <name>", "target chain").choices(CHAIN_CHOICES).default("hoodi")).option("--count <n>", "number of validators", "1").addOption(new Option("--type <wc>", "withdrawal credentials type").choices(WC_TYPE_CHOICES).default("0x01")).option("--mnemonic <phrase>", "BIP-39 mnemonic (random if omitted)").option("--wc <address>", "override withdrawal address (default: Lido vault)").option("--start-index <n>", "first validator index", "0").option("-o, --out <path>", "write deposit_data.json to <path> (else stdout)").option("--json", "emit result as JSON to stdout (mnemonic + keys with 0x-prefixed hex)").addHelpText("after", `
|
|
683
|
+
Examples:
|
|
684
|
+
sm-keys 2 --json
|
|
685
|
+
sm-keys --count 5 --chain mainnet --json
|
|
686
|
+
sm-keys --json --out deposit_data.json`).argument("[count]", "number of validators (positional alias for --count)").helpCommand(true).addCommand(createCompletionCommand()).action((countArg, opts) => {
|
|
687
|
+
run(async () => {
|
|
688
|
+
const result = await deps.makeDepositKeys({
|
|
689
|
+
chain: opts.chain,
|
|
690
|
+
count: Number(countArg ?? opts.count),
|
|
691
|
+
type: opts.type,
|
|
692
|
+
mnemonic: opts.mnemonic,
|
|
693
|
+
withdrawalAddress: opts.wc,
|
|
694
|
+
startIndex: Number(opts.startIndex)
|
|
695
|
+
});
|
|
696
|
+
const { mnemonic, keys } = result;
|
|
697
|
+
if (opts.json) {
|
|
698
|
+
console.log(JSON.stringify(result, bigintReplacer, 2));
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
console.error(`mnemonic: ${mnemonic}`);
|
|
702
|
+
if (opts.out) {
|
|
703
|
+
writeDepositDataFile(opts.out, keys);
|
|
704
|
+
console.error(`wrote ${keys.length} key(s) to ${opts.out}`);
|
|
705
|
+
} else console.log(toDepositDataJson(keys));
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
//#endregion
|
|
710
|
+
//#region src/cli/index.ts
|
|
711
|
+
buildProgram().parseAsync().catch((err) => {
|
|
712
|
+
console.error("Error:", err instanceof Error ? err.message : String(err));
|
|
713
|
+
process.exit(1);
|
|
714
|
+
});
|
|
715
|
+
//#endregion
|
|
716
|
+
export {};
|
|
717
|
+
|
|
718
|
+
//# sourceMappingURL=cli.mjs.map
|