@orbinum/sdk 0.25.0 → 1.0.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/README.md +355 -23
- package/dist/adapters/indexeddb/index.d.mts +152 -0
- package/dist/adapters/indexeddb/index.d.ts +152 -0
- package/dist/adapters/indexeddb/index.js +381 -0
- package/dist/adapters/indexeddb/index.mjs +326 -0
- package/dist/chunk-JMYU5QAK.mjs +40 -0
- package/dist/chunk-Y6LNYJAJ.mjs +1242 -0
- package/dist/index-JYVjYJtf.d.mts +353 -0
- package/dist/index-JYVjYJtf.d.ts +353 -0
- package/dist/index.d.mts +4745 -2971
- package/dist/index.d.ts +4745 -2971
- package/dist/index.js +6319 -3431
- package/dist/index.mjs +4884 -3259
- package/dist/secretStore-CF6Nse__.d.mts +292 -0
- package/dist/secretStore-CF6Nse__.d.ts +292 -0
- package/dist/wallet/worker/index.d.mts +1 -0
- package/dist/wallet/worker/index.d.ts +1 -0
- package/dist/wallet/worker/index.js +859 -0
- package/dist/wallet/worker/index.mjs +28 -0
- package/package.json +24 -7
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a note IS.
|
|
3
|
+
*
|
|
4
|
+
* The protocol's own vocabulary: a note, the inputs that build one, and the
|
|
5
|
+
* plaintext recovered from its memo. Nothing here describes an extrinsic — the
|
|
6
|
+
* argument shapes the pallet accepts live in `pallet/extrinsicParams.ts`,
|
|
7
|
+
* because a wallet can build, decrypt and select notes without ever submitting
|
|
8
|
+
* anything.
|
|
9
|
+
*/
|
|
10
|
+
/** On-chain Merkle tree state for the shielded pool. */
|
|
11
|
+
type MerkleTreeInfo = {
|
|
12
|
+
/** 0x-prefixed current Merkle root hex. */
|
|
13
|
+
root: string;
|
|
14
|
+
/** Number of leaves (commitments) inserted so far. */
|
|
15
|
+
treeSize: number;
|
|
16
|
+
/** Tree depth (levels from leaf to root). */
|
|
17
|
+
depth: number;
|
|
18
|
+
};
|
|
19
|
+
/** A commitment surfaced by the indexer scan feed, for trial-decryption. */
|
|
20
|
+
type ScanCommitment = {
|
|
21
|
+
/** 0x-prefixed 32-byte commitment hex. */
|
|
22
|
+
commitmentHex: string;
|
|
23
|
+
/** Leaf position of the commitment in the Merkle tree. */
|
|
24
|
+
leafIndex: number;
|
|
25
|
+
/** 0x-prefixed encrypted memo hex, or null if none was published. */
|
|
26
|
+
encryptedMemo: string | null;
|
|
27
|
+
};
|
|
28
|
+
/** Plaintext fields recovered from a note's encrypted memo. */
|
|
29
|
+
type DecryptedMemo = {
|
|
30
|
+
/** Note amount in planck. */
|
|
31
|
+
value: bigint;
|
|
32
|
+
/** Owner's BabyJubJub Ax coordinate. */
|
|
33
|
+
ownerPk: bigint;
|
|
34
|
+
/** Blinding scalar used in the commitment. */
|
|
35
|
+
blinding: bigint;
|
|
36
|
+
/** Asset ID of the note. */
|
|
37
|
+
assetId: bigint;
|
|
38
|
+
/** Counterparty BabyJubJub Ax coordinate. Zero for shield/unshield notes. */
|
|
39
|
+
counterpartyPk: bigint;
|
|
40
|
+
/** ZK circuit version the note is spent under, recovered from the memo plaintext. */
|
|
41
|
+
circuitVersion: number;
|
|
42
|
+
};
|
|
43
|
+
/** Input params for NoteBuilder.build(). All fields except value have defaults. */
|
|
44
|
+
type NoteInput = {
|
|
45
|
+
/** Amount in planck (required). */
|
|
46
|
+
value: bigint;
|
|
47
|
+
/** Asset ID — default 0 (native ORB-Privacy). */
|
|
48
|
+
assetId?: bigint;
|
|
49
|
+
/** BabyJubJub Ax coordinate (owner public key x). Default 0n. */
|
|
50
|
+
ownerPk?: bigint;
|
|
51
|
+
/** Random blinding scalar. Defaults to BigInt(Date.now()). */
|
|
52
|
+
blinding?: bigint;
|
|
53
|
+
/** Secret spending key used to derive the nullifier. Default 0n. */
|
|
54
|
+
spendingKey?: bigint;
|
|
55
|
+
/**
|
|
56
|
+
* 32-byte LE-encoded packed BJJ viewing public key of the recipient (from their privacy address).
|
|
57
|
+
* When provided, NoteBuilder.build() will auto-generate the 180-byte ECDH-encrypted memo.
|
|
58
|
+
* Omit to skip memo generation (use buildMemo() separately if needed).
|
|
59
|
+
*/
|
|
60
|
+
viewingPublicKey?: Uint8Array;
|
|
61
|
+
/**
|
|
62
|
+
* BabyJubJub Ax coordinate of the recipient (from their privacy address).
|
|
63
|
+
* Required together with viewingPublicKey to enable stealth address derivation:
|
|
64
|
+
* the commitment will use stealthOwnerPk instead of ownerPk, making each
|
|
65
|
+
* transaction unlinkable even when the same privacy address is reused.
|
|
66
|
+
*/
|
|
67
|
+
recipientOwnerPk?: bigint;
|
|
68
|
+
/** Counterparty BabyJubJub Ax coordinate. Zero for shield/unshield notes. Default 0n. */
|
|
69
|
+
counterpartyPk?: bigint;
|
|
70
|
+
/** Circuit version to stamp on the note. Defaults to `CURRENT_CIRCUIT_VERSION`. */
|
|
71
|
+
circuitVersion?: number;
|
|
72
|
+
/**
|
|
73
|
+
* 32-byte ephemeral secret for the memo ECDH. Self-notes pass a
|
|
74
|
+
* deterministic one (deriveSelfEphSk) so a cold restore recognizes them by
|
|
75
|
+
* ephPk equality with no trial ECDH. Ignored on the stealth path (it
|
|
76
|
+
* generates its own coordinated ephSk). Default: random.
|
|
77
|
+
*/
|
|
78
|
+
ephSkOverride?: Uint8Array;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Circuit version notes are created under today. A note carries its version
|
|
82
|
+
* (`ZkNote.circuitVersion`) so that, after a VK rotation, it is always proven
|
|
83
|
+
* and verified against the circuit that created it. Only one version exists
|
|
84
|
+
* today; callers may pass the chain's active version explicitly.
|
|
85
|
+
*/
|
|
86
|
+
declare const CURRENT_CIRCUIT_VERSION = 1;
|
|
87
|
+
/**
|
|
88
|
+
* Computed ZK note (commitment + nullifier). Built entirely off-chain.
|
|
89
|
+
*
|
|
90
|
+
* commitment = Poseidon(value, assetId, ownerPk, blinding)
|
|
91
|
+
* nullifier = Poseidon(commitment, spendingKey)
|
|
92
|
+
*/
|
|
93
|
+
type ZkNote = {
|
|
94
|
+
/** Note amount in planck. */
|
|
95
|
+
value: bigint;
|
|
96
|
+
/** Asset ID of the note. */
|
|
97
|
+
assetId: bigint;
|
|
98
|
+
/** Owner's BabyJubJub Ax coordinate (or stealth owner Pk for stealth notes). */
|
|
99
|
+
ownerPk: bigint;
|
|
100
|
+
/** Blinding scalar mixed into the commitment. */
|
|
101
|
+
blinding: bigint;
|
|
102
|
+
/** Secret spending key used to derive the nullifier. */
|
|
103
|
+
spendingKey: bigint;
|
|
104
|
+
/** Circuit version this note was created under (see `CURRENT_CIRCUIT_VERSION`). Required. */
|
|
105
|
+
circuitVersion: number;
|
|
106
|
+
/**
|
|
107
|
+
* Global Merkle leaf index, when known. Optional so pre-forest vaults
|
|
108
|
+
* need no migration: notes without it predate the first tree seal and
|
|
109
|
+
* belong to tree 0. Populated on shield and on scan; used only to derive
|
|
110
|
+
* the forest tree for same-tree coin selection (`treeIdOf`).
|
|
111
|
+
*/
|
|
112
|
+
leafIndex?: number;
|
|
113
|
+
/** Whether the note has been spent/nullified on-chain. */
|
|
114
|
+
spent: boolean;
|
|
115
|
+
/** Local timestamp when this note was marked spent, or null if still active/unknown. */
|
|
116
|
+
spentAt: number | null;
|
|
117
|
+
/** Poseidon commitment scalar. */
|
|
118
|
+
commitment: bigint;
|
|
119
|
+
/** Poseidon nullifier scalar. */
|
|
120
|
+
nullifier: bigint;
|
|
121
|
+
/** 0x-prefixed 32-byte little-endian hex commitment. */
|
|
122
|
+
commitmentHex: string;
|
|
123
|
+
/** 0x-prefixed 32-byte little-endian hex nullifier. */
|
|
124
|
+
nullifierHex: string;
|
|
125
|
+
/**
|
|
126
|
+
* 180-byte encrypted memo (ChaCha20-Poly1305 ECDH) as number[] for SCALE encoding.
|
|
127
|
+
* Always populated: uses a dummy memo when no viewingPublicKey is provided.
|
|
128
|
+
*/
|
|
129
|
+
memo: number[];
|
|
130
|
+
/** Counterparty BabyJubJub Ax coordinate. Zero for shield/unshield notes. */
|
|
131
|
+
counterpartyPk: bigint;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* What crosses the worker boundary.
|
|
136
|
+
*
|
|
137
|
+
* Every value here must survive structured clone: it travels through
|
|
138
|
+
* `postMessage` to a worker and back. That rules out classes, functions and
|
|
139
|
+
* bigint-keyed maps — `bigint` itself is fine, `Uint8Array` is fine, anything
|
|
140
|
+
* with a prototype is not.
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Self-note discovery window: how many deterministic ephemeral indexes to
|
|
145
|
+
* precompute. BIP-44-style gap limit — a wallet with more self-created notes
|
|
146
|
+
* than this still finds the excess through the trial-decrypt path (correct,
|
|
147
|
+
* just slower) until the counter syncs. Fixed size, no extension loop; add
|
|
148
|
+
* one when a real wallet approaches this many self notes.
|
|
149
|
+
*/
|
|
150
|
+
declare const SELF_EPH_WINDOW = 1024;
|
|
151
|
+
/**
|
|
152
|
+
* Per-counterparty discovery window. Much smaller than the self window: this
|
|
153
|
+
* counts payments from ONE sender, and a sender who outruns it just falls back
|
|
154
|
+
* to the trial-decrypt path — correct, only slower — until the counter syncs.
|
|
155
|
+
* The window costs two EC muls per index per sender, so it is the one number
|
|
156
|
+
* that scales with how many people the wallet knows.
|
|
157
|
+
*/
|
|
158
|
+
declare const PAIRWISE_EPH_WINDOW = 64;
|
|
159
|
+
/** Wallet keys needed for trial-decryption. Structured-clone transferable. */
|
|
160
|
+
interface ScanKeys {
|
|
161
|
+
viewingKey: Uint8Array;
|
|
162
|
+
spendingKey: bigint;
|
|
163
|
+
ownerPk: bigint;
|
|
164
|
+
/**
|
|
165
|
+
* First leafIndex from which every memo carries a view tag — hints at/after
|
|
166
|
+
* it go through the 1-byte fast-scan filter (skip the AEAD decrypt on
|
|
167
|
+
* mismatch). null/undefined = filter off (network not activated yet).
|
|
168
|
+
*/
|
|
169
|
+
viewTagActivationLeaf?: number | null;
|
|
170
|
+
/**
|
|
171
|
+
* Enable self-note discovery: precompute the deterministic ephPk window and
|
|
172
|
+
* recognize the wallet's own notes (shields, change) by hash lookup — zero
|
|
173
|
+
* trial ECDH for them. Only worth its one-time window cost (two EC muls
|
|
174
|
+
* per index) on full scans/restores; leave off for incremental ticks.
|
|
175
|
+
*/
|
|
176
|
+
selfEph?: boolean;
|
|
177
|
+
/** Window size override (tests/tuning). Default SELF_EPH_WINDOW. */
|
|
178
|
+
selfEphWindowSize?: number;
|
|
179
|
+
/**
|
|
180
|
+
* Counterparties whose future payments can be recognized without an ECDH.
|
|
181
|
+
*
|
|
182
|
+
* A sender's key travels in the plaintext of the first payment they make us,
|
|
183
|
+
* so once that one is decrypted the normal way, every later note from them
|
|
184
|
+
* carries an ephemeral both sides derive — found by the same hash lookup as a
|
|
185
|
+
* self note. A stranger's first payment is unaffected.
|
|
186
|
+
*
|
|
187
|
+
* Each entry is one packed viewing public key. Matching happens entirely on
|
|
188
|
+
* this device: asking a server for a specific ephPk would tell it which notes
|
|
189
|
+
* are ours, which is exactly what the download-everything feed prevents.
|
|
190
|
+
*/
|
|
191
|
+
pairwiseCounterparties?: Uint8Array[];
|
|
192
|
+
/** Per-counterparty window size. Default PAIRWISE_EPH_WINDOW. */
|
|
193
|
+
pairwiseWindowSize?: number;
|
|
194
|
+
}
|
|
195
|
+
interface DecryptBatchResult {
|
|
196
|
+
/** One entry per hint, aligned with the input order (null = not ours). */
|
|
197
|
+
notes: Array<ZkNote | null>;
|
|
198
|
+
/** Hints discarded by the view-tag check alone — no AEAD work attempted. */
|
|
199
|
+
tagFiltered: number;
|
|
200
|
+
/** Hints recognized as own self-notes via the deterministic ephPk window. */
|
|
201
|
+
selfMatched: number;
|
|
202
|
+
/**
|
|
203
|
+
* Hints recognized as coming from a known counterparty, via that sender's
|
|
204
|
+
* precomputed window. Counted apart from `selfMatched` because it answers a
|
|
205
|
+
* different question: whether the pairwise mechanism actually fired, or
|
|
206
|
+
* whether those notes quietly fell through to the expensive path.
|
|
207
|
+
*/
|
|
208
|
+
pairwiseMatched: number;
|
|
209
|
+
/** Highest self-eph index seen (feeds the counter bump), or null. */
|
|
210
|
+
maxSelfEphIndex: number | null;
|
|
211
|
+
}
|
|
212
|
+
/** An empty result — the shape both pool strategies return for zero hints. */
|
|
213
|
+
declare const EMPTY_BATCH_RESULT: DecryptBatchResult;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Trial-decrypts every hint against the wallet's keys. Returns one entry per
|
|
217
|
+
* hint, aligned with the input order: the recovered note, or null when the
|
|
218
|
+
* hint isn't ours (MAC failure, view-tag mismatch) or is malformed — a single
|
|
219
|
+
* bad hint must not kill the batch, the scan just counts it as failed.
|
|
220
|
+
*
|
|
221
|
+
* Order per hint: self-note window match (hash lookup, no EC) → view-tag
|
|
222
|
+
* fast path (one ECDH, one byte) → full trial-decrypt.
|
|
223
|
+
*/
|
|
224
|
+
declare function decryptHintBatch(hints: Array<ScanCommitment & {
|
|
225
|
+
ephPkHex?: string | null;
|
|
226
|
+
}>, keys: ScanKeys): DecryptBatchResult;
|
|
227
|
+
|
|
228
|
+
/** Which precomputed window recognized a hint — the two differ in what they prove. */
|
|
229
|
+
type MatchSource = 'self' | 'pairwise';
|
|
230
|
+
interface KnownEphEntry {
|
|
231
|
+
sharedSecret: Uint8Array;
|
|
232
|
+
index: number;
|
|
233
|
+
source: MatchSource;
|
|
234
|
+
}
|
|
235
|
+
interface KnownEphWindow {
|
|
236
|
+
/** ephPkHex (lowercase) → entry. */
|
|
237
|
+
byEphPk: Map<string, KnownEphEntry>;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Drops the precomputed discovery window and the shared secrets in it.
|
|
241
|
+
*
|
|
242
|
+
* Call when the wallet locks. The cache is keyed by spending key, so it can
|
|
243
|
+
* never serve a different identity — but "cannot be misused" is not "is gone":
|
|
244
|
+
* after `lock()` the session keys are dropped while ~100 KB of ECDH secrets
|
|
245
|
+
* derived from the viewing key stay reachable in module memory, and on a
|
|
246
|
+
* main-thread pool that is the page's own heap.
|
|
247
|
+
*
|
|
248
|
+
* Terminating a worker achieves the same thing by discarding the whole realm.
|
|
249
|
+
* This exists for the main-thread pool, which has no realm to discard, and for
|
|
250
|
+
* hosts that keep their workers warm across a lock.
|
|
251
|
+
*/
|
|
252
|
+
declare function clearKnownEphWindow(): void;
|
|
253
|
+
/**
|
|
254
|
+
* The window for these keys, built on first use and cached after.
|
|
255
|
+
*
|
|
256
|
+
* Returns null when discovery is off entirely (no self-eph, no counterparties)
|
|
257
|
+
* or when the primitives are unavailable — the scan then takes the trial-decrypt
|
|
258
|
+
* path for everything, which is slower but correct.
|
|
259
|
+
*/
|
|
260
|
+
declare function getKnownEphWindow(keys: ScanKeys): KnownEphWindow | null;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* The pool contract, and the minimal Worker surface it drives.
|
|
264
|
+
*
|
|
265
|
+
* `WorkerLike` is deliberately narrower than the DOM `Worker`: the pool only
|
|
266
|
+
* ever posts a message, reads one back, and terminates. Keeping it to those
|
|
267
|
+
* four members is what lets a test pass a fake that runs the kernel inline, and
|
|
268
|
+
* what keeps this file free of `lib.dom`.
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
/** Cap on pool size — EC math parallelizes linearly but tabs share the CPU. */
|
|
272
|
+
/**
|
|
273
|
+
* Ceiling on workers per batch. Past four the ECDH loop is bound by memory
|
|
274
|
+
* bandwidth rather than cores, and every extra worker still costs its own copy
|
|
275
|
+
* of the precomputed discovery window.
|
|
276
|
+
*/
|
|
277
|
+
declare const MAX_WORKERS = 4;
|
|
278
|
+
/**
|
|
279
|
+
* Main-thread strategy only: trial-decrypts to run before yielding so the
|
|
280
|
+
* browser can paint between bursts of synchronous EC math.
|
|
281
|
+
*/
|
|
282
|
+
declare const DECRYPT_YIELD_EVERY = 25;
|
|
283
|
+
/**
|
|
284
|
+
* The message a worker hands back, structurally.
|
|
285
|
+
*
|
|
286
|
+
* Not `MessageEvent`: that name lives in `lib.dom`, and naming it here would put
|
|
287
|
+
* it in the published `.d.ts` of the ROOT entry — so a React Native consumer
|
|
288
|
+
* compiling with `lib: esnext` and no `@types/node` would fail to typecheck an
|
|
289
|
+
* import it never asked for. `data` is the only member the pool reads, and a
|
|
290
|
+
* real `MessageEvent` satisfies this shape.
|
|
291
|
+
*
|
|
292
|
+
* Same reasoning as `CryptoKey` in `utils/crypto/webcrypto-types.d.ts`.
|
|
293
|
+
*/
|
|
294
|
+
interface WorkerMessage {
|
|
295
|
+
data: unknown;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* The minimal Worker surface the pool needs — a real Worker or a test fake.
|
|
299
|
+
*
|
|
300
|
+
* The handler parameters are typed `any` rather than `unknown`, which is the
|
|
301
|
+
* one place this file trades strictness for reach. A DOM `Worker` declares
|
|
302
|
+
* `onerror` as `(event: ErrorEvent) => void`, and function parameters are
|
|
303
|
+
* contravariant: a handler accepting `unknown` is NOT assignable where one
|
|
304
|
+
* accepting `ErrorEvent` is expected. Typing these as `unknown` therefore makes
|
|
305
|
+
* a real browser `Worker` fail to satisfy the interface — the exact consumer
|
|
306
|
+
* this contract exists to serve.
|
|
307
|
+
*
|
|
308
|
+
* `any` keeps both a real Worker and an inline fake assignable while still
|
|
309
|
+
* keeping `MessageEvent`/`ErrorEvent` — both `lib.dom` — out of the published
|
|
310
|
+
* types. The pool reads only `event.data` and ignores the error payload
|
|
311
|
+
* entirely, so nothing downstream depends on the precision given up here.
|
|
312
|
+
*/
|
|
313
|
+
interface WorkerLike {
|
|
314
|
+
postMessage(message: unknown): void;
|
|
315
|
+
onmessage: ((event: any) => void) | null;
|
|
316
|
+
/** Error payload is unused: the pool treats any error as "worker died". */
|
|
317
|
+
onerror: ((event: any) => void) | null;
|
|
318
|
+
terminate(): void;
|
|
319
|
+
}
|
|
320
|
+
type WorkerFactory = () => WorkerLike;
|
|
321
|
+
interface DecryptPool {
|
|
322
|
+
/** Decrypts `hints` in input order. Rejects with AbortError when cancelled. */
|
|
323
|
+
decryptBatch(hints: ScanCommitment[], keys: ScanKeys, signal?: AbortSignal): Promise<DecryptBatchResult>;
|
|
324
|
+
/** Tears down every worker. The pool is per-scan; always call when done. */
|
|
325
|
+
terminate(): void;
|
|
326
|
+
}
|
|
327
|
+
/** The message a worker receives. Structured-clone friendly by construction. */
|
|
328
|
+
interface DecryptRequest {
|
|
329
|
+
hints: ScanCommitment[];
|
|
330
|
+
keys: ScanKeys;
|
|
331
|
+
}
|
|
332
|
+
/** Thrown when a worker dies mid-batch; the factory catches it to fall back. */
|
|
333
|
+
declare const WORKER_CRASHED = "Decrypt worker crashed";
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Builds the decrypt pool for one scan run.
|
|
337
|
+
*
|
|
338
|
+
* `factory` is required rather than defaulted: constructing a worker means
|
|
339
|
+
* naming a module URL, which only the host's bundler can resolve. Pass `null`
|
|
340
|
+
* to decrypt on the calling thread — correct everywhere, and the only option
|
|
341
|
+
* outside a browser.
|
|
342
|
+
*/
|
|
343
|
+
declare function createDecryptPool(options: {
|
|
344
|
+
factory: WorkerFactory | null;
|
|
345
|
+
/** Workers to spread a batch across. Defaults to `MAX_WORKERS`. */
|
|
346
|
+
size?: number;
|
|
347
|
+
}): DecryptPool;
|
|
348
|
+
|
|
349
|
+
declare function createMainThreadPool(): DecryptPool;
|
|
350
|
+
|
|
351
|
+
declare function createWorkerPool(factory: WorkerFactory, size: number): DecryptPool;
|
|
352
|
+
|
|
353
|
+
export { CURRENT_CIRCUIT_VERSION as C, type DecryptedMemo as D, EMPTY_BATCH_RESULT as E, type KnownEphEntry as K, MAX_WORKERS as M, type NoteInput as N, PAIRWISE_EPH_WINDOW as P, type ScanCommitment as S, WORKER_CRASHED as W, type ZkNote as Z, type DecryptPool as a, type ScanKeys as b, DECRYPT_YIELD_EVERY as c, type DecryptBatchResult as d, type DecryptRequest as e, type KnownEphWindow as f, type MatchSource as g, type MerkleTreeInfo as h, SELF_EPH_WINDOW as i, type WorkerFactory as j, type WorkerLike as k, type WorkerMessage as l, clearKnownEphWindow as m, createDecryptPool as n, createMainThreadPool as o, createWorkerPool as p, decryptHintBatch as q, getKnownEphWindow as r };
|