@qntx/nostr 0.1.0 → 0.2.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/dist/abort-Ba8tDrOI.mjs +38 -0
- package/dist/abort-Ba8tDrOI.mjs.map +1 -0
- package/dist/{builder-BphJa-Y-.d.mts → builder-BWn55Paf.d.mts} +20 -14
- package/dist/{builder-q0VsvnYE.mjs → builder-CyrGKRVP.mjs} +32 -16
- package/dist/builder-CyrGKRVP.mjs.map +1 -0
- package/dist/{client-Bd8B1mYm.mjs → client-BWsX9Cv1.mjs} +354 -195
- package/dist/client-BWsX9Cv1.mjs.map +1 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/core.d.mts +8 -8
- package/dist/core.mjs +8 -9
- package/dist/error-BW7re1UN.d.mts +9 -0
- package/dist/error-B__OMBRY.mjs +14 -0
- package/dist/error-B__OMBRY.mjs.map +1 -0
- package/dist/{error-WEFS-R-4.d.mts → error-CR8Urc84.d.mts} +20 -8
- package/dist/{error-CwBxle6N.mjs → error-DrEIM7FO.mjs} +5 -3
- package/dist/error-DrEIM7FO.mjs.map +1 -0
- package/dist/{event-CzoQEFMF.mjs → event-D8Nfoh4K.mjs} +40 -32
- package/dist/event-D8Nfoh4K.mjs.map +1 -0
- package/dist/{event-B5D2jxt_.d.mts → event-fU3Y01PR.d.mts} +23 -20
- package/dist/{filter-BxwjEkZp.mjs → filter-BQl3GlHt.mjs} +42 -35
- package/dist/filter-BQl3GlHt.mjs.map +1 -0
- package/dist/filter-C0IMByE3.d.mts +37 -0
- package/dist/{gossip-C5RVB1UB.d.mts → gossip-BRQwIM_q.d.mts} +25 -23
- package/dist/{gossip-3xkRRCm_.mjs → gossip-oloDMWEj.mjs} +52 -34
- package/dist/gossip-oloDMWEj.mjs.map +1 -0
- package/dist/gossip.d.mts +1 -1
- package/dist/gossip.mjs +1 -1
- package/dist/{http-6vevbBlu.d.mts → http-C4HwIu4B.d.mts} +7 -7
- package/dist/{http-D2rhokZo.mjs → http-CuazNRIP.mjs} +10 -6
- package/dist/http-CuazNRIP.mjs.map +1 -0
- package/dist/index-B425CAcQ.d.mts +328 -0
- package/dist/index-BVyfUBuG.d.mts +181 -0
- package/dist/{index-BYMnhRIC.d.mts → index-Ba7bJ7DD.d.mts} +68 -50
- package/dist/{index-DaRyjo7O.d.mts → index-Boe8FshM.d.mts} +13 -7
- package/dist/index-CUIvFQdE.d.mts +73 -0
- package/dist/index-JdaS_uce.d.mts +207 -0
- package/dist/index.d.mts +22 -20
- package/dist/index.mjs +19 -18
- package/dist/{key-Dn-aX4x4.mjs → key-Bbtys6o7.mjs} +22 -14
- package/dist/key-Bbtys6o7.mjs.map +1 -0
- package/dist/{key-BiGxGLhg.d.mts → key-BlsYhN1V.d.mts} +9 -6
- package/dist/{kind-BLl4cLOc.mjs → kind-Cxwhhkx8.mjs} +2 -1
- package/dist/kind-Cxwhhkx8.mjs.map +1 -0
- package/dist/{loaders-BNQszDAn.mjs → loaders-o6YXB_Ri.mjs} +329 -305
- package/dist/loaders-o6YXB_Ri.mjs.map +1 -0
- package/dist/loaders.d.mts +3 -3
- package/dist/loaders.mjs +2 -2
- package/dist/memory-C2EVx0_O.mjs +46 -0
- package/dist/memory-C2EVx0_O.mjs.map +1 -0
- package/dist/{memory-BCmhZPek.mjs → memory-index-Do1mz0WF.mjs} +212 -82
- package/dist/memory-index-Do1mz0WF.mjs.map +1 -0
- package/dist/{message-C_Uj-Y-c.mjs → message-DcY6Fi9o.mjs} +38 -24
- package/dist/message-DcY6Fi9o.mjs.map +1 -0
- package/dist/{message-DJC-Jz6T.d.mts → message-iGPIqnn0.d.mts} +15 -8
- package/dist/{nip17-BWq-Kfq5.d.mts → nip17-DNEkz8rM.d.mts} +18 -17
- package/dist/{nip19-D7905oIv.d.mts → nip19-BevCJZsp.d.mts} +23 -3
- package/dist/{nip46-C_DoxiS_.d.mts → nip46-DDV4dC56.d.mts} +13 -12
- package/dist/{nip59-DljW_sYh.d.mts → nip59-zQgdLcEr.d.mts} +28 -25
- package/dist/{nip65-Di5hZRuV.d.mts → nip65-DBfh2smt.d.mts} +8 -3
- package/dist/{nip77-ByxlgoQO.d.mts → nip77-DH4RhS5r.d.mts} +9 -8
- package/dist/nips/blossom.d.mts +37 -37
- package/dist/nips/blossom.mjs +67 -52
- package/dist/nips/blossom.mjs.map +1 -1
- package/dist/nips/nip04.d.mts +2 -3
- package/dist/nips/nip04.mjs +6 -10
- package/dist/nips/nip04.mjs.map +1 -1
- package/dist/nips/nip05.d.mts +37 -43
- package/dist/nips/nip05.mjs +57 -57
- package/dist/nips/nip05.mjs.map +1 -1
- package/dist/nips/nip10.d.mts +18 -19
- package/dist/nips/nip10.mjs +76 -61
- package/dist/nips/nip10.mjs.map +1 -1
- package/dist/nips/nip11.d.mts +9 -8
- package/dist/nips/nip11.mjs +14 -11
- package/dist/nips/nip11.mjs.map +1 -1
- package/dist/nips/nip13.d.mts +9 -9
- package/dist/nips/nip13.mjs +15 -17
- package/dist/nips/nip13.mjs.map +1 -1
- package/dist/nips/nip17.d.mts +1 -1
- package/dist/nips/nip17.mjs +17 -12
- package/dist/nips/nip17.mjs.map +1 -1
- package/dist/nips/nip19.d.mts +1 -1
- package/dist/nips/nip19.mjs +52 -29
- package/dist/nips/nip19.mjs.map +1 -1
- package/dist/nips/nip21.d.mts +5 -6
- package/dist/nips/nip21.mjs +8 -7
- package/dist/nips/nip21.mjs.map +1 -1
- package/dist/nips/nip27.d.mts +7 -8
- package/dist/nips/nip27.mjs +26 -25
- package/dist/nips/nip27.mjs.map +1 -1
- package/dist/nips/nip42.d.mts +5 -6
- package/dist/nips/nip42.mjs +3 -3
- package/dist/nips/nip42.mjs.map +1 -1
- package/dist/nips/nip44.d.mts +24 -7
- package/dist/nips/nip44.mjs +25 -15
- package/dist/nips/nip44.mjs.map +1 -1
- package/dist/nips/nip46.d.mts +1 -1
- package/dist/nips/nip46.mjs +52 -49
- package/dist/nips/nip46.mjs.map +1 -1
- package/dist/nips/nip49.d.mts +8 -7
- package/dist/nips/nip49.mjs +16 -12
- package/dist/nips/nip49.mjs.map +1 -1
- package/dist/nips/nip51.d.mts +25 -27
- package/dist/nips/nip51.mjs +47 -36
- package/dist/nips/nip51.mjs.map +1 -1
- package/dist/nips/nip57.d.mts +12 -13
- package/dist/nips/nip57.mjs +35 -38
- package/dist/nips/nip57.mjs.map +1 -1
- package/dist/nips/nip59.d.mts +1 -1
- package/dist/nips/nip59.mjs +14 -18
- package/dist/nips/nip59.mjs.map +1 -1
- package/dist/nips/nip65.d.mts +1 -1
- package/dist/nips/nip65.mjs +11 -8
- package/dist/nips/nip65.mjs.map +1 -1
- package/dist/nips/nip77.d.mts +1 -1
- package/dist/nips/nip77.mjs +56 -34
- package/dist/nips/nip77.mjs.map +1 -1
- package/dist/nips/nip96.d.mts +21 -12
- package/dist/nips/nip96.mjs +59 -36
- package/dist/nips/nip96.mjs.map +1 -1
- package/dist/nips/nip98.d.mts +12 -12
- package/dist/nips/nip98.mjs +18 -19
- package/dist/nips/nip98.mjs.map +1 -1
- package/dist/{pool-C_j1OmBB.mjs → pool-XmAGaufS.mjs} +611 -487
- package/dist/pool-XmAGaufS.mjs.map +1 -0
- package/dist/pool-tEr7c5bG.d.mts +302 -0
- package/dist/reactive-DDlThDSZ.mjs +324 -0
- package/dist/reactive-DDlThDSZ.mjs.map +1 -0
- package/dist/reactive-DFpqtIf_.d.mts +66 -0
- package/dist/relay.d.mts +5 -4
- package/dist/relay.mjs +2 -2
- package/dist/report-CHld4uWj.mjs +32 -0
- package/dist/report-CHld4uWj.mjs.map +1 -0
- package/dist/{signer-CZ6K6FUc.mjs → signer-CKR9EHce.mjs} +107 -72
- package/dist/signer-CKR9EHce.mjs.map +1 -0
- package/dist/signer.d.mts +3 -3
- package/dist/signer.mjs +3 -2
- package/dist/storage-xXxLGCVb.mjs +1376 -0
- package/dist/storage-xXxLGCVb.mjs.map +1 -0
- package/dist/storage.d.mts +4 -4
- package/dist/storage.mjs +5 -4
- package/dist/store.d.mts +2 -0
- package/dist/store.mjs +2 -0
- package/dist/testing.d.mts +125 -0
- package/dist/testing.mjs +957 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/types-2pCUprRU.d.mts +47 -0
- package/dist/types-CRQEk0Oi.d.mts +19 -0
- package/dist/util-LfQirgDk.mjs +113 -0
- package/dist/util-LfQirgDk.mjs.map +1 -0
- package/dist/wasm.d.mts +4 -4
- package/dist/wasm.mjs +54 -55
- package/dist/wasm.mjs.map +1 -1
- package/dist/websocket-CmeqvAkp.d.mts +27 -0
- package/package.json +31 -9
- package/dist/builder-q0VsvnYE.mjs.map +0 -1
- package/dist/client-Bd8B1mYm.mjs.map +0 -1
- package/dist/error-B49rbDzT.d.mts +0 -7
- package/dist/error-CwBxle6N.mjs.map +0 -1
- package/dist/error-DZEs5OuZ.mjs +0 -24
- package/dist/error-DZEs5OuZ.mjs.map +0 -1
- package/dist/event-CzoQEFMF.mjs.map +0 -1
- package/dist/filter-BxwjEkZp.mjs.map +0 -1
- package/dist/filter-DUEKP3q1.d.mts +0 -40
- package/dist/gossip-3xkRRCm_.mjs.map +0 -1
- package/dist/http-D2rhokZo.mjs.map +0 -1
- package/dist/index-C0C4e-Gn.d.mts +0 -55
- package/dist/index-DgOugrpF.d.mts +0 -275
- package/dist/index-EwL6fHLo.d.mts +0 -267
- package/dist/index-k2YhCgsh.d.mts +0 -57
- package/dist/key-Dn-aX4x4.mjs.map +0 -1
- package/dist/kind-BLl4cLOc.mjs.map +0 -1
- package/dist/loaders-BNQszDAn.mjs.map +0 -1
- package/dist/memory-BCmhZPek.mjs.map +0 -1
- package/dist/message-C_Uj-Y-c.mjs.map +0 -1
- package/dist/pool-C_j1OmBB.mjs.map +0 -1
- package/dist/pool-DhRi7l-b.d.mts +0 -297
- package/dist/signer-CZ6K6FUc.mjs.map +0 -1
- package/dist/storage-DOy0iLRE.mjs +0 -870
- package/dist/storage-DOy0iLRE.mjs.map +0 -1
- package/dist/types-BzyADqnw.d.mts +0 -19
- package/dist/types-Dn24TPFs.d.mts +0 -43
- package/dist/util-6tfLQ9JF.mjs +0 -73
- package/dist/util-6tfLQ9JF.mjs.map +0 -1
package/dist/pool-DhRi7l-b.d.mts
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import { n as EventTemplate, t as Event } from "./event-B5D2jxt_.mjs";
|
|
2
|
-
import { t as Filter } from "./filter-DUEKP3q1.mjs";
|
|
3
|
-
import { n as CountResult } from "./message-DJC-Jz6T.mjs";
|
|
4
|
-
import { a as NegentropyStorageVector } from "./nip77-ByxlgoQO.mjs";
|
|
5
|
-
//#region src/relay/subscription.d.ts
|
|
6
|
-
type SubscriptionHandlers = {
|
|
7
|
-
onevent?: (event: Event) => void;
|
|
8
|
-
oneose?: () => void;
|
|
9
|
-
onclose?: (reason: string) => void;
|
|
10
|
-
/** Skip verify + onevent when true. Evaluated after parse, before verify. */
|
|
11
|
-
alreadyHaveEvent?: (id: string) => boolean;
|
|
12
|
-
/**
|
|
13
|
-
* Fired for every EVENT id this sub sees, including duplicates and
|
|
14
|
-
* alreadyHaveEvent hits, after parse and before the verify skip.
|
|
15
|
-
*/
|
|
16
|
-
receivedEvent?: (id: string) => void;
|
|
17
|
-
};
|
|
18
|
-
type SubscribeOptions = SubscriptionHandlers & {
|
|
19
|
-
id?: string;
|
|
20
|
-
/**
|
|
21
|
-
* If set, fire `oneose` once after this many ms if EOSE has not arrived.
|
|
22
|
-
* Does not close the REQ. `Relay.fetch` is the one-shot closer.
|
|
23
|
-
*/
|
|
24
|
-
eoseTimeoutMs?: number;
|
|
25
|
-
/**
|
|
26
|
-
* One-shot REQ: do not join a live coalescing group, and close on EOSE.
|
|
27
|
-
* Default false (live). `Relay.fetch` passes true.
|
|
28
|
-
*/
|
|
29
|
-
closeOnEose?: boolean;
|
|
30
|
-
signal?: AbortSignal;
|
|
31
|
-
};
|
|
32
|
-
declare class Subscription {
|
|
33
|
-
#private;
|
|
34
|
-
private readonly sendClose;
|
|
35
|
-
readonly id: string;
|
|
36
|
-
readonly filters: Filter[];
|
|
37
|
-
readonly handlers: SubscriptionHandlers;
|
|
38
|
-
readonly closeOnEose: boolean;
|
|
39
|
-
eosed: boolean;
|
|
40
|
-
closed: boolean;
|
|
41
|
-
/** True after one CLOSED `auth-required:` retry. */
|
|
42
|
-
authRetried: boolean;
|
|
43
|
-
/** Inclusive NIP-01 `since` watermark from verified EVENTs. */
|
|
44
|
-
lastCreatedAt: number | undefined;
|
|
45
|
-
/** Event ids at `lastCreatedAt` (same-second reconnect dedup). Not all seen ids. */
|
|
46
|
-
readonly idsAtWatermark: Set<string>;
|
|
47
|
-
constructor(filters: Filter[], opts: SubscribeOptions, sendClose: (id: string) => void);
|
|
48
|
-
close(reason?: string): void;
|
|
49
|
-
/** Advance the reconnect watermark after a verified EVENT. */
|
|
50
|
-
noteVerified(event: Event): void;
|
|
51
|
-
/**
|
|
52
|
-
* Filters for re-REQ. Original `filters` stay unchanged.
|
|
53
|
-
* NIP-01 `since` is inclusive — never `lastCreatedAt + 1`.
|
|
54
|
-
*/
|
|
55
|
-
replayFilters(): Filter[];
|
|
56
|
-
}
|
|
57
|
-
/** AsyncIterable wrapper over a subscription's events until EOSE or close. */
|
|
58
|
-
declare function subscriptionToAsyncIterable(start: (handlers: SubscriptionHandlers) => {
|
|
59
|
-
close: (reason?: string) => void;
|
|
60
|
-
}, opts?: {
|
|
61
|
-
signal?: AbortSignal;
|
|
62
|
-
includeEose?: boolean;
|
|
63
|
-
}): AsyncIterable<Event> & {
|
|
64
|
-
close: (reason?: string) => void;
|
|
65
|
-
};
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/relay/websocket.d.ts
|
|
68
|
-
/** Minimal WebSocket surface used by Relay (browser or `ws`). */
|
|
69
|
-
type WebSocketLike = {
|
|
70
|
-
readyState: number;
|
|
71
|
-
send(data: string): void;
|
|
72
|
-
close(code?: number, reason?: string): void;
|
|
73
|
-
addEventListener(type: string, listener: (ev: unknown) => void): void;
|
|
74
|
-
removeEventListener(type: string, listener: (ev: unknown) => void): void;
|
|
75
|
-
ping?(): void;
|
|
76
|
-
/** Node `ws` emits `pong` on the EventEmitter; `addEventListener("pong")` is a no-op. */
|
|
77
|
-
once?(event: string, listener: (...args: unknown[]) => void): void;
|
|
78
|
-
on?(event: string, listener: (...args: unknown[]) => void): void;
|
|
79
|
-
off?(event: string, listener: (...args: unknown[]) => void): void;
|
|
80
|
-
};
|
|
81
|
-
type WebSocketConstructor = {
|
|
82
|
-
new (url: string): WebSocketLike;
|
|
83
|
-
readonly OPEN: number;
|
|
84
|
-
readonly CONNECTING: number;
|
|
85
|
-
readonly CLOSING: number;
|
|
86
|
-
readonly CLOSED: number;
|
|
87
|
-
};
|
|
88
|
-
/** Inject a WebSocket implementation (required on Node unless undici/global is present). */
|
|
89
|
-
declare function useWebSocketImplementation(websocketImplementation: WebSocketConstructor): void;
|
|
90
|
-
declare function getWebSocketImplementation(): WebSocketConstructor;
|
|
91
|
-
//#endregion
|
|
92
|
-
//#region src/relay/relay.d.ts
|
|
93
|
-
declare const RelayStatus: {
|
|
94
|
-
readonly Initialized: "initialized";
|
|
95
|
-
readonly Connecting: "connecting";
|
|
96
|
-
readonly Connected: "connected";
|
|
97
|
-
readonly Disconnected: "disconnected";
|
|
98
|
-
readonly Closed: "closed";
|
|
99
|
-
};
|
|
100
|
-
type RelayStatusName = (typeof RelayStatus)[keyof typeof RelayStatus];
|
|
101
|
-
type RelayOptions = {
|
|
102
|
-
websocketImplementation?: WebSocketConstructor;
|
|
103
|
-
verifyEvent?: (event: Event) => boolean;
|
|
104
|
-
publishTimeoutMs?: number;
|
|
105
|
-
connectTimeoutMs?: number;
|
|
106
|
-
/**
|
|
107
|
-
* When true, unexpected disconnects schedule reconnect with backoff and
|
|
108
|
-
* re-fire open subscriptions. Default false.
|
|
109
|
-
*/
|
|
110
|
-
enableReconnect?: boolean;
|
|
111
|
-
/** Backoff delays in ms between reconnect attempts. */
|
|
112
|
-
reconnectBackoffMs?: number[];
|
|
113
|
-
enablePing?: boolean;
|
|
114
|
-
pingIntervalMs?: number;
|
|
115
|
-
pingTimeoutMs?: number;
|
|
116
|
-
/** When set, CLOSED/OK `auth-required:` triggers AUTH then retries the REQ/EVENT/COUNT. */
|
|
117
|
-
authSigner?: (template: EventTemplate) => Promise<Event>;
|
|
118
|
-
};
|
|
119
|
-
type PublishResult = {
|
|
120
|
-
ok: boolean;
|
|
121
|
-
message: string;
|
|
122
|
-
};
|
|
123
|
-
/**
|
|
124
|
-
* Single-relay NIP-01 client.
|
|
125
|
-
* Connection lifecycle, REQ/CLOSE, EVENT publish ACK, AUTH, COUNT, NIP-77, optional reconnect.
|
|
126
|
-
*/
|
|
127
|
-
declare class Relay {
|
|
128
|
-
#private;
|
|
129
|
-
readonly url: string;
|
|
130
|
-
onnotice: ((msg: string) => void) | null;
|
|
131
|
-
onclose: (() => void) | null;
|
|
132
|
-
/** Fired when the relay sends a NIP-42 AUTH challenge. */
|
|
133
|
-
onauth: ((challenge: string) => void) | null;
|
|
134
|
-
/** Fired after a successful reconnect (not the initial connect). */
|
|
135
|
-
onreconnect: (() => void) | null;
|
|
136
|
-
constructor(url: string, opts?: RelayOptions);
|
|
137
|
-
/** Latest NIP-42 challenge, if any. */
|
|
138
|
-
get challenge(): string | undefined;
|
|
139
|
-
get connected(): boolean;
|
|
140
|
-
get status(): RelayStatusName;
|
|
141
|
-
get generation(): number;
|
|
142
|
-
get reconnectEnabled(): boolean;
|
|
143
|
-
/** User subscriptions only; dummy ping REQs are not counted. */
|
|
144
|
-
get subscriptionCount(): number;
|
|
145
|
-
static connect(url: string, opts?: RelayOptions & {
|
|
146
|
-
signal?: AbortSignal;
|
|
147
|
-
}): Promise<Relay>;
|
|
148
|
-
connect(opts?: {
|
|
149
|
-
signal?: AbortSignal;
|
|
150
|
-
timeoutMs?: number;
|
|
151
|
-
}): Promise<void>;
|
|
152
|
-
/** Graceful shutdown: disables reconnect and closes all subscriptions. */
|
|
153
|
-
close(): void;
|
|
154
|
-
/** Low-level REQ with callbacks. Survives reconnect when enableReconnect is on. */
|
|
155
|
-
subscribe(filters: Filter[], opts?: SubscribeOptions): Subscription;
|
|
156
|
-
/** AsyncIterable of events for filters until the subscription is closed. */
|
|
157
|
-
stream(filters: Filter[], opts?: {
|
|
158
|
-
signal?: AbortSignal;
|
|
159
|
-
id?: string;
|
|
160
|
-
}): AsyncIterable<Event> & {
|
|
161
|
-
close: (reason?: string) => void;
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* One-shot query: collect events until EOSE or timeout, then close.
|
|
165
|
-
*/
|
|
166
|
-
fetch(filters: Filter[], opts?: {
|
|
167
|
-
timeoutMs?: number;
|
|
168
|
-
signal?: AbortSignal;
|
|
169
|
-
id?: string;
|
|
170
|
-
}): Promise<Event[]>;
|
|
171
|
-
/** Publish an event and wait for OK. */
|
|
172
|
-
publish(event: Event, opts?: {
|
|
173
|
-
timeoutMs?: number;
|
|
174
|
-
}): Promise<PublishResult>;
|
|
175
|
-
/**
|
|
176
|
-
* NIP-45 COUNT: ask the relay how many events match `filters`.
|
|
177
|
-
* Resolves with the COUNT payload (count / optional approximate / optional hll).
|
|
178
|
-
*/
|
|
179
|
-
count(filters: Filter[], opts?: {
|
|
180
|
-
id?: string;
|
|
181
|
-
timeoutMs?: number;
|
|
182
|
-
signal?: AbortSignal;
|
|
183
|
-
}): Promise<CountResult>;
|
|
184
|
-
/**
|
|
185
|
-
* NIP-42 AUTH: sign the current challenge and wait for OK.
|
|
186
|
-
*/
|
|
187
|
-
auth(sign: (template: EventTemplate) => Promise<Event>, opts?: {
|
|
188
|
-
timeoutMs?: number;
|
|
189
|
-
}): Promise<PublishResult>;
|
|
190
|
-
/**
|
|
191
|
-
* NIP-77: run Negentropy reconciliation against this relay.
|
|
192
|
-
* Returns the local-only (`have`) and remote-only (`need`) event ids.
|
|
193
|
-
* Does not upload or download events.
|
|
194
|
-
*
|
|
195
|
-
* `timeoutMs` is a single wall-clock deadline for the whole session
|
|
196
|
-
* (`NEG-OPEN` through the last `NEG-MSG`), not a per-message budget.
|
|
197
|
-
* Default: {@link RelayOptions.publishTimeoutMs}.
|
|
198
|
-
*/
|
|
199
|
-
negReconcile(filter: Filter, storage: NegentropyStorageVector, opts?: {
|
|
200
|
-
id?: string;
|
|
201
|
-
timeoutMs?: number;
|
|
202
|
-
signal?: AbortSignal;
|
|
203
|
-
}): Promise<{
|
|
204
|
-
have: string[];
|
|
205
|
-
need: string[];
|
|
206
|
-
}>;
|
|
207
|
-
/** Generate a unique subscription id for this relay instance. */
|
|
208
|
-
nextSubId(prefix?: string): string;
|
|
209
|
-
}
|
|
210
|
-
//#endregion
|
|
211
|
-
//#region src/relay/pool.d.ts
|
|
212
|
-
type PoolOptions = {
|
|
213
|
-
websocketImplementation?: WebSocketConstructor;
|
|
214
|
-
verifyEvent?: RelayOptions["verifyEvent"];
|
|
215
|
-
publishTimeoutMs?: number;
|
|
216
|
-
connectTimeoutMs?: number;
|
|
217
|
-
enableReconnect?: boolean;
|
|
218
|
-
reconnectBackoffMs?: number[];
|
|
219
|
-
enablePing?: boolean;
|
|
220
|
-
pingIntervalMs?: number;
|
|
221
|
-
pingTimeoutMs?: number;
|
|
222
|
-
/**
|
|
223
|
-
* When set, automatically answer NIP-42 AUTH challenges for relays that
|
|
224
|
-
* send them. Return null to skip a given relay URL.
|
|
225
|
-
*/
|
|
226
|
-
automaticallyAuth?: (relayURL: string) => null | ((event: EventTemplate) => Promise<Event>);
|
|
227
|
-
/** When false, ensureRelay rejects isInsecureRelayUrl unless trusted. Default true (allow). */
|
|
228
|
-
allowInsecure?: boolean;
|
|
229
|
-
trustedInsecureUrls?: readonly string[];
|
|
230
|
-
/** Close unused relays. Unset/0 = disabled. */
|
|
231
|
-
idleTimeoutMs?: number;
|
|
232
|
-
idleCleanupIntervalMs?: number;
|
|
233
|
-
onIdleRelaysClosed?: (urls: string[]) => void;
|
|
234
|
-
};
|
|
235
|
-
type PoolPublishResult = {
|
|
236
|
-
url: string;
|
|
237
|
-
result?: PublishResult;
|
|
238
|
-
error?: string;
|
|
239
|
-
};
|
|
240
|
-
type PoolCountResult = {
|
|
241
|
-
url: string;
|
|
242
|
-
count?: number;
|
|
243
|
-
approximate?: boolean;
|
|
244
|
-
hll?: string;
|
|
245
|
-
error?: string;
|
|
246
|
-
};
|
|
247
|
-
/**
|
|
248
|
-
* Multi-relay coordinator: connection reuse, cross-relay event dedup, fan-out publish.
|
|
249
|
-
*/
|
|
250
|
-
declare class Pool {
|
|
251
|
-
#private;
|
|
252
|
-
constructor(opts?: PoolOptions);
|
|
253
|
-
setAllowInsecure(allow: boolean): void;
|
|
254
|
-
setTrustedInsecureUrls(urls: readonly string[]): void;
|
|
255
|
-
cleanIdleRelays(): void;
|
|
256
|
-
ensureRelay(url: string, opts?: {
|
|
257
|
-
signal?: AbortSignal;
|
|
258
|
-
timeoutMs?: number;
|
|
259
|
-
}): Promise<Relay>;
|
|
260
|
-
close(urls?: string[]): void;
|
|
261
|
-
/**
|
|
262
|
-
* Subscribe across relays. Deduplicates by event id.
|
|
263
|
-
* Returns a closer; callbacks receive every new event once.
|
|
264
|
-
*/
|
|
265
|
-
subscribe(relays: string[], filters: Filter[], opts?: SubscribeOptions): {
|
|
266
|
-
close: (reason?: string) => void;
|
|
267
|
-
};
|
|
268
|
-
/** Fetch events until each connected relay EOSE or timeout; dedupe by id. */
|
|
269
|
-
fetch(relays: string[], filters: Filter[], opts?: {
|
|
270
|
-
timeoutMs?: number;
|
|
271
|
-
signal?: AbortSignal;
|
|
272
|
-
}): Promise<Event[]>;
|
|
273
|
-
/** Publish to all listed relays; returns per-relay outcomes. */
|
|
274
|
-
publish(relays: string[], event: Event, opts?: {
|
|
275
|
-
timeoutMs?: number;
|
|
276
|
-
}): Promise<PoolPublishResult[]>;
|
|
277
|
-
/** First successful publish (Promise.any semantics). */
|
|
278
|
-
publishAny(relays: string[], event: Event, opts?: {
|
|
279
|
-
timeoutMs?: number;
|
|
280
|
-
}): Promise<PoolPublishResult>;
|
|
281
|
-
/**
|
|
282
|
-
* NIP-45 COUNT across relays. Per-relay outcomes; failures do not throw.
|
|
283
|
-
* Counts are not summed — each relay reports independently (may overlap).
|
|
284
|
-
*/
|
|
285
|
-
count(relays: string[], filters: Filter[], opts?: {
|
|
286
|
-
timeoutMs?: number;
|
|
287
|
-
signal?: AbortSignal;
|
|
288
|
-
}): Promise<PoolCountResult[]>;
|
|
289
|
-
listRelays(): string[];
|
|
290
|
-
/** Lookup a pooled relay, including disconnected reconnecting entries. */
|
|
291
|
-
getRelay(url: string): Relay | undefined;
|
|
292
|
-
/** Currently connected URLs. Unlike listRelays(), excludes reconnecting/disconnected entries. */
|
|
293
|
-
connectedUrls(): string[];
|
|
294
|
-
}
|
|
295
|
-
//#endregion
|
|
296
|
-
export { subscriptionToAsyncIterable as _, PublishResult as a, RelayStatus as c, WebSocketLike as d, getWebSocketImplementation as f, SubscriptionHandlers as g, Subscription as h, PoolPublishResult as i, RelayStatusName as l, SubscribeOptions as m, PoolCountResult as n, Relay as o, useWebSocketImplementation as p, PoolOptions as r, RelayOptions as s, Pool as t, WebSocketConstructor as u };
|
|
297
|
-
//# sourceMappingURL=pool-DhRi7l-b.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signer-CZ6K6FUc.mjs","names":["#keys","#convKeys","nip04.encrypt","nip04.decrypt","nip44.getConversationKey","nip44.encrypt","#conversationKey","nip44.decrypt","#provider","#resolve","#pool","#ownsPool","#clientSecret","#clientPubkey","#pointer","#conversationKey","#onAuthUrl","#timeoutMs","#perms","#metadata","#listeners","#waitingAuth","#relays","#startSubscription","decrypt","#sub","#open","#sendRequest","#cachedRemotePubkey","#serial","#idPrefix","encrypt"],"sources":["../src/signer/keys.ts","../src/signer/nip07.ts","../src/signer/nip46.ts"],"sourcesContent":["import type { Event, UnsignedEvent } from \"../core/event.ts\";\nimport { CryptoError } from \"../core/error.ts\";\nimport { Keys, SecretKey, getPublicKey, signEvent } from \"../core/key.ts\";\nimport * as nip04 from \"../nips/nip04.ts\";\nimport * as nip44 from \"../nips/nip44.ts\";\nimport type { NostrSigner } from \"./types.ts\";\n\n/** Local secret-key signer with NIP-04 (legacy) and NIP-44 support. */\nexport class KeysSigner implements NostrSigner {\n readonly #keys: Keys;\n readonly #convKeys = new Map<string, Uint8Array>();\n\n constructor(secretKey: SecretKey | Uint8Array | string | Keys) {\n this.#keys = secretKey instanceof Keys ? secretKey : Keys.fromSecretKey(secretKey);\n }\n\n get keys(): Keys {\n return this.#keys;\n }\n\n async getPublicKey(): Promise<string> {\n return this.#keys.publicKey;\n }\n\n async signEvent(unsigned: UnsignedEvent): Promise<Event> {\n const expected = getPublicKey(this.#keys.secretKey);\n if (unsigned.pubkey.toLowerCase() !== expected) {\n throw new CryptoError(\"unsigned event pubkey does not match signer\");\n }\n return signEvent(unsigned, this.#keys.secretKey);\n }\n\n async nip04Encrypt(peer: string, plaintext: string): Promise<string> {\n return nip04.encrypt(this.#keys.secretKey.bytes, peer, plaintext);\n }\n\n async nip04Decrypt(peer: string, ciphertext: string): Promise<string> {\n return nip04.decrypt(this.#keys.secretKey.bytes, peer, ciphertext);\n }\n\n #conversationKey(peer: string): Uint8Array {\n const pk = peer.toLowerCase();\n let key = this.#convKeys.get(pk);\n if (!key) {\n key = nip44.getConversationKey(this.#keys.secretKey.bytes, pk);\n this.#convKeys.set(pk, key);\n }\n return key;\n }\n\n async nip44Encrypt(peer: string, plaintext: string): Promise<string> {\n return nip44.encrypt(plaintext, this.#conversationKey(peer));\n }\n\n async nip44Decrypt(peer: string, payload: string): Promise<string> {\n return nip44.decrypt(payload, this.#conversationKey(peer));\n }\n}\n","import type { Event, EventTemplate, UnsignedEvent } from \"../core/event.ts\";\nimport { signedMatchesUnsigned, validateSignedEvent } from \"../core/event.ts\";\nimport { CryptoError } from \"../core/error.ts\";\nimport { verifyEvent } from \"../core/key.ts\";\nimport type { NostrSigner } from \"./types.ts\";\n\n/**\n * Minimal NIP-07 provider surface (browser extension `window.nostr`).\n * @see https://github.com/nostr-protocol/nips/blob/master/07.md\n */\nexport type WindowNostr = {\n getPublicKey(): Promise<string>;\n signEvent(event: EventTemplate): Promise<Event>;\n nip04?: {\n encrypt(pubkey: string, plaintext: string): Promise<string>;\n decrypt(pubkey: string, ciphertext: string): Promise<string>;\n };\n nip44?: {\n encrypt(pubkey: string, plaintext: string): Promise<string>;\n decrypt(pubkey: string, ciphertext: string): Promise<string>;\n };\n};\n\ntype GlobalWithNostr = typeof globalThis & {\n nostr?: WindowNostr;\n window?: { nostr?: WindowNostr };\n};\n\n/** Resolve `window.nostr` / `globalThis.nostr` when present. */\nexport function getWindowNostr(): WindowNostr | undefined {\n const g = globalThis as GlobalWithNostr;\n return g.nostr ?? g.window?.nostr;\n}\n\n/** True when a NIP-07 provider is injected in the current environment. */\nexport function isNip07Available(): boolean {\n const n = getWindowNostr();\n return Boolean(n && typeof n.getPublicKey === \"function\" && typeof n.signEvent === \"function\");\n}\n\n/**\n * Signer backed by a NIP-07 browser extension (or any injected provider).\n * Never holds secret keys in-process.\n */\nexport class Nip07Signer implements NostrSigner {\n readonly #provider: WindowNostr | undefined;\n\n constructor(provider?: WindowNostr) {\n this.#provider = provider;\n }\n\n #resolve(): WindowNostr {\n const provider = this.#provider ?? getWindowNostr();\n if (!provider) {\n throw new CryptoError(\"NIP-07 provider not available (window.nostr missing)\");\n }\n return provider;\n }\n\n async getPublicKey(): Promise<string> {\n const pk = await this.#resolve().getPublicKey();\n if (typeof pk !== \"string\" || pk.length !== 64) {\n throw new CryptoError(\"NIP-07 getPublicKey returned an invalid pubkey\");\n }\n return pk.toLowerCase();\n }\n\n async signEvent(unsigned: UnsignedEvent): Promise<Event> {\n const provider = this.#resolve();\n const template: EventTemplate = {\n kind: unsigned.kind,\n tags: unsigned.tags.map((t) => [...t] as [string, ...string[]]),\n content: unsigned.content,\n created_at: unsigned.created_at,\n };\n\n const signed = await provider.signEvent(template);\n if (!validateSignedEvent(signed)) {\n throw new CryptoError(\"NIP-07 signEvent returned an invalid event\");\n }\n if (!verifyEvent(signed)) {\n throw new CryptoError(\"NIP-07 signed event failed signature verification\");\n }\n if (!signedMatchesUnsigned(signed, unsigned)) {\n throw new CryptoError(\"NIP-07 signed event does not match unsigned template\");\n }\n return signed;\n }\n\n async nip04Encrypt(peer: string, plaintext: string): Promise<string> {\n const nip04 = this.#resolve().nip04;\n if (!nip04?.encrypt) throw new CryptoError(\"NIP-07 provider does not support nip04.encrypt\");\n return nip04.encrypt(peer, plaintext);\n }\n\n async nip04Decrypt(peer: string, ciphertext: string): Promise<string> {\n const nip04 = this.#resolve().nip04;\n if (!nip04?.decrypt) throw new CryptoError(\"NIP-07 provider does not support nip04.decrypt\");\n return nip04.decrypt(peer, ciphertext);\n }\n\n async nip44Encrypt(peer: string, plaintext: string): Promise<string> {\n const nip44 = this.#resolve().nip44;\n if (!nip44?.encrypt) throw new CryptoError(\"NIP-07 provider does not support nip44.encrypt\");\n return nip44.encrypt(peer, plaintext);\n }\n\n async nip44Decrypt(peer: string, payload: string): Promise<string> {\n const nip44 = this.#resolve().nip44;\n if (!nip44?.decrypt) throw new CryptoError(\"NIP-07 provider does not support nip44.decrypt\");\n return nip44.decrypt(peer, payload);\n }\n}\n","import type { Event, EventTemplate, UnsignedEvent } from \"../core/event.ts\";\nimport { signedMatchesUnsigned, validateSignedEvent } from \"../core/event.ts\";\nimport type { Filter } from \"../core/filter.ts\";\nimport { Kind } from \"../core/kind.ts\";\nimport { SecretKey, finalizeEvent, getPublicKey, verifyEvent } from \"../core/key.ts\";\nimport { Tag } from \"../core/tag.ts\";\nimport { isHex32 } from \"../core/util.ts\";\nimport { decrypt, encrypt, getConversationKey } from \"../nips/nip44.ts\";\nimport {\n Nip46Error,\n decodeNip46Response,\n encodeNip46Request,\n parseBunkerURL,\n parseNostrConnectURI,\n type BunkerPointer,\n type ClientMetadata,\n type Nip46Request,\n} from \"../nips/nip46.ts\";\nimport type { NostrSigner } from \"./types.ts\";\n\n/** Subscribe options used by NIP-46 transport (structural subset of Pool). */\nexport type Nip46SubscribeOptions = {\n signal?: AbortSignal;\n onevent?: (event: Event) => void;\n onclose?: (reason: string) => void;\n};\n\n/**\n * Structural relay transport for NIP-46 RPC.\n * Satisfied by {@link import(\"../relay/pool.ts\").Pool}; constructed above the signer layer\n * so `signer` never imports `relay` (ADR-0001).\n */\nexport type Nip46Transport = {\n subscribe(\n relays: string[],\n filters: Filter[],\n opts?: Nip46SubscribeOptions,\n ): { close: (reason?: string) => void };\n publish(relays: string[], event: Event): Promise<unknown>;\n close(urls?: string[]): void;\n};\n\nexport type Nip46SignerOptions = {\n /**\n * Shared transport. When set, the signer does not close it on {@link Nip46Signer.close}.\n */\n pool?: Nip46Transport;\n /**\n * Factory for a private transport when `pool` is omitted.\n * Typical: `() => new Pool({ websocketImplementation, enableReconnect: true })`.\n */\n createPool?: () => Nip46Transport;\n /**\n * Relays used when the bunker pointer has none, and merged uniquely onto a\n * nonempty pointer (pointer first).\n */\n relays?: string[];\n /**\n * Bunker connection secret when the pointer or bunker:// URL has none.\n */\n secret?: string | null;\n /** Local client key used to encrypt RPC (not the remote user key). */\n clientSecretKey?: SecretKey | Uint8Array | string;\n /** Called when bunker returns `auth_url` for a pending request. */\n onAuthUrl?: (url: string) => void;\n /** Per-request timeout in ms. Default 30s. */\n timeoutMs?: number;\n /** Requested permissions sent with `connect` (`method[:kind]` list). */\n perms?: string[];\n /** Client metadata sent with bunker-initiated `connect`. */\n metadata?: ClientMetadata;\n};\n\nfunction resolveClientSecret(key?: SecretKey | Uint8Array | string): SecretKey {\n if (key === undefined) return SecretKey.generate();\n if (key instanceof SecretKey) return key;\n if (typeof key === \"string\") return SecretKey.fromHex(key);\n return SecretKey.fromBytes(key);\n}\n\nfunction resolveTransport(opts: Nip46SignerOptions): { pool: Nip46Transport; ownsPool: boolean } {\n if (opts.pool) return { pool: opts.pool, ownsPool: false };\n if (opts.createPool) return { pool: opts.createPool(), ownsPool: true };\n throw new Nip46Error(\n \"Nip46Signer requires pool or createPool (inject Pool from @qntx/nostr/relay)\",\n );\n}\n\nfunction applyPointerOpts(pointer: BunkerPointer, opts: Nip46SignerOptions): BunkerPointer {\n let next: BunkerPointer = {\n pubkey: pointer.pubkey.toLowerCase(),\n relays: [...pointer.relays],\n secret: pointer.secret,\n };\n if (opts.secret !== undefined && next.secret == null) {\n next = { ...next, secret: opts.secret };\n }\n\n const relays = next.relays.length > 0 ? next.relays : [...(opts.relays ?? [])];\n if (relays.length === 0) {\n throw new Nip46Error(\"no relays for bunker connection\");\n }\n if (next.relays.length > 0 && opts.relays?.length) {\n const merged = [...next.relays];\n for (const r of opts.relays) {\n if (!merged.includes(r)) merged.push(r);\n }\n return { ...next, relays: merged };\n }\n return { ...next, relays };\n}\n\nfunction resolveBunkerPointer(input: string | BunkerPointer): BunkerPointer {\n if (typeof input !== \"string\") {\n return {\n pubkey: input.pubkey.toLowerCase(),\n relays: [...input.relays],\n secret: input.secret,\n };\n }\n\n const bunker = parseBunkerURL(input);\n if (bunker) return bunker;\n\n throw new Nip46Error(\"invalid bunker input (expected bunker:// URL or BunkerPointer)\");\n}\n\n/**\n * NIP-46 remote signer (bunker / nostrconnect).\n * Implements {@link NostrSigner}; never holds the remote user's secret key.\n * Network I/O is injected via {@link Nip46Transport} (no relay import).\n */\nexport class Nip46Signer implements NostrSigner {\n readonly #pool: Nip46Transport;\n readonly #ownsPool: boolean;\n readonly #clientSecret: SecretKey;\n readonly #clientPubkey: string;\n readonly #pointer: BunkerPointer;\n readonly #conversationKey: Uint8Array;\n readonly #onAuthUrl: ((url: string) => void) | undefined;\n readonly #timeoutMs: number;\n readonly #perms: string[] | undefined;\n readonly #metadata: ClientMetadata | undefined;\n #relays: string[];\n readonly #listeners = new Map<\n string,\n {\n resolve: (v: string) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n readonly #waitingAuth = new Set<string>();\n #sub: { close: (reason?: string) => void } | undefined;\n #open = false;\n #serial = 0;\n #idPrefix = Math.random().toString(36).slice(2, 9);\n #cachedRemotePubkey: string | undefined;\n\n private constructor(\n clientSecret: SecretKey,\n pointer: BunkerPointer,\n pool: Nip46Transport,\n ownsPool: boolean,\n opts: Nip46SignerOptions,\n ) {\n if (pointer.relays.length === 0) {\n throw new Nip46Error(\"bunker pointer has no relays\");\n }\n this.#clientSecret = clientSecret;\n this.#clientPubkey = getPublicKey(clientSecret);\n this.#pointer = {\n pubkey: pointer.pubkey.toLowerCase(),\n relays: [...pointer.relays],\n secret: pointer.secret,\n };\n this.#relays = [...pointer.relays];\n this.#pool = pool;\n this.#ownsPool = ownsPool;\n this.#conversationKey = getConversationKey(clientSecret.bytes, this.#pointer.pubkey);\n this.#onAuthUrl = opts.onAuthUrl;\n this.#timeoutMs = opts.timeoutMs ?? 30_000;\n this.#perms = opts.perms;\n this.#metadata = opts.metadata;\n }\n\n get bunker(): Readonly<BunkerPointer> {\n return {\n pubkey: this.#pointer.pubkey,\n relays: [...this.#relays],\n secret: this.#pointer.secret,\n };\n }\n\n get clientPublicKey(): string {\n return this.#clientPubkey;\n }\n\n /**\n * Subscribe to an already-known bunker pointer. Does not send the `connect` RPC\n * (reconnect without a new handshake).\n * Requires `clientSecretKey` — reconnect must reuse the original client identity.\n */\n static fromBunker(\n pointer: BunkerPointer,\n opts: Nip46SignerOptions & { clientSecretKey: SecretKey | Uint8Array | string },\n ): Nip46Signer {\n if (opts.clientSecretKey === undefined) {\n throw new Nip46Error(\"fromBunker requires clientSecretKey\");\n }\n const resolved = applyPointerOpts(pointer, opts);\n const sk = resolveClientSecret(opts.clientSecretKey);\n const { pool, ownsPool } = resolveTransport(opts);\n const signer = new Nip46Signer(sk, resolved, pool, ownsPool, opts);\n signer.#startSubscription();\n return signer;\n }\n\n /**\n * Connect using a `bunker://` URL or pre-parsed pointer.\n * Invalid strings throw. A NIP-05 identifier is not a bunker pointer.\n * When both pointer and `opts.relays` are nonempty, unique `opts.relays` are appended.\n */\n static async connect(\n input: string | BunkerPointer,\n opts: Nip46SignerOptions = {},\n ): Promise<Nip46Signer> {\n const pointer = resolveBunkerPointer(input);\n const signer = Nip46Signer.fromBunker(pointer, {\n ...opts,\n clientSecretKey: resolveClientSecret(opts.clientSecretKey),\n });\n try {\n await signer.connectRemote();\n try {\n await signer.switchRelays();\n } catch {\n // Bunker may not implement switch_relays.\n }\n await signer.getPublicKey();\n return signer;\n } catch (err) {\n await signer.close();\n throw err;\n }\n }\n\n /**\n * Wait for a bunker to complete a client-initiated `nostrconnect://` handshake.\n * Requires `clientSecretKey` whose pubkey matches the URI client pubkey\n * (build the URI with {@link createNostrConnectURI} after generating keys).\n */\n static async fromNostrConnectURI(\n connectionURI: string,\n opts: Nip46SignerOptions & {\n clientSecretKey: SecretKey | Uint8Array | string;\n signal?: AbortSignal;\n handshakeTimeoutMs?: number;\n },\n ): Promise<Nip46Signer> {\n const params = parseNostrConnectURI(connectionURI);\n const sk = resolveClientSecret(opts.clientSecretKey);\n const clientPubkey = getPublicKey(sk);\n\n if (clientPubkey !== params.clientPubkey) {\n throw new Nip46Error(\"client secret key does not match nostrconnect client pubkey\");\n }\n\n const { pool, ownsPool } = resolveTransport(opts);\n const handshakeTimeoutMs = opts.handshakeTimeoutMs ?? 300_000;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n const finish = (err?: Error, signer?: Nip46Signer) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n sub.close(err ? \"failed\" : \"connected\");\n if (err) {\n if (ownsPool) pool.close();\n reject(err);\n } else if (signer) {\n resolve(signer);\n }\n };\n\n const timer = setTimeout(() => {\n finish(new Nip46Error(\"nostrconnect handshake timed out\"));\n }, handshakeTimeoutMs);\n\n const sub = pool.subscribe(\n params.relays,\n [{ kinds: [Kind.NostrConnect], \"#p\": [clientPubkey], limit: 0 }],\n {\n signal: opts.signal,\n onevent: (event) => {\n try {\n const convKey = getConversationKey(sk.bytes, event.pubkey);\n const payload = decrypt(event.content, convKey);\n const response = decodeNip46Response(payload);\n if (response.result !== params.secret) return;\n\n const pointer: BunkerPointer = {\n pubkey: event.pubkey.toLowerCase(),\n relays: params.relays,\n secret: params.secret,\n };\n const signer = new Nip46Signer(sk, pointer, pool, ownsPool, opts);\n signer.#startSubscription();\n void signer\n .switchRelays()\n .catch(() => undefined)\n .then(() => signer.getPublicKey())\n .then(() => finish(undefined, signer))\n .catch((e) => finish(e instanceof Error ? e : new Nip46Error(String(e))));\n } catch {\n // ignore non-matching events\n }\n },\n onclose: (reason) => {\n if (reason !== \"connected\" && reason !== \"failed\") {\n finish(new Nip46Error(`nostrconnect subscription closed: ${reason}`));\n }\n },\n },\n );\n });\n }\n\n #startSubscription(): void {\n this.#sub?.close();\n this.#sub = this.#pool.subscribe(\n this.#relays,\n [\n {\n kinds: [Kind.NostrConnect],\n authors: [this.#pointer.pubkey],\n \"#p\": [this.#clientPubkey],\n limit: 0,\n },\n ],\n {\n onevent: (event) => {\n try {\n const payload = decrypt(event.content, this.#conversationKey);\n const { id, result, error } = decodeNip46Response(payload);\n\n if (result === \"auth_url\" && this.#waitingAuth.has(id)) {\n this.#waitingAuth.delete(id);\n if (error) this.#onAuthUrl?.(error);\n return;\n }\n\n const listener = this.#listeners.get(id);\n if (!listener) return;\n clearTimeout(listener.timer);\n this.#listeners.delete(id);\n this.#waitingAuth.delete(id);\n if (error) listener.reject(new Nip46Error(error));\n else if (result !== undefined) listener.resolve(result);\n else listener.reject(new Nip46Error(\"empty NIP-46 response\"));\n } catch {\n // ignore decrypt failures from unrelated events\n }\n },\n onclose: () => {\n this.#sub = undefined;\n },\n },\n );\n this.#open = true;\n }\n\n async connectRemote(overrides?: { metadata?: ClientMetadata; perms?: string[] }): Promise<void> {\n const metadata = overrides?.metadata ?? this.#metadata;\n const perms = overrides?.perms ?? this.#perms;\n const params = [this.#pointer.pubkey, this.#pointer.secret ?? \"\"];\n if (perms?.length || metadata) {\n params.push(perms?.length ? perms.join(\",\") : \"\");\n }\n if (metadata) {\n params.push(JSON.stringify(metadata));\n }\n const result = await this.#sendRequest(\"connect\", params);\n if (result === \"ack\") return;\n if (this.#pointer.secret && result === this.#pointer.secret) return;\n throw new Nip46Error(`connect result is not ack or secret: ${result}`);\n }\n\n /**\n * Ask the bunker for its preferred relay list and resubscribe when it changes.\n * Spec result is a JSON array of URLs, or `null` when nothing changes.\n */\n async switchRelays(): Promise<string[] | null> {\n const resp = await this.#sendRequest(\"switch_relays\", []);\n if (resp === \"null\") return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(resp);\n } catch (cause) {\n throw new Nip46Error(\"invalid switch_relays JSON\", {\n cause: cause instanceof Error ? cause : undefined,\n });\n }\n if (\n !Array.isArray(parsed) ||\n parsed.length === 0 ||\n !parsed.every((x) => typeof x === \"string\")\n ) {\n throw new Nip46Error(\"invalid switch_relays result\");\n }\n this.#relays = parsed;\n this.#startSubscription();\n return parsed;\n }\n\n /** Courtesy session teardown. Always closes the local signer afterwards. */\n async logout(): Promise<void> {\n try {\n const resp = await this.#sendRequest(\"logout\", []);\n if (resp !== \"ack\") throw new Nip46Error(`logout result is not ack: ${resp}`);\n } finally {\n await this.close();\n }\n }\n\n async ping(): Promise<void> {\n const resp = await this.#sendRequest(\"ping\", []);\n if (resp !== \"pong\") throw new Nip46Error(`ping result is not pong: ${resp}`);\n }\n\n async getPublicKey(): Promise<string> {\n if (!this.#cachedRemotePubkey) {\n const pk = await this.#sendRequest(\"get_public_key\", []);\n if (!isHex32(pk)) throw new Nip46Error(\"bunker returned invalid pubkey\");\n this.#cachedRemotePubkey = pk.toLowerCase();\n }\n return this.#cachedRemotePubkey;\n }\n\n async signEvent(unsigned: UnsignedEvent): Promise<Event> {\n const template: EventTemplate = {\n kind: unsigned.kind,\n tags: unsigned.tags,\n content: unsigned.content,\n created_at: unsigned.created_at,\n };\n const resp = await this.#sendRequest(\"sign_event\", [JSON.stringify(template)]);\n let signed: unknown;\n try {\n signed = JSON.parse(resp);\n } catch (cause) {\n throw new Nip46Error(\"bunker returned invalid sign_event JSON\", {\n cause: cause instanceof Error ? cause : undefined,\n });\n }\n if (!validateSignedEvent(signed) || !verifyEvent(signed)) {\n throw new Nip46Error(\"bunker returned improperly signed event\");\n }\n if (!signedMatchesUnsigned(signed, unsigned)) {\n throw new Nip46Error(\"signed event does not match unsigned template\");\n }\n return signed;\n }\n\n async nip04Encrypt(peer: string, plaintext: string): Promise<string> {\n return this.#sendRequest(\"nip04_encrypt\", [peer, plaintext]);\n }\n\n async nip04Decrypt(peer: string, ciphertext: string): Promise<string> {\n return this.#sendRequest(\"nip04_decrypt\", [peer, ciphertext]);\n }\n\n async nip44Encrypt(peer: string, plaintext: string): Promise<string> {\n return this.#sendRequest(\"nip44_encrypt\", [peer, plaintext]);\n }\n\n async nip44Decrypt(peer: string, payload: string): Promise<string> {\n return this.#sendRequest(\"nip44_decrypt\", [peer, payload]);\n }\n\n async close(): Promise<void> {\n this.#open = false;\n for (const [, listener] of this.#listeners) {\n clearTimeout(listener.timer);\n listener.reject(new Nip46Error(\"signer closed\"));\n }\n this.#listeners.clear();\n this.#sub?.close(\"signer closed\");\n this.#sub = undefined;\n if (this.#ownsPool) this.#pool.close();\n }\n\n async #sendRequest(method: string, params: string[]): Promise<string> {\n if (!this.#open) throw new Nip46Error(\"signer is closed\");\n if (!this.#sub) this.#startSubscription();\n\n this.#serial += 1;\n const id = `${this.#idPrefix}-${this.#serial}`;\n const req: Nip46Request = { id, method, params };\n const encrypted = encrypt(encodeNip46Request(req), this.#conversationKey);\n\n const event = finalizeEvent(\n {\n kind: Kind.NostrConnect,\n tags: [Tag.p(this.#pointer.pubkey)],\n content: encrypted,\n created_at: Math.floor(Date.now() / 1000),\n },\n this.#clientSecret,\n );\n\n const resultPromise = new Promise<string>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.#listeners.delete(id);\n this.#waitingAuth.delete(id);\n reject(new Nip46Error(`NIP-46 request timed out: ${method}`));\n }, this.#timeoutMs);\n this.#listeners.set(id, { resolve, reject, timer });\n this.#waitingAuth.add(id);\n });\n\n await this.#pool.publish(this.#relays, event);\n return resultPromise;\n }\n}\n"],"mappings":";;;;;;;;;;AAQA,IAAa,aAAb,MAA+C;CAC7C;CACA,4BAAqB,IAAI,IAAwB;CAEjD,YAAY,WAAmD;EAC7D,KAAKA,QAAQ,qBAAqB,OAAO,YAAY,KAAK,cAAc,SAAS;CACnF;CAEA,IAAI,OAAa;EACf,OAAO,KAAKA;CACd;CAEA,MAAM,eAAgC;EACpC,OAAO,KAAKA,MAAM;CACpB;CAEA,MAAM,UAAU,UAAyC;EACvD,MAAM,WAAW,aAAa,KAAKA,MAAM,SAAS;EAClD,IAAI,SAAS,OAAO,YAAY,MAAM,UACpC,MAAM,IAAI,YAAY,6CAA6C;EAErE,OAAO,UAAU,UAAU,KAAKA,MAAM,SAAS;CACjD;CAEA,MAAM,aAAa,MAAc,WAAoC;EACnE,OAAOE,QAAc,KAAKF,MAAM,UAAU,OAAO,MAAM,SAAS;CAClE;CAEA,MAAM,aAAa,MAAc,YAAqC;EACpE,OAAOG,QAAc,KAAKH,MAAM,UAAU,OAAO,MAAM,UAAU;CACnE;CAEA,iBAAiB,MAA0B;EACzC,MAAM,KAAK,KAAK,YAAY;EAC5B,IAAI,MAAM,KAAKC,UAAU,IAAI,EAAE;EAC/B,IAAI,CAAC,KAAK;GACR,MAAMG,mBAAyB,KAAKJ,MAAM,UAAU,OAAO,EAAE;GAC7D,KAAKC,UAAU,IAAI,IAAI,GAAG;EAC5B;EACA,OAAO;CACT;CAEA,MAAM,aAAa,MAAc,WAAoC;EACnE,OAAOI,UAAc,WAAW,KAAKC,iBAAiB,IAAI,CAAC;CAC7D;CAEA,MAAM,aAAa,MAAc,SAAkC;EACjE,OAAOC,UAAc,SAAS,KAAKD,iBAAiB,IAAI,CAAC;CAC3D;AACF;;;;AC5BA,SAAgB,iBAA0C;CACxD,MAAM,IAAI;CACV,OAAO,EAAE,SAAS,EAAE,QAAQ;AAC9B;;AAGA,SAAgB,mBAA4B;CAC1C,MAAM,IAAI,eAAe;CACzB,OAAO,QAAQ,KAAK,OAAO,EAAE,iBAAiB,cAAc,OAAO,EAAE,cAAc,UAAU;AAC/F;;;;;AAMA,IAAa,cAAb,MAAgD;CAC9C;CAEA,YAAY,UAAwB;EAClC,KAAKE,YAAY;CACnB;CAEA,WAAwB;EACtB,MAAM,WAAW,KAAKA,aAAa,eAAe;EAClD,IAAI,CAAC,UACH,MAAM,IAAI,YAAY,sDAAsD;EAE9E,OAAO;CACT;CAEA,MAAM,eAAgC;EACpC,MAAM,KAAK,MAAM,KAAKC,SAAS,CAAC,CAAC,aAAa;EAC9C,IAAI,OAAO,OAAO,YAAY,GAAG,WAAW,IAC1C,MAAM,IAAI,YAAY,gDAAgD;EAExE,OAAO,GAAG,YAAY;CACxB;CAEA,MAAM,UAAU,UAAyC;EACvD,MAAM,WAAW,KAAKA,SAAS;EAC/B,MAAM,WAA0B;GAC9B,MAAM,SAAS;GACf,MAAM,SAAS,KAAK,KAAK,MAAM,CAAC,GAAG,CAAC,CAA0B;GAC9D,SAAS,SAAS;GAClB,YAAY,SAAS;EACvB;EAEA,MAAM,SAAS,MAAM,SAAS,UAAU,QAAQ;EAChD,IAAI,CAAC,oBAAoB,MAAM,GAC7B,MAAM,IAAI,YAAY,4CAA4C;EAEpE,IAAI,CAAC,YAAY,MAAM,GACrB,MAAM,IAAI,YAAY,mDAAmD;EAE3E,IAAI,CAAC,sBAAsB,QAAQ,QAAQ,GACzC,MAAM,IAAI,YAAY,sDAAsD;EAE9E,OAAO;CACT;CAEA,MAAM,aAAa,MAAc,WAAoC;EACnE,MAAM,QAAQ,KAAKA,SAAS,CAAC,CAAC;EAC9B,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,YAAY,gDAAgD;EAC3F,OAAO,MAAM,QAAQ,MAAM,SAAS;CACtC;CAEA,MAAM,aAAa,MAAc,YAAqC;EACpE,MAAM,QAAQ,KAAKA,SAAS,CAAC,CAAC;EAC9B,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,YAAY,gDAAgD;EAC3F,OAAO,MAAM,QAAQ,MAAM,UAAU;CACvC;CAEA,MAAM,aAAa,MAAc,WAAoC;EACnE,MAAM,QAAQ,KAAKA,SAAS,CAAC,CAAC;EAC9B,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,YAAY,gDAAgD;EAC3F,OAAO,MAAM,QAAQ,MAAM,SAAS;CACtC;CAEA,MAAM,aAAa,MAAc,SAAkC;EACjE,MAAM,QAAQ,KAAKA,SAAS,CAAC,CAAC;EAC9B,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,YAAY,gDAAgD;EAC3F,OAAO,MAAM,QAAQ,MAAM,OAAO;CACpC;AACF;;;ACvCA,SAAS,oBAAoB,KAAkD;CAC7E,IAAI,QAAQ,KAAA,GAAW,OAAO,UAAU,SAAS;CACjD,IAAI,eAAe,WAAW,OAAO;CACrC,IAAI,OAAO,QAAQ,UAAU,OAAO,UAAU,QAAQ,GAAG;CACzD,OAAO,UAAU,UAAU,GAAG;AAChC;AAEA,SAAS,iBAAiB,MAAuE;CAC/F,IAAI,KAAK,MAAM,OAAO;EAAE,MAAM,KAAK;EAAM,UAAU;CAAM;CACzD,IAAI,KAAK,YAAY,OAAO;EAAE,MAAM,KAAK,WAAW;EAAG,UAAU;CAAK;CACtE,MAAM,IAAI,WACR,8EACF;AACF;AAEA,SAAS,iBAAiB,SAAwB,MAAyC;CACzF,IAAI,OAAsB;EACxB,QAAQ,QAAQ,OAAO,YAAY;EACnC,QAAQ,CAAC,GAAG,QAAQ,MAAM;EAC1B,QAAQ,QAAQ;CAClB;CACA,IAAI,KAAK,WAAW,KAAA,KAAa,KAAK,UAAU,MAC9C,OAAO;EAAE,GAAG;EAAM,QAAQ,KAAK;CAAO;CAGxC,MAAM,SAAS,KAAK,OAAO,SAAS,IAAI,KAAK,SAAS,CAAC,GAAI,KAAK,UAAU,CAAC,CAAE;CAC7E,IAAI,OAAO,WAAW,GACpB,MAAM,IAAI,WAAW,iCAAiC;CAExD,IAAI,KAAK,OAAO,SAAS,KAAK,KAAK,QAAQ,QAAQ;EACjD,MAAM,SAAS,CAAC,GAAG,KAAK,MAAM;EAC9B,KAAK,MAAM,KAAK,KAAK,QACnB,IAAI,CAAC,OAAO,SAAS,CAAC,GAAG,OAAO,KAAK,CAAC;EAExC,OAAO;GAAE,GAAG;GAAM,QAAQ;EAAO;CACnC;CACA,OAAO;EAAE,GAAG;EAAM;CAAO;AAC3B;AAEA,SAAS,qBAAqB,OAA8C;CAC1E,IAAI,OAAO,UAAU,UACnB,OAAO;EACL,QAAQ,MAAM,OAAO,YAAY;EACjC,QAAQ,CAAC,GAAG,MAAM,MAAM;EACxB,QAAQ,MAAM;CAChB;CAGF,MAAM,SAAS,eAAe,KAAK;CACnC,IAAI,QAAQ,OAAO;CAEnB,MAAM,IAAI,WAAW,gEAAgE;AACvF;;;;;;AAOA,IAAa,cAAb,MAAa,YAAmC;CAC9C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,6BAAsB,IAAI,IAOxB;CACF,+BAAwB,IAAI,IAAY;CACxC;CACA,QAAQ;CACR,UAAU;CACV,YAAY,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;CACjD;CAEA,YACE,cACA,SACA,MACA,UACA,MACA;EACA,IAAI,QAAQ,OAAO,WAAW,GAC5B,MAAM,IAAI,WAAW,8BAA8B;EAErD,KAAKG,gBAAgB;EACrB,KAAKC,gBAAgB,aAAa,YAAY;EAC9C,KAAKC,WAAW;GACd,QAAQ,QAAQ,OAAO,YAAY;GACnC,QAAQ,CAAC,GAAG,QAAQ,MAAM;GAC1B,QAAQ,QAAQ;EAClB;EACA,KAAKQ,UAAU,CAAC,GAAG,QAAQ,MAAM;EACjC,KAAKZ,QAAQ;EACb,KAAKC,YAAY;EACjB,KAAKI,mBAAmB,mBAAmB,aAAa,OAAO,KAAKD,SAAS,MAAM;EACnF,KAAKE,aAAa,KAAK;EACvB,KAAKC,aAAa,KAAK,aAAa;EACpC,KAAKC,SAAS,KAAK;EACnB,KAAKC,YAAY,KAAK;CACxB;CAEA,IAAI,SAAkC;EACpC,OAAO;GACL,QAAQ,KAAKL,SAAS;GACtB,QAAQ,CAAC,GAAG,KAAKQ,OAAO;GACxB,QAAQ,KAAKR,SAAS;EACxB;CACF;CAEA,IAAI,kBAA0B;EAC5B,OAAO,KAAKD;CACd;;;;;;CAOA,OAAO,WACL,SACA,MACa;EACb,IAAI,KAAK,oBAAoB,KAAA,GAC3B,MAAM,IAAI,WAAW,qCAAqC;EAE5D,MAAM,WAAW,iBAAiB,SAAS,IAAI;EAC/C,MAAM,KAAK,oBAAoB,KAAK,eAAe;EACnD,MAAM,EAAE,MAAM,aAAa,iBAAiB,IAAI;EAChD,MAAM,SAAS,IAAI,YAAY,IAAI,UAAU,MAAM,UAAU,IAAI;EACjE,OAAOU,mBAAmB;EAC1B,OAAO;CACT;;;;;;CAOA,aAAa,QACX,OACA,OAA2B,CAAC,GACN;EACtB,MAAM,UAAU,qBAAqB,KAAK;EAC1C,MAAM,SAAS,YAAY,WAAW,SAAS;GAC7C,GAAG;GACH,iBAAiB,oBAAoB,KAAK,eAAe;EAC3D,CAAC;EACD,IAAI;GACF,MAAM,OAAO,cAAc;GAC3B,IAAI;IACF,MAAM,OAAO,aAAa;GAC5B,QAAQ,CAER;GACA,MAAM,OAAO,aAAa;GAC1B,OAAO;EACT,SAAS,KAAK;GACZ,MAAM,OAAO,MAAM;GACnB,MAAM;EACR;CACF;;;;;;CAOA,aAAa,oBACX,eACA,MAKsB;EACtB,MAAM,SAAS,qBAAqB,aAAa;EACjD,MAAM,KAAK,oBAAoB,KAAK,eAAe;EACnD,MAAM,eAAe,aAAa,EAAE;EAEpC,IAAI,iBAAiB,OAAO,cAC1B,MAAM,IAAI,WAAW,6DAA6D;EAGpF,MAAM,EAAE,MAAM,aAAa,iBAAiB,IAAI;EAChD,MAAM,qBAAqB,KAAK,sBAAsB;EAEtD,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,IAAI,UAAU;GACd,MAAM,UAAU,KAAa,WAAyB;IACpD,IAAI,SAAS;IACb,UAAU;IACV,aAAa,KAAK;IAClB,IAAI,MAAM,MAAM,WAAW,WAAW;IACtC,IAAI,KAAK;KACP,IAAI,UAAU,KAAK,MAAM;KACzB,OAAO,GAAG;IACZ,OAAO,IAAI,QACT,QAAQ,MAAM;GAElB;GAEA,MAAM,QAAQ,iBAAiB;IAC7B,OAAO,IAAI,WAAW,kCAAkC,CAAC;GAC3D,GAAG,kBAAkB;GAErB,MAAM,MAAM,KAAK,UACf,OAAO,QACP,CAAC;IAAE,OAAO,CAAC,KAAK,YAAY;IAAG,MAAM,CAAC,YAAY;IAAG,OAAO;GAAE,CAAC,GAC/D;IACE,QAAQ,KAAK;IACb,UAAU,UAAU;KAClB,IAAI;MACF,MAAM,UAAU,mBAAmB,GAAG,OAAO,MAAM,MAAM;MACzD,MAAM,UAAUC,UAAQ,MAAM,SAAS,OAAO;MAE9C,IADiB,oBAAoB,OAC1B,CAAC,CAAC,WAAW,OAAO,QAAQ;MAEvC,MAAM,UAAyB;OAC7B,QAAQ,MAAM,OAAO,YAAY;OACjC,QAAQ,OAAO;OACf,QAAQ,OAAO;MACjB;MACA,MAAM,SAAS,IAAI,YAAY,IAAI,SAAS,MAAM,UAAU,IAAI;MAChE,OAAOD,mBAAmB;MAC1B,OACG,aAAa,CAAC,CACd,YAAY,KAAA,CAAS,CAAC,CACtB,WAAW,OAAO,aAAa,CAAC,CAAC,CACjC,WAAW,OAAO,KAAA,GAAW,MAAM,CAAC,CAAC,CACrC,OAAO,MAAM,OAAO,aAAa,QAAQ,IAAI,IAAI,WAAW,OAAO,CAAC,CAAC,CAAC,CAAC;KAC5E,QAAQ,CAER;IACF;IACA,UAAU,WAAW;KACnB,IAAI,WAAW,eAAe,WAAW,UACvC,OAAO,IAAI,WAAW,qCAAqC,QAAQ,CAAC;IAExE;GACF,CACF;EACF,CAAC;CACH;CAEA,qBAA2B;EACzB,KAAKE,MAAM,MAAM;EACjB,KAAKA,OAAO,KAAKf,MAAM,UACrB,KAAKY,SACL,CACE;GACE,OAAO,CAAC,KAAK,YAAY;GACzB,SAAS,CAAC,KAAKR,SAAS,MAAM;GAC9B,MAAM,CAAC,KAAKD,aAAa;GACzB,OAAO;EACT,CACF,GACA;GACE,UAAU,UAAU;IAClB,IAAI;KACF,MAAM,UAAUW,UAAQ,MAAM,SAAS,KAAKT,gBAAgB;KAC5D,MAAM,EAAE,IAAI,QAAQ,UAAU,oBAAoB,OAAO;KAEzD,IAAI,WAAW,cAAc,KAAKM,aAAa,IAAI,EAAE,GAAG;MACtD,KAAKA,aAAa,OAAO,EAAE;MAC3B,IAAI,OAAO,KAAKL,aAAa,KAAK;MAClC;KACF;KAEA,MAAM,WAAW,KAAKI,WAAW,IAAI,EAAE;KACvC,IAAI,CAAC,UAAU;KACf,aAAa,SAAS,KAAK;KAC3B,KAAKA,WAAW,OAAO,EAAE;KACzB,KAAKC,aAAa,OAAO,EAAE;KAC3B,IAAI,OAAO,SAAS,OAAO,IAAI,WAAW,KAAK,CAAC;UAC3C,IAAI,WAAW,KAAA,GAAW,SAAS,QAAQ,MAAM;UACjD,SAAS,OAAO,IAAI,WAAW,uBAAuB,CAAC;IAC9D,QAAQ,CAER;GACF;GACA,eAAe;IACb,KAAKI,OAAO,KAAA;GACd;EACF,CACF;EACA,KAAKC,QAAQ;CACf;CAEA,MAAM,cAAc,WAA4E;EAC9F,MAAM,WAAW,WAAW,YAAY,KAAKP;EAC7C,MAAM,QAAQ,WAAW,SAAS,KAAKD;EACvC,MAAM,SAAS,CAAC,KAAKJ,SAAS,QAAQ,KAAKA,SAAS,UAAU,EAAE;EAChE,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,OAAO,SAAS,MAAM,KAAK,GAAG,IAAI,EAAE;EAElD,IAAI,UACF,OAAO,KAAK,KAAK,UAAU,QAAQ,CAAC;EAEtC,MAAM,SAAS,MAAM,KAAKa,aAAa,WAAW,MAAM;EACxD,IAAI,WAAW,OAAO;EACtB,IAAI,KAAKb,SAAS,UAAU,WAAW,KAAKA,SAAS,QAAQ;EAC7D,MAAM,IAAI,WAAW,wCAAwC,QAAQ;CACvE;;;;;CAMA,MAAM,eAAyC;EAC7C,MAAM,OAAO,MAAM,KAAKa,aAAa,iBAAiB,CAAC,CAAC;EACxD,IAAI,SAAS,QAAQ,OAAO;EAC5B,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,SAAS,OAAO;GACd,MAAM,IAAI,WAAW,8BAA8B,EACjD,OAAO,iBAAiB,QAAQ,QAAQ,KAAA,EAC1C,CAAC;EACH;EACA,IACE,CAAC,MAAM,QAAQ,MAAM,KACrB,OAAO,WAAW,KAClB,CAAC,OAAO,OAAO,MAAM,OAAO,MAAM,QAAQ,GAE1C,MAAM,IAAI,WAAW,8BAA8B;EAErD,KAAKL,UAAU;EACf,KAAKC,mBAAmB;EACxB,OAAO;CACT;;CAGA,MAAM,SAAwB;EAC5B,IAAI;GACF,MAAM,OAAO,MAAM,KAAKI,aAAa,UAAU,CAAC,CAAC;GACjD,IAAI,SAAS,OAAO,MAAM,IAAI,WAAW,6BAA6B,MAAM;EAC9E,UAAU;GACR,MAAM,KAAK,MAAM;EACnB;CACF;CAEA,MAAM,OAAsB;EAC1B,MAAM,OAAO,MAAM,KAAKA,aAAa,QAAQ,CAAC,CAAC;EAC/C,IAAI,SAAS,QAAQ,MAAM,IAAI,WAAW,4BAA4B,MAAM;CAC9E;CAEA,MAAM,eAAgC;EACpC,IAAI,CAAC,KAAKC,qBAAqB;GAC7B,MAAM,KAAK,MAAM,KAAKD,aAAa,kBAAkB,CAAC,CAAC;GACvD,IAAI,CAAC,QAAQ,EAAE,GAAG,MAAM,IAAI,WAAW,gCAAgC;GACvE,KAAKC,sBAAsB,GAAG,YAAY;EAC5C;EACA,OAAO,KAAKA;CACd;CAEA,MAAM,UAAU,UAAyC;EACvD,MAAM,WAA0B;GAC9B,MAAM,SAAS;GACf,MAAM,SAAS;GACf,SAAS,SAAS;GAClB,YAAY,SAAS;EACvB;EACA,MAAM,OAAO,MAAM,KAAKD,aAAa,cAAc,CAAC,KAAK,UAAU,QAAQ,CAAC,CAAC;EAC7E,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,SAAS,OAAO;GACd,MAAM,IAAI,WAAW,2CAA2C,EAC9D,OAAO,iBAAiB,QAAQ,QAAQ,KAAA,EAC1C,CAAC;EACH;EACA,IAAI,CAAC,oBAAoB,MAAM,KAAK,CAAC,YAAY,MAAM,GACrD,MAAM,IAAI,WAAW,yCAAyC;EAEhE,IAAI,CAAC,sBAAsB,QAAQ,QAAQ,GACzC,MAAM,IAAI,WAAW,+CAA+C;EAEtE,OAAO;CACT;CAEA,MAAM,aAAa,MAAc,WAAoC;EACnE,OAAO,KAAKA,aAAa,iBAAiB,CAAC,MAAM,SAAS,CAAC;CAC7D;CAEA,MAAM,aAAa,MAAc,YAAqC;EACpE,OAAO,KAAKA,aAAa,iBAAiB,CAAC,MAAM,UAAU,CAAC;CAC9D;CAEA,MAAM,aAAa,MAAc,WAAoC;EACnE,OAAO,KAAKA,aAAa,iBAAiB,CAAC,MAAM,SAAS,CAAC;CAC7D;CAEA,MAAM,aAAa,MAAc,SAAkC;EACjE,OAAO,KAAKA,aAAa,iBAAiB,CAAC,MAAM,OAAO,CAAC;CAC3D;CAEA,MAAM,QAAuB;EAC3B,KAAKD,QAAQ;EACb,KAAK,MAAM,GAAG,aAAa,KAAKN,YAAY;GAC1C,aAAa,SAAS,KAAK;GAC3B,SAAS,OAAO,IAAI,WAAW,eAAe,CAAC;EACjD;EACA,KAAKA,WAAW,MAAM;EACtB,KAAKK,MAAM,MAAM,eAAe;EAChC,KAAKA,OAAO,KAAA;EACZ,IAAI,KAAKd,WAAW,KAAKD,MAAM,MAAM;CACvC;CAEA,MAAMiB,aAAa,QAAgB,QAAmC;EACpE,IAAI,CAAC,KAAKD,OAAO,MAAM,IAAI,WAAW,kBAAkB;EACxD,IAAI,CAAC,KAAKD,MAAM,KAAKF,mBAAmB;EAExC,KAAKM,WAAW;EAChB,MAAM,KAAK,GAAG,KAAKC,UAAU,GAAG,KAAKD;EAErC,MAAM,YAAYE,UAAQ,mBAAmB;GADjB;GAAI;GAAQ;EACO,CAAC,GAAG,KAAKhB,gBAAgB;EAExE,MAAM,QAAQ,cACZ;GACE,MAAM,KAAK;GACX,MAAM,CAAC,IAAI,EAAE,KAAKD,SAAS,MAAM,CAAC;GAClC,SAAS;GACT,YAAY,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;EAC1C,GACA,KAAKF,aACP;EAEA,MAAM,gBAAgB,IAAI,SAAiB,SAAS,WAAW;GAC7D,MAAM,QAAQ,iBAAiB;IAC7B,KAAKQ,WAAW,OAAO,EAAE;IACzB,KAAKC,aAAa,OAAO,EAAE;IAC3B,OAAO,IAAI,WAAW,6BAA6B,QAAQ,CAAC;GAC9D,GAAG,KAAKJ,UAAU;GAClB,KAAKG,WAAW,IAAI,IAAI;IAAE;IAAS;IAAQ;GAAM,CAAC;GAClD,KAAKC,aAAa,IAAI,EAAE;EAC1B,CAAC;EAED,MAAM,KAAKX,MAAM,QAAQ,KAAKY,SAAS,KAAK;EAC5C,OAAO;CACT;AACF"}
|