@nextera.one/axis-server-sdk 0.1.1 → 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/dist/core/index.d.mts +85 -0
- package/dist/core/index.d.ts +85 -0
- package/dist/core/index.js +543 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +450 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/index.d.mts +4 -9
- package/dist/index.d.ts +4 -9
- package/dist/index.js +518 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +449 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
7
|
var __export = (target, all) => {
|
|
6
8
|
for (var name in all)
|
|
@@ -14,6 +16,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
14
16
|
}
|
|
15
17
|
return to;
|
|
16
18
|
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
17
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
28
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
19
29
|
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
@@ -27,11 +37,69 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
27
37
|
// src/index.ts
|
|
28
38
|
var index_exports = {};
|
|
29
39
|
__export(index_exports, {
|
|
40
|
+
AXIS_MAGIC: () => AXIS_MAGIC,
|
|
41
|
+
AXIS_VERSION: () => AXIS_VERSION,
|
|
42
|
+
AxisFrameZ: () => AxisFrameZ,
|
|
43
|
+
ERR_BAD_SIGNATURE: () => ERR_BAD_SIGNATURE,
|
|
44
|
+
ERR_CONTRACT_VIOLATION: () => ERR_CONTRACT_VIOLATION,
|
|
45
|
+
ERR_INVALID_PACKET: () => ERR_INVALID_PACKET,
|
|
46
|
+
ERR_REPLAY_DETECTED: () => ERR_REPLAY_DETECTED,
|
|
47
|
+
FLAG_BODY_TLV: () => FLAG_BODY_TLV,
|
|
48
|
+
FLAG_CHAIN_REQ: () => FLAG_CHAIN_REQ,
|
|
49
|
+
FLAG_HAS_WITNESS: () => FLAG_HAS_WITNESS,
|
|
30
50
|
HANDLER_METADATA_KEY: () => HANDLER_METADATA_KEY,
|
|
31
51
|
Handler: () => Handler,
|
|
32
52
|
INTENT_ROUTES_KEY: () => INTENT_ROUTES_KEY,
|
|
33
53
|
Intent: () => Intent,
|
|
34
|
-
IntentRouter: () => IntentRouter
|
|
54
|
+
IntentRouter: () => IntentRouter,
|
|
55
|
+
MAX_BODY_LEN: () => MAX_BODY_LEN,
|
|
56
|
+
MAX_FRAME_LEN: () => MAX_FRAME_LEN,
|
|
57
|
+
MAX_HDR_LEN: () => MAX_HDR_LEN,
|
|
58
|
+
MAX_SIG_LEN: () => MAX_SIG_LEN,
|
|
59
|
+
PROOF_CAPSULE: () => PROOF_CAPSULE,
|
|
60
|
+
PROOF_JWT: () => PROOF_JWT,
|
|
61
|
+
PROOF_LOOM: () => PROOF_LOOM,
|
|
62
|
+
PROOF_MTLS: () => PROOF_MTLS,
|
|
63
|
+
TLV_ACTOR_ID: () => TLV_ACTOR_ID,
|
|
64
|
+
TLV_AUD: () => TLV_AUD,
|
|
65
|
+
TLV_EFFECT: () => TLV_EFFECT,
|
|
66
|
+
TLV_ERROR_CODE: () => TLV_ERROR_CODE,
|
|
67
|
+
TLV_ERROR_MSG: () => TLV_ERROR_MSG,
|
|
68
|
+
TLV_INTENT: () => TLV_INTENT,
|
|
69
|
+
TLV_KID: () => TLV_KID,
|
|
70
|
+
TLV_LOOM_PRESENCE_ID: () => TLV_LOOM_PRESENCE_ID,
|
|
71
|
+
TLV_LOOM_THREAD_HASH: () => TLV_LOOM_THREAD_HASH,
|
|
72
|
+
TLV_LOOM_WRIT: () => TLV_LOOM_WRIT,
|
|
73
|
+
TLV_NODE: () => TLV_NODE,
|
|
74
|
+
TLV_NODE_CERT_HASH: () => TLV_NODE_CERT_HASH,
|
|
75
|
+
TLV_NODE_KID: () => TLV_NODE_KID,
|
|
76
|
+
TLV_NONCE: () => TLV_NONCE,
|
|
77
|
+
TLV_OK: () => TLV_OK,
|
|
78
|
+
TLV_PID: () => TLV_PID,
|
|
79
|
+
TLV_PREV_HASH: () => TLV_PREV_HASH,
|
|
80
|
+
TLV_PROOF_REF: () => TLV_PROOF_REF,
|
|
81
|
+
TLV_PROOF_TYPE: () => TLV_PROOF_TYPE,
|
|
82
|
+
TLV_RECEIPT_HASH: () => TLV_RECEIPT_HASH,
|
|
83
|
+
TLV_RID: () => TLV_RID,
|
|
84
|
+
TLV_TRACE_ID: () => TLV_TRACE_ID,
|
|
85
|
+
TLV_TS: () => TLV_TS,
|
|
86
|
+
computeReceiptHash: () => computeReceiptHash,
|
|
87
|
+
computeSignaturePayload: () => computeSignaturePayload,
|
|
88
|
+
decodeArray: () => decodeArray,
|
|
89
|
+
decodeFrame: () => decodeFrame,
|
|
90
|
+
decodeObject: () => decodeObject,
|
|
91
|
+
decodeTLVs: () => decodeTLVs,
|
|
92
|
+
decodeTLVsList: () => decodeTLVsList,
|
|
93
|
+
decodeVarint: () => decodeVarint,
|
|
94
|
+
encodeFrame: () => encodeFrame,
|
|
95
|
+
encodeTLVs: () => encodeTLVs,
|
|
96
|
+
encodeVarint: () => encodeVarint,
|
|
97
|
+
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
98
|
+
getSignTarget: () => getSignTarget,
|
|
99
|
+
sha256: () => sha256,
|
|
100
|
+
signFrame: () => signFrame,
|
|
101
|
+
varintLength: () => varintLength,
|
|
102
|
+
verifyFrameSignature: () => verifyFrameSignature
|
|
35
103
|
});
|
|
36
104
|
module.exports = __toCommonJS(index_exports);
|
|
37
105
|
|
|
@@ -222,12 +290,460 @@ var IntentRouter = class {
|
|
|
222
290
|
IntentRouter = __decorateClass([
|
|
223
291
|
(0, import_common2.Injectable)()
|
|
224
292
|
], IntentRouter);
|
|
293
|
+
|
|
294
|
+
// src/core/constants.ts
|
|
295
|
+
var AXIS_MAGIC = new Uint8Array([65, 88, 73, 83, 49]);
|
|
296
|
+
var AXIS_VERSION = 1;
|
|
297
|
+
var MAX_HDR_LEN = 2048;
|
|
298
|
+
var MAX_BODY_LEN = 65536;
|
|
299
|
+
var MAX_SIG_LEN = 128;
|
|
300
|
+
var MAX_FRAME_LEN = 70 * 1024;
|
|
301
|
+
var FLAG_BODY_TLV = 1;
|
|
302
|
+
var FLAG_CHAIN_REQ = 2;
|
|
303
|
+
var FLAG_HAS_WITNESS = 4;
|
|
304
|
+
var TLV_PID = 1;
|
|
305
|
+
var TLV_TS = 2;
|
|
306
|
+
var TLV_INTENT = 3;
|
|
307
|
+
var TLV_ACTOR_ID = 4;
|
|
308
|
+
var TLV_PROOF_TYPE = 5;
|
|
309
|
+
var TLV_PROOF_REF = 6;
|
|
310
|
+
var TLV_NONCE = 7;
|
|
311
|
+
var TLV_AUD = 8;
|
|
312
|
+
var TLV_NODE = 9;
|
|
313
|
+
var TLV_TRACE_ID = 10;
|
|
314
|
+
var TLV_KID = 11;
|
|
315
|
+
var TLV_RID = 15;
|
|
316
|
+
var TLV_OK = 16;
|
|
317
|
+
var TLV_EFFECT = 17;
|
|
318
|
+
var TLV_ERROR_CODE = 18;
|
|
319
|
+
var TLV_ERROR_MSG = 19;
|
|
320
|
+
var TLV_PREV_HASH = 20;
|
|
321
|
+
var TLV_RECEIPT_HASH = 21;
|
|
322
|
+
var TLV_NODE_KID = 30;
|
|
323
|
+
var TLV_NODE_CERT_HASH = 34;
|
|
324
|
+
var TLV_LOOM_PRESENCE_ID = 91;
|
|
325
|
+
var TLV_LOOM_WRIT = 92;
|
|
326
|
+
var TLV_LOOM_THREAD_HASH = 93;
|
|
327
|
+
var PROOF_CAPSULE = 1;
|
|
328
|
+
var PROOF_JWT = 2;
|
|
329
|
+
var PROOF_MTLS = 3;
|
|
330
|
+
var PROOF_LOOM = 4;
|
|
331
|
+
var ERR_INVALID_PACKET = "INVALID_PACKET";
|
|
332
|
+
var ERR_BAD_SIGNATURE = "BAD_SIGNATURE";
|
|
333
|
+
var ERR_REPLAY_DETECTED = "REPLAY_DETECTED";
|
|
334
|
+
var ERR_CONTRACT_VIOLATION = "CONTRACT_VIOLATION";
|
|
335
|
+
|
|
336
|
+
// src/core/varint.ts
|
|
337
|
+
function encodeVarint(value) {
|
|
338
|
+
if (value < 0) throw new Error("Varint must be unsigned");
|
|
339
|
+
const bytes = [];
|
|
340
|
+
while (true) {
|
|
341
|
+
const byte = value & 127;
|
|
342
|
+
value >>>= 7;
|
|
343
|
+
if (value === 0) {
|
|
344
|
+
bytes.push(byte);
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
bytes.push(byte | 128);
|
|
348
|
+
}
|
|
349
|
+
return new Uint8Array(bytes);
|
|
350
|
+
}
|
|
351
|
+
function decodeVarint(buf, offset = 0) {
|
|
352
|
+
let value = 0;
|
|
353
|
+
let shift = 0;
|
|
354
|
+
let length = 0;
|
|
355
|
+
while (true) {
|
|
356
|
+
if (offset + length >= buf.length) {
|
|
357
|
+
throw new Error("Varint decode out of bounds");
|
|
358
|
+
}
|
|
359
|
+
const byte = buf[offset + length];
|
|
360
|
+
value += (byte & 127) * Math.pow(2, shift);
|
|
361
|
+
length++;
|
|
362
|
+
shift += 7;
|
|
363
|
+
if ((byte & 128) === 0) {
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
if (length > 8) throw new Error("Varint too large");
|
|
367
|
+
}
|
|
368
|
+
return { value, length };
|
|
369
|
+
}
|
|
370
|
+
function varintLength(value) {
|
|
371
|
+
if (value < 0) throw new Error("Varint must be unsigned");
|
|
372
|
+
let len = 0;
|
|
373
|
+
do {
|
|
374
|
+
value >>>= 7;
|
|
375
|
+
len++;
|
|
376
|
+
} while (value !== 0);
|
|
377
|
+
return len;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/core/tlv.ts
|
|
381
|
+
function encodeTLVs(tlvs) {
|
|
382
|
+
const sorted = [...tlvs].sort((a, b) => a.type - b.type);
|
|
383
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
384
|
+
if (sorted[i].type === sorted[i + 1].type) {
|
|
385
|
+
throw new Error(`Duplicate TLV type: ${sorted[i].type}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
let totalSize = 0;
|
|
389
|
+
for (const t of sorted) {
|
|
390
|
+
totalSize += varintLength(t.type);
|
|
391
|
+
totalSize += varintLength(t.value.length);
|
|
392
|
+
totalSize += t.value.length;
|
|
393
|
+
}
|
|
394
|
+
const buf = new Uint8Array(totalSize);
|
|
395
|
+
let offset = 0;
|
|
396
|
+
for (const t of sorted) {
|
|
397
|
+
const typeBytes = encodeVarint(t.type);
|
|
398
|
+
buf.set(typeBytes, offset);
|
|
399
|
+
offset += typeBytes.length;
|
|
400
|
+
const lenBytes = encodeVarint(t.value.length);
|
|
401
|
+
buf.set(lenBytes, offset);
|
|
402
|
+
offset += lenBytes.length;
|
|
403
|
+
buf.set(t.value, offset);
|
|
404
|
+
offset += t.value.length;
|
|
405
|
+
}
|
|
406
|
+
return buf;
|
|
407
|
+
}
|
|
408
|
+
function decodeTLVsList(buf, maxItems = 1024) {
|
|
409
|
+
const list = [];
|
|
410
|
+
let offset = 0;
|
|
411
|
+
while (offset < buf.length) {
|
|
412
|
+
if (list.length >= maxItems) throw new Error("TLV_LIMIT");
|
|
413
|
+
const { value: type, length: typeLen } = decodeVarint(buf, offset);
|
|
414
|
+
offset += typeLen;
|
|
415
|
+
const { value: len, length: lenLen } = decodeVarint(buf, offset);
|
|
416
|
+
offset += lenLen;
|
|
417
|
+
if (offset + len > buf.length) {
|
|
418
|
+
throw new Error(`TLV violation: Length ${len} exceeds buffer`);
|
|
419
|
+
}
|
|
420
|
+
const value = buf.slice(offset, offset + len);
|
|
421
|
+
list.push({ type, value });
|
|
422
|
+
offset += len;
|
|
423
|
+
}
|
|
424
|
+
return list;
|
|
425
|
+
}
|
|
426
|
+
function decodeTLVs(buf) {
|
|
427
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
428
|
+
let offset = 0;
|
|
429
|
+
let lastType = -1;
|
|
430
|
+
while (offset < buf.length) {
|
|
431
|
+
const { value: type, length: typeLen } = decodeVarint(buf, offset);
|
|
432
|
+
offset += typeLen;
|
|
433
|
+
if (type <= lastType) {
|
|
434
|
+
throw new Error(
|
|
435
|
+
`TLV violation: Unsorted or duplicate type ${type} after ${lastType}`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
lastType = type;
|
|
439
|
+
const { value: len, length: lenLen } = decodeVarint(buf, offset);
|
|
440
|
+
offset += lenLen;
|
|
441
|
+
if (offset + len > buf.length) {
|
|
442
|
+
throw new Error(`TLV violation: Length ${len} exceeds buffer`);
|
|
443
|
+
}
|
|
444
|
+
const value = buf.slice(offset, offset + len);
|
|
445
|
+
map2.set(type, value);
|
|
446
|
+
offset += len;
|
|
447
|
+
}
|
|
448
|
+
return map2;
|
|
449
|
+
}
|
|
450
|
+
function decodeObject(bytes, depth = 0, limits = { maxDepth: 8, maxItems: 128 }) {
|
|
451
|
+
if (depth > limits.maxDepth) {
|
|
452
|
+
throw new Error("OBJECT_DEPTH_EXCEEDED");
|
|
453
|
+
}
|
|
454
|
+
const map2 = decodeTLVs(bytes);
|
|
455
|
+
return map2;
|
|
456
|
+
}
|
|
457
|
+
function decodeArray(bytes, itemType, maxItems = 256) {
|
|
458
|
+
const list = decodeTLVsList(bytes, maxItems);
|
|
459
|
+
const items = [];
|
|
460
|
+
for (const tlv of list) {
|
|
461
|
+
if (tlv.type !== itemType) {
|
|
462
|
+
throw new Error(`INVALID_ARRAY_ITEM:${tlv.type}`);
|
|
463
|
+
}
|
|
464
|
+
items.push(tlv.value);
|
|
465
|
+
}
|
|
466
|
+
return items;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// src/core/axis-bin.ts
|
|
470
|
+
var z = __toESM(require("zod"));
|
|
471
|
+
var AxisFrameZ = z.object({
|
|
472
|
+
/** Flag bits for protocol control (e.g., encryption, compression) */
|
|
473
|
+
flags: z.number().int().nonnegative(),
|
|
474
|
+
/** A map of TLV headers where key=Tag and value=BinaryData */
|
|
475
|
+
headers: z.map(
|
|
476
|
+
z.number(),
|
|
477
|
+
z.custom((v) => v instanceof Uint8Array)
|
|
478
|
+
),
|
|
479
|
+
/** The main payload of the frame */
|
|
480
|
+
body: z.custom((v) => v instanceof Uint8Array),
|
|
481
|
+
/** The cryptographic signature covering the frame (except the signature itself) */
|
|
482
|
+
sig: z.custom((v) => v instanceof Uint8Array)
|
|
483
|
+
});
|
|
484
|
+
function encodeFrame(frame) {
|
|
485
|
+
const hdrBytes = encodeTLVs(
|
|
486
|
+
Array.from(frame.headers.entries()).map(([t, v]) => ({
|
|
487
|
+
type: t,
|
|
488
|
+
value: v
|
|
489
|
+
}))
|
|
490
|
+
);
|
|
491
|
+
if (hdrBytes.length > MAX_HDR_LEN) throw new Error("Header too large");
|
|
492
|
+
if (frame.body.length > MAX_BODY_LEN) throw new Error("Body too large");
|
|
493
|
+
if (frame.sig.length > MAX_SIG_LEN) throw new Error("Signature too large");
|
|
494
|
+
const hdrLenBytes = encodeVarint(hdrBytes.length);
|
|
495
|
+
const bodyLenBytes = encodeVarint(frame.body.length);
|
|
496
|
+
const sigLenBytes = encodeVarint(frame.sig.length);
|
|
497
|
+
const totalLen = 5 + // Magic (AXIS1)
|
|
498
|
+
1 + // Version
|
|
499
|
+
1 + // Flags
|
|
500
|
+
hdrLenBytes.length + bodyLenBytes.length + sigLenBytes.length + hdrBytes.length + frame.body.length + frame.sig.length;
|
|
501
|
+
if (totalLen > MAX_FRAME_LEN) throw new Error("Total frame too large");
|
|
502
|
+
const buf = new Uint8Array(totalLen);
|
|
503
|
+
let offset = 0;
|
|
504
|
+
buf.set(AXIS_MAGIC, offset);
|
|
505
|
+
offset += 5;
|
|
506
|
+
buf[offset++] = AXIS_VERSION;
|
|
507
|
+
buf[offset++] = frame.flags;
|
|
508
|
+
buf.set(hdrLenBytes, offset);
|
|
509
|
+
offset += hdrLenBytes.length;
|
|
510
|
+
buf.set(bodyLenBytes, offset);
|
|
511
|
+
offset += bodyLenBytes.length;
|
|
512
|
+
buf.set(sigLenBytes, offset);
|
|
513
|
+
offset += sigLenBytes.length;
|
|
514
|
+
buf.set(hdrBytes, offset);
|
|
515
|
+
offset += hdrBytes.length;
|
|
516
|
+
buf.set(frame.body, offset);
|
|
517
|
+
offset += frame.body.length;
|
|
518
|
+
buf.set(frame.sig, offset);
|
|
519
|
+
offset += frame.sig.length;
|
|
520
|
+
return buf;
|
|
521
|
+
}
|
|
522
|
+
function decodeFrame(buf) {
|
|
523
|
+
let offset = 0;
|
|
524
|
+
if (offset + 5 > buf.length) throw new Error("Packet too short");
|
|
525
|
+
for (let i = 0; i < 5; i++) {
|
|
526
|
+
if (buf[offset + i] !== AXIS_MAGIC[i]) throw new Error("Invalid Magic");
|
|
527
|
+
}
|
|
528
|
+
offset += 5;
|
|
529
|
+
const ver = buf[offset++];
|
|
530
|
+
if (ver !== AXIS_VERSION) throw new Error(`Unsupported version: ${ver}`);
|
|
531
|
+
const flags = buf[offset++];
|
|
532
|
+
const { value: hdrLen, length: hlLen } = decodeVarint(buf, offset);
|
|
533
|
+
offset += hlLen;
|
|
534
|
+
if (hdrLen > MAX_HDR_LEN) throw new Error("Header limit exceeded");
|
|
535
|
+
const { value: bodyLen, length: blLen } = decodeVarint(buf, offset);
|
|
536
|
+
offset += blLen;
|
|
537
|
+
if (bodyLen > MAX_BODY_LEN) throw new Error("Body limit exceeded");
|
|
538
|
+
const { value: sigLen, length: slLen } = decodeVarint(buf, offset);
|
|
539
|
+
offset += slLen;
|
|
540
|
+
if (sigLen > MAX_SIG_LEN) throw new Error("Signature limit exceeded");
|
|
541
|
+
if (offset + hdrLen + bodyLen + sigLen > buf.length) {
|
|
542
|
+
throw new Error("Frame truncated");
|
|
543
|
+
}
|
|
544
|
+
const hdrBytes = buf.slice(offset, offset + hdrLen);
|
|
545
|
+
offset += hdrLen;
|
|
546
|
+
const bodyBytes = buf.slice(offset, offset + bodyLen);
|
|
547
|
+
offset += bodyLen;
|
|
548
|
+
const sigBytes = buf.slice(offset, offset + sigLen);
|
|
549
|
+
offset += sigLen;
|
|
550
|
+
const headers = decodeTLVs(hdrBytes);
|
|
551
|
+
return {
|
|
552
|
+
flags,
|
|
553
|
+
headers,
|
|
554
|
+
body: bodyBytes,
|
|
555
|
+
sig: sigBytes
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
function getSignTarget(frame) {
|
|
559
|
+
return encodeFrame({
|
|
560
|
+
...frame,
|
|
561
|
+
sig: new Uint8Array(0)
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/core/signature.ts
|
|
566
|
+
var crypto = __toESM(require("crypto"));
|
|
567
|
+
function computeSignaturePayload(frame) {
|
|
568
|
+
const frameWithoutSig = {
|
|
569
|
+
...frame,
|
|
570
|
+
sig: new Uint8Array(0)
|
|
571
|
+
};
|
|
572
|
+
const encoded = encodeFrame(frameWithoutSig);
|
|
573
|
+
return Buffer.from(encoded);
|
|
574
|
+
}
|
|
575
|
+
function signFrame(frame, privateKey) {
|
|
576
|
+
const payload = computeSignaturePayload(frame);
|
|
577
|
+
let keyObject;
|
|
578
|
+
if (privateKey.length === 32) {
|
|
579
|
+
const pkcs8Prefix = Buffer.from([
|
|
580
|
+
48,
|
|
581
|
+
46,
|
|
582
|
+
2,
|
|
583
|
+
1,
|
|
584
|
+
0,
|
|
585
|
+
48,
|
|
586
|
+
5,
|
|
587
|
+
6,
|
|
588
|
+
3,
|
|
589
|
+
43,
|
|
590
|
+
101,
|
|
591
|
+
112,
|
|
592
|
+
4,
|
|
593
|
+
34,
|
|
594
|
+
4,
|
|
595
|
+
32
|
|
596
|
+
]);
|
|
597
|
+
const pkcs8Key = Buffer.concat([pkcs8Prefix, privateKey]);
|
|
598
|
+
keyObject = crypto.createPrivateKey({
|
|
599
|
+
key: pkcs8Key,
|
|
600
|
+
format: "der",
|
|
601
|
+
type: "pkcs8"
|
|
602
|
+
});
|
|
603
|
+
} else {
|
|
604
|
+
keyObject = crypto.createPrivateKey({
|
|
605
|
+
key: privateKey,
|
|
606
|
+
format: "der",
|
|
607
|
+
type: "pkcs8"
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
const signature = crypto.sign(null, payload, keyObject);
|
|
611
|
+
if (signature.length !== 64) {
|
|
612
|
+
throw new Error("Ed25519 signature must be 64 bytes");
|
|
613
|
+
}
|
|
614
|
+
return signature;
|
|
615
|
+
}
|
|
616
|
+
function verifyFrameSignature(frame, publicKey) {
|
|
617
|
+
if (frame.sig.length === 0) {
|
|
618
|
+
return false;
|
|
619
|
+
}
|
|
620
|
+
if (frame.sig.length !== 64) {
|
|
621
|
+
throw new Error("Ed25519 signature must be 64 bytes");
|
|
622
|
+
}
|
|
623
|
+
const payload = computeSignaturePayload(frame);
|
|
624
|
+
try {
|
|
625
|
+
let keyObject;
|
|
626
|
+
if (publicKey.length === 32) {
|
|
627
|
+
const spkiPrefix = Buffer.from([
|
|
628
|
+
48,
|
|
629
|
+
42,
|
|
630
|
+
48,
|
|
631
|
+
5,
|
|
632
|
+
6,
|
|
633
|
+
3,
|
|
634
|
+
43,
|
|
635
|
+
101,
|
|
636
|
+
112,
|
|
637
|
+
3,
|
|
638
|
+
33,
|
|
639
|
+
0
|
|
640
|
+
]);
|
|
641
|
+
const spkiKey = Buffer.concat([spkiPrefix, publicKey]);
|
|
642
|
+
keyObject = crypto.createPublicKey({
|
|
643
|
+
key: spkiKey,
|
|
644
|
+
format: "der",
|
|
645
|
+
type: "spki"
|
|
646
|
+
});
|
|
647
|
+
} else {
|
|
648
|
+
keyObject = crypto.createPublicKey({
|
|
649
|
+
key: publicKey,
|
|
650
|
+
format: "der",
|
|
651
|
+
type: "spki"
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
const valid = crypto.verify(
|
|
655
|
+
null,
|
|
656
|
+
payload,
|
|
657
|
+
keyObject,
|
|
658
|
+
Buffer.from(frame.sig)
|
|
659
|
+
);
|
|
660
|
+
return valid;
|
|
661
|
+
} catch (error) {
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
function generateEd25519KeyPair() {
|
|
666
|
+
const { privateKey, publicKey } = crypto.generateKeyPairSync("ed25519");
|
|
667
|
+
return {
|
|
668
|
+
privateKey: privateKey.export({ type: "pkcs8", format: "der" }),
|
|
669
|
+
publicKey: publicKey.export({ type: "spki", format: "der" })
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
function sha256(data) {
|
|
673
|
+
return crypto.createHash("sha256").update(data).digest();
|
|
674
|
+
}
|
|
675
|
+
function computeReceiptHash(receiptBytes, prevHash) {
|
|
676
|
+
const hasher = crypto.createHash("sha256");
|
|
677
|
+
hasher.update(receiptBytes);
|
|
678
|
+
if (prevHash && prevHash.length > 0) {
|
|
679
|
+
hasher.update(prevHash);
|
|
680
|
+
}
|
|
681
|
+
return hasher.digest();
|
|
682
|
+
}
|
|
225
683
|
// Annotate the CommonJS export names for ESM import in node:
|
|
226
684
|
0 && (module.exports = {
|
|
685
|
+
AXIS_MAGIC,
|
|
686
|
+
AXIS_VERSION,
|
|
687
|
+
AxisFrameZ,
|
|
688
|
+
ERR_BAD_SIGNATURE,
|
|
689
|
+
ERR_CONTRACT_VIOLATION,
|
|
690
|
+
ERR_INVALID_PACKET,
|
|
691
|
+
ERR_REPLAY_DETECTED,
|
|
692
|
+
FLAG_BODY_TLV,
|
|
693
|
+
FLAG_CHAIN_REQ,
|
|
694
|
+
FLAG_HAS_WITNESS,
|
|
227
695
|
HANDLER_METADATA_KEY,
|
|
228
696
|
Handler,
|
|
229
697
|
INTENT_ROUTES_KEY,
|
|
230
698
|
Intent,
|
|
231
|
-
IntentRouter
|
|
699
|
+
IntentRouter,
|
|
700
|
+
MAX_BODY_LEN,
|
|
701
|
+
MAX_FRAME_LEN,
|
|
702
|
+
MAX_HDR_LEN,
|
|
703
|
+
MAX_SIG_LEN,
|
|
704
|
+
PROOF_CAPSULE,
|
|
705
|
+
PROOF_JWT,
|
|
706
|
+
PROOF_LOOM,
|
|
707
|
+
PROOF_MTLS,
|
|
708
|
+
TLV_ACTOR_ID,
|
|
709
|
+
TLV_AUD,
|
|
710
|
+
TLV_EFFECT,
|
|
711
|
+
TLV_ERROR_CODE,
|
|
712
|
+
TLV_ERROR_MSG,
|
|
713
|
+
TLV_INTENT,
|
|
714
|
+
TLV_KID,
|
|
715
|
+
TLV_LOOM_PRESENCE_ID,
|
|
716
|
+
TLV_LOOM_THREAD_HASH,
|
|
717
|
+
TLV_LOOM_WRIT,
|
|
718
|
+
TLV_NODE,
|
|
719
|
+
TLV_NODE_CERT_HASH,
|
|
720
|
+
TLV_NODE_KID,
|
|
721
|
+
TLV_NONCE,
|
|
722
|
+
TLV_OK,
|
|
723
|
+
TLV_PID,
|
|
724
|
+
TLV_PREV_HASH,
|
|
725
|
+
TLV_PROOF_REF,
|
|
726
|
+
TLV_PROOF_TYPE,
|
|
727
|
+
TLV_RECEIPT_HASH,
|
|
728
|
+
TLV_RID,
|
|
729
|
+
TLV_TRACE_ID,
|
|
730
|
+
TLV_TS,
|
|
731
|
+
computeReceiptHash,
|
|
732
|
+
computeSignaturePayload,
|
|
733
|
+
decodeArray,
|
|
734
|
+
decodeFrame,
|
|
735
|
+
decodeObject,
|
|
736
|
+
decodeTLVs,
|
|
737
|
+
decodeTLVsList,
|
|
738
|
+
decodeVarint,
|
|
739
|
+
encodeFrame,
|
|
740
|
+
encodeTLVs,
|
|
741
|
+
encodeVarint,
|
|
742
|
+
generateEd25519KeyPair,
|
|
743
|
+
getSignTarget,
|
|
744
|
+
sha256,
|
|
745
|
+
signFrame,
|
|
746
|
+
varintLength,
|
|
747
|
+
verifyFrameSignature
|
|
232
748
|
});
|
|
233
749
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/decorators/handler.decorator.ts","../src/decorators/intent.decorator.ts","../src/engine/intent.router.ts"],"sourcesContent":["// Decorators\nexport { Handler, HANDLER_METADATA_KEY } from './decorators/handler.decorator';\nexport {\n Intent,\n INTENT_ROUTES_KEY,\n IntentRoute,\n IntentOptions,\n} from './decorators/intent.decorator';\n\n// Engine\nexport { IntentRouter, AxisEffect } from './engine/intent.router';\n\n// Interfaces\nexport { AxisHandler, AxisHandlerInit } from './interfaces/axis-handler.interface';\nexport { AxisCrudHandler } from './interfaces/axis-crud-handler.interface';\n\n// Types\nexport { AxisFrame } from './types/axis-frame';\n","import { Injectable, SetMetadata } from '@nestjs/common';\n\nexport const HANDLER_METADATA_KEY = 'axis:handler';\n\n/**\n * Decorator to mark a class as an Axis Handler.\n * Handlers are responsible for processing intents or specific logic\n * for Axis modules.\n */\nexport function Handler(intent?: string): ClassDecorator {\n return (target: Function) => {\n SetMetadata(HANDLER_METADATA_KEY, { intent })(target);\n Injectable()(target as any);\n };\n}\n","import 'reflect-metadata';\n\nexport const INTENT_ROUTES_KEY = 'axis:intent_routes';\n\nexport interface IntentRoute {\n action: string;\n methodName: string | symbol;\n absolute?: boolean;\n frame?: boolean;\n}\n\nexport interface IntentOptions {\n /** If true, the action is the full intent name (not prefixed with handler name) */\n absolute?: boolean;\n /** If true, register as { handle: fn } for frame-based handlers */\n frame?: boolean;\n}\n\n/**\n * Marks a method as an intent handler.\n *\n * The full intent name is resolved as `{handler_prefix}.{action}` by default.\n * Use `{ absolute: true }` to use the action string as the full intent name.\n * Use `{ frame: true }` for handlers that receive an AxisFrame and return AxisEffect.\n *\n * @example\n * ```ts\n * @Handler('axis.actor_keys')\n * class MyHandler {\n * @Intent('create')\n * async create(body: Uint8Array) { ... }\n *\n * @Intent('public.auth.capsule.issue', { absolute: true })\n * async publicIssue(body: Uint8Array) { ... }\n *\n * @Intent('presence.resume', { frame: true })\n * async handlePresence(frame: AxisFrame) { ... }\n * }\n * ```\n */\nexport function Intent(action: string, options?: IntentOptions): MethodDecorator {\n return (target, propertyKey) => {\n const routes: IntentRoute[] =\n Reflect.getMetadata(INTENT_ROUTES_KEY, target.constructor) || [];\n routes.push({\n action,\n methodName: propertyKey,\n absolute: options?.absolute,\n frame: options?.frame,\n });\n Reflect.defineMetadata(INTENT_ROUTES_KEY, routes, target.constructor);\n };\n}\n","import { Injectable } from '@nestjs/common';\nimport { AxisFrame } from '../types/axis-frame';\nimport { HANDLER_METADATA_KEY } from '../decorators/handler.decorator';\nimport { INTENT_ROUTES_KEY, IntentRoute } from '../decorators/intent.decorator';\n\n/**\n * Represents the outcome of an AXIS intent execution.\n *\n * @interface AxisEffect\n */\nexport interface AxisEffect {\n /** Whether the intent was processed successfully at the application level */\n ok: boolean;\n /** A descriptive string classifier for the result (e.g., 'FILE_CREATED', 'PONG') */\n effect: string;\n /** Optional binary payload (body) to be returned to the requester */\n body?: Uint8Array;\n /** Optional custom TLV headers to be included in the response frame */\n headers?: Map<number, Uint8Array>;\n /** Optional metadata for internal logging or audit (not sent to client) */\n metadata?: any;\n}\n\n/**\n * IntentRouter\n *\n * The central dispatching mechanism of the AXIS backend.\n * Maps binary intents (identified by their name in the header) to specialized handlers.\n *\n * **Features:**\n * 1. **Built-in Fast Path:** Handles high-frequency system intents (ping, time, echo) directly.\n * 2. **Dynamic Handler Registration:** Allows modules to register handlers at runtime.\n * 3. **Decorator-driven Registration:** Uses {@link registerHandler} to auto-register `@Intent`-decorated methods.\n * 4. **Polymorphic Handlers:** Supports both raw function handlers and object-based `{ handle }` handlers.\n *\n * @class IntentRouter\n */\n@Injectable()\nexport class IntentRouter {\n /** Internal registry of dynamic intent handlers */\n private handlers = new Map<string, any>();\n\n /**\n * Registers a handler for a specific intent.\n * Handlers can be functions: `(body, headers) => Promise<Uint8Array | AxisEffect>`\n * Or objects with a method: `handle(frame: AxisFrame) => Promise<AxisEffect>`\n *\n * @param {string} intent - The unique intent identifier (e.g., 'axis.vault.create')\n * @param {any} handler - The handler function or object\n */\n register(intent: string, handler: any) {\n this.handlers.set(intent, handler);\n }\n\n /**\n * Automatically registers all `@Intent`-decorated methods from a handler instance.\n *\n * Reads the handler prefix from `@Handler` metadata (or falls back to `instance.name`),\n * then registers each `@Intent`-decorated method accordingly.\n *\n * @param {any} instance - The handler instance with `@Intent`-decorated methods\n */\n registerHandler(instance: any) {\n const handlerMeta = Reflect.getMetadata(\n HANDLER_METADATA_KEY,\n instance.constructor,\n );\n const prefix: string | undefined = handlerMeta?.intent || instance.name;\n\n const routes: IntentRoute[] =\n Reflect.getMetadata(INTENT_ROUTES_KEY, instance.constructor) || [];\n\n for (const route of routes) {\n const intentName = route.absolute\n ? route.action\n : `${prefix}.${route.action}`;\n const fn = instance[route.methodName].bind(instance);\n\n if (route.frame) {\n this.register(intentName, { handle: fn });\n } else {\n this.register(intentName, fn);\n }\n }\n }\n\n /**\n * Routes a decoded AXIS frame to the appropriate handler.\n *\n * **Precedence:**\n * 1. System Built-ins (`system.ping`, `public.ping`, `system.time`, `system.echo`)\n * 2. Meta-intent execution (`INTENT.EXEC` / `axis.intent.exec`)\n * 3. Dynamically registered handlers from modules.\n *\n * @param {AxisFrame} frame - The validated and decoded binary frame\n * @returns {Promise<AxisEffect>} The resulting effect of the execution\n * @throws {Error} If the intent header is missing or no handler is registered\n */\n async route(frame: AxisFrame): Promise<AxisEffect> {\n const start = process.hrtime();\n let intent = 'unknown';\n\n try {\n // Extract intent from header TLV (tag 3 = TLV_INTENT)\n const intentBytes = frame.headers.get(3);\n if (!intentBytes) throw new Error('Missing intent');\n intent = new TextDecoder().decode(intentBytes);\n\n let effect: AxisEffect;\n\n if (intent === 'system.ping' || intent === 'public.ping') {\n effect = {\n ok: true,\n effect: 'pong',\n headers: new Map([\n [100, new TextEncoder().encode('AXIS_BACKEND_V1')],\n ]),\n body: new TextEncoder().encode(\n JSON.stringify({\n status: 'ok',\n timestamp: new Date().toISOString(),\n version: '1.0.0',\n }),\n ),\n };\n } else if (intent === 'system.time') {\n const ts = Date.now().toString();\n effect = {\n ok: true,\n effect: 'time',\n body: new TextEncoder().encode(\n JSON.stringify({\n ts,\n iso: new Date().toISOString(),\n }),\n ),\n };\n } else if (intent === 'system.echo') {\n effect = {\n ok: true,\n effect: 'echo',\n body: frame.body,\n };\n } else if (intent === 'INTENT.EXEC' || intent === 'axis.intent.exec') {\n // Meta-intent: Unwrap and execute the inner intent\n try {\n const bodyJSON = JSON.parse(new TextDecoder().decode(frame.body));\n const innerIntent = bodyJSON.intent;\n const innerArgs = bodyJSON.args || {};\n\n if (!innerIntent) {\n throw new Error('INTENT.EXEC missing inner intent');\n }\n\n const innerFrame: AxisFrame = {\n ...frame,\n headers: new Map(frame.headers),\n body: new TextEncoder().encode(JSON.stringify(innerArgs)),\n };\n innerFrame.headers.set(3, new TextEncoder().encode(innerIntent));\n\n return await this.route(innerFrame);\n } catch (e: any) {\n throw new Error(`INTENT.EXEC unwrapping failed: ${e.message}`);\n }\n } else {\n const handler = this.handlers.get(intent);\n if (!handler) {\n throw new Error(`Intent not found: ${intent}`);\n }\n\n if (typeof handler === 'function') {\n const resultBody = await handler(frame.body, frame.headers);\n effect = {\n ok: true,\n effect: 'complete',\n body: resultBody,\n };\n } else {\n if (typeof (handler as any).handle === 'function') {\n effect = await (handler as any).handle(frame);\n } else if (typeof (handler as any).execute === 'function') {\n const bodyRes = await (handler as any).execute(\n frame.body,\n frame.headers,\n );\n effect = {\n ok: true,\n effect: 'complete',\n body: bodyRes,\n };\n } else {\n throw new Error(\n `Handler for ${intent} does not implement handle or execute`,\n );\n }\n }\n }\n\n this.recordLatency(intent, start);\n return effect;\n } catch (e: any) {\n console.error(`Error routing intent ${intent}:`, e.message);\n throw e;\n }\n }\n\n private recordLatency(intent: string, start: [number, number]) {\n const diff = process.hrtime(start);\n // Available for subclass telemetry hooks or future logging\n void diff;\n }\n}\n"],"mappings":"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","names":["import_common"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/decorators/handler.decorator.ts","../src/decorators/intent.decorator.ts","../src/engine/intent.router.ts","../src/core/constants.ts","../src/core/varint.ts","../src/core/tlv.ts","../src/core/axis-bin.ts","../src/core/signature.ts"],"sourcesContent":["// Decorators\nexport { Handler, HANDLER_METADATA_KEY } from './decorators/handler.decorator';\nexport {\n Intent,\n INTENT_ROUTES_KEY,\n IntentRoute,\n IntentOptions,\n} from './decorators/intent.decorator';\n\n// Engine\nexport { IntentRouter, AxisEffect } from './engine/intent.router';\n\n// Core Protocol\nexport * from './core';\n\n// Interfaces\nexport { AxisHandler, AxisHandlerInit } from './interfaces/axis-handler.interface';\nexport { AxisCrudHandler } from './interfaces/axis-crud-handler.interface';\n\n// Types\nexport { AxisFrame } from './core/axis-bin';\n","import { Injectable, SetMetadata } from '@nestjs/common';\n\nexport const HANDLER_METADATA_KEY = 'axis:handler';\n\n/**\n * Decorator to mark a class as an Axis Handler.\n * Handlers are responsible for processing intents or specific logic\n * for Axis modules.\n */\nexport function Handler(intent?: string): ClassDecorator {\n return (target: Function) => {\n SetMetadata(HANDLER_METADATA_KEY, { intent })(target);\n Injectable()(target as any);\n };\n}\n","import 'reflect-metadata';\n\nexport const INTENT_ROUTES_KEY = 'axis:intent_routes';\n\nexport interface IntentRoute {\n action: string;\n methodName: string | symbol;\n absolute?: boolean;\n frame?: boolean;\n}\n\nexport interface IntentOptions {\n /** If true, the action is the full intent name (not prefixed with handler name) */\n absolute?: boolean;\n /** If true, register as { handle: fn } for frame-based handlers */\n frame?: boolean;\n}\n\n/**\n * Marks a method as an intent handler.\n *\n * The full intent name is resolved as `{handler_prefix}.{action}` by default.\n * Use `{ absolute: true }` to use the action string as the full intent name.\n * Use `{ frame: true }` for handlers that receive an AxisFrame and return AxisEffect.\n *\n * @example\n * ```ts\n * @Handler('axis.actor_keys')\n * class MyHandler {\n * @Intent('create')\n * async create(body: Uint8Array) { ... }\n *\n * @Intent('public.auth.capsule.issue', { absolute: true })\n * async publicIssue(body: Uint8Array) { ... }\n *\n * @Intent('presence.resume', { frame: true })\n * async handlePresence(frame: AxisFrame) { ... }\n * }\n * ```\n */\nexport function Intent(action: string, options?: IntentOptions): MethodDecorator {\n return (target, propertyKey) => {\n const routes: IntentRoute[] =\n Reflect.getMetadata(INTENT_ROUTES_KEY, target.constructor) || [];\n routes.push({\n action,\n methodName: propertyKey,\n absolute: options?.absolute,\n frame: options?.frame,\n });\n Reflect.defineMetadata(INTENT_ROUTES_KEY, routes, target.constructor);\n };\n}\n","import { Injectable } from '@nestjs/common';\nimport { AxisFrame } from '../core/axis-bin';\nimport { HANDLER_METADATA_KEY } from '../decorators/handler.decorator';\nimport { INTENT_ROUTES_KEY, IntentRoute } from '../decorators/intent.decorator';\n\n/**\n * Represents the outcome of an AXIS intent execution.\n *\n * @interface AxisEffect\n */\nexport interface AxisEffect {\n /** Whether the intent was processed successfully at the application level */\n ok: boolean;\n /** A descriptive string classifier for the result (e.g., 'FILE_CREATED', 'PONG') */\n effect: string;\n /** Optional binary payload (body) to be returned to the requester */\n body?: Uint8Array;\n /** Optional custom TLV headers to be included in the response frame */\n headers?: Map<number, Uint8Array>;\n /** Optional metadata for internal logging or audit (not sent to client) */\n metadata?: any;\n}\n\n/**\n * IntentRouter\n *\n * The central dispatching mechanism of the AXIS backend.\n * Maps binary intents (identified by their name in the header) to specialized handlers.\n *\n * **Features:**\n * 1. **Built-in Fast Path:** Handles high-frequency system intents (ping, time, echo) directly.\n * 2. **Dynamic Handler Registration:** Allows modules to register handlers at runtime.\n * 3. **Decorator-driven Registration:** Uses {@link registerHandler} to auto-register `@Intent`-decorated methods.\n * 4. **Polymorphic Handlers:** Supports both raw function handlers and object-based `{ handle }` handlers.\n *\n * @class IntentRouter\n */\n@Injectable()\nexport class IntentRouter {\n /** Internal registry of dynamic intent handlers */\n private handlers = new Map<string, any>();\n\n /**\n * Registers a handler for a specific intent.\n * Handlers can be functions: `(body, headers) => Promise<Uint8Array | AxisEffect>`\n * Or objects with a method: `handle(frame: AxisFrame) => Promise<AxisEffect>`\n *\n * @param {string} intent - The unique intent identifier (e.g., 'axis.vault.create')\n * @param {any} handler - The handler function or object\n */\n register(intent: string, handler: any) {\n this.handlers.set(intent, handler);\n }\n\n /**\n * Automatically registers all `@Intent`-decorated methods from a handler instance.\n *\n * Reads the handler prefix from `@Handler` metadata (or falls back to `instance.name`),\n * then registers each `@Intent`-decorated method accordingly.\n *\n * @param {any} instance - The handler instance with `@Intent`-decorated methods\n */\n registerHandler(instance: any) {\n const handlerMeta = Reflect.getMetadata(\n HANDLER_METADATA_KEY,\n instance.constructor,\n );\n const prefix: string | undefined = handlerMeta?.intent || instance.name;\n\n const routes: IntentRoute[] =\n Reflect.getMetadata(INTENT_ROUTES_KEY, instance.constructor) || [];\n\n for (const route of routes) {\n const intentName = route.absolute\n ? route.action\n : `${prefix}.${route.action}`;\n const fn = instance[route.methodName].bind(instance);\n\n if (route.frame) {\n this.register(intentName, { handle: fn });\n } else {\n this.register(intentName, fn);\n }\n }\n }\n\n /**\n * Routes a decoded AXIS frame to the appropriate handler.\n *\n * **Precedence:**\n * 1. System Built-ins (`system.ping`, `public.ping`, `system.time`, `system.echo`)\n * 2. Meta-intent execution (`INTENT.EXEC` / `axis.intent.exec`)\n * 3. Dynamically registered handlers from modules.\n *\n * @param {AxisFrame} frame - The validated and decoded binary frame\n * @returns {Promise<AxisEffect>} The resulting effect of the execution\n * @throws {Error} If the intent header is missing or no handler is registered\n */\n async route(frame: AxisFrame): Promise<AxisEffect> {\n const start = process.hrtime();\n let intent = 'unknown';\n\n try {\n // Extract intent from header TLV (tag 3 = TLV_INTENT)\n const intentBytes = frame.headers.get(3);\n if (!intentBytes) throw new Error('Missing intent');\n intent = new TextDecoder().decode(intentBytes);\n\n let effect: AxisEffect;\n\n if (intent === 'system.ping' || intent === 'public.ping') {\n effect = {\n ok: true,\n effect: 'pong',\n headers: new Map([\n [100, new TextEncoder().encode('AXIS_BACKEND_V1')],\n ]),\n body: new TextEncoder().encode(\n JSON.stringify({\n status: 'ok',\n timestamp: new Date().toISOString(),\n version: '1.0.0',\n }),\n ),\n };\n } else if (intent === 'system.time') {\n const ts = Date.now().toString();\n effect = {\n ok: true,\n effect: 'time',\n body: new TextEncoder().encode(\n JSON.stringify({\n ts,\n iso: new Date().toISOString(),\n }),\n ),\n };\n } else if (intent === 'system.echo') {\n effect = {\n ok: true,\n effect: 'echo',\n body: frame.body,\n };\n } else if (intent === 'INTENT.EXEC' || intent === 'axis.intent.exec') {\n // Meta-intent: Unwrap and execute the inner intent\n try {\n const bodyJSON = JSON.parse(new TextDecoder().decode(frame.body));\n const innerIntent = bodyJSON.intent;\n const innerArgs = bodyJSON.args || {};\n\n if (!innerIntent) {\n throw new Error('INTENT.EXEC missing inner intent');\n }\n\n const innerFrame: AxisFrame = {\n ...frame,\n headers: new Map(frame.headers),\n body: new TextEncoder().encode(JSON.stringify(innerArgs)),\n };\n innerFrame.headers.set(3, new TextEncoder().encode(innerIntent));\n\n return await this.route(innerFrame);\n } catch (e: any) {\n throw new Error(`INTENT.EXEC unwrapping failed: ${e.message}`);\n }\n } else {\n const handler = this.handlers.get(intent);\n if (!handler) {\n throw new Error(`Intent not found: ${intent}`);\n }\n\n if (typeof handler === 'function') {\n const resultBody = await handler(frame.body, frame.headers);\n effect = {\n ok: true,\n effect: 'complete',\n body: resultBody,\n };\n } else {\n if (typeof (handler as any).handle === 'function') {\n effect = await (handler as any).handle(frame);\n } else if (typeof (handler as any).execute === 'function') {\n const bodyRes = await (handler as any).execute(\n frame.body,\n frame.headers,\n );\n effect = {\n ok: true,\n effect: 'complete',\n body: bodyRes,\n };\n } else {\n throw new Error(\n `Handler for ${intent} does not implement handle or execute`,\n );\n }\n }\n }\n\n this.recordLatency(intent, start);\n return effect;\n } catch (e: any) {\n console.error(`Error routing intent ${intent}:`, e.message);\n throw e;\n }\n }\n\n private recordLatency(intent: string, start: [number, number]) {\n const diff = process.hrtime(start);\n // Available for subclass telemetry hooks or future logging\n void diff;\n }\n}\n","/**\n * AXIS Protocol Magic Bytes (e.g., 'AXIS1')\n */\nexport const AXIS_MAGIC = new Uint8Array([0x41, 0x58, 0x49, 0x53, 0x31]);\n\n/**\n * AXIS Protocol Version\n */\nexport const AXIS_VERSION = 0x01;\n\n/**\n * Maximum allowed size for the Header section in bytes.\n */\nexport const MAX_HDR_LEN = 2048;\n\n/**\n * Maximum allowed size for the Body section in bytes.\n */\nexport const MAX_BODY_LEN = 65536;\n\n/**\n * Maximum allowed size for the Signature section in bytes.\n */\nexport const MAX_SIG_LEN = 128;\n\n/**\n * Total maximum allowed size for a single AXIS frame.\n */\nexport const MAX_FRAME_LEN = 70 * 1024; // 70 KB\n\n/**\n * Frame Control Flags\n */\nexport const FLAG_BODY_TLV = 0x01;\nexport const FLAG_CHAIN_REQ = 0x02;\nexport const FLAG_HAS_WITNESS = 0x04;\n\n/**\n * TLV Tags for Header Section\n */\nexport const TLV_PID = 1;\nexport const TLV_TS = 2;\nexport const TLV_INTENT = 3;\nexport const TLV_ACTOR_ID = 4;\nexport const TLV_PROOF_TYPE = 5;\nexport const TLV_PROOF_REF = 6;\nexport const TLV_NONCE = 7;\nexport const TLV_AUD = 8;\nexport const TLV_NODE = 9;\nexport const TLV_TRACE_ID = 10;\n/** Key ID for key rotation support */\nexport const TLV_KID = 11;\n\n/**\n * TLV Tags for Receipt Section\n */\nexport const TLV_RID = 15;\nexport const TLV_OK = 16;\nexport const TLV_EFFECT = 17;\nexport const TLV_ERROR_CODE = 18;\nexport const TLV_ERROR_MSG = 19;\nexport const TLV_PREV_HASH = 20;\nexport const TLV_RECEIPT_HASH = 21;\nexport const TLV_NODE_KID = 30;\nexport const TLV_NODE_CERT_HASH = 34;\n\n/**\n * TLV Tags for Loom Runtime (Lawful Execution)\n */\n/** Presence ID - liveness proof (UTF-8 string, e.g., \"pr_abc123\") */\nexport const TLV_LOOM_PRESENCE_ID = 91;\n/** Writ - executable intent (canonical JSON, UTF-8 encoded) */\nexport const TLV_LOOM_WRIT = 92;\n/** Thread Hash - causal continuity (32 bytes, raw binary) */\nexport const TLV_LOOM_THREAD_HASH = 93;\n\n/**\n * Supported Authentication Proof Types\n */\nexport const PROOF_CAPSULE = 1;\nexport const PROOF_JWT = 2;\nexport const PROOF_MTLS = 3;\n/** Loom Presence + Writ proof */\nexport const PROOF_LOOM = 4;\n\n/**\n * Standard Protocol Error Codes\n */\nexport const ERR_INVALID_PACKET = 'INVALID_PACKET';\nexport const ERR_BAD_SIGNATURE = 'BAD_SIGNATURE';\nexport const ERR_REPLAY_DETECTED = 'REPLAY_DETECTED';\nexport const ERR_CONTRACT_VIOLATION = 'CONTRACT_VIOLATION';\n","/**\n * Encodes a number (up to 53 bits safe integer) into a Varint buffer.\n * Varints are a way of encoding integers using one or more bytes.\n * Smaller numbers take fewer bytes.\n *\n * @param {number} value - The unsigned integer to encode\n * @returns {Uint8Array} The encoded binary buffer\n * @throws {Error} If the value is negative\n */\nexport function encodeVarint(value: number): Uint8Array {\n if (value < 0) throw new Error('Varint must be unsigned');\n const bytes: number[] = [];\n while (true) {\n const byte = value & 0x7f;\n value >>>= 7;\n if (value === 0) {\n bytes.push(byte);\n break;\n }\n bytes.push(byte | 0x80);\n }\n return new Uint8Array(bytes);\n}\n\n/**\n * Decodes a Varint from a buffer starting at a specific offset.\n *\n * @param {Uint8Array} buf - The buffer containing the encoded varint\n * @param {number} [offset=0] - The starting position in the buffer\n * @returns {Object} The decoded numeric value and the number of bytes consumed (length)\n * @throws {Error} If the buffer is too small or the varint exceeds 8 bytes (max 53-bit safe int)\n */\nexport function decodeVarint(\n buf: Uint8Array,\n offset = 0,\n): { value: number; length: number } {\n let value = 0;\n let shift = 0;\n let length = 0;\n\n while (true) {\n if (offset + length >= buf.length) {\n throw new Error('Varint decode out of bounds');\n }\n const byte = buf[offset + length];\n value += (byte & 0x7f) * Math.pow(2, shift);\n length++;\n shift += 7;\n if ((byte & 0x80) === 0) {\n break;\n }\n if (length > 8) throw new Error('Varint too large');\n }\n\n return { value, length };\n}\n\n/**\n * Calculates the number of bytes required to encode a value as a varint.\n * Useful for pre-allocating buffers.\n *\n * @param {number} value - The unsigned integer to check\n * @returns {number} The byte length\n * @throws {Error} If the value is negative\n */\nexport function varintLength(value: number): number {\n if (value < 0) throw new Error('Varint must be unsigned');\n let len = 0;\n do {\n value >>>= 7;\n len++;\n } while (value !== 0);\n return len;\n}\n","import { encodeVarint, decodeVarint, varintLength } from './varint';\n\n/**\n * Represents a basic Type-Length-Value structure.\n *\n * @interface TLV\n */\nexport interface TLV {\n /** The tag or type identifier */\n type: number;\n /** The raw binary value */\n value: Uint8Array;\n}\n\n/**\n * Encodes an array of TLVs into a canonical binary buffer.\n *\n * **Canonical Rules:**\n * 1. TLVs MUST be sorted by `type` in ascending order.\n * 2. Duplicate `type` entries are NOT allowed.\n * 3. Format: `[type_varint][len_varint][value_bytes]`\n *\n * @param {TLV[]} tlvs - The list of TLV entries to encode\n * @returns {Uint8Array} The sorted and encoded binary buffer\n * @throws {Error} If duplicate types are detected\n */\nexport function encodeTLVs(tlvs: TLV[]): Uint8Array {\n // 1. Sort by TYPE ascending\n // Create a copy to avoid mutating input\n const sorted = [...tlvs].sort((a, b) => a.type - b.type);\n\n // 2. Check for duplicates\n for (let i = 0; i < sorted.length - 1; i++) {\n if (sorted[i].type === sorted[i + 1].type) {\n throw new Error(`Duplicate TLV type: ${sorted[i].type}`);\n }\n }\n\n // 3. Calculate total size\n let totalSize = 0;\n for (const t of sorted) {\n totalSize += varintLength(t.type);\n totalSize += varintLength(t.value.length);\n totalSize += t.value.length;\n }\n\n // 4. Encode\n const buf = new Uint8Array(totalSize);\n let offset = 0;\n for (const t of sorted) {\n const typeBytes = encodeVarint(t.type);\n buf.set(typeBytes, offset);\n offset += typeBytes.length;\n\n const lenBytes = encodeVarint(t.value.length);\n buf.set(lenBytes, offset);\n offset += lenBytes.length;\n\n buf.set(t.value, offset);\n offset += t.value.length;\n }\n\n return buf;\n}\n\n/**\n * Decodes a binary buffer of TLVs into a flat list.\n * Preserves the original wire order and allows duplicate types.\n *\n * @param {Uint8Array} buf - The buffer containing TLV-encoded data\n * @param {number} [maxItems=1024] - Security limit for the number of parsed items\n * @returns {TLV[]} A list of decoded TLV entries\n * @throws {Error} If the buffer is truncated or malformed\n */\nexport function decodeTLVsList(buf: Uint8Array, maxItems = 1024): TLV[] {\n const list: TLV[] = [];\n let offset = 0;\n\n while (offset < buf.length) {\n if (list.length >= maxItems) throw new Error('TLV_LIMIT');\n\n // Decode TYPE\n const { value: type, length: typeLen } = decodeVarint(buf, offset);\n offset += typeLen;\n\n // Decode LEN\n const { value: len, length: lenLen } = decodeVarint(buf, offset);\n offset += lenLen;\n\n // Check bounds\n if (offset + len > buf.length) {\n throw new Error(`TLV violation: Length ${len} exceeds buffer`);\n }\n\n // Extract VALUE\n const value = buf.slice(offset, offset + len);\n list.push({ type, value });\n offset += len;\n }\n\n return list;\n}\n\n/**\n * Decodes a binary buffer of TLVs into a Map for efficient access.\n * Enforces strict canonical order (sorted tiles) and forbids duplicate types.\n *\n * @param {Uint8Array} buf - The buffer containing canonical TLV data\n * @returns {Map<number, Uint8Array>} Map of Tag -> Value\n * @throws {Error} If canonical order is violated or duplicates are found\n */\nexport function decodeTLVs(buf: Uint8Array): Map<number, Uint8Array> {\n const map = new Map<number, Uint8Array>();\n let offset = 0;\n let lastType = -1;\n\n while (offset < buf.length) {\n // Decode TYPE\n const { value: type, length: typeLen } = decodeVarint(buf, offset);\n offset += typeLen;\n\n // Check canonical order\n if (type <= lastType) {\n throw new Error(\n `TLV violation: Unsorted or duplicate type ${type} after ${lastType}`,\n );\n }\n lastType = type;\n\n // Decode LEN\n const { value: len, length: lenLen } = decodeVarint(buf, offset);\n offset += lenLen;\n\n // Check bounds\n if (offset + len > buf.length) {\n throw new Error(`TLV violation: Length ${len} exceeds buffer`);\n }\n\n // Extract VALUE\n const value = buf.slice(offset, offset + len);\n map.set(type, value);\n offset += len;\n }\n\n return map;\n}\n\n/**\n * Recursive Object Decoder (safe nesting).\n * This follows the AXIS Option A: Nested TLV objects.\n */\nexport function decodeObject(\n bytes: Uint8Array,\n depth = 0,\n limits = { maxDepth: 8, maxItems: 128 },\n): Map<number, any> {\n if (depth > limits.maxDepth) {\n throw new Error('OBJECT_DEPTH_EXCEEDED');\n }\n\n const map = decodeTLVs(bytes);\n // In v1, we leave values as Uint8Array unless schema-driven.\n // The IntentSchemaValidator will handle deeper recursion.\n return map;\n}\n\n/**\n * Array Decoder (explicit container).\n * VALUE = repeated TLVs of one ITEM type.\n */\nexport function decodeArray(\n bytes: Uint8Array,\n itemType: number,\n maxItems = 256,\n): Uint8Array[] {\n const list = decodeTLVsList(bytes, maxItems);\n const items: Uint8Array[] = [];\n\n for (const tlv of list) {\n if (tlv.type !== itemType) {\n throw new Error(`INVALID_ARRAY_ITEM:${tlv.type}`);\n }\n items.push(tlv.value);\n }\n\n return items;\n}\n","import * as z from 'zod';\n\n/**\n * AxisFrame Schema\n *\n * Defines the logical structure of an AXIS frame using Zod for runtime validation.\n * This is used for internal processing after the low-level binary parsing is complete.\n */\nexport const AxisFrameZ = z.object({\n /** Flag bits for protocol control (e.g., encryption, compression) */\n flags: z.number().int().nonnegative(),\n /** A map of TLV headers where key=Tag and value=BinaryData */\n headers: z.map(\n z.number(),\n z.custom<Uint8Array>((v) => v instanceof Uint8Array),\n ),\n /** The main payload of the frame */\n body: z.custom<Uint8Array>((v) => v instanceof Uint8Array),\n /** The cryptographic signature covering the frame (except the signature itself) */\n sig: z.custom<Uint8Array>((v) => v instanceof Uint8Array),\n});\n\n/**\n * Represents a structured AXIS frame.\n * @typedef {Object} AxisFrame\n */\nexport type AxisFrame = z.infer<typeof AxisFrameZ>;\nimport {\n AXIS_MAGIC,\n AXIS_VERSION,\n MAX_BODY_LEN,\n MAX_FRAME_LEN,\n MAX_HDR_LEN,\n MAX_SIG_LEN,\n} from './constants';\nimport { decodeTLVs, encodeTLVs } from './tlv';\nimport { decodeVarint, encodeVarint } from './varint';\n\n/**\n * Encodes a structured AxisFrame into its binary wire representation.\n *\n * **Encoding Steps:**\n * 1. Encodes header TLV map into a single buffer.\n * 2. Validates lengths against MAX_* constants.\n * 3. Encodes lengths (HDR, BODY, SIG) as varints.\n * 4. Assembles the final byte array with magic, version, and flags.\n *\n * @param {AxisFrame} frame - The structured frame to encode\n * @returns {Uint8Array} The full binary frame\n * @throws {Error} If any section exceeds protocol limits\n */\nexport function encodeFrame(frame: AxisFrame): Uint8Array {\n const hdrBytes = encodeTLVs(\n Array.from(frame.headers.entries()).map(([t, v]) => ({\n type: t,\n value: v,\n })),\n );\n\n if (hdrBytes.length > MAX_HDR_LEN) throw new Error('Header too large');\n if (frame.body.length > MAX_BODY_LEN) throw new Error('Body too large');\n if (frame.sig.length > MAX_SIG_LEN) throw new Error('Signature too large');\n\n // Header Len, Body Len, Sig Len\n const hdrLenBytes = encodeVarint(hdrBytes.length);\n const bodyLenBytes = encodeVarint(frame.body.length);\n const sigLenBytes = encodeVarint(frame.sig.length);\n\n const totalLen =\n 5 + // Magic (AXIS1)\n 1 + // Version\n 1 + // Flags\n hdrLenBytes.length +\n bodyLenBytes.length +\n sigLenBytes.length +\n hdrBytes.length +\n frame.body.length +\n frame.sig.length;\n\n if (totalLen > MAX_FRAME_LEN) throw new Error('Total frame too large');\n\n const buf = new Uint8Array(totalLen);\n let offset = 0;\n\n // Magic (AXIS1 - 5 bytes)\n buf.set(AXIS_MAGIC, offset);\n offset += 5;\n\n // Version\n buf[offset++] = AXIS_VERSION;\n\n // Flags\n buf[offset++] = frame.flags;\n\n // Lengths\n buf.set(hdrLenBytes, offset);\n offset += hdrLenBytes.length;\n\n buf.set(bodyLenBytes, offset);\n offset += bodyLenBytes.length;\n\n buf.set(sigLenBytes, offset);\n offset += sigLenBytes.length;\n\n // Payloads\n buf.set(hdrBytes, offset);\n offset += hdrBytes.length;\n\n buf.set(frame.body, offset);\n offset += frame.body.length;\n\n buf.set(frame.sig, offset);\n offset += frame.sig.length;\n\n return buf;\n}\n\n/**\n * Decodes a binary buffer into a structured AxisFrame with strict validation.\n *\n * @param {Uint8Array} buf - Raw bytes from the wire\n * @returns {AxisFrame} The parsed and validated frame\n * @throws {Error} If magic, version, or lengths are invalid\n */\nexport function decodeFrame(buf: Uint8Array): AxisFrame {\n let offset = 0;\n\n // 1. Magic (AXIS1 - 5 bytes)\n if (offset + 5 > buf.length) throw new Error('Packet too short');\n for (let i = 0; i < 5; i++) {\n if (buf[offset + i] !== AXIS_MAGIC[i]) throw new Error('Invalid Magic');\n }\n offset += 5;\n\n // 2. Version\n const ver = buf[offset++];\n if (ver !== AXIS_VERSION) throw new Error(`Unsupported version: ${ver}`);\n\n // 3. Flags\n const flags = buf[offset++];\n\n // 4. Lengths\n const { value: hdrLen, length: hlLen } = decodeVarint(buf, offset);\n offset += hlLen;\n if (hdrLen > MAX_HDR_LEN) throw new Error('Header limit exceeded');\n\n const { value: bodyLen, length: blLen } = decodeVarint(buf, offset);\n offset += blLen;\n if (bodyLen > MAX_BODY_LEN) throw new Error('Body limit exceeded');\n\n const { value: sigLen, length: slLen } = decodeVarint(buf, offset);\n offset += slLen;\n if (sigLen > MAX_SIG_LEN) throw new Error('Signature limit exceeded');\n\n // 5. Extract Bytes\n if (offset + hdrLen + bodyLen + sigLen > buf.length) {\n throw new Error('Frame truncated');\n }\n\n const hdrBytes = buf.slice(offset, offset + hdrLen);\n offset += hdrLen;\n\n const bodyBytes = buf.slice(offset, offset + bodyLen);\n offset += bodyLen;\n\n const sigBytes = buf.slice(offset, offset + sigLen);\n offset += sigLen;\n\n // 6. Decode Header TLVs\n const headers = decodeTLVs(hdrBytes);\n\n return {\n flags,\n headers,\n body: bodyBytes,\n sig: sigBytes,\n };\n}\n\n/**\n * Helper to get canonical bytes for signing.\n * SigTarget = All bytes up to SigLen, with SigLen=0, and no SigBytes.\n */\nexport function getSignTarget(frame: AxisFrame): Uint8Array {\n // Re-encode frame but with empty signature\n // Note: This is efficient enough for v1 (tens of KB).\n return encodeFrame({\n ...frame,\n sig: new Uint8Array(0),\n });\n}\n","import * as crypto from 'crypto';\n\nimport { AxisFrame, encodeFrame } from './axis-bin';\n\n/**\n * Signature utilities for AXIS binary frames\n * Supports Ed25519 signature generation and verification\n */\n\n/**\n * Computes the canonical payload for signing an AXIS frame.\n * The signature covers all bytes of the encoded frame EXCEPT the signature field itself.\n *\n * @param {AxisFrame} frame - The frame to prepare for signing\n * @returns {Buffer} The serialized canonical bytes for the signature algorithm\n */\nexport function computeSignaturePayload(frame: AxisFrame): Buffer {\n // Re-encode frame with empty signature\n const frameWithoutSig: AxisFrame = {\n ...frame,\n sig: new Uint8Array(0),\n };\n\n const encoded = encodeFrame(frameWithoutSig);\n return Buffer.from(encoded);\n}\n\n/**\n * Signs an AXIS frame using the Ed25519 algorithm.\n * Automatically handles both raw 32-byte seeds and pkcs8 DER-encoded private keys.\n *\n * @param {AxisFrame} frame - The frame to sign\n * @param {Buffer} privateKey - Ed25519 private key (32-byte raw OR pkcs8 DER)\n * @returns {Buffer} The 64-byte Ed25519 signature\n * @throws {Error} If key format is invalid or signing fail\n */\nexport function signFrame(frame: AxisFrame, privateKey: Buffer): Buffer {\n const payload = computeSignaturePayload(frame);\n\n let keyObject: crypto.KeyObject;\n\n // Check if key is raw 32-byte seed or DER-encoded\n if (privateKey.length === 32) {\n // Raw seed - wrap in pkcs8 DER format\n // pkcs8 prefix for Ed25519: 0x302e020100300506032b657004220420\n const pkcs8Prefix = Buffer.from([\n 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70,\n 0x04, 0x22, 0x04, 0x20,\n ]);\n const pkcs8Key = Buffer.concat([pkcs8Prefix, privateKey]);\n\n keyObject = crypto.createPrivateKey({\n key: pkcs8Key,\n format: 'der',\n type: 'pkcs8',\n });\n } else {\n // Assume already DER-encoded pkcs8\n keyObject = crypto.createPrivateKey({\n key: privateKey,\n format: 'der',\n type: 'pkcs8',\n });\n }\n\n const signature = crypto.sign(null, payload, keyObject);\n\n if (signature.length !== 64) {\n throw new Error('Ed25519 signature must be 64 bytes');\n }\n\n return signature;\n}\n\n/**\n * Verifies an Ed25519 signature on an AXIS frame.\n * Automatically handles both raw 32-byte public keys and spki DER-encoded public keys.\n *\n * @param {AxisFrame} frame - The frame containing the signature to verify\n * @param {Buffer} publicKey - Ed25519 public key (32-byte raw OR spki DER)\n * @returns {boolean} True if the signature is cryptographically valid\n * @throws {Error} If signature length is invalid\n */\nexport function verifyFrameSignature(\n frame: AxisFrame,\n publicKey: Buffer,\n): boolean {\n if (frame.sig.length === 0) {\n return false; // No signature\n }\n\n if (frame.sig.length !== 64) {\n throw new Error('Ed25519 signature must be 64 bytes');\n }\n\n const payload = computeSignaturePayload(frame);\n\n try {\n let keyObject: crypto.KeyObject;\n\n // Check if key is raw 32-byte or DER-encoded\n if (publicKey.length === 32) {\n // Raw key - wrap in spki DER format\n // spki prefix for Ed25519: 0x302a300506032b6570032100\n const spkiPrefix = Buffer.from([\n 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00,\n ]);\n const spkiKey = Buffer.concat([spkiPrefix, publicKey]);\n\n keyObject = crypto.createPublicKey({\n key: spkiKey,\n format: 'der',\n type: 'spki',\n });\n } else {\n // Assume already DER-encoded spki\n keyObject = crypto.createPublicKey({\n key: publicKey,\n format: 'der',\n type: 'spki',\n });\n }\n\n const valid = crypto.verify(\n null,\n payload,\n keyObject,\n Buffer.from(frame.sig),\n );\n return valid;\n } catch (error) {\n return false;\n }\n}\n\n/**\n * Generates a new Ed25519 key pair for use with the AXIS protocol.\n * Returns keys in canonical DER format (pkcs8 for private, spki for public).\n *\n * @returns {Object} An object containing the privateKey and publicKey as Buffers\n */\nexport function generateEd25519KeyPair(): {\n privateKey: Buffer;\n publicKey: Buffer;\n} {\n const { privateKey, publicKey } = crypto.generateKeyPairSync('ed25519');\n\n return {\n privateKey: privateKey.export({ type: 'pkcs8', format: 'der' }) as Buffer,\n publicKey: publicKey.export({ type: 'spki', format: 'der' }) as Buffer,\n };\n}\n\n/**\n * Computes a standard SHA-256 hash of the provided data.\n *\n * @param {Buffer | Uint8Array} data - The input data to hash\n * @returns {Buffer} The 32-byte SHA-256 digest\n */\nexport function sha256(data: Buffer | Uint8Array): Buffer {\n return crypto.createHash('sha256').update(data).digest();\n}\n\n/**\n * Computes a hash for an AXIS receipt, optionally chaining it to a previous hash.\n * This is used for generating an immutable transaction chain.\n *\n * @param {Buffer | Uint8Array} receiptBytes - The canonical binary representation of the receipt\n * @param {Buffer | Uint8Array} [prevHash] - The hash of the previous receipt in the chain\n * @returns {Buffer} The 32-byte SHA-256 hash of the receipt (and link)\n */\nexport function computeReceiptHash(\n receiptBytes: Buffer | Uint8Array,\n prevHash?: Buffer | Uint8Array,\n): Buffer {\n const hasher = crypto.createHash('sha256');\n hasher.update(receiptBytes);\n\n if (prevHash && prevHash.length > 0) {\n hasher.update(prevHash);\n }\n\n return hasher.digest();\n}\n"],"mappings":"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","names":["import_common","map"]}
|