@hashtree/worker 0.2.1 → 0.2.3
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/app-runtime.d.ts +60 -0
- package/dist/app-runtime.d.ts.map +1 -0
- package/dist/app-runtime.js +271 -0
- package/dist/app-runtime.js.map +1 -0
- package/dist/capabilities/blossomBandwidthTracker.d.ts +26 -0
- package/dist/capabilities/blossomBandwidthTracker.d.ts.map +1 -0
- package/dist/capabilities/blossomBandwidthTracker.js +53 -0
- package/dist/capabilities/blossomBandwidthTracker.js.map +1 -0
- package/dist/capabilities/blossomTransport.d.ts +22 -0
- package/dist/capabilities/blossomTransport.d.ts.map +1 -0
- package/dist/capabilities/blossomTransport.js +139 -0
- package/dist/capabilities/blossomTransport.js.map +1 -0
- package/dist/capabilities/connectivity.d.ts +3 -0
- package/dist/capabilities/connectivity.d.ts.map +1 -0
- package/dist/capabilities/connectivity.js +49 -0
- package/dist/capabilities/connectivity.js.map +1 -0
- package/dist/capabilities/idbStorage.d.ts +25 -0
- package/dist/capabilities/idbStorage.d.ts.map +1 -0
- package/dist/capabilities/idbStorage.js +73 -0
- package/dist/capabilities/idbStorage.js.map +1 -0
- package/dist/capabilities/meshRouterStore.d.ts +71 -0
- package/dist/capabilities/meshRouterStore.d.ts.map +1 -0
- package/dist/capabilities/meshRouterStore.js +316 -0
- package/dist/capabilities/meshRouterStore.js.map +1 -0
- package/dist/capabilities/rootResolver.d.ts +10 -0
- package/dist/capabilities/rootResolver.d.ts.map +1 -0
- package/dist/capabilities/rootResolver.js +392 -0
- package/dist/capabilities/rootResolver.js.map +1 -0
- package/dist/client-id.d.ts +18 -0
- package/dist/client-id.d.ts.map +1 -0
- package/dist/client-id.js +98 -0
- package/dist/client-id.js.map +1 -0
- package/dist/client.d.ts +61 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +417 -0
- package/dist/client.js.map +1 -0
- package/dist/entry.d.ts +2 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +3 -0
- package/dist/entry.js.map +1 -0
- package/dist/htree-path.d.ts +13 -0
- package/dist/htree-path.d.ts.map +1 -0
- package/dist/htree-path.js +38 -0
- package/dist/htree-path.js.map +1 -0
- package/dist/htree-url.d.ts +22 -0
- package/dist/htree-url.d.ts.map +1 -0
- package/dist/htree-url.js +118 -0
- package/dist/htree-url.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mediaStreaming.d.ts +7 -0
- package/dist/mediaStreaming.d.ts.map +1 -0
- package/dist/mediaStreaming.js +48 -0
- package/dist/mediaStreaming.js.map +1 -0
- package/dist/p2p/boundedQueue.d.ts +79 -0
- package/dist/p2p/boundedQueue.d.ts.map +1 -0
- package/dist/p2p/boundedQueue.js +134 -0
- package/dist/p2p/boundedQueue.js.map +1 -0
- package/dist/p2p/errorMessage.d.ts +5 -0
- package/dist/p2p/errorMessage.d.ts.map +1 -0
- package/dist/p2p/errorMessage.js +7 -0
- package/dist/p2p/errorMessage.js.map +1 -0
- package/dist/p2p/index.d.ts +8 -0
- package/dist/p2p/index.d.ts.map +1 -0
- package/dist/p2p/index.js +6 -0
- package/dist/p2p/index.js.map +1 -0
- package/dist/p2p/lruCache.d.ts +26 -0
- package/dist/p2p/lruCache.d.ts.map +1 -0
- package/dist/p2p/lruCache.js +65 -0
- package/dist/p2p/lruCache.js.map +1 -0
- package/dist/p2p/meshQueryRouter.d.ts +57 -0
- package/dist/p2p/meshQueryRouter.d.ts.map +1 -0
- package/dist/p2p/meshQueryRouter.js +264 -0
- package/dist/p2p/meshQueryRouter.js.map +1 -0
- package/dist/p2p/protocol.d.ts +10 -0
- package/dist/p2p/protocol.d.ts.map +1 -0
- package/dist/p2p/protocol.js +2 -0
- package/dist/p2p/protocol.js.map +1 -0
- package/dist/p2p/queryForwardingMachine.d.ts +46 -0
- package/dist/p2p/queryForwardingMachine.d.ts.map +1 -0
- package/dist/p2p/queryForwardingMachine.js +144 -0
- package/dist/p2p/queryForwardingMachine.js.map +1 -0
- package/dist/p2p/signaling.d.ts +63 -0
- package/dist/p2p/signaling.d.ts.map +1 -0
- package/dist/p2p/signaling.js +185 -0
- package/dist/p2p/signaling.js.map +1 -0
- package/dist/p2p/uploadRateLimiter.d.ts +21 -0
- package/dist/p2p/uploadRateLimiter.d.ts.map +1 -0
- package/dist/p2p/uploadRateLimiter.js +62 -0
- package/dist/p2p/uploadRateLimiter.js.map +1 -0
- package/dist/p2p/webrtcController.d.ts +176 -0
- package/dist/p2p/webrtcController.d.ts.map +1 -0
- package/dist/p2p/webrtcController.js +938 -0
- package/dist/p2p/webrtcController.js.map +1 -0
- package/dist/p2p/webrtcProxy.d.ts +62 -0
- package/dist/p2p/webrtcProxy.d.ts.map +1 -0
- package/dist/p2p/webrtcProxy.js +447 -0
- package/dist/p2p/webrtcProxy.js.map +1 -0
- package/dist/privacyGuards.d.ts +14 -0
- package/dist/privacyGuards.d.ts.map +1 -0
- package/dist/privacyGuards.js +27 -0
- package/dist/privacyGuards.js.map +1 -0
- package/dist/protocol.d.ts +225 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +2 -0
- package/dist/protocol.js.map +1 -0
- package/dist/relay/identity.d.ts +36 -0
- package/dist/relay/identity.d.ts.map +1 -0
- package/dist/relay/identity.js +78 -0
- package/dist/relay/identity.js.map +1 -0
- package/dist/relay/mediaHandler.d.ts +64 -0
- package/dist/relay/mediaHandler.d.ts.map +1 -0
- package/dist/relay/mediaHandler.js +1285 -0
- package/dist/relay/mediaHandler.js.map +1 -0
- package/dist/relay/ndk.d.ts +96 -0
- package/dist/relay/ndk.d.ts.map +1 -0
- package/dist/relay/ndk.js +502 -0
- package/dist/relay/ndk.js.map +1 -0
- package/dist/relay/nostr-wasm.d.ts +14 -0
- package/dist/relay/nostr-wasm.d.ts.map +1 -0
- package/dist/relay/nostr-wasm.js +246 -0
- package/dist/relay/nostr-wasm.js.map +1 -0
- package/dist/relay/nostr.d.ts +60 -0
- package/dist/relay/nostr.d.ts.map +1 -0
- package/dist/relay/nostr.js +207 -0
- package/dist/relay/nostr.js.map +1 -0
- package/dist/relay/protocol.d.ts +592 -0
- package/dist/relay/protocol.d.ts.map +1 -0
- package/dist/relay/protocol.js +16 -0
- package/dist/relay/protocol.js.map +1 -0
- package/dist/relay/publicAssetUrl.d.ts +6 -0
- package/dist/relay/publicAssetUrl.d.ts.map +1 -0
- package/dist/relay/publicAssetUrl.js +14 -0
- package/dist/relay/publicAssetUrl.js.map +1 -0
- package/dist/relay/rootPathResolver.d.ts +9 -0
- package/dist/relay/rootPathResolver.d.ts.map +1 -0
- package/dist/relay/rootPathResolver.js +32 -0
- package/dist/relay/rootPathResolver.js.map +1 -0
- package/dist/relay/signing.d.ts +50 -0
- package/dist/relay/signing.d.ts.map +1 -0
- package/dist/relay/signing.js +299 -0
- package/dist/relay/signing.js.map +1 -0
- package/dist/relay/treeRootCache.d.ts +86 -0
- package/dist/relay/treeRootCache.d.ts.map +1 -0
- package/dist/relay/treeRootCache.js +269 -0
- package/dist/relay/treeRootCache.js.map +1 -0
- package/dist/relay/treeRootSubscription.d.ts +55 -0
- package/dist/relay/treeRootSubscription.d.ts.map +1 -0
- package/dist/relay/treeRootSubscription.js +478 -0
- package/dist/relay/treeRootSubscription.js.map +1 -0
- package/dist/relay/utils/constants.d.ts +76 -0
- package/dist/relay/utils/constants.d.ts.map +1 -0
- package/dist/relay/utils/constants.js +113 -0
- package/dist/relay/utils/constants.js.map +1 -0
- package/dist/relay/utils/errorMessage.d.ts +5 -0
- package/dist/relay/utils/errorMessage.d.ts.map +1 -0
- package/dist/relay/utils/errorMessage.js +8 -0
- package/dist/relay/utils/errorMessage.js.map +1 -0
- package/dist/relay/utils/lruCache.d.ts +26 -0
- package/dist/relay/utils/lruCache.d.ts.map +1 -0
- package/dist/relay/utils/lruCache.js +66 -0
- package/dist/relay/utils/lruCache.js.map +1 -0
- package/dist/relay/webrtc.d.ts +2 -0
- package/dist/relay/webrtc.d.ts.map +1 -0
- package/dist/relay/webrtc.js +3 -0
- package/dist/relay/webrtc.js.map +1 -0
- package/dist/relay/webrtcSignaling.d.ts +37 -0
- package/dist/relay/webrtcSignaling.d.ts.map +1 -0
- package/dist/relay/webrtcSignaling.js +86 -0
- package/dist/relay/webrtcSignaling.js.map +1 -0
- package/dist/relay/worker.d.ts +12 -0
- package/dist/relay/worker.d.ts.map +1 -0
- package/dist/relay/worker.js +1540 -0
- package/dist/relay/worker.js.map +1 -0
- package/dist/relay-client.d.ts +31 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +197 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay-entry.d.ts +2 -0
- package/dist/relay-entry.d.ts.map +1 -0
- package/dist/relay-entry.js +2 -0
- package/dist/relay-entry.js.map +1 -0
- package/dist/runtime-network.d.ts +23 -0
- package/dist/runtime-network.d.ts.map +1 -0
- package/dist/runtime-network.js +105 -0
- package/dist/runtime-network.js.map +1 -0
- package/dist/runtime.d.ts +24 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +126 -0
- package/dist/runtime.js.map +1 -0
- package/dist/transferableBytes.d.ts +2 -0
- package/dist/transferableBytes.d.ts.map +1 -0
- package/dist/transferableBytes.js +6 -0
- package/dist/transferableBytes.js.map +1 -0
- package/dist/tree-root.d.ts +201 -0
- package/dist/tree-root.d.ts.map +1 -0
- package/dist/tree-root.js +632 -0
- package/dist/tree-root.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +9 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +793 -0
- package/dist/worker.js.map +1 -0
- package/package.json +14 -14
- package/src/capabilities/blossomTransport.ts +1 -1
- package/src/worker.ts +2 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { resolveTreeRootNow } from './treeRootSubscription';
|
|
2
|
+
export const DEFAULT_ROOT_PATH_RESOLVE_TIMEOUT_MS = 15_000;
|
|
3
|
+
export function parseRootPath(path) {
|
|
4
|
+
const pathParts = path?.split('/').filter(Boolean) ?? [];
|
|
5
|
+
return {
|
|
6
|
+
treeName: pathParts[0] || 'public',
|
|
7
|
+
subPath: pathParts.slice(1),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export async function resolveRootPath(tree, npub, path, timeoutMs = DEFAULT_ROOT_PATH_RESOLVE_TIMEOUT_MS) {
|
|
11
|
+
const exactTreeName = path?.split('/').filter(Boolean).join('/') || 'public';
|
|
12
|
+
const exactRootCid = await resolveTreeRootNow(npub, exactTreeName, timeoutMs);
|
|
13
|
+
if (exactRootCid) {
|
|
14
|
+
return exactRootCid;
|
|
15
|
+
}
|
|
16
|
+
const { treeName, subPath } = parseRootPath(path);
|
|
17
|
+
if (subPath.length === 0) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const rootCid = await resolveTreeRootNow(npub, treeName, timeoutMs);
|
|
21
|
+
if (!rootCid) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (subPath.length === 0) {
|
|
25
|
+
return rootCid;
|
|
26
|
+
}
|
|
27
|
+
if (!tree) {
|
|
28
|
+
throw new Error('Tree not initialized');
|
|
29
|
+
}
|
|
30
|
+
return (await tree.resolvePath(rootCid, subPath))?.cid ?? null;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=rootPathResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rootPathResolver.js","sourceRoot":"","sources":["../../src/relay/rootPathResolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,CAAC,MAAM,oCAAoC,GAAG,MAAM,CAAC;AAO3D,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,MAAM,SAAS,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACzD,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,QAAQ;QAClC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;KAC5B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAA0C,EAC1C,IAAY,EACZ,IAAa,EACb,YAAoB,oCAAoC;IAExD,MAAM,aAAa,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC;IAC7E,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;IAC9E,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Signing & Encryption
|
|
3
|
+
*
|
|
4
|
+
* Provides signing, encryption, and gift wrap functions.
|
|
5
|
+
* Uses nsec directly when available, delegates to main thread otherwise.
|
|
6
|
+
*/
|
|
7
|
+
import type { EventTemplate } from 'nostr-tools';
|
|
8
|
+
import type { SignedEvent } from './protocol';
|
|
9
|
+
export declare function setResponseSender(fn: (msg: unknown) => void): void;
|
|
10
|
+
/**
|
|
11
|
+
* Sign an event with user's real identity.
|
|
12
|
+
* - For nsec login: signs directly with secret key
|
|
13
|
+
* - For extension login: delegates to main thread via NIP-07
|
|
14
|
+
*/
|
|
15
|
+
export declare function signEvent(template: EventTemplate): Promise<SignedEvent>;
|
|
16
|
+
/**
|
|
17
|
+
* Synchronous sign (only works with nsec, falls back to ephemeral)
|
|
18
|
+
*/
|
|
19
|
+
export declare function signEventSync(template: EventTemplate): SignedEvent;
|
|
20
|
+
/**
|
|
21
|
+
* Encrypt plaintext for a recipient using NIP-44
|
|
22
|
+
*/
|
|
23
|
+
export declare function encrypt(recipientPubkey: string, plaintext: string): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Decrypt ciphertext from a sender using NIP-44
|
|
26
|
+
*/
|
|
27
|
+
export declare function decrypt(senderPubkey: string, ciphertext: string): Promise<string>;
|
|
28
|
+
interface Seal {
|
|
29
|
+
pubkey: string;
|
|
30
|
+
kind: number;
|
|
31
|
+
content: string;
|
|
32
|
+
tags: string[][];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gift wrap an event for private delivery.
|
|
36
|
+
*/
|
|
37
|
+
export declare function giftWrap(innerEvent: {
|
|
38
|
+
kind: number;
|
|
39
|
+
content: string;
|
|
40
|
+
tags: string[][];
|
|
41
|
+
}, recipientPubkey: string): Promise<SignedEvent>;
|
|
42
|
+
/**
|
|
43
|
+
* Unwrap a gift wrapped event.
|
|
44
|
+
*/
|
|
45
|
+
export declare function giftUnwrap(event: SignedEvent): Promise<Seal | null>;
|
|
46
|
+
export declare function handleSignedResponse(id: string, event?: SignedEvent, error?: string): void;
|
|
47
|
+
export declare function handleEncryptedResponse(id: string, ciphertext?: string, error?: string): void;
|
|
48
|
+
export declare function handleDecryptedResponse(id: string, plaintext?: string, error?: string): void;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=signing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../src/relay/signing.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAU7D,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,QAE3D;AAgED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAsB7E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,WAAW,CAgBlE;AAMD;;GAEG;AACH,wBAAsB,OAAO,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQzF;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQvF;AAMD,UAAU,IAAI;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,EAC/D,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,WAAW,CAAC,CAwCtB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAOzE;AAyED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,QAMnF;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,QAMtF;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,QAMrF"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* Worker Signing & Encryption
|
|
4
|
+
*
|
|
5
|
+
* Provides signing, encryption, and gift wrap functions.
|
|
6
|
+
* Uses nsec directly when available, delegates to main thread otherwise.
|
|
7
|
+
*/
|
|
8
|
+
import { generateSecretKey, finalizeEvent, nip44 } from 'nostr-tools';
|
|
9
|
+
import { getSecretKey, getPubkey, getEphemeralSecretKey } from './identity';
|
|
10
|
+
// Pending NIP-07 requests (waiting for main thread)
|
|
11
|
+
const pendingSignRequests = new Map();
|
|
12
|
+
const pendingEncryptRequests = new Map();
|
|
13
|
+
const pendingDecryptRequests = new Map();
|
|
14
|
+
// Response sender (set by worker.ts)
|
|
15
|
+
let postResponse = null;
|
|
16
|
+
export function setResponseSender(fn) {
|
|
17
|
+
postResponse = fn;
|
|
18
|
+
}
|
|
19
|
+
function bytesToHex(bytes) {
|
|
20
|
+
let hex = '';
|
|
21
|
+
for (const byte of bytes) {
|
|
22
|
+
hex += byte.toString(16).padStart(2, '0');
|
|
23
|
+
}
|
|
24
|
+
return hex;
|
|
25
|
+
}
|
|
26
|
+
function normalizeTagValue(value) {
|
|
27
|
+
if (typeof value === 'string')
|
|
28
|
+
return value;
|
|
29
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
|
|
30
|
+
return String(value);
|
|
31
|
+
}
|
|
32
|
+
if (value == null)
|
|
33
|
+
return '';
|
|
34
|
+
if (value instanceof Uint8Array)
|
|
35
|
+
return bytesToHex(value);
|
|
36
|
+
if (ArrayBuffer.isView(value)) {
|
|
37
|
+
return bytesToHex(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
38
|
+
}
|
|
39
|
+
if (value instanceof ArrayBuffer)
|
|
40
|
+
return bytesToHex(new Uint8Array(value));
|
|
41
|
+
try {
|
|
42
|
+
return JSON.stringify(value);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return String(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function sanitizeTags(tags) {
|
|
49
|
+
if (!Array.isArray(tags))
|
|
50
|
+
return [];
|
|
51
|
+
let needsSanitize = false;
|
|
52
|
+
for (const tag of tags) {
|
|
53
|
+
if (!Array.isArray(tag)) {
|
|
54
|
+
needsSanitize = true;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
for (const value of tag) {
|
|
58
|
+
if (typeof value !== 'string') {
|
|
59
|
+
needsSanitize = true;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (needsSanitize)
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
if (!needsSanitize)
|
|
67
|
+
return tags;
|
|
68
|
+
const sanitized = [];
|
|
69
|
+
for (const tag of tags) {
|
|
70
|
+
if (!Array.isArray(tag))
|
|
71
|
+
continue;
|
|
72
|
+
const normalized = [];
|
|
73
|
+
for (const value of tag) {
|
|
74
|
+
normalized.push(normalizeTagValue(value));
|
|
75
|
+
}
|
|
76
|
+
sanitized.push(normalized);
|
|
77
|
+
}
|
|
78
|
+
return sanitized;
|
|
79
|
+
}
|
|
80
|
+
// ============================================================================
|
|
81
|
+
// Signing
|
|
82
|
+
// ============================================================================
|
|
83
|
+
/**
|
|
84
|
+
* Sign an event with user's real identity.
|
|
85
|
+
* - For nsec login: signs directly with secret key
|
|
86
|
+
* - For extension login: delegates to main thread via NIP-07
|
|
87
|
+
*/
|
|
88
|
+
export async function signEvent(template) {
|
|
89
|
+
template.tags = sanitizeTags(template.tags ?? []);
|
|
90
|
+
const secretKey = getSecretKey();
|
|
91
|
+
if (secretKey) {
|
|
92
|
+
const event = finalizeEvent(template, secretKey);
|
|
93
|
+
return {
|
|
94
|
+
id: event.id,
|
|
95
|
+
pubkey: event.pubkey,
|
|
96
|
+
kind: event.kind,
|
|
97
|
+
content: event.content,
|
|
98
|
+
tags: event.tags,
|
|
99
|
+
created_at: event.created_at,
|
|
100
|
+
sig: event.sig,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return requestSign({
|
|
105
|
+
kind: template.kind,
|
|
106
|
+
created_at: template.created_at,
|
|
107
|
+
content: template.content,
|
|
108
|
+
tags: template.tags,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Synchronous sign (only works with nsec, falls back to ephemeral)
|
|
114
|
+
*/
|
|
115
|
+
export function signEventSync(template) {
|
|
116
|
+
template.tags = sanitizeTags(template.tags ?? []);
|
|
117
|
+
const secretKey = getSecretKey() || getEphemeralSecretKey();
|
|
118
|
+
if (!secretKey) {
|
|
119
|
+
throw new Error('No signing key available');
|
|
120
|
+
}
|
|
121
|
+
const event = finalizeEvent(template, secretKey);
|
|
122
|
+
return {
|
|
123
|
+
id: event.id,
|
|
124
|
+
pubkey: event.pubkey,
|
|
125
|
+
kind: event.kind,
|
|
126
|
+
content: event.content,
|
|
127
|
+
tags: event.tags,
|
|
128
|
+
created_at: event.created_at,
|
|
129
|
+
sig: event.sig,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// ============================================================================
|
|
133
|
+
// Encryption
|
|
134
|
+
// ============================================================================
|
|
135
|
+
/**
|
|
136
|
+
* Encrypt plaintext for a recipient using NIP-44
|
|
137
|
+
*/
|
|
138
|
+
export async function encrypt(recipientPubkey, plaintext) {
|
|
139
|
+
const secretKey = getSecretKey();
|
|
140
|
+
if (secretKey) {
|
|
141
|
+
const conversationKey = nip44.v2.utils.getConversationKey(secretKey, recipientPubkey);
|
|
142
|
+
return nip44.v2.encrypt(plaintext, conversationKey);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return requestEncrypt(recipientPubkey, plaintext);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Decrypt ciphertext from a sender using NIP-44
|
|
150
|
+
*/
|
|
151
|
+
export async function decrypt(senderPubkey, ciphertext) {
|
|
152
|
+
const secretKey = getSecretKey();
|
|
153
|
+
if (secretKey) {
|
|
154
|
+
const conversationKey = nip44.v2.utils.getConversationKey(secretKey, senderPubkey);
|
|
155
|
+
return nip44.v2.decrypt(ciphertext, conversationKey);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
return requestDecrypt(senderPubkey, ciphertext);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Gift wrap an event for private delivery.
|
|
163
|
+
*/
|
|
164
|
+
export async function giftWrap(innerEvent, recipientPubkey) {
|
|
165
|
+
const myPubkey = getPubkey();
|
|
166
|
+
if (!myPubkey)
|
|
167
|
+
throw new Error('No pubkey available');
|
|
168
|
+
const seal = {
|
|
169
|
+
pubkey: myPubkey,
|
|
170
|
+
kind: innerEvent.kind,
|
|
171
|
+
content: innerEvent.content,
|
|
172
|
+
tags: innerEvent.tags,
|
|
173
|
+
};
|
|
174
|
+
// Generate ephemeral keypair for the wrapper
|
|
175
|
+
const ephemeralSk = generateSecretKey();
|
|
176
|
+
// Encrypt the seal for the recipient
|
|
177
|
+
const conversationKey = nip44.v2.utils.getConversationKey(ephemeralSk, recipientPubkey);
|
|
178
|
+
const encryptedContent = nip44.v2.encrypt(JSON.stringify(seal), conversationKey);
|
|
179
|
+
const createdAt = Math.floor(Date.now() / 1000);
|
|
180
|
+
const expiration = createdAt + 5 * 60;
|
|
181
|
+
const event = finalizeEvent({
|
|
182
|
+
kind: 25050,
|
|
183
|
+
created_at: createdAt,
|
|
184
|
+
tags: [
|
|
185
|
+
['p', recipientPubkey],
|
|
186
|
+
['expiration', expiration.toString()],
|
|
187
|
+
],
|
|
188
|
+
content: encryptedContent,
|
|
189
|
+
}, ephemeralSk);
|
|
190
|
+
return {
|
|
191
|
+
id: event.id,
|
|
192
|
+
pubkey: event.pubkey,
|
|
193
|
+
kind: event.kind,
|
|
194
|
+
content: event.content,
|
|
195
|
+
tags: event.tags,
|
|
196
|
+
created_at: event.created_at,
|
|
197
|
+
sig: event.sig,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Unwrap a gift wrapped event.
|
|
202
|
+
*/
|
|
203
|
+
export async function giftUnwrap(event) {
|
|
204
|
+
try {
|
|
205
|
+
const decrypted = await decrypt(event.pubkey, event.content);
|
|
206
|
+
return JSON.parse(decrypted);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// ============================================================================
|
|
213
|
+
// NIP-07 Delegation (for extension login)
|
|
214
|
+
// ============================================================================
|
|
215
|
+
async function requestSign(event) {
|
|
216
|
+
const id = `sign_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
pendingSignRequests.set(id, (signed, error) => {
|
|
219
|
+
if (error)
|
|
220
|
+
reject(new Error(error));
|
|
221
|
+
else if (signed)
|
|
222
|
+
resolve(signed);
|
|
223
|
+
else
|
|
224
|
+
reject(new Error('Signing failed'));
|
|
225
|
+
});
|
|
226
|
+
postResponse?.({ type: 'signEvent', id, event });
|
|
227
|
+
setTimeout(() => {
|
|
228
|
+
if (pendingSignRequests.has(id)) {
|
|
229
|
+
pendingSignRequests.delete(id);
|
|
230
|
+
reject(new Error('Signing timeout'));
|
|
231
|
+
}
|
|
232
|
+
}, 60000);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
async function requestEncrypt(pubkey, plaintext) {
|
|
236
|
+
const id = `enc_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
237
|
+
return new Promise((resolve, reject) => {
|
|
238
|
+
pendingEncryptRequests.set(id, (ciphertext, error) => {
|
|
239
|
+
if (error)
|
|
240
|
+
reject(new Error(error));
|
|
241
|
+
else if (ciphertext)
|
|
242
|
+
resolve(ciphertext);
|
|
243
|
+
else
|
|
244
|
+
reject(new Error('Encryption failed'));
|
|
245
|
+
});
|
|
246
|
+
postResponse?.({ type: 'nip44Encrypt', id, pubkey, plaintext });
|
|
247
|
+
setTimeout(() => {
|
|
248
|
+
if (pendingEncryptRequests.has(id)) {
|
|
249
|
+
pendingEncryptRequests.delete(id);
|
|
250
|
+
reject(new Error('Encryption timeout'));
|
|
251
|
+
}
|
|
252
|
+
}, 30000);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
async function requestDecrypt(pubkey, ciphertext) {
|
|
256
|
+
const id = `dec_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
257
|
+
return new Promise((resolve, reject) => {
|
|
258
|
+
pendingDecryptRequests.set(id, (plaintext, error) => {
|
|
259
|
+
if (error)
|
|
260
|
+
reject(new Error(error));
|
|
261
|
+
else if (plaintext)
|
|
262
|
+
resolve(plaintext);
|
|
263
|
+
else
|
|
264
|
+
reject(new Error('Decryption failed'));
|
|
265
|
+
});
|
|
266
|
+
postResponse?.({ type: 'nip44Decrypt', id, pubkey, ciphertext });
|
|
267
|
+
setTimeout(() => {
|
|
268
|
+
if (pendingDecryptRequests.has(id)) {
|
|
269
|
+
pendingDecryptRequests.delete(id);
|
|
270
|
+
reject(new Error('Decryption timeout'));
|
|
271
|
+
}
|
|
272
|
+
}, 30000);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// ============================================================================
|
|
276
|
+
// Response Handlers (called by worker.ts when main thread responds)
|
|
277
|
+
// ============================================================================
|
|
278
|
+
export function handleSignedResponse(id, event, error) {
|
|
279
|
+
const resolver = pendingSignRequests.get(id);
|
|
280
|
+
if (resolver) {
|
|
281
|
+
pendingSignRequests.delete(id);
|
|
282
|
+
resolver(event || null, error);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
export function handleEncryptedResponse(id, ciphertext, error) {
|
|
286
|
+
const resolver = pendingEncryptRequests.get(id);
|
|
287
|
+
if (resolver) {
|
|
288
|
+
pendingEncryptRequests.delete(id);
|
|
289
|
+
resolver(ciphertext || null, error);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
export function handleDecryptedResponse(id, plaintext, error) {
|
|
293
|
+
const resolver = pendingDecryptRequests.get(id);
|
|
294
|
+
if (resolver) {
|
|
295
|
+
pendingDecryptRequests.delete(id);
|
|
296
|
+
resolver(plaintext || null, error);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/relay/signing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree Root Cache
|
|
3
|
+
*
|
|
4
|
+
* Persists npub/treeName → CID mappings using any Store implementation.
|
|
5
|
+
* This allows quick resolution of tree roots without waiting for Nostr.
|
|
6
|
+
*
|
|
7
|
+
* Storage format:
|
|
8
|
+
* - Key prefix: "root:" (to distinguish from content chunks)
|
|
9
|
+
* - Key: SHA256("root:" + npub + "/" + treeName)
|
|
10
|
+
* - Value: MessagePack { hash, key?, visibility, updatedAt }
|
|
11
|
+
*/
|
|
12
|
+
import type { CID, Store, TreeVisibility } from '@hashtree/core';
|
|
13
|
+
interface CachedRoot {
|
|
14
|
+
hash: Uint8Array;
|
|
15
|
+
key?: Uint8Array;
|
|
16
|
+
visibility: TreeVisibility;
|
|
17
|
+
labels?: string[];
|
|
18
|
+
updatedAt: number;
|
|
19
|
+
eventId?: string;
|
|
20
|
+
snapshotNhash?: string;
|
|
21
|
+
encryptedKey?: string;
|
|
22
|
+
keyId?: string;
|
|
23
|
+
selfEncryptedKey?: string;
|
|
24
|
+
selfEncryptedLinkKey?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface SetCachedRootResult {
|
|
27
|
+
applied: boolean;
|
|
28
|
+
record: CachedRoot;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Initialize the cache with a store
|
|
32
|
+
*/
|
|
33
|
+
export declare function initTreeRootCache(storeImpl: Store): void;
|
|
34
|
+
export declare function getTreeRootCacheStore(): Store | null;
|
|
35
|
+
/**
|
|
36
|
+
* Get a cached tree root
|
|
37
|
+
*/
|
|
38
|
+
export declare function getCachedRoot(npub: string, treeName: string): Promise<CID | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Get full cached root info (including visibility)
|
|
41
|
+
*/
|
|
42
|
+
export declare function getCachedRootInfo(npub: string, treeName: string): Promise<CachedRoot | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Cache a tree root
|
|
45
|
+
*/
|
|
46
|
+
export declare function setCachedRoot(npub: string, treeName: string, cid: CID, visibility?: TreeVisibility, options?: {
|
|
47
|
+
updatedAt?: number;
|
|
48
|
+
eventId?: string;
|
|
49
|
+
labels?: string[];
|
|
50
|
+
snapshotNhash?: string;
|
|
51
|
+
encryptedKey?: string;
|
|
52
|
+
keyId?: string;
|
|
53
|
+
selfEncryptedKey?: string;
|
|
54
|
+
selfEncryptedLinkKey?: string;
|
|
55
|
+
}): Promise<SetCachedRootResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Merge a decrypted key into an existing cache entry (if hash matches).
|
|
58
|
+
*/
|
|
59
|
+
export declare function mergeCachedRootKey(npub: string, treeName: string, hash: Uint8Array, key: Uint8Array): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Remove a cached tree root
|
|
62
|
+
*/
|
|
63
|
+
export declare function removeCachedRoot(npub: string, treeName: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* List all cached roots for an npub
|
|
66
|
+
* Note: This scans memory cache only - persistent lookup requires iteration
|
|
67
|
+
*/
|
|
68
|
+
export declare function listCachedRoots(npub: string): Array<{
|
|
69
|
+
treeName: string;
|
|
70
|
+
cid: CID;
|
|
71
|
+
visibility: TreeVisibility;
|
|
72
|
+
updatedAt: number;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Clear all cached roots (memory only)
|
|
76
|
+
*/
|
|
77
|
+
export declare function clearMemoryCache(): void;
|
|
78
|
+
export declare function onCachedRootUpdate(listener: (npub: string, treeName: string, cid: CID | null) => void): () => void;
|
|
79
|
+
/**
|
|
80
|
+
* Get cache stats
|
|
81
|
+
*/
|
|
82
|
+
export declare function getCacheStats(): {
|
|
83
|
+
memoryEntries: number;
|
|
84
|
+
};
|
|
85
|
+
export {};
|
|
86
|
+
//# sourceMappingURL=treeRootCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treeRootCache.d.ts","sourceRoot":"","sources":["../../src/relay/treeRootCache.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMjE,UAAU,UAAU;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;CACpB;AAqCD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI,CAExD;AAED,wBAAgB,qBAAqB,IAAI,KAAK,GAAG,IAAI,CAEpD;AAUD;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAwBvF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAqBlG;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,GAAG,EACR,UAAU,GAAE,cAAyB,EACrC,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GACA,OAAO,CAAC,mBAAmB,CAAC,CAyC9B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAsBD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,KAAK,IAAI,GAClE,MAAM,IAAI,CAKZ;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAIzD"}
|