@labacacia/nps-sdk 1.0.0-alpha.3 → 1.0.0-alpha.4

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.
Files changed (212) hide show
  1. package/CHANGELOG.cn.md +53 -0
  2. package/CHANGELOG.md +62 -0
  3. package/README.cn.md +8 -2
  4. package/README.md +8 -2
  5. package/dist/core/anchor-cache.js +104 -0
  6. package/dist/core/anchor-cache.js.map +1 -0
  7. package/dist/core/cache.js +80 -0
  8. package/dist/core/cache.js.map +1 -0
  9. package/dist/core/canonical-json.js +44 -0
  10. package/dist/core/canonical-json.js.map +1 -0
  11. package/dist/core/codec.js +119 -0
  12. package/dist/core/codec.js.map +1 -0
  13. package/dist/core/codecs/index.js +6 -0
  14. package/dist/core/codecs/index.js.map +1 -0
  15. package/dist/core/codecs/ncp-codec.js +93 -0
  16. package/dist/core/codecs/ncp-codec.js.map +1 -0
  17. package/dist/core/codecs/tier1-json-codec.js +28 -0
  18. package/dist/core/codecs/tier1-json-codec.js.map +1 -0
  19. package/dist/core/codecs/tier2-msgpack-codec.js +26 -0
  20. package/dist/core/codecs/tier2-msgpack-codec.js.map +1 -0
  21. package/dist/core/crypto-provider.js +10 -0
  22. package/dist/core/crypto-provider.js.map +1 -0
  23. package/dist/core/exceptions.js +52 -0
  24. package/dist/core/exceptions.js.map +1 -0
  25. package/dist/core/frame-header.js +185 -0
  26. package/dist/core/frame-header.js.map +1 -0
  27. package/dist/core/frame-registry.js +63 -0
  28. package/dist/core/frame-registry.js.map +1 -0
  29. package/dist/core/frames.js +154 -0
  30. package/dist/core/frames.js.map +1 -0
  31. package/dist/core/index.js +21 -405
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/registry.js +17 -0
  34. package/dist/core/registry.js.map +1 -0
  35. package/dist/core/status-codes.js +38 -0
  36. package/dist/core/status-codes.js.map +1 -0
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +9 -5
  39. package/dist/index.js.map +1 -1
  40. package/dist/ncp/frames/anchor-frame.js +54 -0
  41. package/dist/ncp/frames/anchor-frame.js.map +1 -0
  42. package/dist/ncp/frames/caps-frame.js +29 -0
  43. package/dist/ncp/frames/caps-frame.js.map +1 -0
  44. package/dist/ncp/frames/diff-frame.js +37 -0
  45. package/dist/ncp/frames/diff-frame.js.map +1 -0
  46. package/dist/ncp/frames/error-frame.js +13 -0
  47. package/dist/ncp/frames/error-frame.js.map +1 -0
  48. package/dist/ncp/frames/hello-frame.js +25 -0
  49. package/dist/ncp/frames/hello-frame.js.map +1 -0
  50. package/dist/ncp/frames/stream-frame.js +18 -0
  51. package/dist/ncp/frames/stream-frame.js.map +1 -0
  52. package/dist/ncp/frames.js +192 -0
  53. package/dist/ncp/frames.js.map +1 -0
  54. package/dist/ncp/handshake.js +80 -0
  55. package/dist/ncp/handshake.js.map +1 -0
  56. package/dist/ncp/index.d.ts +1 -0
  57. package/dist/ncp/index.d.ts.map +1 -1
  58. package/dist/ncp/index.js +13 -368
  59. package/dist/ncp/index.js.map +1 -1
  60. package/dist/ncp/ncp-error-codes.d.ts +1 -0
  61. package/dist/ncp/ncp-error-codes.d.ts.map +1 -1
  62. package/dist/ncp/ncp-error-codes.js +34 -0
  63. package/dist/ncp/ncp-error-codes.js.map +1 -0
  64. package/dist/ncp/ncp-patch-format.js +13 -0
  65. package/dist/ncp/ncp-patch-format.js.map +1 -0
  66. package/dist/ncp/preamble.d.ts +47 -0
  67. package/dist/ncp/preamble.d.ts.map +1 -0
  68. package/dist/ncp/preamble.js +74 -0
  69. package/dist/ncp/preamble.js.map +1 -0
  70. package/dist/ncp/registry.js +13 -0
  71. package/dist/ncp/registry.js.map +1 -0
  72. package/dist/ncp/stream-manager.js +163 -0
  73. package/dist/ncp/stream-manager.js.map +1 -0
  74. package/dist/ndp/frames.js +87 -0
  75. package/dist/ndp/frames.js.map +1 -0
  76. package/dist/ndp/index.js +6 -223
  77. package/dist/ndp/index.js.map +1 -1
  78. package/dist/ndp/ndp-registry.js +79 -0
  79. package/dist/ndp/ndp-registry.js.map +1 -0
  80. package/dist/ndp/registry.js +10 -0
  81. package/dist/ndp/registry.js.map +1 -0
  82. package/dist/ndp/validator.js +48 -0
  83. package/dist/ndp/validator.js.map +1 -0
  84. package/dist/nip/acme/client.d.ts +31 -0
  85. package/dist/nip/acme/client.d.ts.map +1 -0
  86. package/dist/nip/acme/client.js +136 -0
  87. package/dist/nip/acme/client.js.map +1 -0
  88. package/dist/nip/acme/index.d.ts +6 -0
  89. package/dist/nip/acme/index.d.ts.map +1 -0
  90. package/dist/nip/acme/index.js +8 -0
  91. package/dist/nip/acme/index.js.map +1 -0
  92. package/dist/nip/acme/jws.d.ts +31 -0
  93. package/dist/nip/acme/jws.d.ts.map +1 -0
  94. package/dist/nip/acme/jws.js +76 -0
  95. package/dist/nip/acme/jws.js.map +1 -0
  96. package/dist/nip/acme/messages.d.ts +71 -0
  97. package/dist/nip/acme/messages.d.ts.map +1 -0
  98. package/dist/nip/acme/messages.js +4 -0
  99. package/dist/nip/acme/messages.js.map +1 -0
  100. package/dist/nip/acme/server.d.ts +41 -0
  101. package/dist/nip/acme/server.d.ts.map +1 -0
  102. package/dist/nip/acme/server.js +458 -0
  103. package/dist/nip/acme/server.js.map +1 -0
  104. package/dist/nip/acme/wire.d.ts +19 -0
  105. package/dist/nip/acme/wire.d.ts.map +1 -0
  106. package/dist/nip/acme/wire.js +21 -0
  107. package/dist/nip/acme/wire.js.map +1 -0
  108. package/dist/nip/assurance-level.d.ts +14 -0
  109. package/dist/nip/assurance-level.d.ts.map +1 -0
  110. package/dist/nip/assurance-level.js +33 -0
  111. package/dist/nip/assurance-level.js.map +1 -0
  112. package/dist/nip/cert-format.d.ts +5 -0
  113. package/dist/nip/cert-format.d.ts.map +1 -0
  114. package/dist/nip/cert-format.js +6 -0
  115. package/dist/nip/cert-format.js.map +1 -0
  116. package/dist/nip/error-codes.d.ts +23 -0
  117. package/dist/nip/error-codes.d.ts.map +1 -0
  118. package/dist/nip/error-codes.js +30 -0
  119. package/dist/nip/error-codes.js.map +1 -0
  120. package/dist/nip/frames.d.ts +10 -1
  121. package/dist/nip/frames.d.ts.map +1 -1
  122. package/dist/nip/frames.js +106 -0
  123. package/dist/nip/frames.js.map +1 -0
  124. package/dist/nip/identity.js +94 -0
  125. package/dist/nip/identity.js.map +1 -0
  126. package/dist/nip/index.d.ts +6 -0
  127. package/dist/nip/index.d.ts.map +1 -1
  128. package/dist/nip/index.js +12 -187
  129. package/dist/nip/index.js.map +1 -1
  130. package/dist/nip/registry.js +10 -0
  131. package/dist/nip/registry.js.map +1 -0
  132. package/dist/nip/verifier.d.ts +23 -0
  133. package/dist/nip/verifier.d.ts.map +1 -0
  134. package/dist/nip/verifier.js +90 -0
  135. package/dist/nip/verifier.js.map +1 -0
  136. package/dist/nip/x509/builder.d.ts +35 -0
  137. package/dist/nip/x509/builder.d.ts.map +1 -0
  138. package/dist/nip/x509/builder.js +59 -0
  139. package/dist/nip/x509/builder.js.map +1 -0
  140. package/dist/nip/x509/index.d.ts +4 -0
  141. package/dist/nip/x509/index.d.ts.map +1 -0
  142. package/dist/nip/x509/index.js +6 -0
  143. package/dist/nip/x509/index.js.map +1 -0
  144. package/dist/nip/x509/oids.d.ts +17 -0
  145. package/dist/nip/x509/oids.d.ts.map +1 -0
  146. package/dist/nip/x509/oids.js +23 -0
  147. package/dist/nip/x509/oids.js.map +1 -0
  148. package/dist/nip/x509/verifier.d.ts +26 -0
  149. package/dist/nip/x509/verifier.d.ts.map +1 -0
  150. package/dist/nip/x509/verifier.js +171 -0
  151. package/dist/nip/x509/verifier.js.map +1 -0
  152. package/dist/nop/client.js +90 -0
  153. package/dist/nop/client.js.map +1 -0
  154. package/dist/nop/frames.js +148 -0
  155. package/dist/nop/frames.js.map +1 -0
  156. package/dist/nop/index.js +6 -789
  157. package/dist/nop/index.js.map +1 -1
  158. package/dist/nop/models.js +50 -0
  159. package/dist/nop/models.js.map +1 -0
  160. package/dist/nop/nop-types.js +44 -0
  161. package/dist/nop/nop-types.js.map +1 -0
  162. package/dist/nop/registry.js +11 -0
  163. package/dist/nop/registry.js.map +1 -0
  164. package/dist/nwp/client.js +101 -0
  165. package/dist/nwp/client.js.map +1 -0
  166. package/dist/nwp/frames.js +81 -0
  167. package/dist/nwp/frames.js.map +1 -0
  168. package/dist/nwp/index.js +5 -693
  169. package/dist/nwp/index.js.map +1 -1
  170. package/dist/nwp/registry.js +9 -0
  171. package/dist/nwp/registry.js.map +1 -0
  172. package/dist/setup.js +29 -0
  173. package/dist/setup.js.map +1 -0
  174. package/package.json +2 -1
  175. package/src/index.ts +1 -1
  176. package/src/ncp/index.ts +1 -0
  177. package/src/ncp/ncp-error-codes.ts +2 -0
  178. package/src/ncp/preamble.ts +79 -0
  179. package/src/nip/acme/client.ts +185 -0
  180. package/src/nip/acme/index.ts +8 -0
  181. package/src/nip/acme/jws.ts +109 -0
  182. package/src/nip/acme/messages.ts +85 -0
  183. package/src/nip/acme/server.ts +480 -0
  184. package/src/nip/acme/wire.ts +24 -0
  185. package/src/nip/assurance-level.ts +35 -0
  186. package/src/nip/cert-format.ts +9 -0
  187. package/src/nip/error-codes.ts +36 -0
  188. package/src/nip/frames.ts +35 -3
  189. package/src/nip/index.ts +8 -0
  190. package/src/nip/verifier.ts +122 -0
  191. package/src/nip/x509/builder.ts +91 -0
  192. package/src/nip/x509/index.ts +6 -0
  193. package/src/nip/x509/oids.ts +28 -0
  194. package/src/nip/x509/verifier.ts +214 -0
  195. package/tests/_rfc0002-keys.ts +57 -0
  196. package/tests/ncp/preamble.test.ts +93 -0
  197. package/tests/nip-acme-agent01.test.ts +192 -0
  198. package/tests/nip-x509.test.ts +280 -0
  199. package/dist/core/index.cjs +0 -452
  200. package/dist/core/index.cjs.map +0 -1
  201. package/dist/index.cjs +0 -8
  202. package/dist/index.cjs.map +0 -1
  203. package/dist/ncp/index.cjs +0 -388
  204. package/dist/ncp/index.cjs.map +0 -1
  205. package/dist/ndp/index.cjs +0 -252
  206. package/dist/ndp/index.cjs.map +0 -1
  207. package/dist/nip/index.cjs +0 -214
  208. package/dist/nip/index.cjs.map +0 -1
  209. package/dist/nop/index.cjs +0 -823
  210. package/dist/nop/index.cjs.map +0 -1
  211. package/dist/nwp/index.cjs +0 -720
  212. package/dist/nwp/index.cjs.map +0 -1
