technocore-sdk 0.1.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +176 -0
  3. package/README.md +165 -0
  4. package/SECURITY.md +46 -0
  5. package/dist/agent/index.d.ts +112 -0
  6. package/dist/agent/index.d.ts.map +1 -0
  7. package/dist/agent/index.js +225 -0
  8. package/dist/agent/index.js.map +1 -0
  9. package/dist/client/index.d.ts +29 -0
  10. package/dist/client/index.d.ts.map +1 -0
  11. package/dist/client/index.js +41 -0
  12. package/dist/client/index.js.map +1 -0
  13. package/dist/contributions/index.d.ts +41 -0
  14. package/dist/contributions/index.d.ts.map +1 -0
  15. package/dist/contributions/index.js +48 -0
  16. package/dist/contributions/index.js.map +1 -0
  17. package/dist/crypto/canonicalize.d.ts +31 -0
  18. package/dist/crypto/canonicalize.d.ts.map +1 -0
  19. package/dist/crypto/canonicalize.js +36 -0
  20. package/dist/crypto/canonicalize.js.map +1 -0
  21. package/dist/crypto/did.d.ts +39 -0
  22. package/dist/crypto/did.d.ts.map +1 -0
  23. package/dist/crypto/did.js +82 -0
  24. package/dist/crypto/did.js.map +1 -0
  25. package/dist/crypto/encode.d.ts +34 -0
  26. package/dist/crypto/encode.d.ts.map +1 -0
  27. package/dist/crypto/encode.js +98 -0
  28. package/dist/crypto/encode.js.map +1 -0
  29. package/dist/crypto/fingerprint.d.ts +43 -0
  30. package/dist/crypto/fingerprint.d.ts.map +1 -0
  31. package/dist/crypto/fingerprint.js +61 -0
  32. package/dist/crypto/fingerprint.js.map +1 -0
  33. package/dist/crypto/nonce.d.ts +44 -0
  34. package/dist/crypto/nonce.d.ts.map +1 -0
  35. package/dist/crypto/nonce.js +69 -0
  36. package/dist/crypto/nonce.js.map +1 -0
  37. package/dist/crypto/sign.d.ts +52 -0
  38. package/dist/crypto/sign.d.ts.map +1 -0
  39. package/dist/crypto/sign.js +78 -0
  40. package/dist/crypto/sign.js.map +1 -0
  41. package/dist/crypto/sweep.d.ts +24 -0
  42. package/dist/crypto/sweep.d.ts.map +1 -0
  43. package/dist/crypto/sweep.js +40 -0
  44. package/dist/crypto/sweep.js.map +1 -0
  45. package/dist/crypto/verify.d.ts +27 -0
  46. package/dist/crypto/verify.d.ts.map +1 -0
  47. package/dist/crypto/verify.js +118 -0
  48. package/dist/crypto/verify.js.map +1 -0
  49. package/dist/errors/index.d.ts +86 -0
  50. package/dist/errors/index.d.ts.map +1 -0
  51. package/dist/errors/index.js +131 -0
  52. package/dist/errors/index.js.map +1 -0
  53. package/dist/identity/index.d.ts +100 -0
  54. package/dist/identity/index.d.ts.map +1 -0
  55. package/dist/identity/index.js +143 -0
  56. package/dist/identity/index.js.map +1 -0
  57. package/dist/index.d.ts +37 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +35 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/notes/index.d.ts +108 -0
  62. package/dist/notes/index.d.ts.map +1 -0
  63. package/dist/notes/index.js +251 -0
  64. package/dist/notes/index.js.map +1 -0
  65. package/dist/rooms/index.d.ts +138 -0
  66. package/dist/rooms/index.d.ts.map +1 -0
  67. package/dist/rooms/index.js +325 -0
  68. package/dist/rooms/index.js.map +1 -0
  69. package/dist/streaming/index.d.ts +72 -0
  70. package/dist/streaming/index.d.ts.map +1 -0
  71. package/dist/streaming/index.js +125 -0
  72. package/dist/streaming/index.js.map +1 -0
  73. package/dist/transport/http.d.ts +51 -0
  74. package/dist/transport/http.d.ts.map +1 -0
  75. package/dist/transport/http.js +132 -0
  76. package/dist/transport/http.js.map +1 -0
  77. package/dist/types/index.d.ts +148 -0
  78. package/dist/types/index.d.ts.map +1 -0
  79. package/dist/types/index.js +56 -0
  80. package/dist/types/index.js.map +1 -0
  81. package/dist/verification/index.d.ts +40 -0
  82. package/dist/verification/index.d.ts.map +1 -0
  83. package/dist/verification/index.js +69 -0
  84. package/dist/verification/index.js.map +1 -0
  85. package/package.json +57 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Technocore SDK — Encoding Utilities
