@macula-io/ts 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -272
- package/dist/binding.d.ts +47 -45
- package/dist/binding.js +8 -125
- package/dist/binding.js.map +1 -1
- package/dist/content.js +7 -6
- package/dist/content.js.map +1 -1
- package/dist/directdial.d.ts +3 -3
- package/dist/directdial.js +3 -3
- package/dist/index.d.ts +4 -9
- package/dist/index.js +5 -8
- package/dist/index.js.map +1 -1
- package/dist/key.d.ts +31 -0
- package/dist/key.js +72 -0
- package/dist/key.js.map +1 -0
- package/dist/pool.d.ts +167 -131
- package/dist/pool.js +200 -579
- package/dist/pool.js.map +1 -1
- package/dist/session.d.ts +58 -50
- package/dist/session.js +104 -85
- package/dist/session.js.map +1 -1
- package/dist/stream.d.ts +63 -0
- package/dist/stream.js +93 -0
- package/dist/stream.js.map +1 -0
- package/dist/wire.d.ts +53 -0
- package/dist/wire.js +79 -0
- package/dist/wire.js.map +1 -0
- package/package.json +5 -4
- package/prebuilds/darwin-arm64/@macula-io+ts.node +0 -0
- package/prebuilds/darwin-x64/@macula-io+ts.node +0 -0
- package/prebuilds/linux-arm64/@macula-io+ts.node +0 -0
- package/prebuilds/linux-x64/@macula-io+ts.node +0 -0
- package/prebuilds/win32-x64/@macula-io+ts.node +0 -0
package/dist/binding.js
CHANGED
|
@@ -1,133 +1,16 @@
|
|
|
1
|
-
// Loads the compiled N-API addon (addon/binding.cc) and
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// -buildmode=c-archive, not loaded separately at runtime).
|
|
1
|
+
// Loads the compiled N-API addon (addon/binding.cc) and types its functions.
|
|
2
|
+
// cabi/'s Go code is linked into the addon statically, so it is one
|
|
3
|
+
// self-contained .node file. node-gyp-build picks, at require time, a local
|
|
4
|
+
// build (build/Release/*.node) or the published prebuild for this platform
|
|
5
|
+
// (prebuilds/<platform>-<arch>/*.node), so a consumer installing from npm
|
|
6
|
+
// never runs a compiler.
|
|
8
7
|
//
|
|
9
|
-
//
|
|
10
|
-
// build/Release/*.node (a local dev build via `npm run build:addon:dev`)
|
|
11
|
-
// or prebuilds/<platform>-<arch>/*.node (baked in by `npm run
|
|
12
|
-
// build:prebuilds` / prebuildify, and published as part of the npm
|
|
13
|
-
// package) -- this is the whole point: a consumer installing this
|
|
14
|
-
// package from npm never runs a compiler or fetches anything, because
|
|
15
|
-
// the matching prebuild is already sitting in the downloaded tarball.
|
|
8
|
+
// Internal to the package: the public API is key.ts, pool.ts and stream.ts.
|
|
16
9
|
import { createRequire } from "node:module";
|
|
17
10
|
import { fileURLToPath } from "node:url";
|
|
18
11
|
import { dirname, join } from "node:path";
|
|
19
12
|
const require = createRequire(import.meta.url);
|
|
20
13
|
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
21
14
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
22
|
-
const
|
|
23
|
-
export const native = {
|
|
24
|
-
identityGenerate() {
|
|
25
|
-
return addon.identityGenerate();
|
|
26
|
-
},
|
|
27
|
-
identityFromSeedBytes(seed32) {
|
|
28
|
-
if (seed32.length !== 32) {
|
|
29
|
-
throw new Error(`macula-ts: seed must be exactly 32 bytes, got ${seed32.length}`);
|
|
30
|
-
}
|
|
31
|
-
return addon.identityFromSeedBytes(seed32);
|
|
32
|
-
},
|
|
33
|
-
identityNodeId(handle) {
|
|
34
|
-
return addon.identityNodeId(handle);
|
|
35
|
-
},
|
|
36
|
-
identityPrivateBytes(handle) {
|
|
37
|
-
return addon.identityPrivateBytes(handle);
|
|
38
|
-
},
|
|
39
|
-
identityFree(handle) {
|
|
40
|
-
addon.identityFree(handle);
|
|
41
|
-
},
|
|
42
|
-
identitySign(handle, data) {
|
|
43
|
-
return addon.identitySign(handle, data);
|
|
44
|
-
},
|
|
45
|
-
sessionConnect(host, port, identityHandle) {
|
|
46
|
-
return addon.sessionConnect(host, port, identityHandle);
|
|
47
|
-
},
|
|
48
|
-
sessionRemoteAddr(handle) {
|
|
49
|
-
return addon.sessionRemoteAddr(handle);
|
|
50
|
-
},
|
|
51
|
-
sessionStationNodeId(handle) {
|
|
52
|
-
return addon.sessionStationNodeId(handle);
|
|
53
|
-
},
|
|
54
|
-
sessionClose(handle, identityHandle, reason) {
|
|
55
|
-
return addon.sessionClose(handle, identityHandle, reason);
|
|
56
|
-
},
|
|
57
|
-
sessionCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, bytesMode) {
|
|
58
|
-
return addon.sessionCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, bytesMode);
|
|
59
|
-
},
|
|
60
|
-
ucanMint(identityHandle, issuer, audience, capabilitiesJson, expiresAt, notBefore, nonce, factsJson, proofsJson) {
|
|
61
|
-
return addon.ucanMint(identityHandle, issuer, audience, capabilitiesJson, expiresAt, notBefore, nonce, factsJson, proofsJson);
|
|
62
|
-
},
|
|
63
|
-
ucanDecode(token) {
|
|
64
|
-
return addon.ucanDecode(token);
|
|
65
|
-
},
|
|
66
|
-
sessionCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken, bytesMode) {
|
|
67
|
-
return addon.sessionCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken, bytesMode);
|
|
68
|
-
},
|
|
69
|
-
sessionAdvertise(sessionHandle, identityHandle, realm, procedure) {
|
|
70
|
-
return addon.sessionAdvertise(sessionHandle, identityHandle, realm, procedure);
|
|
71
|
-
},
|
|
72
|
-
sessionUnadvertise(sessionHandle, identityHandle, realm, procedure) {
|
|
73
|
-
return addon.sessionUnadvertise(sessionHandle, identityHandle, realm, procedure);
|
|
74
|
-
},
|
|
75
|
-
serveWaitForCall(sessionHandle, identityHandle, realm, procedure, timeoutMs) {
|
|
76
|
-
return addon.serveWaitForCall(sessionHandle, identityHandle, realm, procedure, timeoutMs);
|
|
77
|
-
},
|
|
78
|
-
pendingCallProcedure(pendingHandle) {
|
|
79
|
-
return addon.pendingCallProcedure(pendingHandle);
|
|
80
|
-
},
|
|
81
|
-
pendingCallPayloadJson(pendingHandle, bytesMode) {
|
|
82
|
-
return addon.pendingCallPayloadJson(pendingHandle, bytesMode);
|
|
83
|
-
},
|
|
84
|
-
pendingCallReplyResult(pendingHandle, resultJson) {
|
|
85
|
-
return addon.pendingCallReplyResult(pendingHandle, resultJson);
|
|
86
|
-
},
|
|
87
|
-
pendingCallReplyError(pendingHandle, detail) {
|
|
88
|
-
return addon.pendingCallReplyError(pendingHandle, detail);
|
|
89
|
-
},
|
|
90
|
-
dhtFindRecordsByType(sessionHandle, identityHandle, recordType) {
|
|
91
|
-
return addon.dhtFindRecordsByType(sessionHandle, identityHandle, recordType);
|
|
92
|
-
},
|
|
93
|
-
dhtFindRecords(sessionHandle, identityHandle, key32) {
|
|
94
|
-
return addon.dhtFindRecords(sessionHandle, identityHandle, key32);
|
|
95
|
-
},
|
|
96
|
-
dhtFindRecord(sessionHandle, identityHandle, key32) {
|
|
97
|
-
return addon.dhtFindRecord(sessionHandle, identityHandle, key32);
|
|
98
|
-
},
|
|
99
|
-
dhtPutProcedureAdvertisement(sessionHandle, identityHandle, realm, procedure, servingStation32, ttlMs) {
|
|
100
|
-
return addon.dhtPutProcedureAdvertisement(sessionHandle, identityHandle, realm, procedure, servingStation32, ttlMs);
|
|
101
|
-
},
|
|
102
|
-
dhtPutContentAnnouncement(sessionHandle, identityHandle, mcid34, endpoint, ttlMs) {
|
|
103
|
-
return addon.dhtPutContentAnnouncement(sessionHandle, identityHandle, mcid34, endpoint, ttlMs);
|
|
104
|
-
},
|
|
105
|
-
sessionPublish(sessionHandle, identityHandle, realm, topic, payloadJson, ttlMs) {
|
|
106
|
-
return addon.sessionPublish(sessionHandle, identityHandle, realm, topic, payloadJson, ttlMs);
|
|
107
|
-
},
|
|
108
|
-
sessionSubscribeStart(sessionHandle, identityHandle, realm, topic, onEvent, bytesMode) {
|
|
109
|
-
return addon.sessionSubscribeStart(sessionHandle, identityHandle, realm, topic, onEvent, bytesMode);
|
|
110
|
-
},
|
|
111
|
-
sessionSubscribeStop(subscriptionHandle) {
|
|
112
|
-
return addon.sessionSubscribeStop(subscriptionHandle);
|
|
113
|
-
},
|
|
114
|
-
contentPut(sessionHandle, identityHandle, data, name) {
|
|
115
|
-
return addon.contentPut(sessionHandle, identityHandle, data, name);
|
|
116
|
-
},
|
|
117
|
-
contentGet(sessionHandle, identityHandle, mcidHex) {
|
|
118
|
-
return addon.contentGet(sessionHandle, identityHandle, mcidHex);
|
|
119
|
-
},
|
|
120
|
-
directdialResolve(sessionHandle, identityHandle, realm, procedure, timeoutMs) {
|
|
121
|
-
return addon.directdialResolve(sessionHandle, identityHandle, realm, procedure, timeoutMs);
|
|
122
|
-
},
|
|
123
|
-
directdialCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, bytesMode) {
|
|
124
|
-
return addon.directdialCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, bytesMode);
|
|
125
|
-
},
|
|
126
|
-
directdialCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken, bytesMode) {
|
|
127
|
-
return addon.directdialCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken, bytesMode);
|
|
128
|
-
},
|
|
129
|
-
directdialAdvertise(sessionHandle, identityHandle, realm, procedure, ttlMs) {
|
|
130
|
-
return addon.directdialAdvertise(sessionHandle, identityHandle, realm, procedure, ttlMs);
|
|
131
|
-
},
|
|
132
|
-
};
|
|
15
|
+
export const native = require("node-gyp-build")(repoRoot);
|
|
133
16
|
//# sourceMappingURL=binding.js.map
|
package/dist/binding.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,oEAAoE;AACpE,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,yBAAyB;AACzB,EAAE;AACF,4EAA4E;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAgBrE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CA2CvD,CAAC"}
|
package/dist/content.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// Content transfer -- macula-go's content package (Put/Get), thin
|
|
2
2
|
// CALL/RESULT wrappers to reserved `_content.*` procedures sent on
|
|
3
3
|
// their OWN dedicated QUIC stream (Session.OpenDedicatedStream on the
|
|
4
|
-
// Go side), NOT the control stream call()/serve()/the DHT
|
|
5
|
-
// methods/subscribe() all
|
|
6
|
-
// Session.putContent()/getContent() (session.ts) are, unlike
|
|
7
|
-
// subject to Session's
|
|
8
|
-
// putContent()/getContent() calls on one Session
|
|
9
|
-
// either (each gets its own fresh dedicated
|
|
4
|
+
// Go side), NOT the shared control stream call()/serve()/the DHT
|
|
5
|
+
// methods/subscribe() all read from -- see cabi/content.go's own doc
|
|
6
|
+
// for why Session.putContent()/getContent() (session.ts) are, unlike
|
|
7
|
+
// those, never subject to Session's same-Session exclusivity guard, and
|
|
8
|
+
// why two concurrent putContent()/getContent() calls on one Session
|
|
9
|
+
// don't race each other either (each gets its own fresh dedicated
|
|
10
|
+
// stream).
|
|
10
11
|
//
|
|
11
12
|
// IMPORTANT: this is a one-time TRANSFER mechanism, not durable object
|
|
12
13
|
// storage. A station may forget content after serving it, there is no
|
package/dist/content.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,mEAAmE;AACnE,sEAAsE;AACtE,
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,mEAAmE;AACnE,sEAAsE;AACtE,iEAAiE;AACjE,qEAAqE;AACrE,qEAAqE;AACrE,wEAAwE;AACxE,oEAAoE;AACpE,kEAAkE;AAClE,WAAW;AACX,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,gEAAgE;AAChE,qEAAqE;AACrE,wEAAwE;AACxE,uEAAuE;AACvE,wDAAwD;AACxD,EAAE;AACF,kEAAkE;AAClE,wEAAwE;AACxE,iEAAiE;AACjE,qEAAqE;AACrE,mEAAmE;AACnE,sEAAsE;AACtE,4BAA4B;AAE5B;;;;;;;sDAOsD;AACtD,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C;2CACuC;IAC9B,IAAI,CAAS;IAEtB,YAAY,IAAY;QACtB,KAAK,CAAC,wCAAwC,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/directdial.d.ts
CHANGED
|
@@ -62,9 +62,9 @@ export interface KeepAdvertisedDirectOptions extends AdvertiseDirectOptions {
|
|
|
62
62
|
* long-lived provider needs to call `AdvertiseDirect` again on its own
|
|
63
63
|
* schedule, and it is this function's CALLER's job to decide WHICH
|
|
64
64
|
* Session that runs on. See `Session.advertiseDirect()`'s own doc for why
|
|
65
|
-
* that must NOT be a Session with an active `serve()` on it
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* that must NOT be a Session with an active `serve()` on it
|
|
66
|
+
* (`advertiseDirect()`'s own `PutRecord` CALL would race `serve()`'s own
|
|
67
|
+
* reads of the same shared control stream): a long-lived provider that
|
|
68
68
|
* also serves `procedure` needs a SEPARATE Session (and identity -- this
|
|
69
69
|
* fleet enforces one connection per identity, kicking whichever connects
|
|
70
70
|
* second) for that, passed here instead of the serving Session.
|
package/dist/directdial.js
CHANGED
|
@@ -37,9 +37,9 @@ export const KEEP_ADVERTISED_DIRECT_INTERVAL_MS = 15 * 60 * 1000;
|
|
|
37
37
|
* long-lived provider needs to call `AdvertiseDirect` again on its own
|
|
38
38
|
* schedule, and it is this function's CALLER's job to decide WHICH
|
|
39
39
|
* Session that runs on. See `Session.advertiseDirect()`'s own doc for why
|
|
40
|
-
* that must NOT be a Session with an active `serve()` on it
|
|
41
|
-
*
|
|
42
|
-
*
|
|
40
|
+
* that must NOT be a Session with an active `serve()` on it
|
|
41
|
+
* (`advertiseDirect()`'s own `PutRecord` CALL would race `serve()`'s own
|
|
42
|
+
* reads of the same shared control stream): a long-lived provider that
|
|
43
43
|
* also serves `procedure` needs a SEPARATE Session (and identity -- this
|
|
44
44
|
* fleet enforces one connection per identity, kicking whichever connects
|
|
45
45
|
* second) for that, passed here instead of the serving Session.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export { DhtRecordType, DHT_DEFAULT_TTL_MS, type DhtRecord } from "./dht.js";
|
|
6
|
-
export type { PublishOptions, PubsubEvent, SubscribeOptions } from "./pubsub.js";
|
|
7
|
-
export { ContentNotFoundError } from "./content.js";
|
|
8
|
-
export { Ucan, type UcanCapability, type UcanFactValue, type UcanMintOptions } from "./ucan.js";
|
|
9
|
-
export { keepAdvertisedDirect, KEEP_ADVERTISED_DIRECT_INTERVAL_MS, type DirectDialTarget, type AdvertiseDirectOptions, type KeepAdvertisedDirectOptions, } from "./directdial.js";
|
|
1
|
+
export { NodeKey, type Profile } from "./key.js";
|
|
2
|
+
export { Pool, Subscription, Served, RecordType, type Seed, type PoolOptions, type LinkStatus, type Provider, type Event, type Request, type DhtRecord, } from "./pool.js";
|
|
3
|
+
export { Stream, StreamMode, type StreamEvent, type StreamRequest } from "./stream.js";
|
|
4
|
+
export { ProviderError, RelayError, StreamError, DEFAULT_CALL_TIMEOUT_MS, type JsonValue, type BytesOutput, type Id, } from "./wire.js";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export { Pool,
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export { ContentNotFoundError } from "./content.js";
|
|
7
|
-
export { Ucan } from "./ucan.js";
|
|
8
|
-
export { keepAdvertisedDirect, KEEP_ADVERTISED_DIRECT_INTERVAL_MS, } from "./directdial.js";
|
|
1
|
+
// @macula-io/ts: the macula 12 mesh from TypeScript, over macula-go.
|
|
2
|
+
export { NodeKey } from "./key.js";
|
|
3
|
+
export { Pool, Subscription, Served, RecordType, } from "./pool.js";
|
|
4
|
+
export { Stream, StreamMode } from "./stream.js";
|
|
5
|
+
export { ProviderError, RelayError, StreamError, DEFAULT_CALL_TIMEOUT_MS, } from "./wire.js";
|
|
9
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,OAAO,EAAgB,MAAM,UAAU,CAAC;AACjD,OAAO,EACL,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,UAAU,GAQX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAwC,MAAM,aAAa,CAAC;AACvF,OAAO,EACL,aAAa,EACb,UAAU,EACV,WAAW,EACX,uBAAuB,GAIxB,MAAM,WAAW,CAAC"}
|
package/dist/key.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Handle } from "./binding.js";
|
|
2
|
+
/** A crypto profile: "pq_hybrid" (the fleet's) or "pq_pure". */
|
|
3
|
+
export type Profile = "pq_hybrid" | "pq_pure";
|
|
4
|
+
export declare class NodeKey {
|
|
5
|
+
private handle;
|
|
6
|
+
private constructor();
|
|
7
|
+
/** A new key whose node_id solves the admission puzzle; takes a second or
|
|
8
|
+
* so, off the event loop. */
|
|
9
|
+
static generate(profile?: Profile): Promise<NodeKey>;
|
|
10
|
+
/** The key in the key file at path. A file its group or others can read,
|
|
11
|
+
* or holding a key of another profile, is refused. */
|
|
12
|
+
static load(path: string, profile?: Profile): Promise<NodeKey>;
|
|
13
|
+
/** The key at path, or a new one saved there when the file does not exist. */
|
|
14
|
+
static loadOrCreate(path: string, profile?: Profile): Promise<NodeKey>;
|
|
15
|
+
/** Writes the key to path, readable by its owner only. */
|
|
16
|
+
save(path: string): Promise<void>;
|
|
17
|
+
/** The key's 32-byte node_id. */
|
|
18
|
+
nodeId(): Uint8Array;
|
|
19
|
+
/** The node_id as lowercase hex. */
|
|
20
|
+
nodeIdHex(): string;
|
|
21
|
+
/** The public key as carried on the wire. */
|
|
22
|
+
publicKey(): Uint8Array;
|
|
23
|
+
/** The key's profile. */
|
|
24
|
+
profile(): Profile;
|
|
25
|
+
/** Signs data as given. */
|
|
26
|
+
sign(data: Uint8Array): Promise<Uint8Array>;
|
|
27
|
+
/** Frees the native key. The NodeKey is unusable after. */
|
|
28
|
+
free(): void;
|
|
29
|
+
/** @internal */
|
|
30
|
+
live(): Handle;
|
|
31
|
+
}
|
package/dist/key.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// A node's identity key, as macula 12 has it: ML-DSA-87 (pq_pure) or the LAMPS
|
|
2
|
+
// composite ML-DSA-87 + RSA-4096-PSS (pq_hybrid, the fleet's profile), whose
|
|
3
|
+
// node_id solves the admission puzzle. Stored in a key file readable by its
|
|
4
|
+
// owner only.
|
|
5
|
+
import { access } from "node:fs/promises";
|
|
6
|
+
import { native } from "./binding.js";
|
|
7
|
+
import { hex } from "./wire.js";
|
|
8
|
+
export class NodeKey {
|
|
9
|
+
handle;
|
|
10
|
+
constructor(handle) {
|
|
11
|
+
this.handle = handle;
|
|
12
|
+
}
|
|
13
|
+
/** A new key whose node_id solves the admission puzzle; takes a second or
|
|
14
|
+
* so, off the event loop. */
|
|
15
|
+
static async generate(profile = "pq_hybrid") {
|
|
16
|
+
return new NodeKey(await native.keyGenerate(profile));
|
|
17
|
+
}
|
|
18
|
+
/** The key in the key file at path. A file its group or others can read,
|
|
19
|
+
* or holding a key of another profile, is refused. */
|
|
20
|
+
static async load(path, profile = "pq_hybrid") {
|
|
21
|
+
return new NodeKey(await native.keyLoad(path, profile));
|
|
22
|
+
}
|
|
23
|
+
/** The key at path, or a new one saved there when the file does not exist. */
|
|
24
|
+
static async loadOrCreate(path, profile = "pq_hybrid") {
|
|
25
|
+
try {
|
|
26
|
+
await access(path);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
const key = await NodeKey.generate(profile);
|
|
30
|
+
await key.save(path);
|
|
31
|
+
return key;
|
|
32
|
+
}
|
|
33
|
+
return NodeKey.load(path, profile);
|
|
34
|
+
}
|
|
35
|
+
/** Writes the key to path, readable by its owner only. */
|
|
36
|
+
async save(path) {
|
|
37
|
+
await native.keySave(this.live(), path);
|
|
38
|
+
}
|
|
39
|
+
/** The key's 32-byte node_id. */
|
|
40
|
+
nodeId() {
|
|
41
|
+
return native.keyNodeId(this.live());
|
|
42
|
+
}
|
|
43
|
+
/** The node_id as lowercase hex. */
|
|
44
|
+
nodeIdHex() {
|
|
45
|
+
return hex(this.nodeId());
|
|
46
|
+
}
|
|
47
|
+
/** The public key as carried on the wire. */
|
|
48
|
+
publicKey() {
|
|
49
|
+
return native.keyPublicKey(this.live());
|
|
50
|
+
}
|
|
51
|
+
/** The key's profile. */
|
|
52
|
+
profile() {
|
|
53
|
+
return native.keyProfile(this.live());
|
|
54
|
+
}
|
|
55
|
+
/** Signs data as given. */
|
|
56
|
+
async sign(data) {
|
|
57
|
+
return native.keySign(this.live(), data);
|
|
58
|
+
}
|
|
59
|
+
/** Frees the native key. The NodeKey is unusable after. */
|
|
60
|
+
free() {
|
|
61
|
+
if (this.handle !== null)
|
|
62
|
+
native.keyFree(this.handle);
|
|
63
|
+
this.handle = null;
|
|
64
|
+
}
|
|
65
|
+
/** @internal */
|
|
66
|
+
live() {
|
|
67
|
+
if (this.handle === null)
|
|
68
|
+
throw new Error("macula-ts: this NodeKey was freed");
|
|
69
|
+
return this.handle;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=key.js.map
|
package/dist/key.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,cAAc;AACd,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAe,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAKhC,MAAM,OAAO,OAAO;IACU,MAAM;IAAlC,YAA4B,MAAqB;sBAArB,MAAM;IAAkB,CAAC;IAErD;iCAC6B;IAC7B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAY,WAAW;QAClD,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;0DACsD;IACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAO,GAAY,WAAW;QAC5D,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,8EAA8E;IAC9E,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,OAAO,GAAY,WAAW;QACpE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,iCAAiC;IACjC,MAAM;QACJ,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,oCAAoC;IACpC,SAAS;QACP,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,yBAAyB;IACzB,OAAO;QACL,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAY,CAAC;IACnD,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,IAAI,CAAC,IAAgB;QACzB,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,2DAA2D;IAC3D,IAAI;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,gBAAgB;IAChB,IAAI;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
|