@@ -1,252 +0,0 @@
1
- 'use strict';
2
-
3
- var ed25519 = require('@noble/ed25519');
4
- var sha512 = require('@noble/hashes/sha512');
5
-
6
- function _interopNamespace(e) {
7
- if (e && e.__esModule) return e;
8
- var n = Object.create(null);
9
- if (e) {
10
- Object.keys(e).forEach(function (k) {
11
- if (k !== 'default') {
12
- var d = Object.getOwnPropertyDescriptor(e, k);
13
- Object.defineProperty(n, k, d.get ? d : {
14
- enumerable: true,
15
- get: function () { return e[k]; }
16
- });
17
- }
18
- });
19
- }
20
- n.default = e;
21
- return Object.freeze(n);
22
- }
23
-
24
- var ed25519__namespace = /*#__PURE__*/_interopNamespace(ed25519);
25
-
26
- // src/ndp/frames.ts
27
- var AnnounceFrame = class _AnnounceFrame {
28
- constructor(nid, addresses, capabilities, ttl, timestamp, signature, nodeType) {
29
- this.nid = nid;
30
- this.addresses = addresses;
31
- this.capabilities = capabilities;
32
- this.ttl = ttl;
33
- this.timestamp = timestamp;
34
- this.signature = signature;
35
- this.nodeType = nodeType;
36
- }
37
- nid;
38
- addresses;
39
- capabilities;
40
- ttl;
41
- timestamp;
42
- signature;
43
- nodeType;
44
- frameType = 48 /* ANNOUNCE */;
45
- preferredTier = 1 /* MSGPACK */;
46
- unsignedDict() {
47
- return {
48
- nid: this.nid,
49
- addresses: this.addresses,
50
- capabilities: this.capabilities,
51
- ttl: this.ttl,
52
- timestamp: this.timestamp,
53
- node_type: this.nodeType ?? null
54
- };
55
- }
56
- toDict() {
57
- return { ...this.unsignedDict(), signature: this.signature };
58
- }
59
- static fromDict(data) {
60
- return new _AnnounceFrame(
61
- data["nid"],
62
- data["addresses"],
63
- data["capabilities"],
64
- data["ttl"],
65
- data["timestamp"],
66
- data["signature"],
67
- data["node_type"] ?? void 0
68
- );
69
- }
70
- };
71
- var ResolveFrame = class _ResolveFrame {
72
- constructor(target, requesterNid, resolved) {
73
- this.target = target;
74
- this.requesterNid = requesterNid;
75
- this.resolved = resolved;
76
- }
77
- target;
78
- requesterNid;
79
- resolved;
80
- frameType = 49 /* RESOLVE */;
81
- preferredTier = 1 /* MSGPACK */;
82
- toDict() {
83
- return {
84
- target: this.target,
85
- requester_nid: this.requesterNid ?? null,
86
- resolved: this.resolved ?? null
87
- };
88
- }
89
- static fromDict(data) {
90
- return new _ResolveFrame(
91
- data["target"],
92
- data["requester_nid"] ?? void 0,
93
- data["resolved"] ?? void 0
94
- );
95
- }
96
- };
97
- var GraphFrame = class _GraphFrame {
98
- constructor(seq, initialSync, nodes, patch) {
99
- this.seq = seq;
100
- this.initialSync = initialSync;
101
- this.nodes = nodes;
102
- this.patch = patch;
103
- }
104
- seq;
105
- initialSync;
106
- nodes;
107
- patch;
108
- frameType = 50 /* GRAPH */;
109
- preferredTier = 1 /* MSGPACK */;
110
- toDict() {
111
- return {
112
- seq: this.seq,
113
- initial_sync: this.initialSync,
114
- nodes: this.nodes ?? null,
115
- patch: this.patch ?? null
116
- };
117
- }
118
- static fromDict(data) {
119
- return new _GraphFrame(
120
- data["seq"],
121
- data["initial_sync"],
122
- data["nodes"] ?? void 0,
123
- data["patch"] ?? void 0
124
- );
125
- }
126
- };
127
-
128
- // src/ndp/registry.ts
129
- function registerNdpFrames(registry) {
130
- registry.register(48 /* ANNOUNCE */, AnnounceFrame);
131
- registry.register(49 /* RESOLVE */, ResolveFrame);
132
- registry.register(50 /* GRAPH */, GraphFrame);
133
- }
134
-
135
- // src/ndp/ndp-registry.ts
136
- var InMemoryNdpRegistry = class _InMemoryNdpRegistry {
137
- _store = /* @__PURE__ */ new Map();
138
- // Replaceable for testing
139
- clock = () => Date.now();
140
- announce(frame) {
141
- const expiresAt = this.clock() + frame.ttl * 1e3;
142
- if (frame.ttl === 0) {
143
- this._store.delete(frame.nid);
144
- return;
145
- }
146
- this._store.set(frame.nid, { frame, expiresAt });
147
- }
148
- getByNid(nid) {
149
- const entry = this._store.get(nid);
150
- if (entry === void 0) return void 0;
151
- if (this.clock() > entry.expiresAt) {
152
- this._store.delete(nid);
153
- return void 0;
154
- }
155
- return entry.frame;
156
- }
157
- resolve(target) {
158
- for (const [nid, entry] of this._store) {
159
- if (this.clock() > entry.expiresAt) {
160
- this._store.delete(nid);
161
- continue;
162
- }
163
- if (!_InMemoryNdpRegistry.nwpTargetMatchesNid(nid, target)) continue;
164
- const addr = entry.frame.addresses[0];
165
- if (addr === void 0) continue;
166
- return { host: addr.host, port: addr.port, ttl: entry.frame.ttl };
167
- }
168
- return void 0;
169
- }
170
- getAll() {
171
- const now = this.clock();
172
- const result = [];
173
- for (const [nid, entry] of this._store) {
174
- if (now > entry.expiresAt) {
175
- this._store.delete(nid);
176
- continue;
177
- }
178
- result.push(entry.frame);
179
- }
180
- return result;
181
- }
182
- static nwpTargetMatchesNid(nid, target) {
183
- const nidParts = nid.split(":");
184
- if (nidParts.length < 5 || nidParts[0] !== "urn" || nidParts[1] !== "nps" || nidParts[2] !== "node") {
185
- return false;
186
- }
187
- if (!target.startsWith("nwp://")) return false;
188
- const nidAuthority = nidParts[3];
189
- const nidPath = nidParts[4];
190
- const rest = target.slice("nwp://".length);
191
- const slashIdx = rest.indexOf("/");
192
- if (slashIdx === -1) return false;
193
- const urlAuthority = rest.slice(0, slashIdx);
194
- const urlPath = rest.slice(slashIdx + 1);
195
- if (urlAuthority !== nidAuthority) return false;
196
- if (urlPath === nidPath) return true;
197
- if (urlPath.startsWith(nidPath + "/")) return true;
198
- return false;
199
- }
200
- };
201
- ed25519__namespace.etc.sha512Sync = (...m) => sha512.sha512(ed25519__namespace.etc.concatBytes(...m));
202
- var NdpAnnounceResult = {
203
- ok: () => ({ isValid: true }),
204
- fail: (errorCode, message) => ({ isValid: false, errorCode, message })
205
- };
206
- var NdpAnnounceValidator = class {
207
- _keys = /* @__PURE__ */ new Map();
208
- // nid → "ed25519:<hex>"
209
- registerPublicKey(nid, encodedPubKey) {
210
- this._keys.set(nid, encodedPubKey);
211
- }
212
- removePublicKey(nid) {
213
- this._keys.delete(nid);
214
- }
215
- get knownPublicKeys() {
216
- return this._keys;
217
- }
218
- validate(frame) {
219
- const encoded = this._keys.get(frame.nid);
220
- if (encoded === void 0) {
221
- return NdpAnnounceResult.fail("NDP-ANNOUNCE-NID-MISMATCH", `No public key registered for NID: ${frame.nid}`);
222
- }
223
- try {
224
- const prefix = "ed25519:";
225
- const pubHex = encoded.startsWith(prefix) ? encoded.slice(prefix.length) : encoded;
226
- const pubKey = Buffer.from(pubHex, "hex");
227
- const sig = frame.signature;
228
- if (!sig.startsWith(prefix)) {
229
- return NdpAnnounceResult.fail("NDP-ANNOUNCE-SIG-INVALID", "Signature must start with 'ed25519:'");
230
- }
231
- const sigBytes = Buffer.from(sig.slice(prefix.length), "base64");
232
- const unsigned = frame.unsignedDict();
233
- const canonical = JSON.stringify(unsigned, Object.keys(unsigned).sort());
234
- const message = new TextEncoder().encode(canonical);
235
- const valid = ed25519__namespace.verify(sigBytes, message, pubKey);
236
- if (!valid) return NdpAnnounceResult.fail("NDP-ANNOUNCE-SIG-INVALID", "Ed25519 signature verification failed.");
237
- return NdpAnnounceResult.ok();
238
- } catch {
239
- return NdpAnnounceResult.fail("NDP-ANNOUNCE-SIG-INVALID", "Ed25519 signature verification failed.");
240
- }
241
- }
242
- };
243
-
244
- exports.AnnounceFrame = AnnounceFrame;
245
- exports.GraphFrame = GraphFrame;
246
- exports.InMemoryNdpRegistry = InMemoryNdpRegistry;
247
- exports.NdpAnnounceResult = NdpAnnounceResult;
248
- exports.NdpAnnounceValidator = NdpAnnounceValidator;
249
- exports.ResolveFrame = ResolveFrame;
250
- exports.registerNdpFrames = registerNdpFrames;
251
- //# sourceMappingURL=index.cjs.map
252
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/ndp/frames.ts","../../src/ndp/registry.ts","../../src/ndp/ndp-registry.ts","../../src/ndp/validator.ts"],"names":["ed25519","sha512"],"mappings":"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","file":"index.cjs","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"]}
@@ -1,214 +0,0 @@
1
- 'use strict';
2
-
3
- var ed25519 = require('@noble/ed25519');
4
- var sha512 = require('@noble/hashes/sha512');
5
- var crypto = require('crypto');
6
- var fs = require('fs');
7
-
8
- function _interopNamespace(e) {
9
- if (e && e.__esModule) return e;
10
- var n = Object.create(null);
11
- if (e) {
12
- Object.keys(e).forEach(function (k) {
13
- if (k !== 'default') {
14
- var d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: function () { return e[k]; }
18
- });
19
- }
20
- });
21
- }
22
- n.default = e;
23
- return Object.freeze(n);
24
- }
25
-
26
- var ed25519__namespace = /*#__PURE__*/_interopNamespace(ed25519);
27
-
28
- // src/nip/frames.ts
29
- var IdentFrame = class _IdentFrame {
30
- constructor(nid, pubKey, metadata, signature) {
31
- this.nid = nid;
32
- this.pubKey = pubKey;
33
- this.metadata = metadata;
34
- this.signature = signature;
35
- }
36
- nid;
37
- pubKey;
38
- metadata;
39
- signature;
40
- frameType = 32 /* IDENT */;
41
- preferredTier = 1 /* MSGPACK */;
42
- unsignedDict() {
43
- return {
44
- nid: this.nid,
45
- pub_key: this.pubKey,
46
- metadata: this.metadata
47
- };
48
- }
49
- toDict() {
50
- return { ...this.unsignedDict(), signature: this.signature };
51
- }
52
- static fromDict(data) {
53
- return new _IdentFrame(
54
- data["nid"],
55
- data["pub_key"],
56
- data["metadata"],
57
- data["signature"]
58
- );
59
- }
60
- };
61
- var TrustFrame = class _TrustFrame {
62
- constructor(issuerNid, subjectNid, scopes, expiresAt, signature) {
63
- this.issuerNid = issuerNid;
64
- this.subjectNid = subjectNid;
65
- this.scopes = scopes;
66
- this.expiresAt = expiresAt;
67
- this.signature = signature;
68
- }
69
- issuerNid;
70
- subjectNid;
71
- scopes;
72
- expiresAt;
73
- signature;
74
- frameType = 33 /* TRUST */;
75
- preferredTier = 1 /* MSGPACK */;
76
- toDict() {
77
- return {
78
- issuer_nid: this.issuerNid,
79
- subject_nid: this.subjectNid,
80
- scopes: this.scopes,
81
- expires_at: this.expiresAt,
82
- signature: this.signature
83
- };
84
- }
85
- static fromDict(data) {
86
- return new _TrustFrame(
87
- data["issuer_nid"],
88
- data["subject_nid"],
89
- data["scopes"],
90
- data["expires_at"],
91
- data["signature"]
92
- );
93
- }
94
- };
95
- var RevokeFrame = class _RevokeFrame {
96
- constructor(nid, reason, revokedAt) {
97
- this.nid = nid;
98
- this.reason = reason;
99
- this.revokedAt = revokedAt;
100
- }
101
- nid;
102
- reason;
103
- revokedAt;
104
- frameType = 34 /* REVOKE */;
105
- preferredTier = 1 /* MSGPACK */;
106
- toDict() {
107
- return {
108
- nid: this.nid,
109
- reason: this.reason ?? null,
110
- revoked_at: this.revokedAt ?? null
111
- };
112
- }
113
- static fromDict(data) {
114
- return new _RevokeFrame(
115
- data["nid"],
116
- data["reason"] ?? void 0,
117
- data["revoked_at"] ?? void 0
118
- );
119
- }
120
- };
121
- ed25519__namespace.etc.sha512Sync = (...m) => sha512.sha512(ed25519__namespace.etc.concatBytes(...m));
122
- var KEY_FILE_VERSION = 1;
123
- var PBKDF2_ITERS = 6e5;
124
- var SALT_BYTES = 16;
125
- var IV_BYTES = 12;
126
- var KEY_BYTES = 32;
127
- var NipIdentity = class _NipIdentity {
128
- constructor(_privKey, pubKey) {
129
- this._privKey = _privKey;
130
- this.pubKey = pubKey;
131
- }
132
- _privKey;
133
- pubKey;
134
- // ── Factory ───────────────────────────────────────────────────────────────
135
- static generate() {
136
- const priv = ed25519__namespace.utils.randomPrivateKey();
137
- const pub = ed25519__namespace.getPublicKey(priv);
138
- return new _NipIdentity(priv, pub);
139
- }
140
- static fromPrivateKey(privKey) {
141
- const pub = ed25519__namespace.getPublicKey(privKey);
142
- return new _NipIdentity(privKey, pub);
143
- }
144
- /** Load from an AES-256-GCM encrypted key file. */
145
- static load(path, passphrase) {
146
- const envelope = JSON.parse(fs.readFileSync(path, "utf8"));
147
- const salt = Buffer.from(envelope.salt, "hex");
148
- const iv = Buffer.from(envelope.iv, "hex");
149
- const ct = Buffer.from(envelope.ciphertext, "hex");
150
- const dk = crypto.pbkdf2Sync(passphrase, salt, PBKDF2_ITERS, KEY_BYTES, "sha256");
151
- const decipher = crypto.createDecipheriv("aes-256-gcm", dk, iv);
152
- const authTag = ct.slice(ct.length - 16);
153
- const body = ct.slice(0, ct.length - 16);
154
- decipher.setAuthTag(authTag);
155
- const priv = Buffer.concat([decipher.update(body), decipher.final()]);
156
- return _NipIdentity.fromPrivateKey(new Uint8Array(priv));
157
- }
158
- /** Save to an AES-256-GCM encrypted key file. */
159
- save(path, passphrase) {
160
- const salt = crypto.randomBytes(SALT_BYTES);
161
- const iv = crypto.randomBytes(IV_BYTES);
162
- const dk = crypto.pbkdf2Sync(passphrase, salt, PBKDF2_ITERS, KEY_BYTES, "sha256");
163
- const cipher = crypto.createCipheriv("aes-256-gcm", dk, iv);
164
- const body = Buffer.concat([cipher.update(Buffer.from(this._privKey)), cipher.final()]);
165
- const tag = cipher.getAuthTag();
166
- const envelope = {
167
- version: KEY_FILE_VERSION,
168
- salt: salt.toString("hex"),
169
- iv: iv.toString("hex"),
170
- ciphertext: Buffer.concat([body, tag]).toString("hex"),
171
- pubKey: Buffer.from(this.pubKey).toString("hex")
172
- };
173
- fs.writeFileSync(path, JSON.stringify(envelope, null, 2), "utf8");
174
- }
175
- // ── Signing ───────────────────────────────────────────────────────────────
176
- /** Sign a dict payload. Returns `ed25519:<base64url>`. */
177
- sign(payload) {
178
- const canonical = JSON.stringify(payload, Object.keys(payload).sort());
179
- const bytes = new TextEncoder().encode(canonical);
180
- const sig = ed25519__namespace.sign(bytes, this._privKey);
181
- return `ed25519:${Buffer.from(sig).toString("base64")}`;
182
- }
183
- /** Verify a signature string against a dict payload. */
184
- verify(payload, signature) {
185
- if (!signature.startsWith("ed25519:")) return false;
186
- try {
187
- const canonical = JSON.stringify(payload, Object.keys(payload).sort());
188
- const bytes = new TextEncoder().encode(canonical);
189
- const sigBytes = Buffer.from(signature.slice("ed25519:".length), "base64");
190
- return ed25519__namespace.verify(sigBytes, bytes, this.pubKey);
191
- } catch {
192
- return false;
193
- }
194
- }
195
- /** Public key as `ed25519:<hex>` string. */
196
- get pubKeyString() {
197
- return `ed25519:${Buffer.from(this.pubKey).toString("hex")}`;
198
- }
199
- };
200
-
201
- // src/nip/registry.ts
202
- function registerNipFrames(registry) {
203
- registry.register(32 /* IDENT */, IdentFrame);
204
- registry.register(33 /* TRUST */, TrustFrame);
205
- registry.register(34 /* REVOKE */, RevokeFrame);
206
- }
207
-
208
- exports.IdentFrame = IdentFrame;
209
- exports.NipIdentity = NipIdentity;
210
- exports.RevokeFrame = RevokeFrame;
211
- exports.TrustFrame = TrustFrame;
212
- exports.registerNipFrames = registerNipFrames;
213
- //# sourceMappingURL=index.cjs.map
214
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/nip/frames.ts","../../src/nip/identity.ts","../../src/nip/registry.ts"],"names":["ed25519","sha512","readFileSync","pbkdf2Sync","createDecipheriv","randomBytes","createCipheriv","writeFileSync"],"mappings":"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","file":"index.cjs","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"]}