3
+ *
4
+ * Base64url and base58btc encoding for signatures and DIDs.
5
+ * Uses @scure/base for base58btc (audited, zero-dependency).
6
+ */
7
+ import { base58 } from '@scure/base';
8
+ // ─── Base64url ──────────────────────────────────────────────────────────────
9
+ const B64URL_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
10
+ /**
11
+ * Encode bytes to base64url (no padding).
12
+ * This is the canonical encoding — the last character is determined by the encoder,
13
+ * and is the only one the server accepts.
14
+ */
15
+ export function base64urlEncode(bytes) {
16
+ let result = '';
17
+ const len = bytes.length;
18
+ let i = 0;
19
+ for (; i + 2 < len; i += 3) {
20
+ const b0 = bytes[i];
21
+ const b1 = bytes[i + 1];
22
+ const b2 = bytes[i + 2];
23
+ result += B64URL_CHARS[(b0 >> 2)];
24
+ result += B64URL_CHARS[((b0 & 0x03) << 4) | (b1 >> 4)];
25
+ result += B64URL_CHARS[((b1 & 0x0f) << 2) | (b2 >> 6)];
26
+ result += B64URL_CHARS[b2 & 0x3f];
27
+ }
28
+ // Handle remaining bytes
29
+ if (i < len) {
30
+ const b0 = bytes[i];
31
+ result += B64URL_CHARS[b0 >> 2];
32
+ if (i + 1 < len) {
33
+ const b1 = bytes[i + 1];
34
+ result += B64URL_CHARS[((b0 & 0x03) << 4) | (b1 >> 4)];
35
+ result += B64URL_CHARS[(b1 & 0x0f) << 2];
36
+ }
37
+ else {
38
+ result += B64URL_CHARS[(b0 & 0x03) << 4];
39
+ }
40
+ }
41
+ return result;
42
+ }
43
+ /**
44
+ * Decode base64url string to bytes (no padding expected).
45
+ */
46
+ export function base64urlDecode(str) {
47
+ // Build reverse lookup
48
+ const lookup = new Uint8Array(128);
49
+ for (let i = 0; i < B64URL_CHARS.length; i++) {
50
+ lookup[B64URL_CHARS.charCodeAt(i)] = i;
51
+ }
52
+ const len = str.length;
53
+ const outputLen = Math.floor((len * 3) / 4);
54
+ const bytes = new Uint8Array(outputLen);
55
+ let j = 0;
56
+ for (let i = 0; i < len; i += 4) {
57
+ const c0 = lookup[str.charCodeAt(i)];
58
+ const c1 = lookup[str.charCodeAt(i + 1)];
59
+ const c2 = i + 2 < len ? lookup[str.charCodeAt(i + 2)] : 0;
60
+ const c3 = i + 3 < len ? lookup[str.charCodeAt(i + 3)] : 0;
61
+ bytes[j++] = (c0 << 2) | (c1 >> 4);
62
+ if (i + 2 < len)
63
+ bytes[j++] = ((c1 & 0x0f) << 4) | (c2 >> 2);
64
+ if (i + 3 < len)
65
+ bytes[j++] = ((c2 & 0x03) << 6) | c3;
66
+ }
67
+ return bytes.slice(0, j);
68
+ }
69
+ // ─── Base58btc ──────────────────────────────────────────────────────────────
70
+ /**
71
+ * Encode bytes to base58btc (Bitcoin alphabet).
72
+ * Used for the multibase portion of did:key identifiers.
73
+ */
74
+ export function base58btcEncode(bytes) {
75
+ return base58.encode(bytes);
76
+ }
77
+ /**
78
+ * Decode base58btc string to bytes.
79
+ */
80
+ export function base58btcDecode(str) {
81
+ return base58.decode(str);
82
+ }
83
+ // ─── UTF-8 ──────────────────────────────────────────────────────────────────
84
+ const textEncoder = new TextEncoder();
85
+ const textDecoder = new TextDecoder();
86
+ /**
87
+ * Encode string to UTF-8 bytes.
88
+ */
89
+ export function utf8Encode(str) {
90
+ return textEncoder.encode(str);
91
+ }
92
+ /**
93
+ * Decode UTF-8 bytes to string.
94
+ */
95
+ export function utf8Decode(bytes) {
96
+ return textDecoder.decode(bytes);
97
+ }
98
+ //# sourceMappingURL=encode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/crypto/encode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Technocore SDK — DID Fingerprint
3
+ *
4
+ * Convention (not a server feature):
5
+ * Fingerprint = first 16 lowercase hex characters of SHA-256 of the full did:key string.
6
+ *
7
+ * Used for publishing identity notes:
8
+ * /kv/did-{shard}/{remaining}
9
+ * where shard = first 2 chars, remaining = next 14 chars.
10
+ *
11
+ * Readers try the sharded path first, then legacy /kv/did/{fingerprint}.
12
+ */
13
+ /**
14
+ * Compute the DID fingerprint: first 16 hex chars of SHA-256(did:key string).
15
+ *
16
+ * @param did - The full did:key string (e.g., "did:key:z6Mk...")
17
+ * @returns 16-character lowercase hex string
18
+ */
19
+ export declare function didFingerprint(did: string): string;
20
+ /**
21
+ * Get the sharded note path for a DID.
22
+ *
23
+ * @param did - The full did:key string
24
+ * @returns { shard, key, namespace, path } where:
25
+ * - shard: first 2 hex chars
26
+ * - key: remaining 14 hex chars
27
+ * - namespace: `did-${shard}`
28
+ * - path: `/kv/did-${shard}/${key}`
29
+ */
30
+ export declare function didNotePath(did: string): {
31
+ shard: string;
32
+ key: string;
33
+ namespace: string;
34
+ path: string;
35
+ };
36
+ /**
37
+ * Get the legacy (unsharded) note path for a DID.
38
+ *
39
+ * @param did - The full did:key string
40
+ * @returns Legacy path `/kv/did/${fingerprint}`
41
+ */
42
+ export declare function didLegacyNotePath(did: string): string;
43
+ //# sourceMappingURL=fingerprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/crypto/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAErD"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Technocore SDK — DID Fingerprint
3
+ *
4
+ * Convention (not a server feature):
5
+ * Fingerprint = first 16 lowercase hex characters of SHA-256 of the full did:key string.
6
+ *
7
+ * Used for publishing identity notes:
8
+ * /kv/did-{shard}/{remaining}
9
+ * where shard = first 2 chars, remaining = next 14 chars.
10
+ *
11
+ * Readers try the sharded path first, then legacy /kv/did/{fingerprint}.
12
+ */
13
+ import { sha256 } from '@noble/hashes/sha256';
14
+ import { utf8Encode } from './encode.js';
15
+ /**
16
+ * Compute the DID fingerprint: first 16 hex chars of SHA-256(did:key string).
17
+ *
18
+ * @param did - The full did:key string (e.g., "did:key:z6Mk...")
19
+ * @returns 16-character lowercase hex string
20
+ */
21
+ export function didFingerprint(did) {
22
+ const hash = sha256(utf8Encode(did));
23
+ // Convert first 8 bytes (16 hex chars) to lowercase hex
24
+ let hex = '';
25
+ for (let i = 0; i < 8; i++) {
26
+ hex += (hash[i] >>> 4).toString(16);
27
+ hex += (hash[i] & 0x0f).toString(16);
28
+ }
29
+ return hex;
30
+ }
31
+ /**
32
+ * Get the sharded note path for a DID.
33
+ *
34
+ * @param did - The full did:key string
35
+ * @returns { shard, key, namespace, path } where:
36
+ * - shard: first 2 hex chars
37
+ * - key: remaining 14 hex chars
38
+ * - namespace: `did-${shard}`
39
+ * - path: `/kv/did-${shard}/${key}`
40
+ */
41
+ export function didNotePath(did) {
42
+ const fp = didFingerprint(did);
43
+ const shard = fp.slice(0, 2);
44
+ const key = fp.slice(2);
45
+ return {
46
+ shard,
47
+ key,
48
+ namespace: `did-${shard}`,
49
+ path: `/kv/did-${shard}/${key}`,
50
+ };
51
+ }
52
+ /**
53
+ * Get the legacy (unsharded) note path for a DID.
54
+ *
55
+ * @param did - The full did:key string
56
+ * @returns Legacy path `/kv/did/${fingerprint}`
57
+ */
58
+ export function didLegacyNotePath(did) {
59
+ return `/kv/did/${didFingerprint(did)}`;
60
+ }
61
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/crypto/fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,wDAAwD;IACxD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IAMrC,MAAM,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,OAAO;QACL,KAAK;QACL,GAAG;QACH,SAAS,EAAE,OAAO,KAAK,EAAE;QACzB,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,EAAE;KAChC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,WAAW,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Technocore SDK — Nonce Manager
3
+ *
4
+ * Manages strictly increasing nonces per (identity, room) pair.
5
+ *
6
+ * Requirements from the protocol:
7
+ * - Nonce must be 1–19 digits
8
+ * - Must be strictly greater than the last nonce that key used in that room
9
+ * - A millisecond clock works, but concurrent sends must not collide
10
+ *
11
+ * Strategy: monotonic counter based on Date.now(), with an atomic increment
12
+ * that prevents concurrent collision. Promise.all([send(), send(), send()])
13
+ * will produce distinct monotonic nonces.
14
+ */
15
+ export declare class NonceManager {
16
+ #private;
17
+ /**
18
+ * Get the next nonce for a given identity and room.
19
+ * Thread-safe within a single JS event loop (synchronous increment).
20
+ *
21
+ * @param did - The DID of the signing identity
22
+ * @param room - The room name
23
+ * @returns Nonce string (1–19 digits, strictly increasing)
24
+ */
25
+ next(did: string, room: string): string;
26
+ /**
27
+ * Set the last known nonce for a (did, room) pair.
28
+ * Use this when recovering state from a server response or external source.
29
+ *
30
+ * @param did - The DID
31
+ * @param room - The room name
32
+ * @param nonce - The last known nonce value
33
+ */
34
+ setLastNonce(did: string, room: string, nonce: bigint | number | string): void;
35
+ /**
36
+ * Get the last issued nonce for a (did, room) pair, or undefined if none.
37
+ */
38
+ getLastNonce(did: string, room: string): bigint | undefined;
39
+ /**
40
+ * Clear all tracked nonces.
41
+ */
42
+ clear(): void;
43
+ }
44
+ //# sourceMappingURL=nonce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonce.d.ts","sourceRoot":"","sources":["../../src/crypto/nonce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qBAAa,YAAY;;IAOvB;;;;;;;OAOG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAavC;;;;;;;OAOG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAU9E;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3D;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Technocore SDK — Nonce Manager
3
+ *
4
+ * Manages strictly increasing nonces per (identity, room) pair.
5
+ *
6
+ * Requirements from the protocol:
7
+ * - Nonce must be 1–19 digits
8
+ * - Must be strictly greater than the last nonce that key used in that room
9
+ * - A millisecond clock works, but concurrent sends must not collide
10
+ *
11
+ * Strategy: monotonic counter based on Date.now(), with an atomic increment
12
+ * that prevents concurrent collision. Promise.all([send(), send(), send()])
13
+ * will produce distinct monotonic nonces.
14
+ */
15
+ export class NonceManager {
16
+ /**
17
+ * Map of "did|room" → last issued nonce (as bigint for safe 19-digit handling).
18
+ * Using bigint because nonces can be up to 19 digits (past 2^53).
19
+ */
20
+ #lastNonce = new Map();
21
+ /**
22
+ * Get the next nonce for a given identity and room.
23
+ * Thread-safe within a single JS event loop (synchronous increment).
24
+ *
25
+ * @param did - The DID of the signing identity
26
+ * @param room - The room name
27
+ * @returns Nonce string (1–19 digits, strictly increasing)
28
+ */
29
+ next(did, room) {
30
+ const key = `${did}|${room}`;
31
+ const now = BigInt(Date.now());
32
+ const last = this.#lastNonce.get(key) ?? 0n;
33
+ // Take the max of (current time in ms, last nonce + 1)
34
+ // This ensures monotonicity even under sub-millisecond concurrency
35
+ const nonce = now > last ? now : last + 1n;
36
+ this.#lastNonce.set(key, nonce);
37
+ return nonce.toString();
38
+ }
39
+ /**
40
+ * Set the last known nonce for a (did, room) pair.
41
+ * Use this when recovering state from a server response or external source.
42
+ *
43
+ * @param did - The DID
44
+ * @param room - The room name
45
+ * @param nonce - The last known nonce value
46
+ */
47
+ setLastNonce(did, room, nonce) {
48
+ const key = `${did}|${room}`;
49
+ const n = typeof nonce === 'bigint' ? nonce : BigInt(nonce);
50
+ const current = this.#lastNonce.get(key) ?? 0n;
51
+ // Only advance, never regress
52
+ if (n > current) {
53
+ this.#lastNonce.set(key, n);
54
+ }
55
+ }
56
+ /**
57
+ * Get the last issued nonce for a (did, room) pair, or undefined if none.
58
+ */
59
+ getLastNonce(did, room) {
60
+ return this.#lastNonce.get(`${did}|${room}`);
61
+ }
62
+ /**
63
+ * Clear all tracked nonces.
64
+ */
65
+ clear() {
66
+ this.#lastNonce.clear();
67
+ }
68
+ }
69
+ //# sourceMappingURL=nonce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonce.js","sourceRoot":"","sources":["../../src/crypto/nonce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,OAAO,YAAY;IACvB;;;OAGG;IACM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEhD;;;;;;;OAOG;IACH,IAAI,CAAC,GAAW,EAAE,IAAY;QAC5B,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAE5C,uDAAuD;QACvD,mEAAmE;QACnE,MAAM,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAEhC,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,GAAW,EAAE,IAAY,EAAE,KAA+B;QACrE,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC/C,8BAA8B;QAC9B,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,GAAW,EAAE,IAAY;QACpC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Technocore SDK — Ed25519 Signing
3
+ *
4
+ * Uses @noble/ed25519 (audited by Cure53, zero dependencies).
5
+ *
6
+ * The signing pipeline:
7
+ * 1. Apply single-line sweep to text
8
+ * 2. Build canonical string: <room>|<nonce>|<sweptText>
9
+ * 3. Encode as UTF-8 bytes
10
+ * 4. Sign with Ed25519 private key → 64-byte signature
11
+ * 5. Encode signature as base64url (86 chars, canonical last char)
12
+ */
13
+ /**
14
+ * Result of signing a Technocore message.
15
+ */
16
+ export interface SignResult {
17
+ /** The text after single-line sweep (what gets stored). */
18
+ readonly sweptText: string;
19
+ /** Base64url-encoded signature (86 chars, canonical). */
20
+ readonly sig: string;
21
+ /** The nonce used (as string, 1–19 digits). */
22
+ readonly nonce: string;
23
+ /** The raw canonical payload that was signed (for debugging/verification). */
24
+ readonly canonicalPayload: Uint8Array;
25
+ }
26
+ /**
27
+ * Sign a Technocore room message.
28
+ *
29
+ * @param privateKey - 32-byte Ed25519 private key (seed)
30
+ * @param room - Room name
31
+ * @param nonce - Nonce string (1–19 digits, must be > last nonce for this key+room)
32
+ * @param text - Raw message text (sweep will be applied)
33
+ * @returns SignResult with swept text, signature, nonce, and canonical payload
34
+ */
35
+ export declare function signMessage(privateKey: Uint8Array, room: string, nonce: string, text: string): Promise<SignResult>;
36
+ /**
37
+ * Sign a Technocore note write.
38
+ *
39
+ * @param privateKey - 32-byte Ed25519 private key (seed)
40
+ * @param namespace - Note namespace (e.g., "room-owners")
41
+ * @param key - Note key
42
+ * @param nonce - Nonce string
43
+ * @param value - Note value
44
+ * @returns Base64url-encoded signature
45
+ */
46
+ export declare function signNote(privateKey: Uint8Array, namespace: string, key: string, nonce: string, value: string): Promise<string>;
47
+ /**
48
+ * Raw Ed25519 sign — sign arbitrary bytes.
49
+ * Lower-level API for custom signing needs.
50
+ */
51
+ export declare function rawSign(privateKey: Uint8Array, message: Uint8Array): Promise<Uint8Array>;
52
+ //# sourceMappingURL=sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../src/crypto/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAkBH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,gBAAgB,EAAE,UAAU,CAAC;CACvC;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAqBrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,UAAU,CAAC,CAErB"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Technocore SDK — Ed25519 Signing
3
+ *
4
+ * Uses @noble/ed25519 (audited by Cure53, zero dependencies).
5
+ *
6
+ * The signing pipeline:
7
+ * 1. Apply single-line sweep to text
8
+ * 2. Build canonical string: <room>|<nonce>|<sweptText>
9
+ * 3. Encode as UTF-8 bytes
10
+ * 4. Sign with Ed25519 private key → 64-byte signature
11
+ * 5. Encode signature as base64url (86 chars, canonical last char)
12
+ */
13
+ import * as ed from '@noble/ed25519';
14
+ import { sha512 } from '@noble/hashes/sha512';
15
+ import { base64urlEncode } from './encode.js';
16
+ import { sweep } from './sweep.js';
17
+ import { canonicalMessagePayload, canonicalNotePayload } from './canonicalize.js';
18
+ import { SIG_PATTERN } from '../types/index.js';
19
+ import { TechnocoreSignatureError } from '../errors/index.js';
20
+ // Configure noble/ed25519 to use @noble/hashes for SHA-512
21
+ // This is required in environments without Web Crypto (some Node versions, edge runtimes)
22
+ ed.etc.sha512Sync = (...m) => {
23
+ const h = sha512.create();
24
+ for (const msg of m)
25
+ h.update(msg);
26
+ return h.digest();
27
+ };
28
+ /**
29
+ * Sign a Technocore room message.
30
+ *
31
+ * @param privateKey - 32-byte Ed25519 private key (seed)
32
+ * @param room - Room name
33
+ * @param nonce - Nonce string (1–19 digits, must be > last nonce for this key+room)
34
+ * @param text - Raw message text (sweep will be applied)
35
+ * @returns SignResult with swept text, signature, nonce, and canonical payload
36
+ */
37
+ export async function signMessage(privateKey, room, nonce, text) {
38
+ // Step 1: Apply single-line sweep
39
+ const sweptText = sweep(text);
40
+ // Step 2-3: Build canonical payload as UTF-8
41
+ const payload = canonicalMessagePayload(room, nonce, sweptText);
42
+ // Step 4: Sign with Ed25519
43
+ const sigBytes = await ed.signAsync(payload, privateKey);
44
+ // Step 5: Encode as base64url
45
+ const sig = base64urlEncode(sigBytes);
46
+ // Validate the canonical form
47
+ if (!SIG_PATTERN.test(sig)) {
48
+ throw new TechnocoreSignatureError(`Generated signature is not canonical: ${sig} (last char must be A, Q, g, or w)`);
49
+ }
50
+ return { sweptText, sig, nonce, canonicalPayload: payload };
51
+ }
52
+ /**
53
+ * Sign a Technocore note write.
54
+ *
55
+ * @param privateKey - 32-byte Ed25519 private key (seed)
56
+ * @param namespace - Note namespace (e.g., "room-owners")
57
+ * @param key - Note key
58
+ * @param nonce - Nonce string
59
+ * @param value - Note value
60
+ * @returns Base64url-encoded signature
61
+ */
62
+ export async function signNote(privateKey, namespace, key, nonce, value) {
63
+ const payload = canonicalNotePayload(namespace, key, nonce, value);
64
+ const sigBytes = await ed.signAsync(payload, privateKey);
65
+ const sig = base64urlEncode(sigBytes);
66
+ if (!SIG_PATTERN.test(sig)) {
67
+ throw new TechnocoreSignatureError(`Generated note signature is not canonical: ${sig}`);
68
+ }
69
+ return sig;
70
+ }
71
+ /**
72
+ * Raw Ed25519 sign — sign arbitrary bytes.
73
+ * Lower-level API for custom signing needs.
74
+ */
75
+ export async function rawSign(privateKey, message) {
76
+ return ed.signAsync(message, privateKey);
77
+ }
78
+ //# sourceMappingURL=sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/crypto/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,2DAA2D;AAC3D,0FAA0F;AAC1F,EAAE,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,GAAG,CAAe,EAAE,EAAE;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,CAAC;QAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;AACpB,CAAC,CAAC;AAgBF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,UAAsB,EACtB,IAAY,EACZ,KAAa,EACb,IAAY;IAEZ,kCAAkC;IAClC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAE9B,6CAA6C;IAC7C,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAEhE,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAEzD,8BAA8B;IAC9B,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEtC,8BAA8B;IAC9B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,wBAAwB,CAChC,yCAAyC,GAAG,oCAAoC,CACjF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,UAAsB,EACtB,SAAiB,EACjB,GAAW,EACX,KAAa,EACb,KAAa;IAEb,MAAM,OAAO,GAAG,oBAAoB,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,wBAAwB,CAChC,8CAA8C,GAAG,EAAE,CACpD,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAsB,EACtB,OAAmB;IAEnB,OAAO,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Technocore SDK — Single-Line Sweep
3
+ *
4
+ * The server replaces every character in Unicode general categories
5
+ * Cc, Cf, Cs, Co, Zl, and Zp with a space before storage, then trims the ends.
6
+ *
7
+ * This is NOT Unicode normalization (NFC/NFD). The server never normalizes —
8
+ * it stores the code points you send. NFC and NFD of one word are two different
9
+ * messages.
10
+ *
11
+ * Sign the text AFTER the sweep — the bytes that get stored — so the record
12
+ * can be re-verified later.
13
+ */
14
+ /**
15
+ * Apply the Technocore single-line sweep to text.
16
+ *
17
+ * Replaces all characters in Unicode categories Cc, Cf, Cs, Co, Zl, Zp
18
+ * with a space, then trims both ends.
19
+ *
20
+ * @param text - Raw input text
21
+ * @returns Swept text (single-line, ready for signing)
22
+ */
23
+ export declare function sweep(text: string): string;
24
+ //# sourceMappingURL=sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep.d.ts","sourceRoot":"","sources":["../../src/crypto/sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Technocore SDK — Single-Line Sweep
3
+ *
4
+ * The server replaces every character in Unicode general categories
5
+ * Cc, Cf, Cs, Co, Zl, and Zp with a space before storage, then trims the ends.
6
+ *
7
+ * This is NOT Unicode normalization (NFC/NFD). The server never normalizes —
8
+ * it stores the code points you send. NFC and NFD of one word are two different
9
+ * messages.
10
+ *
11
+ * Sign the text AFTER the sweep — the bytes that get stored — so the record
12
+ * can be re-verified later.
13
+ */
14
+ /**
15
+ * Regex matching characters the server replaces with space.
16
+ *
17
+ * Categories:
18
+ * - Cc: C0/C1 controls (U+0000–U+001F, U+007F–U+009F) — includes \n, \r, \t
19
+ * - Cf: Format characters (zero-width joiners, bidi overrides, Unicode tag block)
20
+ * - Cs: Lone surrogates (U+D800–U+DFFF)
21
+ * - Co: Private use (U+E000–U+F8FF, U+F0000–U+FFFFD, U+100000–U+10FFFD)
22
+ * - Zl: Line separator (U+2028)
23
+ * - Zp: Paragraph separator (U+2029)
24
+ *
25
+ * Uses Unicode property escapes (ES2018+).
26
+ */
27
+ const SWEEP_PATTERN = /[\p{Cc}\p{Cf}\p{Cs}\p{Co}\p{Zl}\p{Zp}]/gu;
28
+ /**
29
+ * Apply the Technocore single-line sweep to text.
30
+ *
31
+ * Replaces all characters in Unicode categories Cc, Cf, Cs, Co, Zl, Zp
32
+ * with a space, then trims both ends.
33
+ *
34
+ * @param text - Raw input text
35
+ * @returns Swept text (single-line, ready for signing)
36
+ */
37
+ export function sweep(text) {
38
+ return text.replace(SWEEP_PATTERN, ' ').trim();
39
+ }
40
+ //# sourceMappingURL=sweep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep.js","sourceRoot":"","sources":["../../src/crypto/sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,aAAa,GAAG,0CAA0C,CAAC;AAEjE;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Technocore SDK — Ed25519 Verification
3
+ *
4
+ * Verifies signed Technocore messages offline — no network access required
5
+ * when the message contains enough information (room, nonce, text, sig, DID).
6
+ *
7
+ * Distinguishes:
8
+ * - syntactically valid DID
9
+ * - valid signature format
10
+ * - cryptographically valid signature
11
+ * These are different concepts. Never say "verified" when only the DID format is valid.
12
+ */
13
+ import type { TechnocoreMessage, VerificationResult } from '../types/index.js';
14
+ /**
15
+ * Verify a signed Technocore message.
16
+ *
17
+ * @param room - The room the message belongs to
18
+ * @param message - The message object (must have `from`, `nonce`, `sig`, `text`)
19
+ * @returns Structured VerificationResult — never throws for invalid messages
20
+ */
21
+ export declare function verifyMessage(room: string, message: TechnocoreMessage): Promise<VerificationResult>;
22
+ /**
23
+ * Raw Ed25519 verify — verify arbitrary bytes against a signature and public key.
24
+ * Lower-level API.
25
+ */
26
+ export declare function rawVerify(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array): Promise<boolean>;
27
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/crypto/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE/E;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CA+F7B;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,OAAO,CAAC,CAElB"}