@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.
- package/LICENSE +21 -0
- package/dist/bep52.d.ts +179 -0
- package/dist/bep52.d.ts.map +1 -0
- package/dist/bep52.js +384 -0
- package/dist/bep52.js.map +1 -0
- package/dist/builder.d.ts +137 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +281 -0
- package/dist/builder.js.map +1 -0
- package/dist/codec.d.ts +37 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +109 -0
- package/dist/codec.js.map +1 -0
- package/dist/crypto.d.ts +92 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +212 -0
- package/dist/crypto.js.map +1 -0
- package/dist/encrypted.d.ts +114 -0
- package/dist/encrypted.d.ts.map +1 -0
- package/dist/encrypted.js +446 -0
- package/dist/encrypted.js.map +1 -0
- package/dist/hash.d.ts +14 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +27 -0
- package/dist/hash.js.map +1 -0
- package/dist/hashtree.d.ts +237 -0
- package/dist/hashtree.d.ts.map +1 -0
- package/dist/hashtree.js +557 -0
- package/dist/hashtree.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/nhash.d.ts +94 -0
- package/dist/nhash.d.ts.map +1 -0
- package/dist/nhash.js +293 -0
- package/dist/nhash.js.map +1 -0
- package/dist/resolver/index.d.ts +5 -0
- package/dist/resolver/index.d.ts.map +1 -0
- package/dist/resolver/index.js +5 -0
- package/dist/resolver/index.js.map +1 -0
- package/dist/resolver/nostr.d.ts +82 -0
- package/dist/resolver/nostr.d.ts.map +1 -0
- package/dist/resolver/nostr.js +868 -0
- package/dist/resolver/nostr.js.map +1 -0
- package/dist/store/blossom.d.ts +100 -0
- package/dist/store/blossom.d.ts.map +1 -0
- package/dist/store/blossom.js +355 -0
- package/dist/store/blossom.js.map +1 -0
- package/dist/store/dexie.d.ts +44 -0
- package/dist/store/dexie.d.ts.map +1 -0
- package/dist/store/dexie.js +196 -0
- package/dist/store/dexie.js.map +1 -0
- package/dist/store/fallback.d.ts +40 -0
- package/dist/store/fallback.d.ts.map +1 -0
- package/dist/store/fallback.js +71 -0
- package/dist/store/fallback.js.map +1 -0
- package/dist/store/index.d.ts +6 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +6 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/memory.d.ts +29 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +66 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/opfs.d.ts +56 -0
- package/dist/store/opfs.d.ts.map +1 -0
- package/dist/store/opfs.js +200 -0
- package/dist/store/opfs.js.map +1 -0
- package/dist/streaming.d.ts +74 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +199 -0
- package/dist/streaming.js.map +1 -0
- package/dist/tree/create.d.ts +35 -0
- package/dist/tree/create.d.ts.map +1 -0
- package/dist/tree/create.js +90 -0
- package/dist/tree/create.js.map +1 -0
- package/dist/tree/edit.d.ts +28 -0
- package/dist/tree/edit.d.ts.map +1 -0
- package/dist/tree/edit.js +115 -0
- package/dist/tree/edit.js.map +1 -0
- package/dist/tree/editEncrypted.d.ts +46 -0
- package/dist/tree/editEncrypted.d.ts.map +1 -0
- package/dist/tree/editEncrypted.js +225 -0
- package/dist/tree/editEncrypted.js.map +1 -0
- package/dist/tree/index.d.ts +7 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +7 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/read.d.ts +75 -0
- package/dist/tree/read.d.ts.map +1 -0
- package/dist/tree/read.js +389 -0
- package/dist/tree/read.js.map +1 -0
- package/dist/tree/writeAt.d.ts +44 -0
- package/dist/tree/writeAt.d.ts.map +1 -0
- package/dist/tree/writeAt.js +282 -0
- package/dist/tree/writeAt.js.map +1 -0
- package/dist/types.d.ts +274 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/dist/verify.d.ts +12 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +32 -0
- package/dist/verify.js.map +1 -0
- package/dist/visibility.d.ts +50 -0
- package/dist/visibility.d.ts.map +1 -0
- package/dist/visibility.js +111 -0
- package/dist/visibility.js.map +1 -0
- package/dist/webrtc/index.d.ts +4 -0
- package/dist/webrtc/index.d.ts.map +1 -0
- package/dist/webrtc/index.js +4 -0
- package/dist/webrtc/index.js.map +1 -0
- package/dist/webrtc/lruCache.d.ts +20 -0
- package/dist/webrtc/lruCache.d.ts.map +1 -0
- package/dist/webrtc/lruCache.js +59 -0
- package/dist/webrtc/lruCache.js.map +1 -0
- package/dist/webrtc/peer.d.ts +122 -0
- package/dist/webrtc/peer.d.ts.map +1 -0
- package/dist/webrtc/peer.js +583 -0
- package/dist/webrtc/peer.js.map +1 -0
- package/dist/webrtc/protocol.d.ts +76 -0
- package/dist/webrtc/protocol.d.ts.map +1 -0
- package/dist/webrtc/protocol.js +167 -0
- package/dist/webrtc/protocol.js.map +1 -0
- package/dist/webrtc/store.d.ts +190 -0
- package/dist/webrtc/store.d.ts.map +1 -0
- package/dist/webrtc/store.js +1043 -0
- package/dist/webrtc/store.js.map +1 -0
- package/dist/webrtc/types.d.ts +196 -0
- package/dist/webrtc/types.d.ts.map +1 -0
- package/dist/webrtc/types.js +46 -0
- package/dist/webrtc/types.js.map +1 -0
- package/dist/worker/protocol.d.ts +493 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +15 -0
- package/dist/worker/protocol.js.map +1 -0
- package/package.json +59 -0
package/dist/verify.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree verification utilities
|
|
3
|
+
*/
|
|
4
|
+
import { toHex } from './types.js';
|
|
5
|
+
import { tryDecodeTreeNode } from './codec.js';
|
|
6
|
+
/**
|
|
7
|
+
* Verify tree integrity - checks that all referenced hashes exist
|
|
8
|
+
*/
|
|
9
|
+
export async function verifyTree(store, rootHash) {
|
|
10
|
+
const missing = [];
|
|
11
|
+
const visited = new Set();
|
|
12
|
+
async function check(hash) {
|
|
13
|
+
const hex = toHex(hash);
|
|
14
|
+
if (visited.has(hex))
|
|
15
|
+
return;
|
|
16
|
+
visited.add(hex);
|
|
17
|
+
const data = await store.get(hash);
|
|
18
|
+
if (!data) {
|
|
19
|
+
missing.push(hash);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const node = tryDecodeTreeNode(data);
|
|
23
|
+
if (node) {
|
|
24
|
+
for (const link of node.links) {
|
|
25
|
+
await check(link.hash);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
await check(rootHash);
|
|
30
|
+
return { valid: missing.length === 0, missing };
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,KAAK,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAY,EACZ,QAAc;IAEd,MAAM,OAAO,GAAW,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,UAAU,KAAK,CAAC,IAAU;QAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEjB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEtB,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree visibility and encryption utilities
|
|
3
|
+
*
|
|
4
|
+
* ## Encryption Modes
|
|
5
|
+
*
|
|
6
|
+
* - **Unencrypted**: No CHK, just hash - anyone with hash can read
|
|
7
|
+
* - **Public**: CHK encrypted, ["key", "<hex>"] in event - anyone can decrypt
|
|
8
|
+
* - **Link-visible**: CHK + XOR mask, ["encryptedKey", XOR(key,secret)] - need #k=<secret> URL
|
|
9
|
+
* - **Private**: CHK + NIP-44 to self, ["selfEncryptedKey", "..."] - author only
|
|
10
|
+
*
|
|
11
|
+
* Default is Public (CHK encrypted, key in nostr event).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Tree visibility levels
|
|
15
|
+
*/
|
|
16
|
+
export type TreeVisibility = 'public' | 'link-visible' | 'private';
|
|
17
|
+
/**
|
|
18
|
+
* Generate a random 32-byte link key for link-visible trees
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateLinkKey(): Uint8Array;
|
|
21
|
+
/**
|
|
22
|
+
* Compute keyId from link key (first 8 bytes of SHA-256 hash)
|
|
23
|
+
* Used to identify which link key was used without revealing the key
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeKeyId(linkKey: Uint8Array): Promise<Uint8Array>;
|
|
26
|
+
/**
|
|
27
|
+
* Encrypt a CHK key for link-visible visibility using XOR (one-time pad)
|
|
28
|
+
* @param chkKey - The CHK key to encrypt (32 bytes)
|
|
29
|
+
* @param linkKey - The link decryption key (32 bytes)
|
|
30
|
+
* @returns Encrypted key (32 bytes) - XOR of chkKey and linkKey
|
|
31
|
+
*/
|
|
32
|
+
export declare function encryptKeyForLink(chkKey: Uint8Array, linkKey: Uint8Array): Uint8Array;
|
|
33
|
+
/**
|
|
34
|
+
* Decrypt a CHK key for link-visible visibility
|
|
35
|
+
* Supports both new XOR format (32 bytes) and legacy AES-GCM format (60 bytes)
|
|
36
|
+
* @param encryptedKey - Encrypted key (32 bytes for XOR, 60 bytes for AES-GCM)
|
|
37
|
+
* @param linkKey - The link decryption key (32 bytes)
|
|
38
|
+
* @returns Decrypted CHK key (32 bytes), or null if decryption fails
|
|
39
|
+
*/
|
|
40
|
+
export declare function decryptKeyFromLink(encryptedKey: Uint8Array, linkKey: Uint8Array): Promise<Uint8Array | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Hex string versions of the encryption functions for convenience
|
|
43
|
+
*/
|
|
44
|
+
export declare const hex: {
|
|
45
|
+
generateLinkKey(): string;
|
|
46
|
+
computeKeyId(linkKeyHex: string): Promise<string>;
|
|
47
|
+
encryptKeyForLink(chkKeyHex: string, linkKeyHex: string): string;
|
|
48
|
+
decryptKeyFromLink(encryptedKeyHex: string, linkKeyHex: string): Promise<string | null>;
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visibility.d.ts","sourceRoot":"","sources":["../src/visibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,cAAc,GAAG,SAAS,CAAC;AAEnE;;GAEG;AACH,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAG3E;AA2CD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,CAErF;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgBlH;AAED;;GAEG;AACH,eAAO,MAAM,GAAG;uBACK,MAAM;6BAIM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iCAK1B,MAAM,cAAc,MAAM,GAAG,MAAM;wCAKtB,MAAM,cAAc,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAI9F,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree visibility and encryption utilities
|
|
3
|
+
*
|
|
4
|
+
* ## Encryption Modes
|
|
5
|
+
*
|
|
6
|
+
* - **Unencrypted**: No CHK, just hash - anyone with hash can read
|
|
7
|
+
* - **Public**: CHK encrypted, ["key", "<hex>"] in event - anyone can decrypt
|
|
8
|
+
* - **Link-visible**: CHK + XOR mask, ["encryptedKey", XOR(key,secret)] - need #k=<secret> URL
|
|
9
|
+
* - **Private**: CHK + NIP-44 to self, ["selfEncryptedKey", "..."] - author only
|
|
10
|
+
*
|
|
11
|
+
* Default is Public (CHK encrypted, key in nostr event).
|
|
12
|
+
*/
|
|
13
|
+
import { sha256 } from './hash.js';
|
|
14
|
+
import { toHex, fromHex } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Generate a random 32-byte link key for link-visible trees
|
|
17
|
+
*/
|
|
18
|
+
export function generateLinkKey() {
|
|
19
|
+
return crypto.getRandomValues(new Uint8Array(32));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compute keyId from link key (first 8 bytes of SHA-256 hash)
|
|
23
|
+
* Used to identify which link key was used without revealing the key
|
|
24
|
+
*/
|
|
25
|
+
export async function computeKeyId(linkKey) {
|
|
26
|
+
const hash = await sha256(linkKey);
|
|
27
|
+
return hash.slice(0, 8);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* XOR two 32-byte arrays
|
|
31
|
+
* Used for encrypting/decrypting CHK keys with link keys.
|
|
32
|
+
* XOR with random key is one-time pad (information-theoretically secure).
|
|
33
|
+
*/
|
|
34
|
+
function xor32(a, b) {
|
|
35
|
+
const result = new Uint8Array(32);
|
|
36
|
+
for (let i = 0; i < 32; i++) {
|
|
37
|
+
result[i] = a[i] ^ b[i];
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Legacy AES-GCM decryption for backward compatibility
|
|
43
|
+
* Old format: 12-byte nonce + ciphertext + 16-byte tag = 60 bytes total
|
|
44
|
+
*/
|
|
45
|
+
async function decryptAesGcm(encryptedKey, linkKey) {
|
|
46
|
+
try {
|
|
47
|
+
const keyBuffer = new ArrayBuffer(linkKey.length);
|
|
48
|
+
new Uint8Array(keyBuffer).set(linkKey);
|
|
49
|
+
const nonce = encryptedKey.slice(0, 12);
|
|
50
|
+
const ciphertext = encryptedKey.slice(12);
|
|
51
|
+
const ciphertextBuffer = new ArrayBuffer(ciphertext.length);
|
|
52
|
+
new Uint8Array(ciphertextBuffer).set(ciphertext);
|
|
53
|
+
const cryptoKey = await crypto.subtle.importKey('raw', keyBuffer, { name: 'AES-GCM' }, false, ['decrypt']);
|
|
54
|
+
const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, cryptoKey, ciphertextBuffer);
|
|
55
|
+
return new Uint8Array(plaintext);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Encrypt a CHK key for link-visible visibility using XOR (one-time pad)
|
|
63
|
+
* @param chkKey - The CHK key to encrypt (32 bytes)
|
|
64
|
+
* @param linkKey - The link decryption key (32 bytes)
|
|
65
|
+
* @returns Encrypted key (32 bytes) - XOR of chkKey and linkKey
|
|
66
|
+
*/
|
|
67
|
+
export function encryptKeyForLink(chkKey, linkKey) {
|
|
68
|
+
return xor32(chkKey, linkKey);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Decrypt a CHK key for link-visible visibility
|
|
72
|
+
* Supports both new XOR format (32 bytes) and legacy AES-GCM format (60 bytes)
|
|
73
|
+
* @param encryptedKey - Encrypted key (32 bytes for XOR, 60 bytes for AES-GCM)
|
|
74
|
+
* @param linkKey - The link decryption key (32 bytes)
|
|
75
|
+
* @returns Decrypted CHK key (32 bytes), or null if decryption fails
|
|
76
|
+
*/
|
|
77
|
+
export async function decryptKeyFromLink(encryptedKey, linkKey) {
|
|
78
|
+
if (linkKey.length !== 32) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// New XOR format: 32 bytes
|
|
82
|
+
if (encryptedKey.length === 32) {
|
|
83
|
+
return xor32(encryptedKey, linkKey);
|
|
84
|
+
}
|
|
85
|
+
// Legacy AES-GCM format: 60 bytes (12 nonce + 32 ciphertext + 16 tag)
|
|
86
|
+
if (encryptedKey.length === 60) {
|
|
87
|
+
return decryptAesGcm(encryptedKey, linkKey);
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Hex string versions of the encryption functions for convenience
|
|
93
|
+
*/
|
|
94
|
+
export const hex = {
|
|
95
|
+
generateLinkKey() {
|
|
96
|
+
return toHex(generateLinkKey());
|
|
97
|
+
},
|
|
98
|
+
async computeKeyId(linkKeyHex) {
|
|
99
|
+
const keyId = await computeKeyId(fromHex(linkKeyHex));
|
|
100
|
+
return toHex(keyId);
|
|
101
|
+
},
|
|
102
|
+
encryptKeyForLink(chkKeyHex, linkKeyHex) {
|
|
103
|
+
const encrypted = encryptKeyForLink(fromHex(chkKeyHex), fromHex(linkKeyHex));
|
|
104
|
+
return toHex(encrypted);
|
|
105
|
+
},
|
|
106
|
+
async decryptKeyFromLink(encryptedKeyHex, linkKeyHex) {
|
|
107
|
+
const decrypted = await decryptKeyFromLink(fromHex(encryptedKeyHex), fromHex(linkKeyHex));
|
|
108
|
+
return decrypted ? toHex(decrypted) : null;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visibility.js","sourceRoot":"","sources":["../src/visibility.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { WebRTCStore, DEFAULT_RELAYS } from './store.js';
|
|
2
|
+
export { Peer } from './peer.js';
|
|
3
|
+
export { PeerId, generateUuid, type SignalingMessage, type WebRTCStoreConfig, type PeerStatus, type WebRTCStoreEvent, type WebRTCStoreEventHandler, type EventSigner, type EventEncrypter, type EventDecrypter, type GiftWrapper, type GiftUnwrapper, type SignedEvent, type PeerPool, type PeerClassifier, type PoolConfig, type WebRTCStats, type BandwidthSample, } from './types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,MAAM,EACN,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,MAAM,EACN,YAAY,GAiBb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple LRU Cache implementation
|
|
3
|
+
*/
|
|
4
|
+
export declare class LRUCache<K, V> {
|
|
5
|
+
private cache;
|
|
6
|
+
private maxSize;
|
|
7
|
+
constructor(maxSize?: number);
|
|
8
|
+
get(key: K): V | undefined;
|
|
9
|
+
set(key: K, value: V): void;
|
|
10
|
+
has(key: K): boolean;
|
|
11
|
+
delete(key: K): boolean;
|
|
12
|
+
clear(): void;
|
|
13
|
+
get size(): number;
|
|
14
|
+
keys(): IterableIterator<K>;
|
|
15
|
+
values(): IterableIterator<V>;
|
|
16
|
+
entries(): IterableIterator<[K, V]>;
|
|
17
|
+
forEach(callback: (value: V, key: K) => void): void;
|
|
18
|
+
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=lruCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lruCache.d.ts","sourceRoot":"","sources":["../../src/webrtc/lruCache.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,QAAQ,CAAC,CAAC,EAAE,CAAC;IACxB,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAY;IAIjC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAU1B,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAe3B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIvB,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAI3B,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAI5B,OAAO,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAIpC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI;IAInD,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAG9C"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple LRU Cache implementation
|
|
3
|
+
*/
|
|
4
|
+
export class LRUCache {
|
|
5
|
+
cache = new Map();
|
|
6
|
+
maxSize;
|
|
7
|
+
constructor(maxSize = 100) {
|
|
8
|
+
this.maxSize = maxSize;
|
|
9
|
+
}
|
|
10
|
+
get(key) {
|
|
11
|
+
const value = this.cache.get(key);
|
|
12
|
+
if (value !== undefined) {
|
|
13
|
+
// Move to end (most recently used)
|
|
14
|
+
this.cache.delete(key);
|
|
15
|
+
this.cache.set(key, value);
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
set(key, value) {
|
|
20
|
+
// Delete first to reset position if exists
|
|
21
|
+
this.cache.delete(key);
|
|
22
|
+
// Evict oldest if at capacity
|
|
23
|
+
if (this.cache.size >= this.maxSize) {
|
|
24
|
+
const oldest = this.cache.keys().next().value;
|
|
25
|
+
if (oldest !== undefined) {
|
|
26
|
+
this.cache.delete(oldest);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
this.cache.set(key, value);
|
|
30
|
+
}
|
|
31
|
+
has(key) {
|
|
32
|
+
return this.cache.has(key);
|
|
33
|
+
}
|
|
34
|
+
delete(key) {
|
|
35
|
+
return this.cache.delete(key);
|
|
36
|
+
}
|
|
37
|
+
clear() {
|
|
38
|
+
this.cache.clear();
|
|
39
|
+
}
|
|
40
|
+
get size() {
|
|
41
|
+
return this.cache.size;
|
|
42
|
+
}
|
|
43
|
+
keys() {
|
|
44
|
+
return this.cache.keys();
|
|
45
|
+
}
|
|
46
|
+
values() {
|
|
47
|
+
return this.cache.values();
|
|
48
|
+
}
|
|
49
|
+
*entries() {
|
|
50
|
+
yield* this.cache.entries();
|
|
51
|
+
}
|
|
52
|
+
forEach(callback) {
|
|
53
|
+
this.cache.forEach(callback);
|
|
54
|
+
}
|
|
55
|
+
[Symbol.iterator]() {
|
|
56
|
+
return this.entries();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=lruCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lruCache.js","sourceRoot":"","sources":["../../src/webrtc/lruCache.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,QAAQ;IACX,KAAK,GAAG,IAAI,GAAG,EAAQ,CAAC;IACxB,OAAO,CAAS;IAExB,YAAY,UAAkB,GAAG;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,GAAM;QACR,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,mCAAmC;YACnC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,GAAG,CAAC,GAAM,EAAE,KAAQ;QAClB,2CAA2C;QAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEvB,8BAA8B;QAC9B,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC9C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,GAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,GAAM;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,CAAC,OAAO;QACN,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,QAAoC;QAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC;QACf,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebRTC peer connection for hashtree data exchange
|
|
3
|
+
*/
|
|
4
|
+
import type { Store, Hash } from '../types.js';
|
|
5
|
+
import type { SignalingMessage, PeerId } from './types.js';
|
|
6
|
+
export declare class Peer {
|
|
7
|
+
readonly peerId: string;
|
|
8
|
+
readonly pubkey: string;
|
|
9
|
+
readonly direction: 'inbound' | 'outbound';
|
|
10
|
+
private pc;
|
|
11
|
+
private dataChannel;
|
|
12
|
+
private localStore;
|
|
13
|
+
private sendSignaling;
|
|
14
|
+
private onClose;
|
|
15
|
+
private onConnected?;
|
|
16
|
+
private onConnectedFired;
|
|
17
|
+
private debug;
|
|
18
|
+
private makingOffer;
|
|
19
|
+
private ignoreOffer;
|
|
20
|
+
private isPolite;
|
|
21
|
+
private myPeerId;
|
|
22
|
+
private ourRequests;
|
|
23
|
+
private theirRequests;
|
|
24
|
+
private requestTimeout;
|
|
25
|
+
private pendingCandidates;
|
|
26
|
+
private candidateBatchTimeout;
|
|
27
|
+
private queuedRemoteCandidates;
|
|
28
|
+
private onForwardRequest?;
|
|
29
|
+
private stats;
|
|
30
|
+
private pendingReassemblies;
|
|
31
|
+
private reassemblyCleanupInterval?;
|
|
32
|
+
private htlConfig;
|
|
33
|
+
readonly createdAt: number;
|
|
34
|
+
connectedAt?: number;
|
|
35
|
+
constructor(options: {
|
|
36
|
+
peerId: PeerId;
|
|
37
|
+
myPeerId: string;
|
|
38
|
+
direction: 'inbound' | 'outbound';
|
|
39
|
+
localStore: Store | null;
|
|
40
|
+
sendSignaling: (msg: SignalingMessage) => Promise<void>;
|
|
41
|
+
onClose: () => void;
|
|
42
|
+
onConnected?: () => void;
|
|
43
|
+
onForwardRequest?: (hash: Uint8Array, excludePeerId: string, htl: number) => Promise<Uint8Array | null>;
|
|
44
|
+
requestTimeout?: number;
|
|
45
|
+
debug?: boolean;
|
|
46
|
+
});
|
|
47
|
+
private log;
|
|
48
|
+
get state(): RTCPeerConnectionState;
|
|
49
|
+
get isConnected(): boolean;
|
|
50
|
+
get pendingTheirRequestsCount(): number;
|
|
51
|
+
private scheduleCandidateBatch;
|
|
52
|
+
private setupPeerConnection;
|
|
53
|
+
private setupDataChannel;
|
|
54
|
+
private handleMessage;
|
|
55
|
+
private handleRequest;
|
|
56
|
+
private sendResponse;
|
|
57
|
+
/**
|
|
58
|
+
* Handle a fragmented response - buffer and reassemble
|
|
59
|
+
* Returns assembled data when complete, null when waiting for more fragments
|
|
60
|
+
*/
|
|
61
|
+
private handleFragmentResponse;
|
|
62
|
+
/**
|
|
63
|
+
* Assemble fragments in order into a single buffer
|
|
64
|
+
*/
|
|
65
|
+
private assembleFragments;
|
|
66
|
+
/**
|
|
67
|
+
* Clean up stale reassemblies (stalled or timed out)
|
|
68
|
+
*/
|
|
69
|
+
private cleanupStaleReassemblies;
|
|
70
|
+
/**
|
|
71
|
+
* Request data by hash from this peer
|
|
72
|
+
* @param htl Hops To Live - decremented before sending
|
|
73
|
+
*/
|
|
74
|
+
request(hash: Hash, htl?: number): Promise<Uint8Array | null>;
|
|
75
|
+
/**
|
|
76
|
+
* Get per-peer statistics
|
|
77
|
+
*/
|
|
78
|
+
getStats(): {
|
|
79
|
+
requestsSent: number;
|
|
80
|
+
requestsReceived: number;
|
|
81
|
+
responsesSent: number;
|
|
82
|
+
responsesReceived: number;
|
|
83
|
+
receiveErrors: number;
|
|
84
|
+
fragmentsSent: number;
|
|
85
|
+
fragmentsReceived: number;
|
|
86
|
+
fragmentTimeouts: number;
|
|
87
|
+
reassembliesCompleted: number;
|
|
88
|
+
bytesSent: number;
|
|
89
|
+
bytesReceived: number;
|
|
90
|
+
bytesForwarded: number;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Send data to this peer for a hash they previously requested
|
|
94
|
+
* Returns true if this peer had requested this hash
|
|
95
|
+
*/
|
|
96
|
+
sendData(hash: Uint8Array, data: Uint8Array): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Check if this peer has requested a hash
|
|
99
|
+
*/
|
|
100
|
+
hasRequested(hash: Uint8Array): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get count of pending requests from this peer
|
|
103
|
+
*/
|
|
104
|
+
getTheirRequestCount(): number;
|
|
105
|
+
/**
|
|
106
|
+
* Initiate connection (create offer)
|
|
107
|
+
* Uses perfect negotiation pattern - both peers can call this
|
|
108
|
+
*/
|
|
109
|
+
connect(): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Handle incoming signaling message
|
|
112
|
+
* Implements perfect negotiation pattern for collision handling
|
|
113
|
+
*/
|
|
114
|
+
handleSignaling(msg: SignalingMessage): Promise<void>;
|
|
115
|
+
private addRemoteCandidate;
|
|
116
|
+
private processQueuedCandidates;
|
|
117
|
+
/**
|
|
118
|
+
* Close the peer connection
|
|
119
|
+
*/
|
|
120
|
+
close(): void;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=peer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../../src/webrtc/peer.ts"],"names":[],"mappings":"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"}
|