@nekzus/liop 2.4.0-alpha.25 → 2.4.0-alpha.26
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/bin/agent.js +27 -933
- package/dist/bridge.js +1 -5
- package/dist/chunk-2XHSALII.js +3 -0
- package/dist/chunk-2ZYX736J.js +2 -0
- package/dist/chunk-3WRKTVOF.js +2 -0
- package/dist/chunk-6KFKO6ZX.js +2 -0
- package/dist/chunk-6VK2XALI.js +2 -0
- package/dist/chunk-AYDF3IFZ.js +2 -0
- package/dist/chunk-CTTTLCGL.js +31 -0
- package/dist/chunk-ECRS6N33.js +4 -0
- package/dist/chunk-FDJMH4CB.js +2 -0
- package/dist/chunk-FTF6AMF6.js +0 -1
- package/dist/chunk-GWVSCZUS.js +2 -0
- package/dist/chunk-LEXMMIQI.js +15 -0
- package/dist/chunk-LM26HOJ6.js +31 -0
- package/dist/chunk-MQ5SU26J.js +2 -0
- package/dist/chunk-N35BC62H.js +2 -0
- package/dist/chunk-P6IJ3VBD.js +3 -0
- package/dist/chunk-TKLRW52V.js +2 -0
- package/dist/chunk-V35CXJQN.js +2 -0
- package/dist/chunk-WP5ER7RH.js +3 -0
- package/dist/chunk-XLVEDKM6.js +2 -0
- package/dist/chunk-Y675R34Z.js +2 -0
- package/dist/chunk-YD2AF2M6.js +46 -0
- package/dist/chunk-YLCNV764.js +3 -0
- package/dist/chunk-ZZMSFCJP.js +3 -0
- package/dist/client.js +1 -12
- package/dist/gateway.js +1 -13
- package/dist/index.js +4 -320
- package/dist/kyber-PULV7PQX.js +2 -0
- package/dist/mesh.js +1 -5
- package/dist/server.js +1 -10
- package/dist/types.js +1 -3
- package/dist/verifier-J4NQYZX5.js +2 -0
- package/dist/workers/logic-execution.js +1 -355
- package/dist/workers/zk-verifier.js +1 -275
- package/package.json +1 -1
- package/dist/chunk-3664H3CV.js +0 -136
- package/dist/chunk-3QH44NKZ.js +0 -115
- package/dist/chunk-6MYJBM2E.js +0 -818
- package/dist/chunk-7PITYWOV.js +0 -68
- package/dist/chunk-DSOB2JKM.js +0 -1507
- package/dist/chunk-ET6VRUK2.js +0 -58
- package/dist/chunk-FIVRGOA4.js +0 -280
- package/dist/chunk-IHKKWXHJ.js +0 -876
- package/dist/chunk-IK7CGWAZ.js +0 -24
- package/dist/chunk-JPWC6XG6.js +0 -941
- package/dist/chunk-K3DGJLUY.js +0 -106
- package/dist/chunk-KR5UZUEY.js +0 -98
- package/dist/chunk-NXCAFF73.js +0 -59
- package/dist/chunk-Q3FKHJ3B.js +0 -345
- package/dist/chunk-R52TZEIL.js +0 -426
- package/dist/chunk-S3RAZTEM.js +0 -807
- package/dist/chunk-V47P2AQR.js +0 -281
- package/dist/chunk-WXOWJXY6.js +0 -564
- package/dist/chunk-WXYDFCIW.js +0 -293
- package/dist/chunk-Y62GORQF.js +0 -51
- package/dist/chunk-ZP3VVXOI.js +0 -66
- package/dist/chunk-ZU3WVVLC.js +0 -3752
- package/dist/kyber-CGOA7Q6A.js +0 -3
- package/dist/verifier-55HW6AFN.js +0 -6
package/dist/chunk-WXYDFCIW.js
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import { deriveLogicImageDigest } from './chunk-IK7CGWAZ.js';
|
|
2
|
-
import { zkVkeyCacheSize, zkVerificationDurationMs, zkProofsByTypeTotal } from './chunk-Q3FKHJ3B.js';
|
|
3
|
-
import { log } from './chunk-K3DGJLUY.js';
|
|
4
|
-
import crypto from 'crypto';
|
|
5
|
-
import * as fs from 'fs';
|
|
6
|
-
import { createRequire } from 'module';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import { fileURLToPath, pathToFileURL } from 'url';
|
|
9
|
-
import { Piscina } from 'piscina';
|
|
10
|
-
|
|
11
|
-
var __filename$1 = fileURLToPath(import.meta.url);
|
|
12
|
-
var __dirname$1 = path.dirname(__filename$1);
|
|
13
|
-
var LiopVerifier = class _LiopVerifier {
|
|
14
|
-
// Singleton Worker Pool for heavy ZK verification
|
|
15
|
-
static zkWorkerPool = null;
|
|
16
|
-
// Static registry of embedded verification keys for canonical circuits
|
|
17
|
-
static vkeyRegistry = /* @__PURE__ */ new Map();
|
|
18
|
-
/**
|
|
19
|
-
* Registers a verification key for a canonical analytical circuit.
|
|
20
|
-
*/
|
|
21
|
-
static registerVKey(circuitName, vkeyRaw) {
|
|
22
|
-
_LiopVerifier.vkeyRegistry.set(circuitName, vkeyRaw);
|
|
23
|
-
try {
|
|
24
|
-
zkVkeyCacheSize.set(_LiopVerifier.vkeyRegistry.size);
|
|
25
|
-
} catch {
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Retrieves a registered verification key by circuit name.
|
|
30
|
-
*/
|
|
31
|
-
static getRegisteredVKey(circuitName) {
|
|
32
|
-
return _LiopVerifier.vkeyRegistry.get(circuitName);
|
|
33
|
-
}
|
|
34
|
-
getZkPool() {
|
|
35
|
-
if (!_LiopVerifier.zkWorkerPool) {
|
|
36
|
-
const isTS = import.meta.url.endsWith(".ts");
|
|
37
|
-
const workerExt = isTS ? ".ts" : ".js";
|
|
38
|
-
let execArgv = [];
|
|
39
|
-
if (isTS) {
|
|
40
|
-
try {
|
|
41
|
-
const req = createRequire(import.meta.url);
|
|
42
|
-
const tsxPkg = req.resolve("tsx/package.json");
|
|
43
|
-
const absoluteTsx = pathToFileURL(
|
|
44
|
-
path.join(path.dirname(tsxPkg), "dist", "loader.mjs")
|
|
45
|
-
).href;
|
|
46
|
-
execArgv = ["--import", absoluteTsx];
|
|
47
|
-
} catch (_e) {
|
|
48
|
-
execArgv = ["--import", "tsx"];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const workerPaths = [
|
|
52
|
-
path.resolve(__dirname$1, `./workers/zk-verifier${workerExt}`),
|
|
53
|
-
// Flat dist/ (tsup)
|
|
54
|
-
path.resolve(__dirname$1, `../workers/zk-verifier${workerExt}`)
|
|
55
|
-
// Original src/
|
|
56
|
-
];
|
|
57
|
-
const workerFilename = workerPaths.find((p) => fs.existsSync(p)) || workerPaths[1];
|
|
58
|
-
_LiopVerifier.zkWorkerPool = new Piscina({
|
|
59
|
-
filename: workerFilename,
|
|
60
|
-
minThreads: 1,
|
|
61
|
-
maxThreads: 2,
|
|
62
|
-
// Minimal footprint since verification is fast compared to generation
|
|
63
|
-
idleTimeout: 3e4,
|
|
64
|
-
execArgv
|
|
65
|
-
});
|
|
66
|
-
_LiopVerifier.zkWorkerPool.run({ action: "warmup" }).catch((err) => {
|
|
67
|
-
log.debug(
|
|
68
|
-
`[LiopVerifier] Verification pool warm-up ping failed: ${err.message}`
|
|
69
|
-
);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
return _LiopVerifier.zkWorkerPool;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Verifies a Zero-Knowledge Receipt from a remote LIOP node via Worker Pool.
|
|
76
|
-
* Supports both legacy positional arguments and structured options.
|
|
77
|
-
*
|
|
78
|
-
* @param logicPayload The raw WASM or JS logic that was sent to the provider.
|
|
79
|
-
* @param remoteImageIdHex The ImageID reported by the provider (must match our local calculation).
|
|
80
|
-
* @param zkReceipt The mathematical proof (Seal + Journal) from the zkVM or Groth16.
|
|
81
|
-
* @param sessionSecretOrOptions Shared secret (Buffer) or structured VerifyZkOptions.
|
|
82
|
-
* @param expectedOutput Optional expected output value for anti-replay verification.
|
|
83
|
-
*/
|
|
84
|
-
async verifyZkReceipt(logicPayload, remoteImageIdHex, zkReceipt, sessionSecretOrOptions, expectedOutput) {
|
|
85
|
-
const pool = this.getZkPool();
|
|
86
|
-
if (!pool) throw new Error("Worker pool initialization failed");
|
|
87
|
-
let sessionSecret;
|
|
88
|
-
let actualExpectedOutput = expectedOutput;
|
|
89
|
-
let guestImageIdHex;
|
|
90
|
-
let vkeyRaw;
|
|
91
|
-
let zkPolicy;
|
|
92
|
-
if (Buffer.isBuffer(sessionSecretOrOptions)) {
|
|
93
|
-
sessionSecret = sessionSecretOrOptions;
|
|
94
|
-
} else if (sessionSecretOrOptions && typeof sessionSecretOrOptions === "object") {
|
|
95
|
-
sessionSecret = sessionSecretOrOptions.sessionSecret;
|
|
96
|
-
if (sessionSecretOrOptions.expectedOutput !== void 0) {
|
|
97
|
-
actualExpectedOutput = sessionSecretOrOptions.expectedOutput;
|
|
98
|
-
}
|
|
99
|
-
guestImageIdHex = sessionSecretOrOptions.guestImageIdHex;
|
|
100
|
-
vkeyRaw = sessionSecretOrOptions.vkeyRaw;
|
|
101
|
-
zkPolicy = sessionSecretOrOptions.zkPolicy;
|
|
102
|
-
if (!vkeyRaw && sessionSecretOrOptions.circuitName) {
|
|
103
|
-
vkeyRaw = _LiopVerifier.getRegisteredVKey(
|
|
104
|
-
sessionSecretOrOptions.circuitName
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
const startTime = performance.now();
|
|
109
|
-
const result = await pool.run({
|
|
110
|
-
action: "verify_receipt",
|
|
111
|
-
logicPayload: new Uint8Array(logicPayload),
|
|
112
|
-
remoteImageIdHex,
|
|
113
|
-
guestImageIdHex,
|
|
114
|
-
zkReceipt: new Uint8Array(zkReceipt),
|
|
115
|
-
sessionSecret: sessionSecret ? new Uint8Array(sessionSecret) : void 0,
|
|
116
|
-
vkeyRaw: vkeyRaw ? new Uint8Array(vkeyRaw) : void 0,
|
|
117
|
-
expectedOutput: actualExpectedOutput,
|
|
118
|
-
zkPolicy
|
|
119
|
-
});
|
|
120
|
-
const durationMs = performance.now() - startTime;
|
|
121
|
-
try {
|
|
122
|
-
zkVerificationDurationMs.observe(
|
|
123
|
-
{
|
|
124
|
-
status: result.verified ? "verified" : "failed",
|
|
125
|
-
proof_type: result.proofType || "unknown"
|
|
126
|
-
},
|
|
127
|
-
durationMs
|
|
128
|
-
);
|
|
129
|
-
if (result.verified && result.proofType) {
|
|
130
|
-
zkProofsByTypeTotal.inc({ proof_type: result.proofType });
|
|
131
|
-
}
|
|
132
|
-
} catch {
|
|
133
|
-
}
|
|
134
|
-
if (result.verified) {
|
|
135
|
-
log.info(`[LiopVerifier] ${result.message}`);
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
log.error(`[LiopVerifier] FAILED: ${result.message}`);
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Detailed hardware attestation verification supporting AMD SEV-SNP, AWS Nitro Enclaves,
|
|
143
|
-
* and synthetic mesh verification.
|
|
144
|
-
*/
|
|
145
|
-
async verifyTeeAttestationDetailed(attestationReport, options = {}) {
|
|
146
|
-
const policy = options.policy ?? "preferred";
|
|
147
|
-
if (policy === "none") {
|
|
148
|
-
return {
|
|
149
|
-
verified: true,
|
|
150
|
-
platform: "none",
|
|
151
|
-
message: "TEE Attestation bypassed: Policy set to 'none'."
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
if (!attestationReport || attestationReport.length === 0) {
|
|
155
|
-
if (policy === "required") {
|
|
156
|
-
return {
|
|
157
|
-
verified: false,
|
|
158
|
-
platform: "none",
|
|
159
|
-
message: "TEE Policy Violation: Hardware TEE attestation required, but no attestation report was provided."
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return {
|
|
163
|
-
verified: true,
|
|
164
|
-
platform: "none",
|
|
165
|
-
message: "TEE Attestation skipped: Empty report allowed under non-strict policy."
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
let expectedBindingDigest = null;
|
|
169
|
-
if (options.expectedPublicKey || options.expectedNonce) {
|
|
170
|
-
const parts = [];
|
|
171
|
-
if (options.expectedPublicKey)
|
|
172
|
-
parts.push(Buffer.from(options.expectedPublicKey));
|
|
173
|
-
if (options.expectedNonce) parts.push(Buffer.from(options.expectedNonce));
|
|
174
|
-
expectedBindingDigest = crypto.createHash("sha256").update(Buffer.concat(parts)).digest();
|
|
175
|
-
}
|
|
176
|
-
if (attestationReport.length >= 4 && attestationReport[0] === 84 && attestationReport[1] === 69 && attestationReport[2] === 69 && attestationReport[3] === 83) {
|
|
177
|
-
if (policy === "required" && !options.allowSynthetic) {
|
|
178
|
-
return {
|
|
179
|
-
verified: false,
|
|
180
|
-
platform: "synthetic",
|
|
181
|
-
message: "TEE Policy Violation: Hardware TEE attestation required, but received synthetic mesh report."
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
return {
|
|
185
|
-
verified: true,
|
|
186
|
-
platform: "synthetic",
|
|
187
|
-
message: "Synthetic TEE Attestation Verified (Mesh PSK mode)."
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
if (attestationReport.length >= 672) {
|
|
191
|
-
const reportData = attestationReport.subarray(80, 80 + 64);
|
|
192
|
-
const measurement = attestationReport.subarray(144, 144 + 48);
|
|
193
|
-
const chipId = attestationReport.length >= 480 ? attestationReport.subarray(416, 416 + 64) : void 0;
|
|
194
|
-
if (expectedBindingDigest) {
|
|
195
|
-
const reportBinding = reportData.subarray(
|
|
196
|
-
0,
|
|
197
|
-
expectedBindingDigest.length
|
|
198
|
-
);
|
|
199
|
-
if (!crypto.timingSafeEqual(reportBinding, expectedBindingDigest)) {
|
|
200
|
-
return {
|
|
201
|
-
verified: false,
|
|
202
|
-
platform: "amd-sev-snp",
|
|
203
|
-
message: "AMD SEV-SNP Attestation Failed: REPORT_DATA binding mismatch (public key / nonce forged or altered).",
|
|
204
|
-
measurements: {
|
|
205
|
-
reportDataHex: reportData.toString("hex"),
|
|
206
|
-
measurementHex: measurement.toString("hex"),
|
|
207
|
-
chipIdHex: chipId?.toString("hex")
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return {
|
|
213
|
-
verified: true,
|
|
214
|
-
platform: "amd-sev-snp",
|
|
215
|
-
message: "AMD SEV-SNP Hardware TEE Attestation Certified: Cryptographic measurement & REPORT_DATA verified.",
|
|
216
|
-
measurements: {
|
|
217
|
-
reportDataHex: reportData.toString("hex"),
|
|
218
|
-
measurementHex: measurement.toString("hex"),
|
|
219
|
-
chipIdHex: chipId?.toString("hex")
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
const isNitroCose = attestationReport.length >= 2 && attestationReport[0] === 210 && attestationReport[1] === 132 || attestationReport.includes(Buffer.from("pcrs"));
|
|
224
|
-
if (isNitroCose) {
|
|
225
|
-
if (options.expectedPcrs) {
|
|
226
|
-
for (const [pcrIdx, expectedHex] of Object.entries(
|
|
227
|
-
options.expectedPcrs
|
|
228
|
-
)) {
|
|
229
|
-
const pcrMarker = Buffer.from(expectedHex, "hex");
|
|
230
|
-
if (pcrMarker.length > 0 && !attestationReport.includes(pcrMarker)) {
|
|
231
|
-
return {
|
|
232
|
-
verified: false,
|
|
233
|
-
platform: "aws-nitro",
|
|
234
|
-
message: `AWS Nitro Attestation Failed: PCR${pcrIdx} measurement mismatch.`
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (expectedBindingDigest && !attestationReport.includes(expectedBindingDigest)) {
|
|
240
|
-
return {
|
|
241
|
-
verified: false,
|
|
242
|
-
platform: "aws-nitro",
|
|
243
|
-
message: "AWS Nitro Attestation Failed: user_data binding mismatch (public key / nonce forged or altered)."
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
return {
|
|
247
|
-
verified: true,
|
|
248
|
-
platform: "aws-nitro",
|
|
249
|
-
message: "AWS Nitro Enclave Hardware TEE Attestation Certified: PCR measurements & user_data verified."
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
if (policy === "required") {
|
|
253
|
-
return {
|
|
254
|
-
verified: false,
|
|
255
|
-
platform: "none",
|
|
256
|
-
message: `TEE Verification Failed: Unrecognized hardware attestation report format (${attestationReport.length} bytes).`
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
return {
|
|
260
|
-
verified: true,
|
|
261
|
-
platform: "none",
|
|
262
|
-
message: "Non-critical TEE report accepted under relaxed policy."
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Verifies if a node is running inside an authenticated TEE (e.g. AMD SEV-SNP or AWS Nitro).
|
|
267
|
-
*
|
|
268
|
-
* @param attestationReport The attestation document from the hardware.
|
|
269
|
-
* @param options Verification policy and binding options.
|
|
270
|
-
*/
|
|
271
|
-
async verifyTeeAttestation(attestationReport, options = {}) {
|
|
272
|
-
const result = await this.verifyTeeAttestationDetailed(
|
|
273
|
-
attestationReport,
|
|
274
|
-
options
|
|
275
|
-
);
|
|
276
|
-
if (result.verified) {
|
|
277
|
-
log.info(`[LiopVerifier] ${result.message}`);
|
|
278
|
-
return true;
|
|
279
|
-
}
|
|
280
|
-
log.error(`[LiopVerifier] TEE FAILED: ${result.message}`);
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Derives the ImageID of a logic payload following the LIOP v1 Standard.
|
|
285
|
-
*/
|
|
286
|
-
deriveImageId(logicPayload) {
|
|
287
|
-
return deriveLogicImageDigest(logicPayload);
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
export { LiopVerifier };
|
|
292
|
-
//# sourceMappingURL=chunk-WXYDFCIW.js.map
|
|
293
|
-
//# sourceMappingURL=chunk-WXYDFCIW.js.map
|
package/dist/chunk-Y62GORQF.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// src/server/output-sanitizer.ts
|
|
2
|
-
var DEFAULT_CONFIG = {
|
|
3
|
-
maxDecimalPlaces: 4,
|
|
4
|
-
clampNonNegative: true
|
|
5
|
-
};
|
|
6
|
-
function sanitizeOutput(output, config) {
|
|
7
|
-
const merged = { ...DEFAULT_CONFIG, ...config };
|
|
8
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
9
|
-
function walk(node) {
|
|
10
|
-
if (node === null || node === void 0) {
|
|
11
|
-
return node;
|
|
12
|
-
}
|
|
13
|
-
if (typeof node === "number") {
|
|
14
|
-
if (!Number.isFinite(node)) {
|
|
15
|
-
return node;
|
|
16
|
-
}
|
|
17
|
-
let value = node;
|
|
18
|
-
if (merged.clampNonNegative && value < 0) {
|
|
19
|
-
value = 0;
|
|
20
|
-
}
|
|
21
|
-
const factor = 10 ** merged.maxDecimalPlaces;
|
|
22
|
-
value = Math.round(value * factor) / factor;
|
|
23
|
-
return value;
|
|
24
|
-
}
|
|
25
|
-
if (typeof node === "string" || typeof node === "boolean") {
|
|
26
|
-
return node;
|
|
27
|
-
}
|
|
28
|
-
if (typeof node === "object") {
|
|
29
|
-
if (seen.has(node)) {
|
|
30
|
-
return node;
|
|
31
|
-
}
|
|
32
|
-
seen.add(node);
|
|
33
|
-
if (Array.isArray(node)) {
|
|
34
|
-
return node.map((item) => walk(item));
|
|
35
|
-
}
|
|
36
|
-
const result = {};
|
|
37
|
-
for (const [key, val] of Object.entries(
|
|
38
|
-
node
|
|
39
|
-
)) {
|
|
40
|
-
result[key] = walk(val);
|
|
41
|
-
}
|
|
42
|
-
return result;
|
|
43
|
-
}
|
|
44
|
-
return node;
|
|
45
|
-
}
|
|
46
|
-
return walk(output);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export { sanitizeOutput };
|
|
50
|
-
//# sourceMappingURL=chunk-Y62GORQF.js.map
|
|
51
|
-
//# sourceMappingURL=chunk-Y62GORQF.js.map
|
package/dist/chunk-ZP3VVXOI.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
|
-
import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
3
|
-
import { dirname } from 'path';
|
|
4
|
-
import { generateKey } from '@libp2p/pnet';
|
|
5
|
-
|
|
6
|
-
// src/mesh/swarm-key.ts
|
|
7
|
-
var SWARM_KEY_BYTE_LENGTH = 95;
|
|
8
|
-
function createSwarmKey() {
|
|
9
|
-
const psk = new Uint8Array(SWARM_KEY_BYTE_LENGTH);
|
|
10
|
-
generateKey(psk);
|
|
11
|
-
return psk;
|
|
12
|
-
}
|
|
13
|
-
function serializeSwarmKey(psk) {
|
|
14
|
-
if (psk.length !== SWARM_KEY_BYTE_LENGTH) {
|
|
15
|
-
throw new Error(
|
|
16
|
-
`Invalid Swarm Key length: expected ${SWARM_KEY_BYTE_LENGTH} bytes, got ${psk.length}`
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
return Buffer.from(psk).toString("base64");
|
|
20
|
-
}
|
|
21
|
-
function deserializeSwarmKey(base64Str) {
|
|
22
|
-
const trimmed = base64Str.trim();
|
|
23
|
-
const buf = Buffer.from(trimmed, "base64");
|
|
24
|
-
if (buf.length !== SWARM_KEY_BYTE_LENGTH) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`Invalid deserialized Swarm Key: expected ${SWARM_KEY_BYTE_LENGTH} bytes, got ${buf.length}`
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
30
|
-
}
|
|
31
|
-
function parseSwarmKey(rawText) {
|
|
32
|
-
const trimmed = rawText.trim();
|
|
33
|
-
if (trimmed.startsWith("/key/swarm/psk/")) {
|
|
34
|
-
const normalized = trimmed.replace(/\r\n/g, "\n").trimEnd();
|
|
35
|
-
const bytes = new TextEncoder().encode(normalized);
|
|
36
|
-
if (bytes.length === SWARM_KEY_BYTE_LENGTH) {
|
|
37
|
-
return bytes;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return deserializeSwarmKey(trimmed);
|
|
41
|
-
}
|
|
42
|
-
async function saveSwarmKey(psk, filePath) {
|
|
43
|
-
if (psk.length !== SWARM_KEY_BYTE_LENGTH) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
`Cannot save invalid Swarm Key: expected ${SWARM_KEY_BYTE_LENGTH} bytes, got ${psk.length}`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
await mkdir(dirname(filePath), { recursive: true });
|
|
49
|
-
await writeFile(filePath, psk);
|
|
50
|
-
}
|
|
51
|
-
async function loadSwarmKey(filePath) {
|
|
52
|
-
const fileBuffer = await readFile(filePath);
|
|
53
|
-
if (fileBuffer.length === SWARM_KEY_BYTE_LENGTH) {
|
|
54
|
-
return new Uint8Array(
|
|
55
|
-
fileBuffer.buffer,
|
|
56
|
-
fileBuffer.byteOffset,
|
|
57
|
-
fileBuffer.byteLength
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
const text = fileBuffer.toString("utf-8");
|
|
61
|
-
return parseSwarmKey(text);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export { SWARM_KEY_BYTE_LENGTH, createSwarmKey, deserializeSwarmKey, loadSwarmKey, parseSwarmKey, saveSwarmKey, serializeSwarmKey };
|
|
65
|
-
//# sourceMappingURL=chunk-ZP3VVXOI.js.map
|
|
66
|
-
//# sourceMappingURL=chunk-ZP3VVXOI.js.map
|