@labacacia/nps-sdk 1.0.0-alpha.1 → 1.0.0-alpha.3
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/CHANGELOG.cn.md +57 -0
- package/CHANGELOG.md +57 -0
- package/CONTRIBUTING.cn.md +35 -0
- package/CONTRIBUTING.md +2 -0
- package/README.cn.md +155 -0
- package/README.md +5 -3
- package/dist/core/anchor-cache.d.ts +0 -0
- package/dist/core/anchor-cache.d.ts.map +0 -0
- package/dist/core/cache.d.ts +0 -0
- package/dist/core/cache.d.ts.map +0 -0
- package/dist/core/canonical-json.d.ts +0 -0
- package/dist/core/canonical-json.d.ts.map +0 -0
- package/dist/core/codec.d.ts +0 -0
- package/dist/core/codec.d.ts.map +0 -0
- package/dist/core/codecs/index.d.ts +0 -0
- package/dist/core/codecs/index.d.ts.map +0 -0
- package/dist/core/codecs/ncp-codec.d.ts +0 -0
- package/dist/core/codecs/ncp-codec.d.ts.map +0 -0
- package/dist/core/codecs/tier1-json-codec.d.ts +0 -0
- package/dist/core/codecs/tier1-json-codec.d.ts.map +0 -0
- package/dist/core/codecs/tier2-msgpack-codec.d.ts +0 -0
- package/dist/core/codecs/tier2-msgpack-codec.d.ts.map +0 -0
- package/dist/core/crypto-provider.d.ts +0 -0
- package/dist/core/crypto-provider.d.ts.map +0 -0
- package/dist/core/exceptions.d.ts +0 -0
- package/dist/core/exceptions.d.ts.map +0 -0
- package/dist/core/frame-header.d.ts +0 -0
- package/dist/core/frame-header.d.ts.map +0 -0
- package/dist/core/frame-registry.d.ts +0 -0
- package/dist/core/frame-registry.d.ts.map +0 -0
- package/dist/core/frames.d.ts +1 -0
- package/dist/core/frames.d.ts.map +1 -1
- package/dist/core/index.cjs +90 -9
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +6 -4
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +405 -9
- package/dist/core/index.js.map +1 -1
- package/dist/core/registry.d.ts +0 -0
- package/dist/core/registry.d.ts.map +0 -0
- package/dist/core/status-codes.d.ts +0 -0
- package/dist/core/status-codes.d.ts.map +0 -0
- package/dist/index.cjs +3 -1551
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/ncp/frames/anchor-frame.d.ts +0 -0
- package/dist/ncp/frames/anchor-frame.d.ts.map +0 -0
- package/dist/ncp/frames/caps-frame.d.ts +0 -0
- package/dist/ncp/frames/caps-frame.d.ts.map +0 -0
- package/dist/ncp/frames/diff-frame.d.ts +0 -0
- package/dist/ncp/frames/diff-frame.d.ts.map +0 -0
- package/dist/ncp/frames/error-frame.d.ts +0 -0
- package/dist/ncp/frames/error-frame.d.ts.map +0 -0
- package/dist/ncp/frames/hello-frame.d.ts +0 -0
- package/dist/ncp/frames/hello-frame.d.ts.map +0 -0
- package/dist/ncp/frames/stream-frame.d.ts +0 -0
- package/dist/ncp/frames/stream-frame.d.ts.map +0 -0
- package/dist/ncp/frames.d.ts +18 -0
- package/dist/ncp/frames.d.ts.map +1 -1
- package/dist/ncp/handshake.d.ts +0 -0
- package/dist/ncp/handshake.d.ts.map +0 -0
- package/dist/ncp/index.cjs +364 -164
- package/dist/ncp/index.cjs.map +1 -1
- package/dist/ncp/index.d.ts +0 -0
- package/dist/ncp/index.d.ts.map +0 -0
- package/dist/ncp/index.js +368 -12
- package/dist/ncp/index.js.map +1 -1
- package/dist/ncp/ncp-error-codes.d.ts +0 -0
- package/dist/ncp/ncp-error-codes.d.ts.map +0 -0
- package/dist/ncp/ncp-patch-format.d.ts +0 -0
- package/dist/ncp/ncp-patch-format.d.ts.map +0 -0
- package/dist/ncp/registry.d.ts +0 -0
- package/dist/ncp/registry.d.ts.map +1 -1
- package/dist/ncp/stream-manager.d.ts +0 -0
- package/dist/ncp/stream-manager.d.ts.map +0 -0
- package/dist/ndp/frames.d.ts +0 -0
- package/dist/ndp/frames.d.ts.map +0 -0
- package/dist/ndp/index.cjs +0 -0
- package/dist/ndp/index.cjs.map +0 -0
- package/dist/ndp/index.d.ts +0 -0
- package/dist/ndp/index.d.ts.map +0 -0
- package/dist/ndp/index.js +223 -6
- package/dist/ndp/index.js.map +1 -1
- package/dist/ndp/ndp-registry.d.ts +0 -0
- package/dist/ndp/ndp-registry.d.ts.map +0 -0
- package/dist/ndp/registry.d.ts +0 -0
- package/dist/ndp/registry.d.ts.map +0 -0
- package/dist/ndp/validator.d.ts +0 -0
- package/dist/ndp/validator.d.ts.map +0 -0
- package/dist/nip/frames.d.ts +0 -0
- package/dist/nip/frames.d.ts.map +0 -0
- package/dist/nip/identity.d.ts +0 -0
- package/dist/nip/identity.d.ts.map +0 -0
- package/dist/nip/index.cjs +0 -0
- package/dist/nip/index.cjs.map +0 -0
- package/dist/nip/index.d.ts +0 -0
- package/dist/nip/index.d.ts.map +0 -0
- package/dist/nip/index.js +187 -5
- package/dist/nip/index.js.map +1 -1
- package/dist/nip/registry.d.ts +0 -0
- package/dist/nip/registry.d.ts.map +0 -0
- package/dist/nop/client.d.ts +0 -0
- package/dist/nop/client.d.ts.map +0 -0
- package/dist/nop/frames.d.ts +0 -0
- package/dist/nop/frames.d.ts.map +0 -0
- package/dist/nop/index.cjs +62 -1
- package/dist/nop/index.cjs.map +1 -1
- package/dist/nop/index.d.ts +0 -0
- package/dist/nop/index.d.ts.map +0 -0
- package/dist/nop/index.js +789 -6
- package/dist/nop/index.js.map +1 -1
- package/dist/nop/models.d.ts +0 -0
- package/dist/nop/models.d.ts.map +0 -0
- package/dist/nop/nop-types.d.ts +0 -0
- package/dist/nop/nop-types.d.ts.map +0 -0
- package/dist/nop/registry.d.ts +0 -0
- package/dist/nop/registry.d.ts.map +0 -0
- package/dist/nwp/client.d.ts +0 -0
- package/dist/nwp/client.d.ts.map +0 -0
- package/dist/nwp/frames.d.ts +0 -0
- package/dist/nwp/frames.d.ts.map +0 -0
- package/dist/nwp/index.cjs +64 -2
- package/dist/nwp/index.cjs.map +1 -1
- package/dist/nwp/index.d.ts +0 -0
- package/dist/nwp/index.d.ts.map +0 -0
- package/dist/nwp/index.js +693 -5
- package/dist/nwp/index.js.map +1 -1
- package/dist/nwp/registry.d.ts +0 -0
- package/dist/nwp/registry.d.ts.map +0 -0
- package/dist/setup.d.ts +0 -0
- package/dist/setup.d.ts.map +0 -0
- package/doc/nps-sdk.core.cn.md +321 -0
- package/doc/nps-sdk.core.md +326 -0
- package/doc/nps-sdk.ncp.cn.md +270 -0
- package/doc/nps-sdk.ncp.md +276 -0
- package/doc/nps-sdk.ndp.cn.md +267 -0
- package/doc/nps-sdk.ndp.md +273 -0
- package/doc/nps-sdk.nip.cn.md +235 -0
- package/doc/nps-sdk.nip.md +242 -0
- package/doc/nps-sdk.nop.cn.md +329 -0
- package/doc/nps-sdk.nop.md +332 -0
- package/doc/nps-sdk.nwp.cn.md +217 -0
- package/doc/nps-sdk.nwp.md +224 -0
- package/doc/overview.cn.md +149 -0
- package/doc/overview.md +153 -0
- package/package.json +21 -4
- package/src/core/frames.ts +1 -0
- package/src/core/index.ts +37 -5
- package/src/index.ts +1 -1
- package/src/ncp/frames.ts +52 -0
- package/src/ncp/registry.ts +2 -1
- package/dist/codec-CmHeovTV.d.cts +0 -120
- package/dist/codec-CmHeovTV.d.ts +0 -120
- package/dist/core/anchor-cache.js +0 -104
- package/dist/core/anchor-cache.js.map +0 -1
- package/dist/core/cache.js +0 -80
- package/dist/core/cache.js.map +0 -1
- package/dist/core/canonical-json.js +0 -44
- package/dist/core/canonical-json.js.map +0 -1
- package/dist/core/codec.js +0 -119
- package/dist/core/codec.js.map +0 -1
- package/dist/core/codecs/index.js +0 -6
- package/dist/core/codecs/index.js.map +0 -1
- package/dist/core/codecs/ncp-codec.js +0 -93
- package/dist/core/codecs/ncp-codec.js.map +0 -1
- package/dist/core/codecs/tier1-json-codec.js +0 -28
- package/dist/core/codecs/tier1-json-codec.js.map +0 -1
- package/dist/core/codecs/tier2-msgpack-codec.js +0 -26
- package/dist/core/codecs/tier2-msgpack-codec.js.map +0 -1
- package/dist/core/crypto-provider.js +0 -10
- package/dist/core/crypto-provider.js.map +0 -1
- package/dist/core/exceptions.js +0 -52
- package/dist/core/exceptions.js.map +0 -1
- package/dist/core/frame-header.js +0 -185
- package/dist/core/frame-header.js.map +0 -1
- package/dist/core/frame-registry.js +0 -63
- package/dist/core/frame-registry.js.map +0 -1
- package/dist/core/frames.js +0 -153
- package/dist/core/frames.js.map +0 -1
- package/dist/core/index.d.cts +0 -41
- package/dist/core/registry.js +0 -17
- package/dist/core/registry.js.map +0 -1
- package/dist/core/status-codes.js +0 -38
- package/dist/core/status-codes.js.map +0 -1
- package/dist/frames-B3qLdl_g.d.cts +0 -77
- package/dist/frames-Ff7-ZPUl.d.ts +0 -77
- package/dist/index.d.cts +0 -21
- package/dist/ncp/frames/anchor-frame.js +0 -54
- package/dist/ncp/frames/anchor-frame.js.map +0 -1
- package/dist/ncp/frames/caps-frame.js +0 -29
- package/dist/ncp/frames/caps-frame.js.map +0 -1
- package/dist/ncp/frames/diff-frame.js +0 -37
- package/dist/ncp/frames/diff-frame.js.map +0 -1
- package/dist/ncp/frames/error-frame.js +0 -13
- package/dist/ncp/frames/error-frame.js.map +0 -1
- package/dist/ncp/frames/hello-frame.js +0 -25
- package/dist/ncp/frames/hello-frame.js.map +0 -1
- package/dist/ncp/frames/stream-frame.js +0 -18
- package/dist/ncp/frames/stream-frame.js.map +0 -1
- package/dist/ncp/frames.js +0 -147
- package/dist/ncp/frames.js.map +0 -1
- package/dist/ncp/handshake.js +0 -80
- package/dist/ncp/handshake.js.map +0 -1
- package/dist/ncp/index.d.cts +0 -6
- package/dist/ncp/ncp-error-codes.js +0 -32
- package/dist/ncp/ncp-error-codes.js.map +0 -1
- package/dist/ncp/ncp-patch-format.js +0 -13
- package/dist/ncp/ncp-patch-format.js.map +0 -1
- package/dist/ncp/registry.js +0 -12
- package/dist/ncp/registry.js.map +0 -1
- package/dist/ncp/stream-manager.js +0 -163
- package/dist/ncp/stream-manager.js.map +0 -1
- package/dist/ndp/frames.js +0 -87
- package/dist/ndp/frames.js.map +0 -1
- package/dist/ndp/index.d.cts +0 -86
- package/dist/ndp/ndp-registry.js +0 -79
- package/dist/ndp/ndp-registry.js.map +0 -1
- package/dist/ndp/registry.js +0 -10
- package/dist/ndp/registry.js.map +0 -1
- package/dist/ndp/validator.js +0 -48
- package/dist/ndp/validator.js.map +0 -1
- package/dist/nip/frames.js +0 -81
- package/dist/nip/frames.js.map +0 -1
- package/dist/nip/identity.js +0 -94
- package/dist/nip/identity.js.map +0 -1
- package/dist/nip/index.d.cts +0 -65
- package/dist/nip/registry.js +0 -10
- package/dist/nip/registry.js.map +0 -1
- package/dist/nop/client.js +0 -90
- package/dist/nop/client.js.map +0 -1
- package/dist/nop/frames.js +0 -148
- package/dist/nop/frames.js.map +0 -1
- package/dist/nop/index.d.cts +0 -155
- package/dist/nop/models.js +0 -50
- package/dist/nop/models.js.map +0 -1
- package/dist/nop/nop-types.js +0 -44
- package/dist/nop/nop-types.js.map +0 -1
- package/dist/nop/registry.js +0 -11
- package/dist/nop/registry.js.map +0 -1
- package/dist/nwp/client.js +0 -101
- package/dist/nwp/client.js.map +0 -1
- package/dist/nwp/frames.js +0 -81
- package/dist/nwp/frames.js.map +0 -1
- package/dist/nwp/index.d.cts +0 -65
- package/dist/nwp/registry.js +0 -9
- package/dist/nwp/registry.js.map +0 -1
- package/dist/setup.js +0 -29
- package/dist/setup.js.map +0 -1
package/dist/ndp/frames.d.ts.map
CHANGED
|
File without changes
|
package/dist/ndp/index.cjs
CHANGED
|
File without changes
|
package/dist/ndp/index.cjs.map
CHANGED
|
File without changes
|
package/dist/ndp/index.d.ts
CHANGED
|
File without changes
|
package/dist/ndp/index.d.ts.map
CHANGED
|
File without changes
|
package/dist/ndp/index.js
CHANGED
|
@@ -1,7 +1,224 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import * as ed25519 from '@noble/ed25519';
|
|
2
|
+
import { sha512 } from '@noble/hashes/sha512';
|
|
3
|
+
|
|
4
|
+
// src/ndp/frames.ts
|
|
5
|
+
var AnnounceFrame = class _AnnounceFrame {
|
|
6
|
+
constructor(nid, addresses, capabilities, ttl, timestamp, signature, nodeType) {
|
|
7
|
+
this.nid = nid;
|
|
8
|
+
this.addresses = addresses;
|
|
9
|
+
this.capabilities = capabilities;
|
|
10
|
+
this.ttl = ttl;
|
|
11
|
+
this.timestamp = timestamp;
|
|
12
|
+
this.signature = signature;
|
|
13
|
+
this.nodeType = nodeType;
|
|
14
|
+
}
|
|
15
|
+
nid;
|
|
16
|
+
addresses;
|
|
17
|
+
capabilities;
|
|
18
|
+
ttl;
|
|
19
|
+
timestamp;
|
|
20
|
+
signature;
|
|
21
|
+
nodeType;
|
|
22
|
+
frameType = 48 /* ANNOUNCE */;
|
|
23
|
+
preferredTier = 1 /* MSGPACK */;
|
|
24
|
+
unsignedDict() {
|
|
25
|
+
return {
|
|
26
|
+
nid: this.nid,
|
|
27
|
+
addresses: this.addresses,
|
|
28
|
+
capabilities: this.capabilities,
|
|
29
|
+
ttl: this.ttl,
|
|
30
|
+
timestamp: this.timestamp,
|
|
31
|
+
node_type: this.nodeType ?? null
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
toDict() {
|
|
35
|
+
return { ...this.unsignedDict(), signature: this.signature };
|
|
36
|
+
}
|
|
37
|
+
static fromDict(data) {
|
|
38
|
+
return new _AnnounceFrame(
|
|
39
|
+
data["nid"],
|
|
40
|
+
data["addresses"],
|
|
41
|
+
data["capabilities"],
|
|
42
|
+
data["ttl"],
|
|
43
|
+
data["timestamp"],
|
|
44
|
+
data["signature"],
|
|
45
|
+
data["node_type"] ?? void 0
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var ResolveFrame = class _ResolveFrame {
|
|
50
|
+
constructor(target, requesterNid, resolved) {
|
|
51
|
+
this.target = target;
|
|
52
|
+
this.requesterNid = requesterNid;
|
|
53
|
+
this.resolved = resolved;
|
|
54
|
+
}
|
|
55
|
+
target;
|
|
56
|
+
requesterNid;
|
|
57
|
+
resolved;
|
|
58
|
+
frameType = 49 /* RESOLVE */;
|
|
59
|
+
preferredTier = 1 /* MSGPACK */;
|
|
60
|
+
toDict() {
|
|
61
|
+
return {
|
|
62
|
+
target: this.target,
|
|
63
|
+
requester_nid: this.requesterNid ?? null,
|
|
64
|
+
resolved: this.resolved ?? null
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
static fromDict(data) {
|
|
68
|
+
return new _ResolveFrame(
|
|
69
|
+
data["target"],
|
|
70
|
+
data["requester_nid"] ?? void 0,
|
|
71
|
+
data["resolved"] ?? void 0
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var GraphFrame = class _GraphFrame {
|
|
76
|
+
constructor(seq, initialSync, nodes, patch) {
|
|
77
|
+
this.seq = seq;
|
|
78
|
+
this.initialSync = initialSync;
|
|
79
|
+
this.nodes = nodes;
|
|
80
|
+
this.patch = patch;
|
|
81
|
+
}
|
|
82
|
+
seq;
|
|
83
|
+
initialSync;
|
|
84
|
+
nodes;
|
|
85
|
+
patch;
|
|
86
|
+
frameType = 50 /* GRAPH */;
|
|
87
|
+
preferredTier = 1 /* MSGPACK */;
|
|
88
|
+
toDict() {
|
|
89
|
+
return {
|
|
90
|
+
seq: this.seq,
|
|
91
|
+
initial_sync: this.initialSync,
|
|
92
|
+
nodes: this.nodes ?? null,
|
|
93
|
+
patch: this.patch ?? null
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
static fromDict(data) {
|
|
97
|
+
return new _GraphFrame(
|
|
98
|
+
data["seq"],
|
|
99
|
+
data["initial_sync"],
|
|
100
|
+
data["nodes"] ?? void 0,
|
|
101
|
+
data["patch"] ?? void 0
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// src/ndp/registry.ts
|
|
107
|
+
function registerNdpFrames(registry) {
|
|
108
|
+
registry.register(48 /* ANNOUNCE */, AnnounceFrame);
|
|
109
|
+
registry.register(49 /* RESOLVE */, ResolveFrame);
|
|
110
|
+
registry.register(50 /* GRAPH */, GraphFrame);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/ndp/ndp-registry.ts
|
|
114
|
+
var InMemoryNdpRegistry = class _InMemoryNdpRegistry {
|
|
115
|
+
_store = /* @__PURE__ */ new Map();
|
|
116
|
+
// Replaceable for testing
|
|
117
|
+
clock = () => Date.now();
|
|
118
|
+
announce(frame) {
|
|
119
|
+
const expiresAt = this.clock() + frame.ttl * 1e3;
|
|
120
|
+
if (frame.ttl === 0) {
|
|
121
|
+
this._store.delete(frame.nid);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this._store.set(frame.nid, { frame, expiresAt });
|
|
125
|
+
}
|
|
126
|
+
getByNid(nid) {
|
|
127
|
+
const entry = this._store.get(nid);
|
|
128
|
+
if (entry === void 0) return void 0;
|
|
129
|
+
if (this.clock() > entry.expiresAt) {
|
|
130
|
+
this._store.delete(nid);
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
return entry.frame;
|
|
134
|
+
}
|
|
135
|
+
resolve(target) {
|
|
136
|
+
for (const [nid, entry] of this._store) {
|
|
137
|
+
if (this.clock() > entry.expiresAt) {
|
|
138
|
+
this._store.delete(nid);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (!_InMemoryNdpRegistry.nwpTargetMatchesNid(nid, target)) continue;
|
|
142
|
+
const addr = entry.frame.addresses[0];
|
|
143
|
+
if (addr === void 0) continue;
|
|
144
|
+
return { host: addr.host, port: addr.port, ttl: entry.frame.ttl };
|
|
145
|
+
}
|
|
146
|
+
return void 0;
|
|
147
|
+
}
|
|
148
|
+
getAll() {
|
|
149
|
+
const now = this.clock();
|
|
150
|
+
const result = [];
|
|
151
|
+
for (const [nid, entry] of this._store) {
|
|
152
|
+
if (now > entry.expiresAt) {
|
|
153
|
+
this._store.delete(nid);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
result.push(entry.frame);
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
static nwpTargetMatchesNid(nid, target) {
|
|
161
|
+
const nidParts = nid.split(":");
|
|
162
|
+
if (nidParts.length < 5 || nidParts[0] !== "urn" || nidParts[1] !== "nps" || nidParts[2] !== "node") {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
if (!target.startsWith("nwp://")) return false;
|
|
166
|
+
const nidAuthority = nidParts[3];
|
|
167
|
+
const nidPath = nidParts[4];
|
|
168
|
+
const rest = target.slice("nwp://".length);
|
|
169
|
+
const slashIdx = rest.indexOf("/");
|
|
170
|
+
if (slashIdx === -1) return false;
|
|
171
|
+
const urlAuthority = rest.slice(0, slashIdx);
|
|
172
|
+
const urlPath = rest.slice(slashIdx + 1);
|
|
173
|
+
if (urlAuthority !== nidAuthority) return false;
|
|
174
|
+
if (urlPath === nidPath) return true;
|
|
175
|
+
if (urlPath.startsWith(nidPath + "/")) return true;
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
ed25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));
|
|
180
|
+
var NdpAnnounceResult = {
|
|
181
|
+
ok: () => ({ isValid: true }),
|
|
182
|
+
fail: (errorCode, message) => ({ isValid: false, errorCode, message })
|
|
183
|
+
};
|
|
184
|
+
var NdpAnnounceValidator = class {
|
|
185
|
+
_keys = /* @__PURE__ */ new Map();
|
|
186
|
+
// nid → "ed25519:<hex>"
|
|
187
|
+
registerPublicKey(nid, encodedPubKey) {
|
|
188
|
+
this._keys.set(nid, encodedPubKey);
|
|
189
|
+
}
|
|
190
|
+
removePublicKey(nid) {
|
|
191
|
+
this._keys.delete(nid);
|
|
192
|
+
}
|
|
193
|
+
get knownPublicKeys() {
|
|
194
|
+
return this._keys;
|
|
195
|
+
}
|
|
196
|
+
validate(frame) {
|
|
197
|
+
const encoded = this._keys.get(frame.nid);
|
|
198
|
+
if (encoded === void 0) {
|
|
199
|
+
return NdpAnnounceResult.fail("NDP-ANNOUNCE-NID-MISMATCH", `No public key registered for NID: ${frame.nid}`);
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
const prefix = "ed25519:";
|
|
203
|
+
const pubHex = encoded.startsWith(prefix) ? encoded.slice(prefix.length) : encoded;
|
|
204
|
+
const pubKey = Buffer.from(pubHex, "hex");
|
|
205
|
+
const sig = frame.signature;
|
|
206
|
+
if (!sig.startsWith(prefix)) {
|
|
207
|
+
return NdpAnnounceResult.fail("NDP-ANNOUNCE-SIG-INVALID", "Signature must start with 'ed25519:'");
|
|
208
|
+
}
|
|
209
|
+
const sigBytes = Buffer.from(sig.slice(prefix.length), "base64");
|
|
210
|
+
const unsigned = frame.unsignedDict();
|
|
211
|
+
const canonical = JSON.stringify(unsigned, Object.keys(unsigned).sort());
|
|
212
|
+
const message = new TextEncoder().encode(canonical);
|
|
213
|
+
const valid = ed25519.verify(sigBytes, message, pubKey);
|
|
214
|
+
if (!valid) return NdpAnnounceResult.fail("NDP-ANNOUNCE-SIG-INVALID", "Ed25519 signature verification failed.");
|
|
215
|
+
return NdpAnnounceResult.ok();
|
|
216
|
+
} catch {
|
|
217
|
+
return NdpAnnounceResult.fail("NDP-ANNOUNCE-SIG-INVALID", "Ed25519 signature verification failed.");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
export { AnnounceFrame, GraphFrame, InMemoryNdpRegistry, NdpAnnounceResult, NdpAnnounceValidator, ResolveFrame, registerNdpFrames };
|
|
223
|
+
//# sourceMappingURL=index.js.map
|
|
7
224
|
//# sourceMappingURL=index.js.map
|
package/dist/ndp/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ndp/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,sCAAsC;AAEtC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"sources":["../../src/ndp/frames.ts","../../src/ndp/registry.ts","../../src/ndp/ndp-registry.ts","../../src/ndp/validator.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncodingTier, FrameType } from \"../core/frames.js\";\nimport type { NpsFrame } from \"../core/codec.js\";\n\nexport interface NdpAddress {\n host: string;\n port: number;\n protocol: string;\n}\n\nexport interface NdpGraphNode {\n nid: string;\n addresses: readonly NdpAddress[];\n capabilities: readonly string[];\n nodeType?: string;\n}\n\nexport interface NdpResolveResult {\n host: string;\n port: number;\n ttl: number;\n certFingerprint?: string;\n}\n\nexport class AnnounceFrame implements NpsFrame {\n readonly frameType = FrameType.ANNOUNCE;\n readonly preferredTier = EncodingTier.MSGPACK;\n\n constructor(\n public readonly nid: string,\n public readonly addresses: readonly NdpAddress[],\n public readonly capabilities: readonly string[],\n public readonly ttl: number,\n public readonly timestamp: string,\n public readonly signature: string,\n public readonly nodeType?: string,\n ) {}\n\n unsignedDict(): Record<string, unknown> {\n return {\n nid: this.nid,\n addresses: this.addresses,\n capabilities: this.capabilities,\n ttl: this.ttl,\n timestamp: this.timestamp,\n node_type: this.nodeType ?? null,\n };\n }\n\n toDict(): Record<string, unknown> {\n return { ...this.unsignedDict(), signature: this.signature };\n }\n\n static fromDict(data: Record<string, unknown>): AnnounceFrame {\n return new AnnounceFrame(\n data[\"nid\"] as string,\n data[\"addresses\"] as NdpAddress[],\n data[\"capabilities\"] as string[],\n data[\"ttl\"] as number,\n data[\"timestamp\"] as string,\n data[\"signature\"] as string,\n (data[\"node_type\"] as string | null) ?? undefined,\n );\n }\n}\n\nexport class ResolveFrame implements NpsFrame {\n readonly frameType = FrameType.RESOLVE;\n readonly preferredTier = EncodingTier.MSGPACK;\n\n constructor(\n public readonly target: string,\n public readonly requesterNid?: string,\n public readonly resolved?: NdpResolveResult,\n ) {}\n\n toDict(): Record<string, unknown> {\n return {\n target: this.target,\n requester_nid: this.requesterNid ?? null,\n resolved: this.resolved ?? null,\n };\n }\n\n static fromDict(data: Record<string, unknown>): ResolveFrame {\n return new ResolveFrame(\n data[\"target\"] as string,\n (data[\"requester_nid\"] as string | null) ?? undefined,\n (data[\"resolved\"] as NdpResolveResult | null) ?? undefined,\n );\n }\n}\n\nexport class GraphFrame implements NpsFrame {\n readonly frameType = FrameType.GRAPH;\n readonly preferredTier = EncodingTier.MSGPACK;\n\n constructor(\n public readonly seq: number,\n public readonly initialSync: boolean,\n public readonly nodes?: readonly NdpGraphNode[],\n public readonly patch?: readonly Record<string, unknown>[],\n ) {}\n\n toDict(): Record<string, unknown> {\n return {\n seq: this.seq,\n initial_sync: this.initialSync,\n nodes: this.nodes ?? null,\n patch: this.patch ?? null,\n };\n }\n\n static fromDict(data: Record<string, unknown>): GraphFrame {\n return new GraphFrame(\n data[\"seq\"] as number,\n data[\"initial_sync\"] as boolean,\n (data[\"nodes\"] as NdpGraphNode[] | null) ?? undefined,\n (data[\"patch\"] as Record<string, unknown>[] | null) ?? undefined,\n );\n }\n}\n","// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\nimport { FrameRegistry } from \"../core/registry.js\";\nimport { FrameType } from \"../core/frames.js\";\nimport { AnnounceFrame, GraphFrame, ResolveFrame } from \"./frames.js\";\n\nexport function registerNdpFrames(registry: FrameRegistry): void {\n registry.register(FrameType.ANNOUNCE, AnnounceFrame);\n registry.register(FrameType.RESOLVE, ResolveFrame);\n registry.register(FrameType.GRAPH, GraphFrame);\n}\n","// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { AnnounceFrame, NdpResolveResult } from \"./frames.js\";\n\ninterface RegistryEntry {\n frame: AnnounceFrame;\n expiresAt: number;\n}\n\nexport class InMemoryNdpRegistry {\n private readonly _store = new Map<string, RegistryEntry>();\n\n // Replaceable for testing\n clock: () => number = () => Date.now();\n\n announce(frame: AnnounceFrame): void {\n const expiresAt = this.clock() + frame.ttl * 1000;\n if (frame.ttl === 0) {\n this._store.delete(frame.nid);\n return;\n }\n this._store.set(frame.nid, { frame, expiresAt });\n }\n\n getByNid(nid: string): AnnounceFrame | undefined {\n const entry = this._store.get(nid);\n if (entry === undefined) return undefined;\n if (this.clock() > entry.expiresAt) {\n this._store.delete(nid);\n return undefined;\n }\n return entry.frame;\n }\n\n resolve(target: string): NdpResolveResult | undefined {\n for (const [nid, entry] of this._store) {\n if (this.clock() > entry.expiresAt) { this._store.delete(nid); continue; }\n if (!InMemoryNdpRegistry.nwpTargetMatchesNid(nid, target)) continue;\n const addr = entry.frame.addresses[0];\n if (addr === undefined) continue;\n return { host: addr.host, port: addr.port, ttl: entry.frame.ttl };\n }\n return undefined;\n }\n\n getAll(): AnnounceFrame[] {\n const now = this.clock();\n const result: AnnounceFrame[] = [];\n for (const [nid, entry] of this._store) {\n if (now > entry.expiresAt) { this._store.delete(nid); continue; }\n result.push(entry.frame);\n }\n return result;\n }\n\n static nwpTargetMatchesNid(nid: string, target: string): boolean {\n // NID: urn:nps:node:{authority}:{path-segment}\n // target: nwp://{authority}/{path}\n const nidParts = nid.split(\":\");\n if (nidParts.length < 5 || nidParts[0] !== \"urn\" || nidParts[1] !== \"nps\" || nidParts[2] !== \"node\") {\n return false;\n }\n if (!target.startsWith(\"nwp://\")) return false;\n\n const nidAuthority = nidParts[3]!;\n const nidPath = nidParts[4]!;\n const rest = target.slice(\"nwp://\".length);\n const slashIdx = rest.indexOf(\"/\");\n if (slashIdx === -1) return false;\n\n const urlAuthority = rest.slice(0, slashIdx);\n const urlPath = rest.slice(slashIdx + 1); // without leading slash\n\n if (urlAuthority !== nidAuthority) return false;\n\n // nidPath must be a prefix of urlPath at a segment boundary\n if (urlPath === nidPath) return true;\n if (urlPath.startsWith(nidPath + \"/\")) return true;\n return false;\n }\n}\n","// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\nimport * as ed25519 from \"@noble/ed25519\";\nimport { sha512 } from \"@noble/hashes/sha512\";\nimport type { AnnounceFrame } from \"./frames.js\";\n\ned25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));\n\nexport interface NdpAnnounceResult {\n isValid: boolean;\n errorCode?: string;\n message?: string;\n}\n\nexport const NdpAnnounceResult = {\n ok: (): NdpAnnounceResult => ({ isValid: true }),\n fail: (errorCode: string, message: string): NdpAnnounceResult => ({ isValid: false, errorCode, message }),\n};\n\nexport class NdpAnnounceValidator {\n private readonly _keys = new Map<string, string>(); // nid → \"ed25519:<hex>\"\n\n registerPublicKey(nid: string, encodedPubKey: string): void {\n this._keys.set(nid, encodedPubKey);\n }\n\n removePublicKey(nid: string): void {\n this._keys.delete(nid);\n }\n\n get knownPublicKeys(): ReadonlyMap<string, string> {\n return this._keys;\n }\n\n validate(frame: AnnounceFrame): NdpAnnounceResult {\n const encoded = this._keys.get(frame.nid);\n if (encoded === undefined) {\n return NdpAnnounceResult.fail(\"NDP-ANNOUNCE-NID-MISMATCH\", `No public key registered for NID: ${frame.nid}`);\n }\n\n try {\n const prefix = \"ed25519:\";\n const pubHex = encoded.startsWith(prefix) ? encoded.slice(prefix.length) : encoded;\n const pubKey = Buffer.from(pubHex, \"hex\");\n\n const sig = frame.signature;\n if (!sig.startsWith(prefix)) {\n return NdpAnnounceResult.fail(\"NDP-ANNOUNCE-SIG-INVALID\", \"Signature must start with 'ed25519:'\");\n }\n const sigBytes = Buffer.from(sig.slice(prefix.length), \"base64\");\n\n const unsigned = frame.unsignedDict();\n const canonical = JSON.stringify(unsigned, Object.keys(unsigned).sort());\n const message = new TextEncoder().encode(canonical);\n\n const valid = ed25519.verify(sigBytes, message, pubKey);\n if (!valid) return NdpAnnounceResult.fail(\"NDP-ANNOUNCE-SIG-INVALID\", \"Ed25519 signature verification failed.\");\n return NdpAnnounceResult.ok();\n } catch {\n return NdpAnnounceResult.fail(\"NDP-ANNOUNCE-SIG-INVALID\", \"Ed25519 signature verification failed.\");\n }\n }\n}\n"]}
|
|
File without changes
|
|
File without changes
|
package/dist/ndp/registry.d.ts
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/ndp/validator.d.ts
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/nip/frames.d.ts
CHANGED
|
File without changes
|
package/dist/nip/frames.d.ts.map
CHANGED
|
File without changes
|
package/dist/nip/identity.d.ts
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/nip/index.cjs
CHANGED
|
File without changes
|
package/dist/nip/index.cjs.map
CHANGED
|
File without changes
|
package/dist/nip/index.d.ts
CHANGED
|
File without changes
|
package/dist/nip/index.d.ts.map
CHANGED
|
File without changes
|
package/dist/nip/index.js
CHANGED
|
@@ -1,6 +1,188 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import * as ed25519 from '@noble/ed25519';
|
|
2
|
+
import { sha512 } from '@noble/hashes/sha512';
|
|
3
|
+
import { pbkdf2Sync, createDecipheriv, randomBytes, createCipheriv } from 'crypto';
|
|
4
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
5
|
+
|
|
6
|
+
// src/nip/frames.ts
|
|
7
|
+
var IdentFrame = class _IdentFrame {
|
|
8
|
+
constructor(nid, pubKey, metadata, signature) {
|
|
9
|
+
this.nid = nid;
|
|
10
|
+
this.pubKey = pubKey;
|
|
11
|
+
this.metadata = metadata;
|
|
12
|
+
this.signature = signature;
|
|
13
|
+
}
|
|
14
|
+
nid;
|
|
15
|
+
pubKey;
|
|
16
|
+
metadata;
|
|
17
|
+
signature;
|
|
18
|
+
frameType = 32 /* IDENT */;
|
|
19
|
+
preferredTier = 1 /* MSGPACK */;
|
|
20
|
+
unsignedDict() {
|
|
21
|
+
return {
|
|
22
|
+
nid: this.nid,
|
|
23
|
+
pub_key: this.pubKey,
|
|
24
|
+
metadata: this.metadata
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
toDict() {
|
|
28
|
+
return { ...this.unsignedDict(), signature: this.signature };
|
|
29
|
+
}
|
|
30
|
+
static fromDict(data) {
|
|
31
|
+
return new _IdentFrame(
|
|
32
|
+
data["nid"],
|
|
33
|
+
data["pub_key"],
|
|
34
|
+
data["metadata"],
|
|
35
|
+
data["signature"]
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var TrustFrame = class _TrustFrame {
|
|
40
|
+
constructor(issuerNid, subjectNid, scopes, expiresAt, signature) {
|
|
41
|
+
this.issuerNid = issuerNid;
|
|
42
|
+
this.subjectNid = subjectNid;
|
|
43
|
+
this.scopes = scopes;
|
|
44
|
+
this.expiresAt = expiresAt;
|
|
45
|
+
this.signature = signature;
|
|
46
|
+
}
|
|
47
|
+
issuerNid;
|
|
48
|
+
subjectNid;
|
|
49
|
+
scopes;
|
|
50
|
+
expiresAt;
|
|
51
|
+
signature;
|
|
52
|
+
frameType = 33 /* TRUST */;
|
|
53
|
+
preferredTier = 1 /* MSGPACK */;
|
|
54
|
+
toDict() {
|
|
55
|
+
return {
|
|
56
|
+
issuer_nid: this.issuerNid,
|
|
57
|
+
subject_nid: this.subjectNid,
|
|
58
|
+
scopes: this.scopes,
|
|
59
|
+
expires_at: this.expiresAt,
|
|
60
|
+
signature: this.signature
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
static fromDict(data) {
|
|
64
|
+
return new _TrustFrame(
|
|
65
|
+
data["issuer_nid"],
|
|
66
|
+
data["subject_nid"],
|
|
67
|
+
data["scopes"],
|
|
68
|
+
data["expires_at"],
|
|
69
|
+
data["signature"]
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var RevokeFrame = class _RevokeFrame {
|
|
74
|
+
constructor(nid, reason, revokedAt) {
|
|
75
|
+
this.nid = nid;
|
|
76
|
+
this.reason = reason;
|
|
77
|
+
this.revokedAt = revokedAt;
|
|
78
|
+
}
|
|
79
|
+
nid;
|
|
80
|
+
reason;
|
|
81
|
+
revokedAt;
|
|
82
|
+
frameType = 34 /* REVOKE */;
|
|
83
|
+
preferredTier = 1 /* MSGPACK */;
|
|
84
|
+
toDict() {
|
|
85
|
+
return {
|
|
86
|
+
nid: this.nid,
|
|
87
|
+
reason: this.reason ?? null,
|
|
88
|
+
revoked_at: this.revokedAt ?? null
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
static fromDict(data) {
|
|
92
|
+
return new _RevokeFrame(
|
|
93
|
+
data["nid"],
|
|
94
|
+
data["reason"] ?? void 0,
|
|
95
|
+
data["revoked_at"] ?? void 0
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
ed25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));
|
|
100
|
+
var KEY_FILE_VERSION = 1;
|
|
101
|
+
var PBKDF2_ITERS = 6e5;
|
|
102
|
+
var SALT_BYTES = 16;
|
|
103
|
+
var IV_BYTES = 12;
|
|
104
|
+
var KEY_BYTES = 32;
|
|
105
|
+
var NipIdentity = class _NipIdentity {
|
|
106
|
+
constructor(_privKey, pubKey) {
|
|
107
|
+
this._privKey = _privKey;
|
|
108
|
+
this.pubKey = pubKey;
|
|
109
|
+
}
|
|
110
|
+
_privKey;
|
|
111
|
+
pubKey;
|
|
112
|
+
// ── Factory ───────────────────────────────────────────────────────────────
|
|
113
|
+
static generate() {
|
|
114
|
+
const priv = ed25519.utils.randomPrivateKey();
|
|
115
|
+
const pub = ed25519.getPublicKey(priv);
|
|
116
|
+
return new _NipIdentity(priv, pub);
|
|
117
|
+
}
|
|
118
|
+
static fromPrivateKey(privKey) {
|
|
119
|
+
const pub = ed25519.getPublicKey(privKey);
|
|
120
|
+
return new _NipIdentity(privKey, pub);
|
|
121
|
+
}
|
|
122
|
+
/** Load from an AES-256-GCM encrypted key file. */
|
|
123
|
+
static load(path, passphrase) {
|
|
124
|
+
const envelope = JSON.parse(readFileSync(path, "utf8"));
|
|
125
|
+
const salt = Buffer.from(envelope.salt, "hex");
|
|
126
|
+
const iv = Buffer.from(envelope.iv, "hex");
|
|
127
|
+
const ct = Buffer.from(envelope.ciphertext, "hex");
|
|
128
|
+
const dk = pbkdf2Sync(passphrase, salt, PBKDF2_ITERS, KEY_BYTES, "sha256");
|
|
129
|
+
const decipher = createDecipheriv("aes-256-gcm", dk, iv);
|
|
130
|
+
const authTag = ct.slice(ct.length - 16);
|
|
131
|
+
const body = ct.slice(0, ct.length - 16);
|
|
132
|
+
decipher.setAuthTag(authTag);
|
|
133
|
+
const priv = Buffer.concat([decipher.update(body), decipher.final()]);
|
|
134
|
+
return _NipIdentity.fromPrivateKey(new Uint8Array(priv));
|
|
135
|
+
}
|
|
136
|
+
/** Save to an AES-256-GCM encrypted key file. */
|
|
137
|
+
save(path, passphrase) {
|
|
138
|
+
const salt = randomBytes(SALT_BYTES);
|
|
139
|
+
const iv = randomBytes(IV_BYTES);
|
|
140
|
+
const dk = pbkdf2Sync(passphrase, salt, PBKDF2_ITERS, KEY_BYTES, "sha256");
|
|
141
|
+
const cipher = createCipheriv("aes-256-gcm", dk, iv);
|
|
142
|
+
const body = Buffer.concat([cipher.update(Buffer.from(this._privKey)), cipher.final()]);
|
|
143
|
+
const tag = cipher.getAuthTag();
|
|
144
|
+
const envelope = {
|
|
145
|
+
version: KEY_FILE_VERSION,
|
|
146
|
+
salt: salt.toString("hex"),
|
|
147
|
+
iv: iv.toString("hex"),
|
|
148
|
+
ciphertext: Buffer.concat([body, tag]).toString("hex"),
|
|
149
|
+
pubKey: Buffer.from(this.pubKey).toString("hex")
|
|
150
|
+
};
|
|
151
|
+
writeFileSync(path, JSON.stringify(envelope, null, 2), "utf8");
|
|
152
|
+
}
|
|
153
|
+
// ── Signing ───────────────────────────────────────────────────────────────
|
|
154
|
+
/** Sign a dict payload. Returns `ed25519:<base64url>`. */
|
|
155
|
+
sign(payload) {
|
|
156
|
+
const canonical = JSON.stringify(payload, Object.keys(payload).sort());
|
|
157
|
+
const bytes = new TextEncoder().encode(canonical);
|
|
158
|
+
const sig = ed25519.sign(bytes, this._privKey);
|
|
159
|
+
return `ed25519:${Buffer.from(sig).toString("base64")}`;
|
|
160
|
+
}
|
|
161
|
+
/** Verify a signature string against a dict payload. */
|
|
162
|
+
verify(payload, signature) {
|
|
163
|
+
if (!signature.startsWith("ed25519:")) return false;
|
|
164
|
+
try {
|
|
165
|
+
const canonical = JSON.stringify(payload, Object.keys(payload).sort());
|
|
166
|
+
const bytes = new TextEncoder().encode(canonical);
|
|
167
|
+
const sigBytes = Buffer.from(signature.slice("ed25519:".length), "base64");
|
|
168
|
+
return ed25519.verify(sigBytes, bytes, this.pubKey);
|
|
169
|
+
} catch {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/** Public key as `ed25519:<hex>` string. */
|
|
174
|
+
get pubKeyString() {
|
|
175
|
+
return `ed25519:${Buffer.from(this.pubKey).toString("hex")}`;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/nip/registry.ts
|
|
180
|
+
function registerNipFrames(registry) {
|
|
181
|
+
registry.register(32 /* IDENT */, IdentFrame);
|
|
182
|
+
registry.register(33 /* TRUST */, TrustFrame);
|
|
183
|
+
registry.register(34 /* REVOKE */, RevokeFrame);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export { IdentFrame, NipIdentity, RevokeFrame, TrustFrame, registerNipFrames };
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
6
188
|
//# sourceMappingURL=index.js.map
|
package/dist/nip/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nip/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,sCAAsC;AAEtC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"sources":["../../src/nip/frames.ts","../../src/nip/identity.ts","../../src/nip/registry.ts"],"names":[],"mappings":";;;;;;AAcO,IAAM,UAAA,GAAN,MAAM,WAAA,CAA+B;AAAA,EAI1C,WAAA,CACkB,GAAA,EACA,MAAA,EACA,QAAA,EACA,SAAA,EAChB;AAJgB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EACf;AAAA,EAJe,GAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EAPT,SAAA,GAAA,EAAA;AAAA,EACA,aAAA,GAAA,CAAA;AAAA,EAST,YAAA,GAAwC;AACtC,IAAA,OAAO;AAAA,MACL,KAAU,IAAA,CAAK,GAAA;AAAA,MACf,SAAU,IAAA,CAAK,MAAA;AAAA,MACf,UAAU,IAAA,CAAK;AAAA,KACjB;AAAA,EACF;AAAA,EAEA,MAAA,GAAkC;AAChC,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,cAAa,EAAG,SAAA,EAAW,KAAK,SAAA,EAAU;AAAA,EAC7D;AAAA,EAEA,OAAO,SAAS,IAAA,EAA2C;AACzD,IAAA,OAAO,IAAI,WAAA;AAAA,MACT,KAAK,KAAK,CAAA;AAAA,MACV,KAAK,SAAS,CAAA;AAAA,MACd,KAAK,UAAU,CAAA;AAAA,MACf,KAAK,WAAW;AAAA,KAClB;AAAA,EACF;AACF;AAEO,IAAM,UAAA,GAAN,MAAM,WAAA,CAA+B;AAAA,EAI1C,WAAA,CACkB,SAAA,EACA,UAAA,EACA,MAAA,EACA,WACA,SAAA,EAChB;AALgB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EACf;AAAA,EALe,SAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EART,SAAA,GAAA,EAAA;AAAA,EACA,aAAA,GAAA,CAAA;AAAA,EAUT,MAAA,GAAkC;AAChC,IAAA,OAAO;AAAA,MACL,YAAa,IAAA,CAAK,SAAA;AAAA,MAClB,aAAa,IAAA,CAAK,UAAA;AAAA,MAClB,QAAa,IAAA,CAAK,MAAA;AAAA,MAClB,YAAa,IAAA,CAAK,SAAA;AAAA,MAClB,WAAa,IAAA,CAAK;AAAA,KACpB;AAAA,EACF;AAAA,EAEA,OAAO,SAAS,IAAA,EAA2C;AACzD,IAAA,OAAO,IAAI,WAAA;AAAA,MACT,KAAK,YAAY,CAAA;AAAA,MACjB,KAAK,aAAa,CAAA;AAAA,MAClB,KAAK,QAAQ,CAAA;AAAA,MACb,KAAK,YAAY,CAAA;AAAA,MACjB,KAAK,WAAW;AAAA,KAClB;AAAA,EACF;AACF;AAEO,IAAM,WAAA,GAAN,MAAM,YAAA,CAAgC;AAAA,EAI3C,WAAA,CACkB,GAAA,EACA,MAAA,EACA,SAAA,EAChB;AAHgB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EACf;AAAA,EAHe,GAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EANT,SAAA,GAAA,EAAA;AAAA,EACA,aAAA,GAAA,CAAA;AAAA,EAQT,MAAA,GAAkC;AAChC,IAAA,OAAO;AAAA,MACL,KAAY,IAAA,CAAK,GAAA;AAAA,MACjB,MAAA,EAAY,KAAK,MAAA,IAAc,IAAA;AAAA,MAC/B,UAAA,EAAY,KAAK,SAAA,IAAc;AAAA,KACjC;AAAA,EACF;AAAA,EAEA,OAAO,SAAS,IAAA,EAA4C;AAC1D,IAAA,OAAO,IAAI,YAAA;AAAA,MACT,KAAK,KAAK,CAAA;AAAA,MACT,IAAA,CAAK,QAAQ,CAAA,IAA2B,MAAA;AAAA,MACxC,IAAA,CAAK,YAAY,CAAA,IAAuB;AAAA,KAC3C;AAAA,EACF;AACF;AC3FQ,OAAA,CAAA,GAAA,CAAI,UAAA,GAAa,IAAI,CAAA,KAAM,MAAA,CAAe,YAAI,WAAA,CAAY,GAAG,CAAC,CAAC,CAAA;AAEvE,IAAM,gBAAA,GAAmB,CAAA;AACzB,IAAM,YAAA,GAAmB,GAAA;AACzB,IAAM,UAAA,GAAmB,EAAA;AACzB,IAAM,QAAA,GAAmB,EAAA;AACzB,IAAM,SAAA,GAAmB,EAAA;AAUlB,IAAM,WAAA,GAAN,MAAM,YAAA,CAAY;AAAA,EACf,WAAA,CACW,UACA,MAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAChB;AAAA,EAFgB,QAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAKnB,OAAO,QAAA,GAAwB;AAC7B,IAAA,MAAM,IAAA,GAAe,cAAM,gBAAA,EAAiB;AAC5C,IAAA,MAAM,GAAA,GAAe,qBAAa,IAAI,CAAA;AACtC,IAAA,OAAO,IAAI,YAAA,CAAY,IAAA,EAAM,GAAG,CAAA;AAAA,EAClC;AAAA,EAEA,OAAO,eAAe,OAAA,EAAkC;AACtD,IAAA,MAAM,GAAA,GAAc,qBAAa,OAAO,CAAA;AACxC,IAAA,OAAO,IAAI,YAAA,CAAY,OAAA,EAAS,GAAG,CAAA;AAAA,EACrC;AAAA;AAAA,EAGA,OAAO,IAAA,CAAK,IAAA,EAAc,UAAA,EAAiC;AACzD,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,IAAA,EAAM,MAAM,CAAC,CAAA;AACtD,IAAA,MAAM,IAAA,GAAY,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,MAAY,KAAK,CAAA;AACxD,IAAA,MAAM,EAAA,GAAY,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,IAAY,KAAK,CAAA;AACxD,IAAA,MAAM,EAAA,GAAY,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,YAAY,KAAK,CAAA;AAExD,IAAA,MAAM,KAAK,UAAA,CAAW,UAAA,EAAY,IAAA,EAAM,YAAA,EAAc,WAAW,QAAQ,CAAA;AACzE,IAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,aAAA,EAAe,EAAA,EAAI,EAAE,CAAA;AAEvD,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,KAAA,CAAM,EAAA,CAAG,SAAS,EAAE,CAAA;AACvC,IAAA,MAAM,OAAU,EAAA,CAAG,KAAA,CAAM,CAAA,EAAG,EAAA,CAAG,SAAS,EAAE,CAAA;AAC1C,IAAC,QAAA,CAAqF,WAAW,OAAO,CAAA;AACxG,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,CAAC,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA,EAAG,QAAA,CAAS,KAAA,EAAO,CAAC,CAAA;AACpE,IAAA,OAAO,YAAA,CAAY,cAAA,CAAe,IAAI,UAAA,CAAW,IAAI,CAAC,CAAA;AAAA,EACxD;AAAA;AAAA,EAGA,IAAA,CAAK,MAAc,UAAA,EAA0B;AAC3C,IAAA,MAAM,IAAA,GAAS,YAAY,UAAU,CAAA;AACrC,IAAA,MAAM,EAAA,GAAS,YAAY,QAAQ,CAAA;AACnC,IAAA,MAAM,KAAS,UAAA,CAAW,UAAA,EAAY,IAAA,EAAM,YAAA,EAAc,WAAW,QAAQ,CAAA;AAC7E,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,aAAA,EAAe,EAAA,EAAI,EAAE,CAAA;AACnD,IAAA,MAAM,IAAA,GAAS,MAAA,CAAO,MAAA,CAAO,CAAC,OAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAC,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AACxF,IAAA,MAAM,GAAA,GAAU,OAAwE,UAAA,EAAW;AAEnG,IAAA,MAAM,QAAA,GAA4B;AAAA,MAChC,OAAA,EAAY,gBAAA;AAAA,MACZ,IAAA,EAAY,IAAA,CAAK,QAAA,CAAS,KAAK,CAAA;AAAA,MAC/B,EAAA,EAAY,EAAA,CAAG,QAAA,CAAS,KAAK,CAAA;AAAA,MAC7B,UAAA,EAAY,OAAO,MAAA,CAAO,CAAC,MAAM,GAAG,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA;AAAA,MACrD,QAAY,MAAA,CAAO,IAAA,CAAK,KAAK,MAAM,CAAA,CAAE,SAAS,KAAK;AAAA,KACrD;AACA,IAAA,aAAA,CAAc,MAAM,IAAA,CAAK,SAAA,CAAU,UAAU,IAAA,EAAM,CAAC,GAAG,MAAM,CAAA;AAAA,EAC/D;AAAA;AAAA;AAAA,EAKA,KAAK,OAAA,EAA0C;AAC7C,IAAA,MAAM,SAAA,GAAY,KAAK,SAAA,CAAU,OAAA,EAAS,OAAO,IAAA,CAAK,OAAO,CAAA,CAAE,IAAA,EAAM,CAAA;AACrE,IAAA,MAAM,KAAA,GAAY,IAAI,WAAA,EAAY,CAAE,OAAO,SAAS,CAAA;AACpD,IAAA,MAAM,GAAA,GAAoB,OAAA,CAAA,IAAA,CAAK,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA;AACnD,IAAA,OAAO,WAAW,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAC,CAAA,CAAA;AAAA,EACvD;AAAA;AAAA,EAGA,MAAA,CAAO,SAAkC,SAAA,EAA4B;AACnE,IAAA,IAAI,CAAC,SAAA,CAAU,UAAA,CAAW,UAAU,GAAG,OAAO,KAAA;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,KAAK,SAAA,CAAU,OAAA,EAAS,OAAO,IAAA,CAAK,OAAO,CAAA,CAAE,IAAA,EAAM,CAAA;AACrE,MAAA,MAAM,KAAA,GAAY,IAAI,WAAA,EAAY,CAAE,OAAO,SAAS,CAAA;AACpD,MAAA,MAAM,QAAA,GAAY,OAAO,IAAA,CAAK,SAAA,CAAU,MAAM,UAAA,CAAW,MAAM,GAAG,QAAQ,CAAA;AAC1E,MAAA,OAAe,OAAA,CAAA,MAAA,CAAO,QAAA,EAAU,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AAAA,IACpD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,YAAA,GAAuB;AACzB,IAAA,OAAO,CAAA,QAAA,EAAW,OAAO,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA;AAAA,EAC5D;AACF;;;ACzGO,SAAS,kBAAkB,QAAA,EAA+B;AAC/D,EAAA,QAAA,CAAS,yBAA2B,UAAU,CAAA;AAC9C,EAAA,QAAA,CAAS,yBAA2B,UAAU,CAAA;AAC9C,EAAA,QAAA,CAAS,0BAA2B,WAAW,CAAA;AACjD","file":"index.js","sourcesContent":["// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncodingTier, FrameType } from \"../core/frames.js\";\nimport type { NpsFrame } from \"../core/codec.js\";\n\nexport interface IdentMetadata {\n issuer: string;\n issuedAt: string;\n expiresAt?: string;\n capabilities?: readonly string[];\n scopes?: readonly string[];\n}\n\nexport class IdentFrame implements NpsFrame {\n readonly frameType = FrameType.IDENT;\n readonly preferredTier = EncodingTier.MSGPACK;\n\n constructor(\n public readonly nid: string,\n public readonly pubKey: string,\n public readonly metadata: IdentMetadata,\n public readonly signature: string,\n ) {}\n\n unsignedDict(): Record<string, unknown> {\n return {\n nid: this.nid,\n pub_key: this.pubKey,\n metadata: this.metadata,\n };\n }\n\n toDict(): Record<string, unknown> {\n return { ...this.unsignedDict(), signature: this.signature };\n }\n\n static fromDict(data: Record<string, unknown>): IdentFrame {\n return new IdentFrame(\n data[\"nid\"] as string,\n data[\"pub_key\"] as string,\n data[\"metadata\"] as IdentMetadata,\n data[\"signature\"] as string,\n );\n }\n}\n\nexport class TrustFrame implements NpsFrame {\n readonly frameType = FrameType.TRUST;\n readonly preferredTier = EncodingTier.MSGPACK;\n\n constructor(\n public readonly issuerNid: string,\n public readonly subjectNid: string,\n public readonly scopes: readonly string[],\n public readonly expiresAt: string,\n public readonly signature: string,\n ) {}\n\n toDict(): Record<string, unknown> {\n return {\n issuer_nid: this.issuerNid,\n subject_nid: this.subjectNid,\n scopes: this.scopes,\n expires_at: this.expiresAt,\n signature: this.signature,\n };\n }\n\n static fromDict(data: Record<string, unknown>): TrustFrame {\n return new TrustFrame(\n data[\"issuer_nid\"] as string,\n data[\"subject_nid\"] as string,\n data[\"scopes\"] as string[],\n data[\"expires_at\"] as string,\n data[\"signature\"] as string,\n );\n }\n}\n\nexport class RevokeFrame implements NpsFrame {\n readonly frameType = FrameType.REVOKE;\n readonly preferredTier = EncodingTier.MSGPACK;\n\n constructor(\n public readonly nid: string,\n public readonly reason?: string,\n public readonly revokedAt?: string,\n ) {}\n\n toDict(): Record<string, unknown> {\n return {\n nid: this.nid,\n reason: this.reason ?? null,\n revoked_at: this.revokedAt ?? null,\n };\n }\n\n static fromDict(data: Record<string, unknown>): RevokeFrame {\n return new RevokeFrame(\n data[\"nid\"] as string,\n (data[\"reason\"] as string | null) ?? undefined,\n (data[\"revoked_at\"] as string | null) ?? undefined,\n );\n }\n}\n","// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * NipIdentity — Ed25519 key management and signing for NPS NID identity.\n * Uses @noble/ed25519 for signing; node:crypto for key storage encryption.\n */\n\nimport * as ed25519 from \"@noble/ed25519\";\nimport { sha512 } from \"@noble/hashes/sha512\";\nimport { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from \"node:crypto\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\n\n// noble/ed25519 requires sha512 to be set explicitly in Node environments\ned25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));\n\nconst KEY_FILE_VERSION = 1;\nconst PBKDF2_ITERS = 600_000;\nconst SALT_BYTES = 16;\nconst IV_BYTES = 12;\nconst KEY_BYTES = 32;\n\ninterface KeyFileEnvelope {\n version: number;\n salt: string; // hex\n iv: string; // hex\n ciphertext: string; // hex\n pubKey: string; // hex\n}\n\nexport class NipIdentity {\n private constructor(\n private readonly _privKey: Uint8Array,\n public readonly pubKey: Uint8Array,\n ) {}\n\n // ── Factory ───────────────────────────────────────────────────────────────\n\n static generate(): NipIdentity {\n const priv = ed25519.utils.randomPrivateKey();\n const pub = ed25519.getPublicKey(priv);\n return new NipIdentity(priv, pub);\n }\n\n static fromPrivateKey(privKey: Uint8Array): NipIdentity {\n const pub = ed25519.getPublicKey(privKey);\n return new NipIdentity(privKey, pub);\n }\n\n /** Load from an AES-256-GCM encrypted key file. */\n static load(path: string, passphrase: string): NipIdentity {\n const envelope = JSON.parse(readFileSync(path, \"utf8\")) as KeyFileEnvelope;\n const salt = Buffer.from(envelope.salt, \"hex\");\n const iv = Buffer.from(envelope.iv, \"hex\");\n const ct = Buffer.from(envelope.ciphertext, \"hex\");\n\n const dk = pbkdf2Sync(passphrase, salt, PBKDF2_ITERS, KEY_BYTES, \"sha256\");\n const decipher = createDecipheriv(\"aes-256-gcm\", dk, iv);\n // Last 16 bytes of ciphertext are the GCM auth tag\n const authTag = ct.slice(ct.length - 16);\n const body = ct.slice(0, ct.length - 16);\n (decipher as ReturnType<typeof createDecipheriv> & { setAuthTag(tag: Buffer): void }).setAuthTag(authTag);\n const priv = Buffer.concat([decipher.update(body), decipher.final()]);\n return NipIdentity.fromPrivateKey(new Uint8Array(priv));\n }\n\n /** Save to an AES-256-GCM encrypted key file. */\n save(path: string, passphrase: string): void {\n const salt = randomBytes(SALT_BYTES);\n const iv = randomBytes(IV_BYTES);\n const dk = pbkdf2Sync(passphrase, salt, PBKDF2_ITERS, KEY_BYTES, \"sha256\");\n const cipher = createCipheriv(\"aes-256-gcm\", dk, iv);\n const body = Buffer.concat([cipher.update(Buffer.from(this._privKey)), cipher.final()]);\n const tag = (cipher as ReturnType<typeof createCipheriv> & { getAuthTag(): Buffer }).getAuthTag();\n\n const envelope: KeyFileEnvelope = {\n version: KEY_FILE_VERSION,\n salt: salt.toString(\"hex\"),\n iv: iv.toString(\"hex\"),\n ciphertext: Buffer.concat([body, tag]).toString(\"hex\"),\n pubKey: Buffer.from(this.pubKey).toString(\"hex\"),\n };\n writeFileSync(path, JSON.stringify(envelope, null, 2), \"utf8\");\n }\n\n // ── Signing ───────────────────────────────────────────────────────────────\n\n /** Sign a dict payload. Returns `ed25519:<base64url>`. */\n sign(payload: Record<string, unknown>): string {\n const canonical = JSON.stringify(payload, Object.keys(payload).sort());\n const bytes = new TextEncoder().encode(canonical);\n const sig = ed25519.sign(bytes, this._privKey);\n return `ed25519:${Buffer.from(sig).toString(\"base64\")}`;\n }\n\n /** Verify a signature string against a dict payload. */\n verify(payload: Record<string, unknown>, signature: string): boolean {\n if (!signature.startsWith(\"ed25519:\")) return false;\n try {\n const canonical = JSON.stringify(payload, Object.keys(payload).sort());\n const bytes = new TextEncoder().encode(canonical);\n const sigBytes = Buffer.from(signature.slice(\"ed25519:\".length), \"base64\");\n return ed25519.verify(sigBytes, bytes, this.pubKey);\n } catch {\n return false;\n }\n }\n\n /** Public key as `ed25519:<hex>` string. */\n get pubKeyString(): string {\n return `ed25519:${Buffer.from(this.pubKey).toString(\"hex\")}`;\n }\n}\n","// Copyright 2026 INNO LOTUS PTY LTD\n// SPDX-License-Identifier: Apache-2.0\n\nimport { FrameRegistry } from \"../core/registry.js\";\nimport { FrameType } from \"../core/frames.js\";\nimport { IdentFrame, TrustFrame, RevokeFrame } from \"./frames.js\";\n\nexport function registerNipFrames(registry: FrameRegistry): void {\n registry.register(FrameType.IDENT, IdentFrame);\n registry.register(FrameType.TRUST, TrustFrame);\n registry.register(FrameType.REVOKE, RevokeFrame);\n}\n"]}
|
package/dist/nip/registry.d.ts
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/nop/client.d.ts
CHANGED
|
File without changes
|
package/dist/nop/client.d.ts.map
CHANGED
|
File without changes
|
package/dist/nop/frames.d.ts
CHANGED
|
File without changes
|
package/dist/nop/frames.d.ts.map
CHANGED
|
File without changes
|
package/dist/nop/index.cjs
CHANGED
|
@@ -75,12 +75,20 @@ function computeDelayMs(policy, attempt) {
|
|
|
75
75
|
var NpsError = class extends Error {
|
|
76
76
|
constructor(message) {
|
|
77
77
|
super(message);
|
|
78
|
-
this.name =
|
|
78
|
+
this.name = "NpsError";
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
var NpsFrameError = class extends NpsError {
|
|
82
|
+
constructor(message) {
|
|
83
|
+
super(message);
|
|
84
|
+
this.name = "NpsFrameError";
|
|
85
|
+
}
|
|
82
86
|
};
|
|
83
87
|
var NpsCodecError = class extends NpsError {
|
|
88
|
+
constructor(message) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.name = "NpsCodecError";
|
|
91
|
+
}
|
|
84
92
|
};
|
|
85
93
|
|
|
86
94
|
// src/core/frames.ts
|
|
@@ -641,6 +649,58 @@ var ErrorFrame = class _ErrorFrame {
|
|
|
641
649
|
);
|
|
642
650
|
}
|
|
643
651
|
};
|
|
652
|
+
var HelloFrame = class _HelloFrame {
|
|
653
|
+
constructor(npsVersion, supportedEncodings, supportedProtocols, minVersion, agentId, maxFramePayload = _HelloFrame.DEFAULT_MAX_FRAME_PAYLOAD, extSupport = false, maxConcurrentStreams = _HelloFrame.DEFAULT_MAX_CONCURRENT_STREAMS, e2eEncAlgorithms) {
|
|
654
|
+
this.npsVersion = npsVersion;
|
|
655
|
+
this.supportedEncodings = supportedEncodings;
|
|
656
|
+
this.supportedProtocols = supportedProtocols;
|
|
657
|
+
this.minVersion = minVersion;
|
|
658
|
+
this.agentId = agentId;
|
|
659
|
+
this.maxFramePayload = maxFramePayload;
|
|
660
|
+
this.extSupport = extSupport;
|
|
661
|
+
this.maxConcurrentStreams = maxConcurrentStreams;
|
|
662
|
+
this.e2eEncAlgorithms = e2eEncAlgorithms;
|
|
663
|
+
}
|
|
664
|
+
npsVersion;
|
|
665
|
+
supportedEncodings;
|
|
666
|
+
supportedProtocols;
|
|
667
|
+
minVersion;
|
|
668
|
+
agentId;
|
|
669
|
+
maxFramePayload;
|
|
670
|
+
extSupport;
|
|
671
|
+
maxConcurrentStreams;
|
|
672
|
+
e2eEncAlgorithms;
|
|
673
|
+
frameType = 6 /* HELLO */;
|
|
674
|
+
preferredTier = 0 /* JSON */;
|
|
675
|
+
static DEFAULT_MAX_FRAME_PAYLOAD = 65535;
|
|
676
|
+
static DEFAULT_MAX_CONCURRENT_STREAMS = 32;
|
|
677
|
+
toDict() {
|
|
678
|
+
return {
|
|
679
|
+
nps_version: this.npsVersion,
|
|
680
|
+
supported_encodings: [...this.supportedEncodings],
|
|
681
|
+
supported_protocols: [...this.supportedProtocols],
|
|
682
|
+
min_version: this.minVersion ?? null,
|
|
683
|
+
agent_id: this.agentId ?? null,
|
|
684
|
+
max_frame_payload: this.maxFramePayload,
|
|
685
|
+
ext_support: this.extSupport,
|
|
686
|
+
max_concurrent_streams: this.maxConcurrentStreams,
|
|
687
|
+
e2e_enc_algorithms: this.e2eEncAlgorithms ? [...this.e2eEncAlgorithms] : null
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
static fromDict(data) {
|
|
691
|
+
return new _HelloFrame(
|
|
692
|
+
data["nps_version"],
|
|
693
|
+
data["supported_encodings"] ?? [],
|
|
694
|
+
data["supported_protocols"] ?? [],
|
|
695
|
+
data["min_version"] ?? void 0,
|
|
696
|
+
data["agent_id"] ?? void 0,
|
|
697
|
+
data["max_frame_payload"] ?? _HelloFrame.DEFAULT_MAX_FRAME_PAYLOAD,
|
|
698
|
+
data["ext_support"] ?? false,
|
|
699
|
+
data["max_concurrent_streams"] ?? _HelloFrame.DEFAULT_MAX_CONCURRENT_STREAMS,
|
|
700
|
+
data["e2e_enc_algorithms"] ?? void 0
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
};
|
|
644
704
|
|
|
645
705
|
// src/ncp/registry.ts
|
|
646
706
|
function registerNcpFrames(registry) {
|
|
@@ -648,6 +708,7 @@ function registerNcpFrames(registry) {
|
|
|
648
708
|
registry.register(2 /* DIFF */, DiffFrame);
|
|
649
709
|
registry.register(3 /* STREAM */, StreamFrame);
|
|
650
710
|
registry.register(4 /* CAPS */, CapsFrame);
|
|
711
|
+
registry.register(6 /* HELLO */, HelloFrame);
|
|
651
712
|
registry.register(254 /* ERROR */, ErrorFrame);
|
|
652
713
|
}
|
|
653
714
|
|