@hashtree/core 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 (138) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bep52.d.ts +179 -0
  3. package/dist/bep52.d.ts.map +1 -0
  4. package/dist/bep52.js +384 -0
  5. package/dist/bep52.js.map +1 -0
  6. package/dist/builder.d.ts +137 -0
  7. package/dist/builder.d.ts.map +1 -0
  8. package/dist/builder.js +281 -0
  9. package/dist/builder.js.map +1 -0
  10. package/dist/codec.d.ts +37 -0
  11. package/dist/codec.d.ts.map +1 -0
  12. package/dist/codec.js +109 -0
  13. package/dist/codec.js.map +1 -0
  14. package/dist/crypto.d.ts +92 -0
  15. package/dist/crypto.d.ts.map +1 -0
  16. package/dist/crypto.js +212 -0
  17. package/dist/crypto.js.map +1 -0
  18. package/dist/encrypted.d.ts +114 -0
  19. package/dist/encrypted.d.ts.map +1 -0
  20. package/dist/encrypted.js +446 -0
  21. package/dist/encrypted.js.map +1 -0
  22. package/dist/hash.d.ts +14 -0
  23. package/dist/hash.d.ts.map +1 -0
  24. package/dist/hash.js +27 -0
  25. package/dist/hash.js.map +1 -0
  26. package/dist/hashtree.d.ts +237 -0
  27. package/dist/hashtree.d.ts.map +1 -0
  28. package/dist/hashtree.js +557 -0
  29. package/dist/hashtree.js.map +1 -0
  30. package/dist/index.d.ts +27 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +44 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/nhash.d.ts +94 -0
  35. package/dist/nhash.d.ts.map +1 -0
  36. package/dist/nhash.js +293 -0
  37. package/dist/nhash.js.map +1 -0
  38. package/dist/resolver/index.d.ts +5 -0
  39. package/dist/resolver/index.d.ts.map +1 -0
  40. package/dist/resolver/index.js +5 -0
  41. package/dist/resolver/index.js.map +1 -0
  42. package/dist/resolver/nostr.d.ts +82 -0
  43. package/dist/resolver/nostr.d.ts.map +1 -0
  44. package/dist/resolver/nostr.js +868 -0
  45. package/dist/resolver/nostr.js.map +1 -0
  46. package/dist/store/blossom.d.ts +100 -0
  47. package/dist/store/blossom.d.ts.map +1 -0
  48. package/dist/store/blossom.js +355 -0
  49. package/dist/store/blossom.js.map +1 -0
  50. package/dist/store/dexie.d.ts +44 -0
  51. package/dist/store/dexie.d.ts.map +1 -0
  52. package/dist/store/dexie.js +196 -0
  53. package/dist/store/dexie.js.map +1 -0
  54. package/dist/store/fallback.d.ts +40 -0
  55. package/dist/store/fallback.d.ts.map +1 -0
  56. package/dist/store/fallback.js +71 -0
  57. package/dist/store/fallback.js.map +1 -0
  58. package/dist/store/index.d.ts +6 -0
  59. package/dist/store/index.d.ts.map +1 -0
  60. package/dist/store/index.js +6 -0
  61. package/dist/store/index.js.map +1 -0
  62. package/dist/store/memory.d.ts +29 -0
  63. package/dist/store/memory.d.ts.map +1 -0
  64. package/dist/store/memory.js +66 -0
  65. package/dist/store/memory.js.map +1 -0
  66. package/dist/store/opfs.d.ts +56 -0
  67. package/dist/store/opfs.d.ts.map +1 -0
  68. package/dist/store/opfs.js +200 -0
  69. package/dist/store/opfs.js.map +1 -0
  70. package/dist/streaming.d.ts +74 -0
  71. package/dist/streaming.d.ts.map +1 -0
  72. package/dist/streaming.js +199 -0
  73. package/dist/streaming.js.map +1 -0
  74. package/dist/tree/create.d.ts +35 -0
  75. package/dist/tree/create.d.ts.map +1 -0
  76. package/dist/tree/create.js +90 -0
  77. package/dist/tree/create.js.map +1 -0
  78. package/dist/tree/edit.d.ts +28 -0
  79. package/dist/tree/edit.d.ts.map +1 -0
  80. package/dist/tree/edit.js +115 -0
  81. package/dist/tree/edit.js.map +1 -0
  82. package/dist/tree/editEncrypted.d.ts +46 -0
  83. package/dist/tree/editEncrypted.d.ts.map +1 -0
  84. package/dist/tree/editEncrypted.js +225 -0
  85. package/dist/tree/editEncrypted.js.map +1 -0
  86. package/dist/tree/index.d.ts +7 -0
  87. package/dist/tree/index.d.ts.map +1 -0
  88. package/dist/tree/index.js +7 -0
  89. package/dist/tree/index.js.map +1 -0
  90. package/dist/tree/read.d.ts +75 -0
  91. package/dist/tree/read.d.ts.map +1 -0
  92. package/dist/tree/read.js +389 -0
  93. package/dist/tree/read.js.map +1 -0
  94. package/dist/tree/writeAt.d.ts +44 -0
  95. package/dist/tree/writeAt.d.ts.map +1 -0
  96. package/dist/tree/writeAt.js +282 -0
  97. package/dist/tree/writeAt.js.map +1 -0
  98. package/dist/types.d.ts +274 -0
  99. package/dist/types.d.ts.map +1 -0
  100. package/dist/types.js +47 -0
  101. package/dist/types.js.map +1 -0
  102. package/dist/verify.d.ts +12 -0
  103. package/dist/verify.d.ts.map +1 -0
  104. package/dist/verify.js +32 -0
  105. package/dist/verify.js.map +1 -0
  106. package/dist/visibility.d.ts +50 -0
  107. package/dist/visibility.d.ts.map +1 -0
  108. package/dist/visibility.js +111 -0
  109. package/dist/visibility.js.map +1 -0
  110. package/dist/webrtc/index.d.ts +4 -0
  111. package/dist/webrtc/index.d.ts.map +1 -0
  112. package/dist/webrtc/index.js +4 -0
  113. package/dist/webrtc/index.js.map +1 -0
  114. package/dist/webrtc/lruCache.d.ts +20 -0
  115. package/dist/webrtc/lruCache.d.ts.map +1 -0
  116. package/dist/webrtc/lruCache.js +59 -0
  117. package/dist/webrtc/lruCache.js.map +1 -0
  118. package/dist/webrtc/peer.d.ts +122 -0
  119. package/dist/webrtc/peer.d.ts.map +1 -0
  120. package/dist/webrtc/peer.js +583 -0
  121. package/dist/webrtc/peer.js.map +1 -0
  122. package/dist/webrtc/protocol.d.ts +76 -0
  123. package/dist/webrtc/protocol.d.ts.map +1 -0
  124. package/dist/webrtc/protocol.js +167 -0
  125. package/dist/webrtc/protocol.js.map +1 -0
  126. package/dist/webrtc/store.d.ts +190 -0
  127. package/dist/webrtc/store.d.ts.map +1 -0
  128. package/dist/webrtc/store.js +1043 -0
  129. package/dist/webrtc/store.js.map +1 -0
  130. package/dist/webrtc/types.d.ts +196 -0
  131. package/dist/webrtc/types.d.ts.map +1 -0
  132. package/dist/webrtc/types.js +46 -0
  133. package/dist/webrtc/types.js.map +1 -0
  134. package/dist/worker/protocol.d.ts +493 -0
  135. package/dist/worker/protocol.d.ts.map +1 -0
  136. package/dist/worker/protocol.js +15 -0
  137. package/dist/worker/protocol.js.map +1 -0
  138. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,OAAO,EACL,QAAQ,EACR,KAAK,EACL,OAAO,EACP,GAAG,GACJ,MAAM,YAAY,CAAC;AAEpB,iBAAiB;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,uBAAuB;AACvB,OAAO;AACL,2EAA2E;AAC3E,UAAU,EACV,UAAU,EACV,WAAW,EACX,gBAAgB;AAChB,yDAAyD;AACzD,OAAO,EACP,OAAO,EACP,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,EACb,aAAa,GAEd,MAAM,aAAa,CAAC;AAErB,oBAAoB;AACpB,OAAO,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,mBAAmB;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EACL,YAAY,GAQb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,kEAAkE;AAClE,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,kBAAkB,GAInB,MAAM,eAAe,CAAC;AAKvB,oBAAoB;AACpB,OAAO,EAEL,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,IAAI,EACJ,MAAM,EACN,YAAY,GAgBb,MAAM,mBAAmB,CAAC;AAE3B,+CAA+C;AAC/C,iDAAiD;AACjD,4EAA4E;AAC5E,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,kBAAkB,GAGnB,MAAM,YAAY,CAAC;AAEpB,0DAA0D;AAC1D,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AAEpC,gBAAgB;AAChB,OAAO,EACL,sBAAsB;AACtB,eAAe;AACf,sBAAsB,IAAI,uBAAuB,GAQlD,MAAM,qBAAqB,CAAC;AAE7B,oCAAoC;AACpC,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,MAAM,EACN,OAAO,EACP,OAAO,EACP,cAAc,EACd,YAAY,GAIb,MAAM,YAAY,CAAC;AAEpB,0DAA0D;AAC1D,OAAO,EACL,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,GAAG,IAAI,aAAa,GAErB,MAAM,iBAAiB,CAAC;AAwBzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Bech32-encoded identifiers for hashtree content
