@zama-fhe/sdk 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.
@@ -0,0 +1,317 @@
1
+ import { BaseWorkerClient, EncryptionFailedError, TokenError } from '../chunk-VRLLWHHL.js';
2
+ import { mergeFhevmConfig, buildEIP712DomainType, withRetry } from '../chunk-UE6IBC3M.js';
3
+ export { HardhatConfig, MainnetConfig, SepoliaConfig } from '../chunk-UE6IBC3M.js';
4
+ import { availableParallelism } from 'os';
5
+ import { Worker } from 'worker_threads';
6
+ import { randomUUID } from 'crypto';
7
+
8
+ var NodeWorkerClient = class extends BaseWorkerClient {
9
+ constructor(config) {
10
+ super(config, config.logger);
11
+ }
12
+ createWorker() {
13
+ return new Worker(new URL("./relayer-sdk.node-worker.js", import.meta.url));
14
+ }
15
+ wireEvents(worker) {
16
+ worker.on("message", (response) => this.handleResponse(response));
17
+ worker.on("error", (error) => this.handleWorkerError(error.message));
18
+ worker.on("messageerror", () => this.handleWorkerMessageError());
19
+ }
20
+ postMessage(worker, request) {
21
+ worker.postMessage(request);
22
+ }
23
+ terminateWorker(worker) {
24
+ worker.terminate();
25
+ }
26
+ generateRequestId() {
27
+ return randomUUID();
28
+ }
29
+ getInitPayload() {
30
+ return {
31
+ type: "NODE_INIT",
32
+ payload: { fhevmConfig: this.config.fhevmConfig }
33
+ };
34
+ }
35
+ onWorkerReady(worker) {
36
+ worker.unref();
37
+ }
38
+ };
39
+
40
+ // src/worker/worker.node-pool.ts
41
+ var MAX_DEFAULT_POOL_SIZE = 4;
42
+ var NodeWorkerPool = class {
43
+ #workers = [];
44
+ #activeCount = [];
45
+ #config;
46
+ #poolSize;
47
+ #initPromise = null;
48
+ /**
49
+ * @param config - Pool configuration. Set `poolSize` to override the default
50
+ * (`min(os.availableParallelism(), 4)`).
51
+ */
52
+ constructor(config) {
53
+ this.#config = config;
54
+ this.#poolSize = config.poolSize ?? Math.min(availableParallelism(), MAX_DEFAULT_POOL_SIZE);
55
+ }
56
+ get poolSize() {
57
+ return this.#poolSize;
58
+ }
59
+ async initPool() {
60
+ if (this.#workers.length > 0) return;
61
+ if (!this.#initPromise) {
62
+ this.#initPromise = this.#doInitPool().finally(() => {
63
+ this.#initPromise = null;
64
+ });
65
+ }
66
+ return this.#initPromise;
67
+ }
68
+ async #doInitPool() {
69
+ for (let i = 0; i < this.#poolSize; i++) {
70
+ this.#workers.push(new NodeWorkerClient(this.#config));
71
+ this.#activeCount.push(0);
72
+ }
73
+ try {
74
+ await Promise.all(this.#workers.map((w) => w.initWorker()));
75
+ } catch (error) {
76
+ for (const worker of this.#workers) {
77
+ worker.terminate();
78
+ }
79
+ this.#workers.length = 0;
80
+ this.#activeCount.length = 0;
81
+ throw error;
82
+ }
83
+ }
84
+ terminate() {
85
+ for (const worker of this.#workers) {
86
+ worker.terminate();
87
+ }
88
+ this.#workers.length = 0;
89
+ this.#activeCount.length = 0;
90
+ }
91
+ /**
92
+ * Pick the worker with the fewest in-flight requests (least-connections).
93
+ * Returns the index so #dispatch can track the active count.
94
+ */
95
+ #leastBusyIndex() {
96
+ let minIndex = 0;
97
+ let minCount = this.#activeCount[0];
98
+ for (let i = 1; i < this.#activeCount.length; i++) {
99
+ if (this.#activeCount[i] < minCount) {
100
+ minCount = this.#activeCount[i];
101
+ minIndex = i;
102
+ }
103
+ }
104
+ return minIndex;
105
+ }
106
+ async #dispatch(fn) {
107
+ if (this.#workers.length === 0) {
108
+ throw new Error("NodeWorkerPool not initialized. Call initPool() first.");
109
+ }
110
+ const index = this.#leastBusyIndex();
111
+ this.#activeCount[index]++;
112
+ try {
113
+ return await fn(this.#workers[index]);
114
+ } finally {
115
+ this.#activeCount[index]--;
116
+ }
117
+ }
118
+ async generateKeypair() {
119
+ return this.#dispatch((w) => w.generateKeypair());
120
+ }
121
+ async createEIP712(params) {
122
+ return this.#dispatch((w) => w.createEIP712(params));
123
+ }
124
+ async encrypt(params) {
125
+ return this.#dispatch((w) => w.encrypt(params));
126
+ }
127
+ async userDecrypt(params) {
128
+ return this.#dispatch((w) => w.userDecrypt(params));
129
+ }
130
+ async publicDecrypt(handles) {
131
+ return this.#dispatch((w) => w.publicDecrypt(handles));
132
+ }
133
+ async createDelegatedUserDecryptEIP712(params) {
134
+ return this.#dispatch((w) => w.createDelegatedUserDecryptEIP712(params));
135
+ }
136
+ async delegatedUserDecrypt(params) {
137
+ return this.#dispatch((w) => w.delegatedUserDecrypt(params));
138
+ }
139
+ async requestZKProofVerification(zkProof) {
140
+ return this.#dispatch((w) => w.requestZKProofVerification(zkProof));
141
+ }
142
+ async getPublicKey() {
143
+ return this.#dispatch((w) => w.getPublicKey());
144
+ }
145
+ async getPublicParams(bits) {
146
+ return this.#dispatch((w) => w.getPublicParams(bits));
147
+ }
148
+ };
149
+
150
+ // src/relayer/relayer-node.ts
151
+ var RelayerNode = class {
152
+ #config;
153
+ #pool = null;
154
+ #initPromise = null;
155
+ #ensureLock = null;
156
+ #terminated = false;
157
+ #resolvedChainId = null;
158
+ constructor(config) {
159
+ this.#config = config;
160
+ }
161
+ async #getPoolConfig() {
162
+ const chainId = await this.#config.getChainId();
163
+ const { transports, poolSize } = this.#config;
164
+ return {
165
+ fhevmConfig: mergeFhevmConfig(chainId, transports[chainId]),
166
+ poolSize,
167
+ logger: this.#config.logger
168
+ };
169
+ }
170
+ async #ensurePool() {
171
+ if (this.#ensureLock) return this.#ensureLock;
172
+ this.#ensureLock = this.#ensurePoolInner();
173
+ try {
174
+ return await this.#ensureLock;
175
+ } finally {
176
+ this.#ensureLock = null;
177
+ }
178
+ }
179
+ async #ensurePoolInner() {
180
+ if (this.#terminated) {
181
+ throw new EncryptionFailedError("RelayerNode has been terminated");
182
+ }
183
+ const chainId = await this.#config.getChainId();
184
+ if (this.#resolvedChainId !== null && chainId !== this.#resolvedChainId) {
185
+ this.#pool?.terminate();
186
+ this.#pool = null;
187
+ this.#initPromise = null;
188
+ }
189
+ this.#resolvedChainId = chainId;
190
+ if (!this.#initPromise) {
191
+ this.#initPromise = this.#initPool().catch((error) => {
192
+ this.#initPromise = null;
193
+ throw error instanceof TokenError ? error : new EncryptionFailedError("Failed to initialize FHE worker pool", {
194
+ cause: error instanceof Error ? error : void 0
195
+ });
196
+ });
197
+ }
198
+ return this.#initPromise;
199
+ }
200
+ async #initPool() {
201
+ const poolConfig = await this.#getPoolConfig();
202
+ const pool = new NodeWorkerPool(poolConfig);
203
+ await pool.initPool();
204
+ if (this.#terminated) {
205
+ pool.terminate();
206
+ throw new Error("RelayerNode was terminated during initialization");
207
+ }
208
+ this.#pool = pool;
209
+ return pool;
210
+ }
211
+ terminate() {
212
+ this.#terminated = true;
213
+ if (this.#pool) {
214
+ this.#pool.terminate();
215
+ this.#pool = null;
216
+ }
217
+ this.#initPromise = null;
218
+ this.#ensureLock = null;
219
+ }
220
+ async generateKeypair() {
221
+ const pool = await this.#ensurePool();
222
+ const result = await pool.generateKeypair();
223
+ return {
224
+ publicKey: result.publicKey,
225
+ privateKey: result.privateKey
226
+ };
227
+ }
228
+ async createEIP712(publicKey, contractAddresses, startTimestamp, durationDays = 7) {
229
+ const pool = await this.#ensurePool();
230
+ const result = await pool.createEIP712({
231
+ publicKey,
232
+ contractAddresses,
233
+ startTimestamp,
234
+ durationDays
235
+ });
236
+ const domain = {
237
+ name: result.domain.name,
238
+ version: result.domain.version,
239
+ chainId: result.domain.chainId,
240
+ verifyingContract: result.domain.verifyingContract
241
+ };
242
+ return {
243
+ domain,
244
+ types: {
245
+ EIP712Domain: buildEIP712DomainType(domain),
246
+ UserDecryptRequestVerification: result.types.UserDecryptRequestVerification
247
+ },
248
+ message: {
249
+ publicKey: result.message.publicKey,
250
+ contractAddresses: result.message.contractAddresses,
251
+ startTimestamp: result.message.startTimestamp,
252
+ durationDays: result.message.durationDays,
253
+ extraData: result.message.extraData
254
+ }
255
+ };
256
+ }
257
+ async encrypt(params) {
258
+ return withRetry(async () => {
259
+ const pool = await this.#ensurePool();
260
+ const result = await pool.encrypt(params);
261
+ return { handles: result.handles, inputProof: result.inputProof };
262
+ });
263
+ }
264
+ async userDecrypt(params) {
265
+ return withRetry(async () => {
266
+ const pool = await this.#ensurePool();
267
+ const result = await pool.userDecrypt(params);
268
+ return result.clearValues;
269
+ });
270
+ }
271
+ async publicDecrypt(handles) {
272
+ return withRetry(async () => {
273
+ const pool = await this.#ensurePool();
274
+ const result = await pool.publicDecrypt(handles);
275
+ return {
276
+ clearValues: result.clearValues,
277
+ abiEncodedClearValues: result.abiEncodedClearValues,
278
+ decryptionProof: result.decryptionProof
279
+ };
280
+ });
281
+ }
282
+ async createDelegatedUserDecryptEIP712(publicKey, contractAddresses, delegatorAddress, startTimestamp, durationDays = 7) {
283
+ const pool = await this.#ensurePool();
284
+ return pool.createDelegatedUserDecryptEIP712({
285
+ publicKey,
286
+ contractAddresses,
287
+ delegatorAddress,
288
+ startTimestamp,
289
+ durationDays
290
+ });
291
+ }
292
+ async delegatedUserDecrypt(params) {
293
+ return withRetry(async () => {
294
+ const pool = await this.#ensurePool();
295
+ const result = await pool.delegatedUserDecrypt(params);
296
+ return result.clearValues;
297
+ });
298
+ }
299
+ async requestZKProofVerification(zkProof) {
300
+ return withRetry(async () => {
301
+ const pool = await this.#ensurePool();
302
+ return pool.requestZKProofVerification(zkProof);
303
+ });
304
+ }
305
+ async getPublicKey() {
306
+ const pool = await this.#ensurePool();
307
+ return (await pool.getPublicKey()).result;
308
+ }
309
+ async getPublicParams(bits) {
310
+ const pool = await this.#ensurePool();
311
+ return (await pool.getPublicParams(bits)).result;
312
+ }
313
+ };
314
+
315
+ export { NodeWorkerClient, NodeWorkerPool, RelayerNode };
316
+ //# sourceMappingURL=index.js.map
317
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/worker/worker.node-client.ts","../../src/worker/worker.node-pool.ts","../../src/relayer/relayer-node.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { Worker } from \"node:worker_threads\";\nimport { randomUUID } from \"node:crypto\";\nimport type { FhevmInstanceConfig } from \"../relayer/relayer-sdk.types\";\nimport type {\n GenericLogger,\n WorkerRequest,\n WorkerRequestType,\n WorkerResponse,\n} from \"./worker.types\";\nimport { BaseWorkerClient } from \"./worker.base-client\";\n\nexport interface NodeWorkerClientConfig {\n fhevmConfig: FhevmInstanceConfig;\n /** Optional logger for tracing worker request lifecycle. */\n logger?: GenericLogger;\n}\n\n/**\n * Client for communicating with the RelayerSDK Node.js worker thread.\n * Provides a promise-based API for FHE operations using node:worker_threads.\n */\nexport class NodeWorkerClient extends BaseWorkerClient<Worker, NodeWorkerClientConfig> {\n constructor(config: NodeWorkerClientConfig) {\n super(config, config.logger);\n }\n\n protected createWorker(): Worker {\n return new Worker(new URL(\"./relayer-sdk.node-worker.js\", import.meta.url));\n }\n\n protected wireEvents(worker: Worker): void {\n worker.on(\"message\", (response: WorkerResponse<unknown>) => this.handleResponse(response));\n worker.on(\"error\", (error: Error) => this.handleWorkerError(error.message));\n worker.on(\"messageerror\", () => this.handleWorkerMessageError());\n }\n\n protected postMessage(worker: Worker, request: WorkerRequest): void {\n worker.postMessage(request);\n }\n\n protected terminateWorker(worker: Worker): void {\n worker.terminate();\n }\n\n protected generateRequestId(): string {\n return randomUUID();\n }\n\n protected getInitPayload(): {\n type: WorkerRequestType;\n payload: WorkerRequest[\"payload\"];\n } {\n return {\n type: \"NODE_INIT\",\n payload: { fhevmConfig: this.config.fhevmConfig },\n };\n }\n\n protected onWorkerReady(worker: Worker): void {\n worker.unref();\n }\n}\n","import { availableParallelism } from \"node:os\";\nimport { NodeWorkerClient } from \"./worker.node-client\";\nimport type { NodeWorkerClientConfig } from \"./worker.node-client\";\nimport type { ZKProofLike } from \"../relayer/relayer-sdk.types\";\nimport type {\n CreateDelegatedEIP712Payload,\n CreateDelegatedEIP712ResponseData,\n CreateEIP712Payload,\n CreateEIP712ResponseData,\n DelegatedUserDecryptPayload,\n DelegatedUserDecryptResponseData,\n EncryptPayload,\n EncryptResponseData,\n GenerateKeypairResponseData,\n GetPublicKeyResponseData,\n GetPublicParamsResponseData,\n PublicDecryptResponseData,\n RequestZKProofVerificationResponseData,\n UserDecryptPayload,\n UserDecryptResponseData,\n} from \"./worker.types\";\n\nexport interface NodeWorkerPoolConfig extends NodeWorkerClientConfig {\n poolSize?: number;\n}\n\nconst MAX_DEFAULT_POOL_SIZE = 4;\n\n/**\n * Pool of Node.js worker threads for parallel FHE operations.\n *\n * **Default pool size:** `min(os.availableParallelism(), 4)`. Each worker loads\n * the full WASM module (~50–100 MB), so size the pool based on available memory.\n *\n * **Scheduling:** Least-connections — each request is dispatched to the worker\n * with the fewest in-flight operations.\n *\n * **When to override pool size:**\n * - High-throughput batch processing (e.g. bulk encryptions): increase to match CPU cores.\n * - Memory-constrained environments: decrease to 1–2 workers.\n *\n * **Lifecycle:**\n * 1. Construct with config: `new NodeWorkerPool({ fhevmConfig })`\n * 2. Initialize all workers: `await pool.initPool()`\n * 3. Use: `await pool.encrypt(...)`, `await pool.userDecrypt(...)`, etc.\n * 4. Shut down: `pool.terminate()`\n *\n * `initPool()` is idempotent — concurrent calls share the same initialization promise.\n * If any worker fails to initialize, all workers are terminated and the error is propagated.\n */\nexport class NodeWorkerPool {\n readonly #workers: NodeWorkerClient[] = [];\n readonly #activeCount: number[] = [];\n readonly #config: NodeWorkerPoolConfig;\n readonly #poolSize: number;\n #initPromise: Promise<void> | null = null;\n\n /**\n * @param config - Pool configuration. Set `poolSize` to override the default\n * (`min(os.availableParallelism(), 4)`).\n */\n constructor(config: NodeWorkerPoolConfig) {\n this.#config = config;\n this.#poolSize = config.poolSize ?? Math.min(availableParallelism(), MAX_DEFAULT_POOL_SIZE);\n }\n\n get poolSize(): number {\n return this.#poolSize;\n }\n\n async initPool(): Promise<void> {\n if (this.#workers.length > 0) return;\n if (!this.#initPromise) {\n this.#initPromise = this.#doInitPool().finally(() => {\n this.#initPromise = null;\n });\n }\n return this.#initPromise;\n }\n\n async #doInitPool(): Promise<void> {\n for (let i = 0; i < this.#poolSize; i++) {\n this.#workers.push(new NodeWorkerClient(this.#config));\n this.#activeCount.push(0);\n }\n try {\n await Promise.all(this.#workers.map((w) => w.initWorker()));\n } catch (error) {\n // Terminate any workers that did initialize and reset state\n for (const worker of this.#workers) {\n worker.terminate();\n }\n this.#workers.length = 0;\n this.#activeCount.length = 0;\n throw error;\n }\n }\n\n terminate(): void {\n for (const worker of this.#workers) {\n worker.terminate();\n }\n this.#workers.length = 0;\n this.#activeCount.length = 0;\n }\n\n /**\n * Pick the worker with the fewest in-flight requests (least-connections).\n * Returns the index so #dispatch can track the active count.\n */\n #leastBusyIndex(): number {\n let minIndex = 0;\n let minCount = this.#activeCount[0]!;\n for (let i = 1; i < this.#activeCount.length; i++) {\n if (this.#activeCount[i]! < minCount) {\n minCount = this.#activeCount[i]!;\n minIndex = i;\n }\n }\n return minIndex;\n }\n\n async #dispatch<T>(fn: (worker: NodeWorkerClient) => Promise<T>): Promise<T> {\n if (this.#workers.length === 0) {\n throw new Error(\"NodeWorkerPool not initialized. Call initPool() first.\");\n }\n const index = this.#leastBusyIndex();\n this.#activeCount[index]!++;\n try {\n return await fn(this.#workers[index]!);\n } finally {\n this.#activeCount[index]!--;\n }\n }\n\n async generateKeypair(): Promise<GenerateKeypairResponseData> {\n return this.#dispatch((w) => w.generateKeypair());\n }\n\n async createEIP712(params: CreateEIP712Payload): Promise<CreateEIP712ResponseData> {\n return this.#dispatch((w) => w.createEIP712(params));\n }\n\n async encrypt(params: EncryptPayload): Promise<EncryptResponseData> {\n return this.#dispatch((w) => w.encrypt(params));\n }\n\n async userDecrypt(params: UserDecryptPayload): Promise<UserDecryptResponseData> {\n return this.#dispatch((w) => w.userDecrypt(params));\n }\n\n async publicDecrypt(handles: string[]): Promise<PublicDecryptResponseData> {\n return this.#dispatch((w) => w.publicDecrypt(handles));\n }\n\n async createDelegatedUserDecryptEIP712(\n params: CreateDelegatedEIP712Payload,\n ): Promise<CreateDelegatedEIP712ResponseData> {\n return this.#dispatch((w) => w.createDelegatedUserDecryptEIP712(params));\n }\n\n async delegatedUserDecrypt(\n params: DelegatedUserDecryptPayload,\n ): Promise<DelegatedUserDecryptResponseData> {\n return this.#dispatch((w) => w.delegatedUserDecrypt(params));\n }\n\n async requestZKProofVerification(\n zkProof: ZKProofLike,\n ): Promise<RequestZKProofVerificationResponseData> {\n return this.#dispatch((w) => w.requestZKProofVerification(zkProof));\n }\n\n async getPublicKey(): Promise<GetPublicKeyResponseData> {\n return this.#dispatch((w) => w.getPublicKey());\n }\n\n async getPublicParams(bits: number): Promise<GetPublicParamsResponseData> {\n return this.#dispatch((w) => w.getPublicParams(bits));\n }\n}\n","import type { FhevmInstanceConfig } from \"@zama-fhe/relayer-sdk/node\";\nimport type { RelayerSDK } from \"./relayer-sdk\";\nimport { buildEIP712DomainType, mergeFhevmConfig, withRetry } from \"./relayer-utils\";\nimport { TokenError, EncryptionFailedError } from \"../token/errors\";\nimport type {\n Address,\n DelegatedUserDecryptParams,\n EIP712TypedData,\n EncryptParams,\n EncryptResult,\n FHEKeypair,\n InputProofBytesType,\n KmsDelegatedUserDecryptEIP712Type,\n PublicDecryptResult,\n UserDecryptParams,\n ZKProofLike,\n} from \"./relayer-sdk.types\";\nimport { NodeWorkerPool, type NodeWorkerPoolConfig } from \"../worker/worker.node-pool\";\n\nexport interface RelayerNodeConfig {\n transports: Record<number, Partial<FhevmInstanceConfig>>;\n /** Resolve the current chain ID. Called lazily before each operation; the pool is re-initialized when the value changes. */\n getChainId: () => Promise<number>;\n poolSize?: number;\n /** Optional logger for observing worker lifecycle and request timing. */\n logger?: import(\"../worker/worker.types\").GenericLogger;\n}\n\n/**\n * RelayerNode — Node.js FHE backend using a worker thread.\n * Offloads CPU-intensive WASM/FHE operations to a node:worker_threads worker.\n */\nexport class RelayerNode implements RelayerSDK {\n readonly #config: RelayerNodeConfig;\n #pool: NodeWorkerPool | null = null;\n #initPromise: Promise<NodeWorkerPool> | null = null;\n #ensureLock: Promise<NodeWorkerPool> | null = null;\n #terminated = false;\n #resolvedChainId: number | null = null;\n\n constructor(config: RelayerNodeConfig) {\n this.#config = config;\n }\n\n async #getPoolConfig(): Promise<NodeWorkerPoolConfig> {\n const chainId = await this.#config.getChainId();\n const { transports, poolSize } = this.#config;\n\n return {\n fhevmConfig: mergeFhevmConfig(chainId, transports[chainId]),\n poolSize,\n logger: this.#config.logger,\n };\n }\n\n async #ensurePool(): Promise<NodeWorkerPool> {\n if (this.#ensureLock) return this.#ensureLock;\n this.#ensureLock = this.#ensurePoolInner();\n try {\n return await this.#ensureLock;\n } finally {\n this.#ensureLock = null;\n }\n }\n\n async #ensurePoolInner(): Promise<NodeWorkerPool> {\n if (this.#terminated) {\n throw new EncryptionFailedError(\"RelayerNode has been terminated\");\n }\n\n const chainId = await this.#config.getChainId();\n\n // Chain changed → tear down old pool, re-init\n if (this.#resolvedChainId !== null && chainId !== this.#resolvedChainId) {\n this.#pool?.terminate();\n this.#pool = null;\n this.#initPromise = null;\n }\n\n this.#resolvedChainId = chainId;\n\n if (!this.#initPromise) {\n this.#initPromise = this.#initPool().catch((error) => {\n this.#initPromise = null;\n throw error instanceof TokenError\n ? error\n : new EncryptionFailedError(\"Failed to initialize FHE worker pool\", {\n cause: error instanceof Error ? error : undefined,\n });\n });\n }\n return this.#initPromise;\n }\n\n async #initPool(): Promise<NodeWorkerPool> {\n const poolConfig = await this.#getPoolConfig();\n const pool = new NodeWorkerPool(poolConfig);\n await pool.initPool();\n if (this.#terminated) {\n pool.terminate();\n throw new Error(\"RelayerNode was terminated during initialization\");\n }\n this.#pool = pool;\n return pool;\n }\n\n terminate(): void {\n this.#terminated = true;\n if (this.#pool) {\n this.#pool.terminate();\n this.#pool = null;\n }\n this.#initPromise = null;\n this.#ensureLock = null;\n }\n\n async generateKeypair(): Promise<FHEKeypair> {\n const pool = await this.#ensurePool();\n const result = await pool.generateKeypair();\n return {\n publicKey: result.publicKey,\n privateKey: result.privateKey,\n };\n }\n\n async createEIP712(\n publicKey: string,\n contractAddresses: Address[],\n startTimestamp: number,\n durationDays: number = 7,\n ): Promise<EIP712TypedData> {\n const pool = await this.#ensurePool();\n const result = await pool.createEIP712({\n publicKey,\n contractAddresses,\n startTimestamp,\n durationDays,\n });\n\n const domain = {\n name: result.domain.name,\n version: result.domain.version,\n chainId: result.domain.chainId,\n verifyingContract: result.domain.verifyingContract,\n };\n\n return {\n domain,\n types: {\n EIP712Domain: buildEIP712DomainType(domain),\n UserDecryptRequestVerification: result.types.UserDecryptRequestVerification,\n },\n message: {\n publicKey: result.message.publicKey,\n contractAddresses: result.message.contractAddresses,\n startTimestamp: result.message.startTimestamp,\n durationDays: result.message.durationDays,\n extraData: result.message.extraData,\n },\n };\n }\n\n async encrypt(params: EncryptParams): Promise<EncryptResult> {\n return withRetry(async () => {\n const pool = await this.#ensurePool();\n const result = await pool.encrypt(params);\n return { handles: result.handles, inputProof: result.inputProof };\n });\n }\n\n async userDecrypt(params: UserDecryptParams): Promise<Record<string, bigint>> {\n return withRetry(async () => {\n const pool = await this.#ensurePool();\n const result = await pool.userDecrypt(params);\n return result.clearValues;\n });\n }\n\n async publicDecrypt(handles: string[]): Promise<PublicDecryptResult> {\n return withRetry(async () => {\n const pool = await this.#ensurePool();\n const result = await pool.publicDecrypt(handles);\n return {\n clearValues: result.clearValues,\n abiEncodedClearValues: result.abiEncodedClearValues,\n decryptionProof: result.decryptionProof,\n };\n });\n }\n\n async createDelegatedUserDecryptEIP712(\n publicKey: string,\n contractAddresses: Address[],\n delegatorAddress: string,\n startTimestamp: number,\n durationDays: number = 7,\n ): Promise<KmsDelegatedUserDecryptEIP712Type> {\n const pool = await this.#ensurePool();\n return pool.createDelegatedUserDecryptEIP712({\n publicKey,\n contractAddresses,\n delegatorAddress,\n startTimestamp,\n durationDays,\n });\n }\n\n async delegatedUserDecrypt(params: DelegatedUserDecryptParams): Promise<Record<string, bigint>> {\n return withRetry(async () => {\n const pool = await this.#ensurePool();\n const result = await pool.delegatedUserDecrypt(params);\n return result.clearValues;\n });\n }\n\n async requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType> {\n return withRetry(async () => {\n const pool = await this.#ensurePool();\n return pool.requestZKProofVerification(zkProof);\n });\n }\n\n async getPublicKey(): Promise<{\n publicKeyId: string;\n publicKey: Uint8Array;\n } | null> {\n const pool = await this.#ensurePool();\n return (await pool.getPublicKey()).result;\n }\n\n async getPublicParams(\n bits: number,\n ): Promise<{ publicParams: Uint8Array; publicParamsId: string } | null> {\n const pool = await this.#ensurePool();\n return (await pool.getPublicParams(bits)).result;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,320 @@
1
+ import { convertToBigIntRecord } from './chunk-UE6IBC3M.js';
2
+ import { parentPort } from 'worker_threads';
3
+
4
+ if (!parentPort) {
5
+ throw new Error("This script must be run as a worker thread");
6
+ }
7
+ var port = parentPort;
8
+ var sdkInstance = null;
9
+ function sendSuccess(id, type, data, transfer) {
10
+ const response = { id, type, success: true, data };
11
+ port.postMessage(response, transfer);
12
+ }
13
+ function sendError(id, type, error) {
14
+ const response = { id, type, success: false, error };
15
+ port.postMessage(response);
16
+ }
17
+ async function handleNodeInit(request) {
18
+ const { id, type, payload } = request;
19
+ const { fhevmConfig } = payload;
20
+ try {
21
+ const nodeSdk = await import('@zama-fhe/relayer-sdk/node');
22
+ const config = {
23
+ ...fhevmConfig,
24
+ batchRpcCalls: false
25
+ };
26
+ sdkInstance = await nodeSdk.createInstance(config);
27
+ sendSuccess(id, type, { initialized: true });
28
+ } catch (error) {
29
+ const message = error instanceof Error ? error.message : String(error);
30
+ console.error("[NodeWorker] Init error:", message);
31
+ sendError(id, type, message);
32
+ }
33
+ }
34
+ async function handleEncrypt(request) {
35
+ const { id, type, payload } = request;
36
+ const { values, contractAddress, userAddress } = payload;
37
+ try {
38
+ if (!sdkInstance) {
39
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
40
+ }
41
+ const input = sdkInstance.createEncryptedInput(contractAddress, userAddress);
42
+ for (const value of values) {
43
+ input.add64(value);
44
+ }
45
+ const encrypted = await input.encrypt();
46
+ const response = {
47
+ handles: encrypted.handles,
48
+ inputProof: encrypted.inputProof
49
+ };
50
+ const transferList = [
51
+ encrypted.inputProof.buffer,
52
+ ...encrypted.handles.map((h) => h.buffer)
53
+ ];
54
+ sendSuccess(id, type, response, transferList);
55
+ } catch (error) {
56
+ const message = error instanceof Error ? error.message : String(error);
57
+ console.error("[NodeWorker] Encrypt error:", message);
58
+ sendError(id, type, message);
59
+ }
60
+ }
61
+ async function handleUserDecrypt(request) {
62
+ const { id, type, payload } = request;
63
+ try {
64
+ if (!sdkInstance) {
65
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
66
+ }
67
+ const handleContractPairs = payload.handles.map((handle) => ({
68
+ handle,
69
+ contractAddress: payload.contractAddress
70
+ }));
71
+ const result = await sdkInstance.userDecrypt(
72
+ handleContractPairs,
73
+ payload.privateKey,
74
+ payload.publicKey,
75
+ payload.signature,
76
+ payload.signedContractAddresses,
77
+ payload.signerAddress,
78
+ payload.startTimestamp,
79
+ payload.durationDays
80
+ );
81
+ const response = {
82
+ clearValues: convertToBigIntRecord(result)
83
+ };
84
+ sendSuccess(id, type, response);
85
+ } catch (error) {
86
+ const message = error instanceof Error ? error.message : String(error);
87
+ console.error("[NodeWorker] UserDecrypt error:", message);
88
+ sendError(id, type, message);
89
+ }
90
+ }
91
+ async function handlePublicDecrypt(request) {
92
+ const { id, type, payload } = request;
93
+ try {
94
+ if (!sdkInstance) {
95
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
96
+ }
97
+ const result = await sdkInstance.publicDecrypt(payload.handles);
98
+ const response = {
99
+ clearValues: convertToBigIntRecord(result.clearValues),
100
+ abiEncodedClearValues: result.abiEncodedClearValues,
101
+ decryptionProof: result.decryptionProof
102
+ };
103
+ sendSuccess(id, type, response);
104
+ } catch (error) {
105
+ const message = error instanceof Error ? error.message : String(error);
106
+ console.error("[NodeWorker] PublicDecrypt error:", message);
107
+ sendError(id, type, message);
108
+ }
109
+ }
110
+ function handleGenerateKeypair(request) {
111
+ const { id, type } = request;
112
+ try {
113
+ if (!sdkInstance) {
114
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
115
+ }
116
+ const keypair = sdkInstance.generateKeypair();
117
+ const response = {
118
+ publicKey: keypair.publicKey,
119
+ privateKey: keypair.privateKey
120
+ };
121
+ sendSuccess(id, type, response);
122
+ } catch (error) {
123
+ const message = error instanceof Error ? error.message : String(error);
124
+ console.error("[NodeWorker] GenerateKeypair error:", message);
125
+ sendError(id, type, message);
126
+ }
127
+ }
128
+ function handleCreateEIP712(request) {
129
+ const { id, type, payload } = request;
130
+ try {
131
+ if (!sdkInstance) {
132
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
133
+ }
134
+ const eip712 = sdkInstance.createEIP712(
135
+ payload.publicKey,
136
+ payload.contractAddresses,
137
+ payload.startTimestamp,
138
+ payload.durationDays
139
+ );
140
+ const response = {
141
+ domain: {
142
+ name: eip712.domain.name,
143
+ version: eip712.domain.version,
144
+ chainId: Number(eip712.domain.chainId),
145
+ verifyingContract: eip712.domain.verifyingContract
146
+ },
147
+ types: {
148
+ UserDecryptRequestVerification: eip712.types.UserDecryptRequestVerification.map(
149
+ (field) => ({
150
+ name: field.name,
151
+ type: field.type
152
+ })
153
+ )
154
+ },
155
+ message: {
156
+ publicKey: eip712.message.publicKey,
157
+ contractAddresses: [...eip712.message.contractAddresses],
158
+ startTimestamp: BigInt(eip712.message.startTimestamp),
159
+ durationDays: BigInt(eip712.message.durationDays),
160
+ extraData: eip712.message.extraData
161
+ }
162
+ };
163
+ sendSuccess(id, type, response);
164
+ } catch (error) {
165
+ const message = error instanceof Error ? error.message : String(error);
166
+ console.error("[NodeWorker] CreateEIP712 error:", message);
167
+ sendError(id, type, message);
168
+ }
169
+ }
170
+ function handleCreateDelegatedEIP712(request) {
171
+ const { id, type, payload } = request;
172
+ try {
173
+ if (!sdkInstance) {
174
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
175
+ }
176
+ const result = sdkInstance.createDelegatedUserDecryptEIP712(
177
+ payload.publicKey,
178
+ payload.contractAddresses,
179
+ payload.delegatorAddress,
180
+ payload.startTimestamp,
181
+ payload.durationDays
182
+ );
183
+ sendSuccess(id, type, result);
184
+ } catch (error) {
185
+ const message = error instanceof Error ? error.message : String(error);
186
+ console.error("[NodeWorker] CreateDelegatedEIP712 error:", message);
187
+ sendError(id, type, message);
188
+ }
189
+ }
190
+ async function handleDelegatedUserDecrypt(request) {
191
+ const { id, type, payload } = request;
192
+ try {
193
+ if (!sdkInstance) {
194
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
195
+ }
196
+ const handleContractPairs = payload.handles.map((handle) => ({
197
+ handle,
198
+ contractAddress: payload.contractAddress
199
+ }));
200
+ const result = await sdkInstance.delegatedUserDecrypt(
201
+ handleContractPairs,
202
+ payload.privateKey,
203
+ payload.publicKey,
204
+ payload.signature,
205
+ payload.signedContractAddresses,
206
+ payload.delegatorAddress,
207
+ payload.delegateAddress,
208
+ payload.startTimestamp,
209
+ payload.durationDays
210
+ );
211
+ const response = {
212
+ clearValues: convertToBigIntRecord(result)
213
+ };
214
+ sendSuccess(id, type, response);
215
+ } catch (error) {
216
+ const message = error instanceof Error ? error.message : String(error);
217
+ console.error("[NodeWorker] DelegatedUserDecrypt error:", message);
218
+ sendError(id, type, message);
219
+ }
220
+ }
221
+ async function handleRequestZKProofVerification(request) {
222
+ const { id, type, payload } = request;
223
+ try {
224
+ if (!sdkInstance) {
225
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
226
+ }
227
+ const result = await sdkInstance.requestZKProofVerification(payload.zkProof);
228
+ const transferList = [
229
+ result.inputProof.buffer,
230
+ ...result.handles.map((h) => h.buffer)
231
+ ];
232
+ sendSuccess(id, type, result, transferList);
233
+ } catch (error) {
234
+ const message = error instanceof Error ? error.message : String(error);
235
+ console.error("[NodeWorker] RequestZKProofVerification error:", message);
236
+ sendError(id, type, message);
237
+ }
238
+ }
239
+ function handleGetPublicKey(request) {
240
+ const { id, type } = request;
241
+ try {
242
+ if (!sdkInstance) {
243
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
244
+ }
245
+ const result = sdkInstance.getPublicKey();
246
+ const response = { result };
247
+ sendSuccess(id, type, response);
248
+ } catch (error) {
249
+ const message = error instanceof Error ? error.message : String(error);
250
+ console.error("[NodeWorker] GetPublicKey error:", message);
251
+ sendError(id, type, message);
252
+ }
253
+ }
254
+ function handleGetPublicParams(request) {
255
+ const { id, type, payload } = request;
256
+ try {
257
+ if (!sdkInstance) {
258
+ throw new Error("SDK not initialized. Call NODE_INIT first.");
259
+ }
260
+ const result = sdkInstance.getPublicParams(
261
+ payload.bits
262
+ );
263
+ const response = { result };
264
+ sendSuccess(id, type, response);
265
+ } catch (error) {
266
+ const message = error instanceof Error ? error.message : String(error);
267
+ console.error("[NodeWorker] GetPublicParams error:", message);
268
+ sendError(id, type, message);
269
+ }
270
+ }
271
+ port.on("message", async (request) => {
272
+ try {
273
+ switch (request.type) {
274
+ case "NODE_INIT":
275
+ await handleNodeInit(request);
276
+ break;
277
+ case "ENCRYPT":
278
+ await handleEncrypt(request);
279
+ break;
280
+ case "USER_DECRYPT":
281
+ await handleUserDecrypt(request);
282
+ break;
283
+ case "PUBLIC_DECRYPT":
284
+ await handlePublicDecrypt(request);
285
+ break;
286
+ case "GENERATE_KEYPAIR":
287
+ handleGenerateKeypair(request);
288
+ break;
289
+ case "CREATE_EIP712":
290
+ handleCreateEIP712(request);
291
+ break;
292
+ case "CREATE_DELEGATED_EIP712":
293
+ handleCreateDelegatedEIP712(request);
294
+ break;
295
+ case "DELEGATED_USER_DECRYPT":
296
+ await handleDelegatedUserDecrypt(request);
297
+ break;
298
+ case "REQUEST_ZK_PROOF_VERIFICATION":
299
+ await handleRequestZKProofVerification(request);
300
+ break;
301
+ case "GET_PUBLIC_KEY":
302
+ handleGetPublicKey(request);
303
+ break;
304
+ case "GET_PUBLIC_PARAMS":
305
+ handleGetPublicParams(request);
306
+ break;
307
+ default:
308
+ console.error("[NodeWorker] Unknown request type:", request.type);
309
+ }
310
+ } catch (err) {
311
+ const message = err instanceof Error ? err.message : String(err);
312
+ sendError(
313
+ request?.id ?? "unknown",
314
+ request?.type ?? "UNKNOWN",
315
+ message
316
+ );
317
+ }
318
+ });
319
+ //# sourceMappingURL=relayer-sdk.node-worker.js.map
320
+ //# sourceMappingURL=relayer-sdk.node-worker.js.map