3
+ *
4
+ * Similar to nostr's nip19 (npub, nprofile, nevent, naddr),
5
+ * provides human-readable, copy-pasteable identifiers.
6
+ *
7
+ * Types:
8
+ * - nhash: Permalink (hash + optional decrypt key)
9
+ * - npath: Live reference (pubkey + tree + path + optional decrypt key)
10
+ */
11
+ import type { Hash, CID } from './types.js';
12
+ /**
13
+ * NHash data - permalink to content by hash
14
+ * Path is kept in URL segments, not encoded in nhash (e.g., /nhash1.../path/to/file)
15
+ */
16
+ export interface NHashData {
17
+ /** 32-byte merkle hash (hex string) */
18
+ hash: string;
19
+ /** 32-byte decryption key (hex string) - optional */
20
+ decryptKey?: string;
21
+ }
22
+ /**
23
+ * NPath data - live reference via pubkey + tree + path
24
+ */
25
+ export interface NPathData {
26
+ /** 32-byte nostr pubkey (hex string) */
27
+ pubkey: string;
28
+ /** Tree name (e.g., "home", "photos") */
29
+ treeName: string;
30
+ /** Path segments within the tree (e.g., ["folder", "file.txt"]) */
31
+ path: string[];
32
+ /** 32-byte decryption key (hex string) - optional */
33
+ decryptKey?: string;
34
+ }
35
+ export type DecodeResult = {
36
+ type: 'nhash';
37
+ data: CID;
38
+ } | {
39
+ type: 'npath';
40
+ data: NPathData;
41
+ };
42
+ /**
43
+ * Encode an nhash permalink
44
+ *
45
+ * Path is kept in URL segments, not encoded in nhash.
46
+ * Use format: /nhash1.../path/to/file
47
+ *
48
+ * @example
49
+ * // Simple hash
50
+ * const encoded = nhashEncode('abc123...');
51
+ * const encoded = nhashEncode(hashBytes);
52
+ *
53
+ * @example
54
+ * // Hash with decrypt key (hex strings)
55
+ * const encoded = nhashEncode({ hash: 'abc123...', decryptKey: 'key...' });
56
+ *
57
+ * @example
58
+ * // CID with Uint8Array fields
59
+ * const encoded = nhashEncode({ hash: hashBytes, key: keyBytes });
60
+ */
61
+ export declare function nhashEncode(data: string | Hash | NHashData | CID): string;
62
+ /**
63
+ * Decode an nhash string to CID (Uint8Array fields)
64
+ *
65
+ * Path is kept in URL segments, not encoded in nhash.
66
+ */
67
+ export declare function nhashDecode(code: string): CID;
68
+ /**
69
+ * Encode an npath live reference
70
+ *
71
+ * @example
72
+ * const encoded = npathEncode({
73
+ * pubkey: 'abc123...',
74
+ * treeName: 'home',
75
+ * path: ['photos', 'vacation.jpg'],
76
+ * });
77
+ */
78
+ export declare function npathEncode(data: NPathData): string;
79
+ /**
80
+ * Decode an npath string
81
+ */
82
+ export declare function npathDecode(code: string): NPathData;
83
+ /**
84
+ * Decode any nhash or npath string
85
+ */
86
+ export declare function decode(code: string): DecodeResult;
87
+ export declare function isNHash(value: string | undefined | null): boolean;
88
+ export declare function isNPath(value: string | undefined | null): boolean;
89
+ export declare const NHashTypeGuard: {
90
+ isNHash: typeof isNHash;
91
+ isNPath: typeof isNPath;
92
+ };
93
+ export declare const BECH32_REGEX: RegExp;
94
+ //# sourceMappingURL=nhash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nhash.d.ts","sourceRoot":"","sources":["../src/nhash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAoB5C;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAgFvC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,GAAG,MAAM,CA0DzE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAqC7C;AAMD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAwBnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAmCnD;AAMD;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAajD;AAMD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEjE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEjE;AAED,eAAO,MAAM,cAAc;;;CAG1B,CAAC;AAEF,eAAO,MAAM,YAAY,QAA6D,CAAC"}
package/dist/nhash.js ADDED
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Bech32-encoded identifiers for hashtree content
3
+ *
4
+ * Similar to nostr's nip19 (npub, nprofile, nevent, naddr),
5
+ * provides human-readable, copy-pasteable identifiers.
6
+ *
7
+ * Types:
8
+ * - nhash: Permalink (hash + optional decrypt key)
9
+ * - npath: Live reference (pubkey + tree + path + optional decrypt key)
10
+ */
11
+ import { bech32 } from '@scure/base';
12
+ import { bytesToHex, hexToBytes, concatBytes } from '@noble/hashes/utils.js';
13
+ const BECH32_MAX_SIZE = 5000;
14
+ const utf8Encoder = new TextEncoder();
15
+ const utf8Decoder = new TextDecoder('utf-8');
16
+ // TLV type constants
17
+ const TLV = {
18
+ /** 32-byte hash (required for nhash) */
19
+ HASH: 0,
20
+ /** 32-byte nostr pubkey (required for npath) */
21
+ PUBKEY: 2,
22
+ /** UTF-8 tree name (required for npath) */
23
+ TREE_NAME: 3,
24
+ /** UTF-8 path segment (can appear multiple times, in order) */
25
+ PATH: 4,
26
+ /** 32-byte decryption key (optional) */
27
+ DECRYPT_KEY: 5,
28
+ };
29
+ /**
30
+ * Parse TLV-encoded data into a map of type -> values[]
31
+ */
32
+ function parseTLV(data) {
33
+ const result = {};
34
+ let offset = 0;
35
+ while (offset < data.length) {
36
+ if (offset + 2 > data.length) {
37
+ throw new Error('TLV: unexpected end of data');
38
+ }
39
+ const t = data[offset];
40
+ const l = data[offset + 1];
41
+ offset += 2;
42
+ if (offset + l > data.length) {
43
+ throw new Error(`TLV: not enough data for type ${t}, need ${l} bytes`);
44
+ }
45
+ const v = data.slice(offset, offset + l);
46
+ offset += l;
47
+ result[t] = result[t] || [];
48
+ result[t].push(v);
49
+ }
50
+ return result;
51
+ }
52
+ /**
53
+ * Encode TLV data to bytes
54
+ */
55
+ function encodeTLV(tlv) {
56
+ const entries = [];
57
+ // Process in ascending key order for consistent encoding
58
+ const keys = Object.keys(tlv).map(Number).sort((a, b) => a - b);
59
+ for (const t of keys) {
60
+ const values = tlv[t];
61
+ for (const v of values) {
62
+ if (v.length > 255) {
63
+ throw new Error(`TLV value too long for type ${t}: ${v.length} bytes`);
64
+ }
65
+ const entry = new Uint8Array(v.length + 2);
66
+ entry[0] = t;
67
+ entry[1] = v.length;
68
+ entry.set(v, 2);
69
+ entries.push(entry);
70
+ }
71
+ }
72
+ return concatBytes(...entries);
73
+ }
74
+ /**
75
+ * Encode bech32 with given prefix and data
76
+ */
77
+ function encodeBech32(prefix, data) {
78
+ const words = bech32.toWords(data);
79
+ return bech32.encode(prefix, words, BECH32_MAX_SIZE);
80
+ }
81
+ // ============================================================================
82
+ // nhash - Permalink (hash + optional decrypt key)
83
+ // ============================================================================
84
+ /**
85
+ * Check if object is a CID (has hash as Uint8Array)
86
+ */
87
+ function isCID(data) {
88
+ return (typeof data === 'object' &&
89
+ data !== null &&
90
+ 'hash' in data &&
91
+ data.hash instanceof Uint8Array);
92
+ }
93
+ /**
94
+ * Encode an nhash permalink
95
+ *
96
+ * Path is kept in URL segments, not encoded in nhash.
97
+ * Use format: /nhash1.../path/to/file
98
+ *
99
+ * @example
100
+ * // Simple hash
101
+ * const encoded = nhashEncode('abc123...');
102
+ * const encoded = nhashEncode(hashBytes);
103
+ *
104
+ * @example
105
+ * // Hash with decrypt key (hex strings)
106
+ * const encoded = nhashEncode({ hash: 'abc123...', decryptKey: 'key...' });
107
+ *
108
+ * @example
109
+ * // CID with Uint8Array fields
110
+ * const encoded = nhashEncode({ hash: hashBytes, key: keyBytes });
111
+ */
112
+ export function nhashEncode(data) {
113
+ // Simple hash-only case
114
+ if (typeof data === 'string' || data instanceof Uint8Array) {
115
+ const hashBytes = typeof data === 'string' ? hexToBytes(data) : data;
116
+ if (hashBytes.length !== 32) {
117
+ throw new Error(`Hash must be 32 bytes, got ${hashBytes.length}`);
118
+ }
119
+ return encodeBech32('nhash', hashBytes);
120
+ }
121
+ // CID type (Uint8Array fields)
122
+ if (isCID(data)) {
123
+ const hashBytes = data.hash;
124
+ if (hashBytes.length !== 32) {
125
+ throw new Error(`Hash must be 32 bytes, got ${hashBytes.length}`);
126
+ }
127
+ // No key - simple encoding
128
+ if (!data.key) {
129
+ return encodeBech32('nhash', hashBytes);
130
+ }
131
+ // Has key - use TLV
132
+ const tlv = {
133
+ [TLV.HASH]: [hashBytes],
134
+ };
135
+ if (data.key.length !== 32) {
136
+ throw new Error(`Decrypt key must be 32 bytes, got ${data.key.length}`);
137
+ }
138
+ tlv[TLV.DECRYPT_KEY] = [data.key];
139
+ return encodeBech32('nhash', encodeTLV(tlv));
140
+ }
141
+ // NHashData type (hex string fields)
142
+ const hashBytes = hexToBytes(data.hash);
143
+ if (hashBytes.length !== 32) {
144
+ throw new Error(`Hash must be 32 bytes, got ${hashBytes.length}`);
145
+ }
146
+ // No decrypt key - simple encoding
147
+ if (!data.decryptKey) {
148
+ return encodeBech32('nhash', hashBytes);
149
+ }
150
+ // Has decrypt key - use TLV
151
+ const tlv = {
152
+ [TLV.HASH]: [hashBytes],
153
+ };
154
+ const keyBytes = hexToBytes(data.decryptKey);
155
+ if (keyBytes.length !== 32) {
156
+ throw new Error(`Decrypt key must be 32 bytes, got ${keyBytes.length}`);
157
+ }
158
+ tlv[TLV.DECRYPT_KEY] = [keyBytes];
159
+ return encodeBech32('nhash', encodeTLV(tlv));
160
+ }
161
+ /**
162
+ * Decode an nhash string to CID (Uint8Array fields)
163
+ *
164
+ * Path is kept in URL segments, not encoded in nhash.
165
+ */
166
+ export function nhashDecode(code) {
167
+ if (code.startsWith('hashtree:')) {
168
+ code = code.substring(9);
169
+ }
170
+ const { prefix, words } = bech32.decode(code, BECH32_MAX_SIZE);
171
+ if (prefix !== 'nhash') {
172
+ throw new Error(`Expected nhash prefix, got ${prefix}`);
173
+ }
174
+ const data = new Uint8Array(bech32.fromWords(words));
175
+ // Simple 32-byte hash (no TLV)
176
+ if (data.length === 32) {
177
+ return { hash: data };
178
+ }
179
+ // Parse TLV
180
+ const tlv = parseTLV(data);
181
+ if (!tlv[TLV.HASH]?.[0] || tlv[TLV.HASH][0].length !== 32) {
182
+ throw new Error('nhash: missing or invalid hash');
183
+ }
184
+ const result = {
185
+ hash: tlv[TLV.HASH][0],
186
+ };
187
+ if (tlv[TLV.DECRYPT_KEY]?.[0]) {
188
+ if (tlv[TLV.DECRYPT_KEY][0].length !== 32) {
189
+ throw new Error('nhash: decrypt key must be 32 bytes');
190
+ }
191
+ result.key = tlv[TLV.DECRYPT_KEY][0];
192
+ }
193
+ return result;
194
+ }
195
+ // ============================================================================
196
+ // npath - Live reference (pubkey + tree + path + optional decrypt key)
197
+ // ============================================================================
198
+ /**
199
+ * Encode an npath live reference
200
+ *
201
+ * @example
202
+ * const encoded = npathEncode({
203
+ * pubkey: 'abc123...',
204
+ * treeName: 'home',
205
+ * path: ['photos', 'vacation.jpg'],
206
+ * });
207
+ */
208
+ export function npathEncode(data) {
209
+ const pubkeyBytes = hexToBytes(data.pubkey);
210
+ if (pubkeyBytes.length !== 32) {
211
+ throw new Error(`Pubkey must be 32 bytes, got ${pubkeyBytes.length}`);
212
+ }
213
+ const tlv = {
214
+ [TLV.PUBKEY]: [pubkeyBytes],
215
+ [TLV.TREE_NAME]: [utf8Encoder.encode(data.treeName)],
216
+ };
217
+ if (data.path && data.path.length > 0) {
218
+ tlv[TLV.PATH] = data.path.map(p => utf8Encoder.encode(p));
219
+ }
220
+ if (data.decryptKey) {
221
+ const keyBytes = hexToBytes(data.decryptKey);
222
+ if (keyBytes.length !== 32) {
223
+ throw new Error(`Decrypt key must be 32 bytes, got ${keyBytes.length}`);
224
+ }
225
+ tlv[TLV.DECRYPT_KEY] = [keyBytes];
226
+ }
227
+ return encodeBech32('npath', encodeTLV(tlv));
228
+ }
229
+ /**
230
+ * Decode an npath string
231
+ */
232
+ export function npathDecode(code) {
233
+ if (code.startsWith('hashtree:')) {
234
+ code = code.substring(9);
235
+ }
236
+ const { prefix, words } = bech32.decode(code, BECH32_MAX_SIZE);
237
+ if (prefix !== 'npath') {
238
+ throw new Error(`Expected npath prefix, got ${prefix}`);
239
+ }
240
+ const data = new Uint8Array(bech32.fromWords(words));
241
+ const tlv = parseTLV(data);
242
+ if (!tlv[TLV.PUBKEY]?.[0] || tlv[TLV.PUBKEY][0].length !== 32) {
243
+ throw new Error('npath: missing or invalid pubkey');
244
+ }
245
+ if (!tlv[TLV.TREE_NAME]?.[0]) {
246
+ throw new Error('npath: missing tree name');
247
+ }
248
+ const result = {
249
+ pubkey: bytesToHex(tlv[TLV.PUBKEY][0]),
250
+ treeName: utf8Decoder.decode(tlv[TLV.TREE_NAME][0]),
251
+ path: tlv[TLV.PATH] ? tlv[TLV.PATH].map(p => utf8Decoder.decode(p)) : [],
252
+ };
253
+ if (tlv[TLV.DECRYPT_KEY]?.[0]) {
254
+ if (tlv[TLV.DECRYPT_KEY][0].length !== 32) {
255
+ throw new Error('npath: decrypt key must be 32 bytes');
256
+ }
257
+ result.decryptKey = bytesToHex(tlv[TLV.DECRYPT_KEY][0]);
258
+ }
259
+ return result;
260
+ }
261
+ // ============================================================================
262
+ // Generic decode
263
+ // ============================================================================
264
+ /**
265
+ * Decode any nhash or npath string
266
+ */
267
+ export function decode(code) {
268
+ if (code.startsWith('hashtree:')) {
269
+ code = code.substring(9);
270
+ }
271
+ if (code.startsWith('nhash1')) {
272
+ return { type: 'nhash', data: nhashDecode(code) };
273
+ }
274
+ if (code.startsWith('npath1')) {
275
+ return { type: 'npath', data: npathDecode(code) };
276
+ }
277
+ throw new Error(`Unknown prefix, expected nhash1 or npath1`);
278
+ }
279
+ // ============================================================================
280
+ // Type guards
281
+ // ============================================================================
282
+ export function isNHash(value) {
283
+ return /^nhash1[a-z\d]+$/.test(value || '');
284
+ }
285
+ export function isNPath(value) {
286
+ return /^npath1[a-z\d]+$/.test(value || '');
287
+ }
288
+ export const NHashTypeGuard = {
289
+ isNHash,
290
+ isNPath,
291
+ };
292
+ export const BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;
293
+ //# sourceMappingURL=nhash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nhash.js","sourceRoot":"","sources":["../src/nhash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Ref resolvers - map human-readable keys to merkle root hashes (refs)
3
+ */
4
+ export { createNostrRefResolver, type NostrRefResolverConfig, type VisibilityCallbacks, type ParsedTreeVisibility, type NostrRefResolverConfig as NostrRootResolverConfig, type NostrEvent, type NostrFilter, type Nip19Like, } from './nostr.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resolver/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAEzB,KAAK,sBAAsB,IAAI,uBAAuB,EACtD,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Ref resolvers - map human-readable keys to merkle root hashes (refs)
3
+ */
4
+ export { createNostrRefResolver, } from './nostr.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resolver/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,sBAAsB,GASvB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * NostrRefResolver - Maps npub/treename keys to merkle root hashes (refs)
3
+ *
4
+ * Key format: "npub1.../treename"
5
+ *
6
+ * This resolver provides direct callback subscriptions that bypass React's
7
+ * render cycle. Components can subscribe to hash changes and update directly
8
+ * (e.g., MediaSource append) without triggering re-renders.
9
+ */
10
+ import type { RefResolver } from '../types.js';
11
+ import { type TreeVisibility } from '../visibility.js';
12
+ export interface NostrEvent {
13
+ id?: string;
14
+ pubkey: string;
15
+ kind: number;
16
+ content: string;
17
+ tags: string[][];
18
+ created_at: number;
19
+ }
20
+ export interface Nip19Like {
21
+ decode(str: string): {
22
+ type: string;
23
+ data: unknown;
24
+ };
25
+ npubEncode(pubkey: string): string;
26
+ }
27
+ export interface NostrFilter {
28
+ kinds?: number[];
29
+ authors?: string[];
30
+ '#d'?: string[];
31
+ '#l'?: string[];
32
+ }
33
+ /**
34
+ * Parsed visibility info from a nostr event
35
+ */
36
+ export interface ParsedTreeVisibility {
37
+ hash: string;
38
+ visibility: TreeVisibility;
39
+ /** Plaintext key (for public trees) */
40
+ key?: string;
41
+ /** Encrypted key (for link-visible trees) - decrypt with link key */
42
+ encryptedKey?: string;
43
+ /** Key ID (for link-visible trees) - identifies which link key to use */
44
+ keyId?: string;
45
+ /** Self-encrypted key (for private/link-visible trees) - decrypt with NIP-44 */
46
+ selfEncryptedKey?: string;
47
+ /** Self-encrypted link key (for link-visible trees) - allows owner to recover link key for sharing */
48
+ selfEncryptedLinkKey?: string;
49
+ }
50
+ /** Event type for publishing (created_at optional - usually auto-set by NDK) */
51
+ export type NostrPublishEvent = Omit<NostrEvent, 'id' | 'pubkey' | 'created_at'> & {
52
+ created_at?: number;
53
+ };
54
+ /**
55
+ * Visibility callbacks for encryption/decryption
56
+ * Used for private trees (NIP-44 self-encryption)
57
+ */
58
+ export interface VisibilityCallbacks {
59
+ /** NIP-44 encrypt data to a pubkey */
60
+ encrypt?: (data: Uint8Array, toPubkey: string) => Promise<string>;
61
+ /** NIP-44 decrypt data from a pubkey */
62
+ decrypt?: (ciphertext: string, fromPubkey: string) => Promise<Uint8Array | null>;
63
+ /** Get link key from URL context (for link-visible trees) */
64
+ getLinkKey?: () => Uint8Array | null;
65
+ }
66
+ export interface NostrRefResolverConfig {
67
+ /** Subscribe to nostr events - returns unsubscribe function */
68
+ subscribe: (filter: NostrFilter, onEvent: (event: NostrEvent) => void) => () => void;
69
+ /** Publish a nostr event - returns true on success. created_at is optional (for delete events) */
70
+ publish: (event: NostrPublishEvent) => Promise<boolean>;
71
+ /** Get current user's pubkey (for ownership checks) */
72
+ getPubkey: () => string | null;
73
+ /** nip19 encode/decode functions from nostr-tools */
74
+ nip19: Nip19Like;
75
+ /** Optional visibility callbacks for private/link-visible trees */
76
+ visibility?: VisibilityCallbacks;
77
+ }
78
+ /**
79
+ * Create a NostrRefResolver instance
80
+ */
81
+ export declare function createNostrRefResolver(config: NostrRefResolverConfig): RefResolver;
82
+ //# sourceMappingURL=nostr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nostr.d.ts","sourceRoot":"","sources":["../../src/resolver/nostr.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAqF,MAAM,aAAa,CAAC;AAElI,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACpC;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAYD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,cAAc,CAAC;IAC3B,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sGAAsG;IACtG,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAgGD,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,YAAY,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3G;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClE,wCAAwC;IACxC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACjF,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,sBAAsB;IACrC,+DAA+D;IAC/D,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACrF,kGAAkG;IAClG,OAAO,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,uDAAuD;IACvD,SAAS,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC/B,qDAAqD;IACrD,KAAK,EAAE,SAAS,CAAC;IACjB,mEAAmE;IACnE,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED;;GAEG;AAEH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,WAAW,CAs1BlF"}