@zama-fhe/sdk 1.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.md +801 -0
- package/dist/chunk-5QJTGZHY.js +101 -0
- package/dist/chunk-5QJTGZHY.js.map +1 -0
- package/dist/chunk-6JRD26PS.js +114 -0
- package/dist/chunk-6JRD26PS.js.map +1 -0
- package/dist/chunk-PHE3BSIB.js +5143 -0
- package/dist/chunk-PHE3BSIB.js.map +1 -0
- package/dist/chunk-UF47M3QR.js +32 -0
- package/dist/chunk-UF47M3QR.js.map +1 -0
- package/dist/chunk-WYWAO3QE.js +182 -0
- package/dist/chunk-WYWAO3QE.js.map +1 -0
- package/dist/cleartext/index.d.ts +45 -0
- package/dist/cleartext/index.js +522 -0
- package/dist/cleartext/index.js.map +1 -0
- package/dist/ethers/index.d.ts +86 -0
- package/dist/ethers/index.js +148 -0
- package/dist/ethers/index.js.map +1 -0
- package/dist/index.d.ts +33405 -0
- package/dist/index.js +3563 -0
- package/dist/index.js.map +1 -0
- package/dist/node/index.d.ts +195 -0
- package/dist/node/index.js +337 -0
- package/dist/node/index.js.map +1 -0
- package/dist/relayer-sdk-Dh9aQmBm.d.ts +39 -0
- package/dist/relayer-sdk.node-worker.d.ts +2 -0
- package/dist/relayer-sdk.node-worker.js +348 -0
- package/dist/relayer-sdk.node-worker.js.map +1 -0
- package/dist/relayer-sdk.types-CgHZ6qZn.d.ts +327 -0
- package/dist/relayer-sdk.worker.js +511 -0
- package/dist/relayer-sdk.worker.js.map +1 -0
- package/dist/relayer-utils-phBmWrNB.d.ts +10 -0
- package/dist/token.types-CUTkehsp.d.ts +299 -0
- package/dist/transfer-batcher-CNtrNMz6.d.ts +197 -0
- package/dist/viem/index.d.ts +58 -0
- package/dist/viem/index.js +143 -0
- package/dist/viem/index.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { G as GenericLogger, F as FHEKeypair, E as EIP712TypedData, a as EncryptParams, b as EncryptResult, U as UserDecryptParams, D as DecryptedValue, P as PublicDecryptResult, c as DelegatedUserDecryptParams, W as WorkerRequest, d as WorkerRequestType, e as WorkerResponse, f as GenerateKeypairResponseData, C as CreateEIP712Payload, g as CreateEIP712ResponseData, h as EncryptPayload, i as EncryptResponseData, j as UserDecryptPayload, k as UserDecryptResponseData, l as PublicDecryptResponseData, m as CreateDelegatedEIP712Payload, n as CreateDelegatedEIP712ResponseData, o as DelegatedUserDecryptPayload, p as DelegatedUserDecryptResponseData, R as RequestZKProofVerificationResponseData, q as GetPublicKeyResponseData, r as GetPublicParamsResponseData } from '../relayer-sdk.types-CgHZ6qZn.js';
|
|
2
|
+
export { B as BaseRequest, s as CreateDelegatedEIP712Request, t as CreateEIP712Request, u as DelegatedUserDecryptRequest, v as EncryptRequest, w as ErrorResponse, x as GenerateKeypairRequest, y as GetPublicKeyRequest, z as GetPublicParamsRequest, I as InitRequest, N as NodeInitRequest, A as PublicDecryptRequest, J as RequestZKProofVerificationRequest, S as SuccessResponse, K as UpdateCsrfRequest, L as UserDecryptRequest } from '../relayer-sdk.types-CgHZ6qZn.js';
|
|
3
|
+
import { FhevmInstanceConfig } from '@zama-fhe/relayer-sdk/node';
|
|
4
|
+
import { R as RelayerSDK } from '../relayer-sdk-Dh9aQmBm.js';
|
|
5
|
+
import { Address, KmsDelegatedUserDecryptEIP712Type, ZKProofLike, InputProofBytesType, FhevmInstanceConfig as FhevmInstanceConfig$1 } from '@zama-fhe/relayer-sdk/bundle';
|
|
6
|
+
import { Worker } from 'node:worker_threads';
|
|
7
|
+
import { a as GenericStorage } from '../token.types-CUTkehsp.js';
|
|
8
|
+
export { H as HardhatConfig, M as MainnetConfig, S as SepoliaConfig } from '../relayer-utils-phBmWrNB.js';
|
|
9
|
+
|
|
10
|
+
interface RelayerNodeConfig {
|
|
11
|
+
transports: Record<number, Partial<FhevmInstanceConfig>>;
|
|
12
|
+
/** Resolve the current chain ID. Called lazily before each operation; the pool is re-initialized when the value changes. */
|
|
13
|
+
getChainId: () => Promise<number>;
|
|
14
|
+
poolSize?: number;
|
|
15
|
+
/** Optional logger for observing worker lifecycle and request timing. */
|
|
16
|
+
logger?: GenericLogger;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* RelayerNode — Node.js encryption/decryption layer using a worker thread pool.
|
|
20
|
+
* Offloads CPU-intensive WASM/FHE operations to `node:worker_threads`.
|
|
21
|
+
*
|
|
22
|
+
* Uses the same promise lock pattern as {@link RelayerWeb}:
|
|
23
|
+
* `#ensureLock` serializes concurrent callers, `#initPromise` caches the
|
|
24
|
+
* resolved pool, and chain switches tear down the old pool within the lock.
|
|
25
|
+
* See the RelayerWeb class doc for a detailed explanation.
|
|
26
|
+
*/
|
|
27
|
+
declare class RelayerNode implements RelayerSDK {
|
|
28
|
+
#private;
|
|
29
|
+
constructor(config: RelayerNodeConfig);
|
|
30
|
+
terminate(): void;
|
|
31
|
+
generateKeypair(): Promise<FHEKeypair>;
|
|
32
|
+
createEIP712(publicKey: string, contractAddresses: Address[], startTimestamp: number, durationDays?: number): Promise<EIP712TypedData>;
|
|
33
|
+
encrypt(params: EncryptParams): Promise<EncryptResult>;
|
|
34
|
+
userDecrypt(params: UserDecryptParams): Promise<Record<string, DecryptedValue>>;
|
|
35
|
+
publicDecrypt(handles: string[]): Promise<PublicDecryptResult>;
|
|
36
|
+
createDelegatedUserDecryptEIP712(publicKey: string, contractAddresses: Address[], delegatorAddress: string, startTimestamp: number, durationDays?: number): Promise<KmsDelegatedUserDecryptEIP712Type>;
|
|
37
|
+
delegatedUserDecrypt(params: DelegatedUserDecryptParams): Promise<Record<string, DecryptedValue>>;
|
|
38
|
+
requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType>;
|
|
39
|
+
getPublicKey(): Promise<{
|
|
40
|
+
publicKeyId: string;
|
|
41
|
+
publicKey: Uint8Array;
|
|
42
|
+
} | null>;
|
|
43
|
+
getPublicParams(bits: number): Promise<{
|
|
44
|
+
publicParams: Uint8Array;
|
|
45
|
+
publicParamsId: string;
|
|
46
|
+
} | null>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Abstract base class for worker clients (browser Web Worker and Node.js worker_threads).
|
|
51
|
+
* Encapsulates all shared logic: pending request tracking, timeouts, init dedup, domain methods.
|
|
52
|
+
* Subclasses implement the abstract hooks for platform-specific worker creation and messaging.
|
|
53
|
+
*/
|
|
54
|
+
declare abstract class BaseWorkerClient<TWorker, TConfig> {
|
|
55
|
+
#private;
|
|
56
|
+
protected readonly config: TConfig;
|
|
57
|
+
protected readonly logger: GenericLogger | undefined;
|
|
58
|
+
constructor(config: TConfig, logger: GenericLogger | undefined);
|
|
59
|
+
/** Create the platform-specific worker instance. */
|
|
60
|
+
protected abstract createWorker(): TWorker;
|
|
61
|
+
/** Wire message/error/messageerror events on the worker. */
|
|
62
|
+
protected abstract wireEvents(worker: TWorker): void;
|
|
63
|
+
/** Post a message to the worker. */
|
|
64
|
+
protected abstract postMessage(worker: TWorker, request: WorkerRequest): void;
|
|
65
|
+
/** Terminate the platform-specific worker. */
|
|
66
|
+
protected abstract terminateWorker(worker: TWorker): void;
|
|
67
|
+
/** Generate a unique request ID. */
|
|
68
|
+
protected abstract generateRequestId(): string;
|
|
69
|
+
/** Return the init request type and payload. */
|
|
70
|
+
protected abstract getInitPayload(): {
|
|
71
|
+
type: WorkerRequestType;
|
|
72
|
+
payload: WorkerRequest["payload"];
|
|
73
|
+
};
|
|
74
|
+
/** Optional hook called after worker init succeeds (e.g. for node worker.unref()). */
|
|
75
|
+
protected onWorkerReady?(_worker: TWorker): void;
|
|
76
|
+
initWorker(): Promise<TWorker>;
|
|
77
|
+
terminate(): void;
|
|
78
|
+
protected handleResponse(response: WorkerResponse<unknown>): void;
|
|
79
|
+
protected handleWorkerError(message: string): void;
|
|
80
|
+
protected handleWorkerMessageError(): void;
|
|
81
|
+
protected sendRequestTo<T>(worker: TWorker, type: WorkerRequestType, payload: WorkerRequest["payload"], timeoutMs?: number): Promise<T>;
|
|
82
|
+
protected sendRequest<T>(type: WorkerRequestType, payload: WorkerRequest["payload"], timeoutMs?: number): Promise<T>;
|
|
83
|
+
generateKeypair(): Promise<GenerateKeypairResponseData>;
|
|
84
|
+
createEIP712(params: CreateEIP712Payload): Promise<CreateEIP712ResponseData>;
|
|
85
|
+
encrypt(params: EncryptPayload): Promise<EncryptResponseData>;
|
|
86
|
+
userDecrypt(params: UserDecryptPayload): Promise<UserDecryptResponseData>;
|
|
87
|
+
publicDecrypt(handles: string[]): Promise<PublicDecryptResponseData>;
|
|
88
|
+
createDelegatedUserDecryptEIP712(params: CreateDelegatedEIP712Payload): Promise<CreateDelegatedEIP712ResponseData>;
|
|
89
|
+
delegatedUserDecrypt(params: DelegatedUserDecryptPayload): Promise<DelegatedUserDecryptResponseData>;
|
|
90
|
+
requestZKProofVerification(zkProof: ZKProofLike): Promise<RequestZKProofVerificationResponseData>;
|
|
91
|
+
getPublicKey(): Promise<GetPublicKeyResponseData>;
|
|
92
|
+
getPublicParams(bits: number): Promise<GetPublicParamsResponseData>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
interface NodeWorkerClientConfig {
|
|
96
|
+
fhevmConfig: FhevmInstanceConfig$1;
|
|
97
|
+
/** Optional logger for tracing worker request lifecycle. */
|
|
98
|
+
logger?: GenericLogger;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Client for communicating with the RelayerSDK Node.js worker thread.
|
|
102
|
+
* Provides a promise-based API for FHE operations using node:worker_threads.
|
|
103
|
+
*/
|
|
104
|
+
declare class NodeWorkerClient extends BaseWorkerClient<Worker, NodeWorkerClientConfig> {
|
|
105
|
+
constructor(config: NodeWorkerClientConfig);
|
|
106
|
+
protected createWorker(): Worker;
|
|
107
|
+
protected wireEvents(worker: Worker): void;
|
|
108
|
+
protected postMessage(worker: Worker, request: WorkerRequest): void;
|
|
109
|
+
protected terminateWorker(worker: Worker): void;
|
|
110
|
+
protected generateRequestId(): string;
|
|
111
|
+
protected getInitPayload(): {
|
|
112
|
+
type: WorkerRequestType;
|
|
113
|
+
payload: WorkerRequest["payload"];
|
|
114
|
+
};
|
|
115
|
+
protected onWorkerReady(worker: Worker): void;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface NodeWorkerPoolConfig extends NodeWorkerClientConfig {
|
|
119
|
+
poolSize?: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Pool of Node.js worker threads for parallel FHE operations.
|
|
123
|
+
*
|
|
124
|
+
* **Default pool size:** `min(os.availableParallelism(), 4)`. Each worker loads
|
|
125
|
+
* the full WASM module (~50–100 MB), so size the pool based on available memory.
|
|
126
|
+
*
|
|
127
|
+
* **Scheduling:** Least-connections — each request is dispatched to the worker
|
|
128
|
+
* with the fewest in-flight operations.
|
|
129
|
+
*
|
|
130
|
+
* **When to override pool size:**
|
|
131
|
+
* - High-throughput batch processing (e.g. bulk encryptions): increase to match CPU cores.
|
|
132
|
+
* - Memory-constrained environments: decrease to 1–2 workers.
|
|
133
|
+
*
|
|
134
|
+
* **Lifecycle:**
|
|
135
|
+
* 1. Construct with config: `new NodeWorkerPool({ fhevmConfig })`
|
|
136
|
+
* 2. Initialize all workers: `await pool.initPool()`
|
|
137
|
+
* 3. Use: `await pool.encrypt(...)`, `await pool.userDecrypt(...)`, etc.
|
|
138
|
+
* 4. Shut down: `pool.terminate()`
|
|
139
|
+
*
|
|
140
|
+
* `initPool()` is idempotent — concurrent calls share the same initialization promise.
|
|
141
|
+
* If any worker fails to initialize, all workers are terminated and the error is propagated.
|
|
142
|
+
*/
|
|
143
|
+
declare class NodeWorkerPool {
|
|
144
|
+
#private;
|
|
145
|
+
/**
|
|
146
|
+
* @param config - Pool configuration. Set `poolSize` to override the default
|
|
147
|
+
* (`min(os.availableParallelism(), 4)`).
|
|
148
|
+
*/
|
|
149
|
+
constructor(config: NodeWorkerPoolConfig);
|
|
150
|
+
get poolSize(): number;
|
|
151
|
+
initPool(): Promise<void>;
|
|
152
|
+
terminate(): void;
|
|
153
|
+
generateKeypair(): Promise<GenerateKeypairResponseData>;
|
|
154
|
+
createEIP712(params: CreateEIP712Payload): Promise<CreateEIP712ResponseData>;
|
|
155
|
+
encrypt(params: EncryptPayload): Promise<EncryptResponseData>;
|
|
156
|
+
userDecrypt(params: UserDecryptPayload): Promise<UserDecryptResponseData>;
|
|
157
|
+
publicDecrypt(handles: string[]): Promise<PublicDecryptResponseData>;
|
|
158
|
+
createDelegatedUserDecryptEIP712(params: CreateDelegatedEIP712Payload): Promise<CreateDelegatedEIP712ResponseData>;
|
|
159
|
+
delegatedUserDecrypt(params: DelegatedUserDecryptPayload): Promise<DelegatedUserDecryptResponseData>;
|
|
160
|
+
requestZKProofVerification(zkProof: ZKProofLike): Promise<RequestZKProofVerificationResponseData>;
|
|
161
|
+
getPublicKey(): Promise<GetPublicKeyResponseData>;
|
|
162
|
+
getPublicParams(bits: number): Promise<GetPublicParamsResponseData>;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* {@link GenericStorage} backed by Node.js {@link AsyncLocalStorage}.
|
|
167
|
+
*
|
|
168
|
+
* Each async context (e.g. HTTP request) gets its own isolated `Map`,
|
|
169
|
+
* so credentials from one request never leak into another.
|
|
170
|
+
*
|
|
171
|
+
* Call {@link run} to establish a context before using the SDK:
|
|
172
|
+
*
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { asyncLocalStorage } from "@zama-fhe/sdk/node";
|
|
175
|
+
*
|
|
176
|
+
* app.post("/api/transfer", (req, res) => {
|
|
177
|
+
* asyncLocalStorage.run(async () => {
|
|
178
|
+
* const sdk = new ZamaSDK({ relayer, signer, storage: asyncLocalStorage });
|
|
179
|
+
* // credentials are scoped to this request
|
|
180
|
+
* });
|
|
181
|
+
* });
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
declare class AsyncLocalMapStorage implements GenericStorage {
|
|
185
|
+
#private;
|
|
186
|
+
/** Execute `fn` within an isolated storage context. */
|
|
187
|
+
run<R>(fn: () => R | Promise<R>): R | Promise<R>;
|
|
188
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
189
|
+
set<T = unknown>(key: string, value: T): Promise<void>;
|
|
190
|
+
delete(key: string): Promise<void>;
|
|
191
|
+
}
|
|
192
|
+
/** Default singleton for application-wide use. */
|
|
193
|
+
declare const asyncLocalStorage: AsyncLocalMapStorage;
|
|
194
|
+
|
|
195
|
+
export { AsyncLocalMapStorage, BaseWorkerClient, CreateDelegatedEIP712Payload, CreateDelegatedEIP712ResponseData, CreateEIP712Payload, CreateEIP712ResponseData, DelegatedUserDecryptParams, DelegatedUserDecryptPayload, DelegatedUserDecryptResponseData, EIP712TypedData, EncryptParams, EncryptPayload, EncryptResponseData, EncryptResult, FHEKeypair, GenerateKeypairResponseData, GenericLogger, GenericStorage, GetPublicKeyResponseData, GetPublicParamsResponseData, NodeWorkerClient, type NodeWorkerClientConfig, NodeWorkerPool, type NodeWorkerPoolConfig, PublicDecryptResponseData, PublicDecryptResult, RelayerNode, type RelayerNodeConfig, RelayerSDK, RequestZKProofVerificationResponseData, UserDecryptParams, UserDecryptPayload, UserDecryptResponseData, WorkerRequest, WorkerRequestType, WorkerResponse, asyncLocalStorage };
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { BaseWorkerClient } from '../chunk-WYWAO3QE.js';
|
|
2
|
+
export { BaseWorkerClient } from '../chunk-WYWAO3QE.js';
|
|
3
|
+
import { EncryptionFailedError, ZamaError } from '../chunk-6JRD26PS.js';
|
|
4
|
+
import { mergeFhevmConfig, buildEIP712DomainType, withRetry } from '../chunk-5QJTGZHY.js';
|
|
5
|
+
export { HardhatConfig, MainnetConfig, SepoliaConfig } from '../chunk-5QJTGZHY.js';
|
|
6
|
+
import { availableParallelism } from 'os';
|
|
7
|
+
import { Worker } from 'worker_threads';
|
|
8
|
+
import { randomUUID } from 'crypto';
|
|
9
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
10
|
+
|
|
11
|
+
var NodeWorkerClient = class extends BaseWorkerClient {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super(config, config.logger);
|
|
14
|
+
}
|
|
15
|
+
createWorker() {
|
|
16
|
+
return new Worker(new URL("./relayer-sdk.node-worker.js", import.meta.url));
|
|
17
|
+
}
|
|
18
|
+
wireEvents(worker) {
|
|
19
|
+
worker.on("message", (response) => this.handleResponse(response));
|
|
20
|
+
worker.on("error", (error) => this.handleWorkerError(error.message));
|
|
21
|
+
worker.on("messageerror", () => this.handleWorkerMessageError());
|
|
22
|
+
}
|
|
23
|
+
postMessage(worker, request) {
|
|
24
|
+
worker.postMessage(request);
|
|
25
|
+
}
|
|
26
|
+
terminateWorker(worker) {
|
|
27
|
+
worker.terminate();
|
|
28
|
+
}
|
|
29
|
+
generateRequestId() {
|
|
30
|
+
return randomUUID();
|
|
31
|
+
}
|
|
32
|
+
getInitPayload() {
|
|
33
|
+
return {
|
|
34
|
+
type: "NODE_INIT",
|
|
35
|
+
payload: { fhevmConfig: this.config.fhevmConfig }
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
onWorkerReady(worker) {
|
|
39
|
+
worker.unref();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/worker/worker.node-pool.ts
|
|
44
|
+
var MAX_DEFAULT_POOL_SIZE = 4;
|
|
45
|
+
var NodeWorkerPool = class {
|
|
46
|
+
#workers = [];
|
|
47
|
+
#activeCount = [];
|
|
48
|
+
#config;
|
|
49
|
+
#poolSize;
|
|
50
|
+
#initPromise = null;
|
|
51
|
+
/**
|
|
52
|
+
* @param config - Pool configuration. Set `poolSize` to override the default
|
|
53
|
+
* (`min(os.availableParallelism(), 4)`).
|
|
54
|
+
*/
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.#config = config;
|
|
57
|
+
this.#poolSize = config.poolSize ?? Math.min(availableParallelism(), MAX_DEFAULT_POOL_SIZE);
|
|
58
|
+
}
|
|
59
|
+
get poolSize() {
|
|
60
|
+
return this.#poolSize;
|
|
61
|
+
}
|
|
62
|
+
async initPool() {
|
|
63
|
+
if (this.#workers.length > 0) return;
|
|
64
|
+
if (!this.#initPromise) {
|
|
65
|
+
this.#initPromise = this.#doInitPool().finally(() => {
|
|
66
|
+
this.#initPromise = null;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return this.#initPromise;
|
|
70
|
+
}
|
|
71
|
+
async #doInitPool() {
|
|
72
|
+
for (let i = 0; i < this.#poolSize; i++) {
|
|
73
|
+
this.#workers.push(new NodeWorkerClient(this.#config));
|
|
74
|
+
this.#activeCount.push(0);
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await Promise.all(this.#workers.map((w) => w.initWorker()));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
for (const worker of this.#workers) {
|
|
80
|
+
worker.terminate();
|
|
81
|
+
}
|
|
82
|
+
this.#workers.length = 0;
|
|
83
|
+
this.#activeCount.length = 0;
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
terminate() {
|
|
88
|
+
for (const worker of this.#workers) {
|
|
89
|
+
worker.terminate();
|
|
90
|
+
}
|
|
91
|
+
this.#workers.length = 0;
|
|
92
|
+
this.#activeCount.length = 0;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Pick the worker with the fewest in-flight requests (least-connections).
|
|
96
|
+
* Returns the index so #dispatch can track the active count.
|
|
97
|
+
*/
|
|
98
|
+
#leastBusyIndex() {
|
|
99
|
+
let minIndex = 0;
|
|
100
|
+
let minCount = this.#activeCount[0];
|
|
101
|
+
for (let i = 1; i < this.#activeCount.length; i++) {
|
|
102
|
+
if (this.#activeCount[i] < minCount) {
|
|
103
|
+
minCount = this.#activeCount[i];
|
|
104
|
+
minIndex = i;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return minIndex;
|
|
108
|
+
}
|
|
109
|
+
async #dispatch(fn) {
|
|
110
|
+
if (this.#workers.length === 0) {
|
|
111
|
+
throw new Error("NodeWorkerPool not initialized. Call initPool() first.");
|
|
112
|
+
}
|
|
113
|
+
const index = this.#leastBusyIndex();
|
|
114
|
+
this.#activeCount[index]++;
|
|
115
|
+
try {
|
|
116
|
+
return await fn(this.#workers[index]);
|
|
117
|
+
} finally {
|
|
118
|
+
this.#activeCount[index]--;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async generateKeypair() {
|
|
122
|
+
return this.#dispatch((w) => w.generateKeypair());
|
|
123
|
+
}
|
|
124
|
+
async createEIP712(params) {
|
|
125
|
+
return this.#dispatch((w) => w.createEIP712(params));
|
|
126
|
+
}
|
|
127
|
+
async encrypt(params) {
|
|
128
|
+
return this.#dispatch((w) => w.encrypt(params));
|
|
129
|
+
}
|
|
130
|
+
async userDecrypt(params) {
|
|
131
|
+
return this.#dispatch((w) => w.userDecrypt(params));
|
|
132
|
+
}
|
|
133
|
+
async publicDecrypt(handles) {
|
|
134
|
+
return this.#dispatch((w) => w.publicDecrypt(handles));
|
|
135
|
+
}
|
|
136
|
+
async createDelegatedUserDecryptEIP712(params) {
|
|
137
|
+
return this.#dispatch((w) => w.createDelegatedUserDecryptEIP712(params));
|
|
138
|
+
}
|
|
139
|
+
async delegatedUserDecrypt(params) {
|
|
140
|
+
return this.#dispatch((w) => w.delegatedUserDecrypt(params));
|
|
141
|
+
}
|
|
142
|
+
async requestZKProofVerification(zkProof) {
|
|
143
|
+
return this.#dispatch((w) => w.requestZKProofVerification(zkProof));
|
|
144
|
+
}
|
|
145
|
+
async getPublicKey() {
|
|
146
|
+
return this.#dispatch((w) => w.getPublicKey());
|
|
147
|
+
}
|
|
148
|
+
async getPublicParams(bits) {
|
|
149
|
+
return this.#dispatch((w) => w.getPublicParams(bits));
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// src/relayer/relayer-node.ts
|
|
154
|
+
var RelayerNode = class {
|
|
155
|
+
#config;
|
|
156
|
+
#pool = null;
|
|
157
|
+
#initPromise = null;
|
|
158
|
+
#ensureLock = null;
|
|
159
|
+
#terminated = false;
|
|
160
|
+
#resolvedChainId = null;
|
|
161
|
+
constructor(config) {
|
|
162
|
+
this.#config = config;
|
|
163
|
+
}
|
|
164
|
+
async #getPoolConfig() {
|
|
165
|
+
const chainId = await this.#config.getChainId();
|
|
166
|
+
const { transports, poolSize } = this.#config;
|
|
167
|
+
return {
|
|
168
|
+
fhevmConfig: mergeFhevmConfig(chainId, transports[chainId]),
|
|
169
|
+
poolSize,
|
|
170
|
+
logger: this.#config.logger
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async #ensurePool() {
|
|
174
|
+
if (this.#ensureLock) return this.#ensureLock;
|
|
175
|
+
this.#ensureLock = this.#ensurePoolInner();
|
|
176
|
+
try {
|
|
177
|
+
return await this.#ensureLock;
|
|
178
|
+
} finally {
|
|
179
|
+
this.#ensureLock = null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async #ensurePoolInner() {
|
|
183
|
+
if (this.#terminated) {
|
|
184
|
+
throw new EncryptionFailedError("RelayerNode has been terminated");
|
|
185
|
+
}
|
|
186
|
+
const chainId = await this.#config.getChainId();
|
|
187
|
+
if (this.#resolvedChainId !== null && chainId !== this.#resolvedChainId) {
|
|
188
|
+
this.#pool?.terminate();
|
|
189
|
+
this.#pool = null;
|
|
190
|
+
this.#initPromise = null;
|
|
191
|
+
}
|
|
192
|
+
this.#resolvedChainId = chainId;
|
|
193
|
+
if (!this.#initPromise) {
|
|
194
|
+
this.#initPromise = this.#initPool().catch((error) => {
|
|
195
|
+
this.#initPromise = null;
|
|
196
|
+
throw error instanceof ZamaError ? error : new EncryptionFailedError("Failed to initialize FHE worker pool", {
|
|
197
|
+
cause: error instanceof Error ? error : void 0
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return this.#initPromise;
|
|
202
|
+
}
|
|
203
|
+
async #initPool() {
|
|
204
|
+
const poolConfig = await this.#getPoolConfig();
|
|
205
|
+
const pool = new NodeWorkerPool(poolConfig);
|
|
206
|
+
await pool.initPool();
|
|
207
|
+
if (this.#terminated) {
|
|
208
|
+
pool.terminate();
|
|
209
|
+
throw new Error("RelayerNode was terminated during initialization");
|
|
210
|
+
}
|
|
211
|
+
this.#pool = pool;
|
|
212
|
+
return pool;
|
|
213
|
+
}
|
|
214
|
+
terminate() {
|
|
215
|
+
this.#terminated = true;
|
|
216
|
+
if (this.#pool) {
|
|
217
|
+
this.#pool.terminate();
|
|
218
|
+
this.#pool = null;
|
|
219
|
+
}
|
|
220
|
+
this.#initPromise = null;
|
|
221
|
+
this.#ensureLock = null;
|
|
222
|
+
}
|
|
223
|
+
async generateKeypair() {
|
|
224
|
+
const pool = await this.#ensurePool();
|
|
225
|
+
const result = await pool.generateKeypair();
|
|
226
|
+
return {
|
|
227
|
+
publicKey: result.publicKey,
|
|
228
|
+
privateKey: result.privateKey
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
async createEIP712(publicKey, contractAddresses, startTimestamp, durationDays = 7) {
|
|
232
|
+
const pool = await this.#ensurePool();
|
|
233
|
+
const result = await pool.createEIP712({
|
|
234
|
+
publicKey,
|
|
235
|
+
contractAddresses,
|
|
236
|
+
startTimestamp,
|
|
237
|
+
durationDays
|
|
238
|
+
});
|
|
239
|
+
const domain = {
|
|
240
|
+
name: result.domain.name,
|
|
241
|
+
version: result.domain.version,
|
|
242
|
+
chainId: result.domain.chainId,
|
|
243
|
+
verifyingContract: result.domain.verifyingContract
|
|
244
|
+
};
|
|
245
|
+
return {
|
|
246
|
+
domain,
|
|
247
|
+
types: {
|
|
248
|
+
EIP712Domain: buildEIP712DomainType(domain),
|
|
249
|
+
UserDecryptRequestVerification: result.types.UserDecryptRequestVerification
|
|
250
|
+
},
|
|
251
|
+
message: {
|
|
252
|
+
publicKey: result.message.publicKey,
|
|
253
|
+
contractAddresses: result.message.contractAddresses,
|
|
254
|
+
startTimestamp: result.message.startTimestamp,
|
|
255
|
+
durationDays: result.message.durationDays,
|
|
256
|
+
extraData: result.message.extraData
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
async encrypt(params) {
|
|
261
|
+
return withRetry(async () => {
|
|
262
|
+
const pool = await this.#ensurePool();
|
|
263
|
+
const result = await pool.encrypt(params);
|
|
264
|
+
return { handles: result.handles, inputProof: result.inputProof };
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
async userDecrypt(params) {
|
|
268
|
+
return withRetry(async () => {
|
|
269
|
+
const pool = await this.#ensurePool();
|
|
270
|
+
const result = await pool.userDecrypt(params);
|
|
271
|
+
return result.clearValues;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async publicDecrypt(handles) {
|
|
275
|
+
return withRetry(async () => {
|
|
276
|
+
const pool = await this.#ensurePool();
|
|
277
|
+
const result = await pool.publicDecrypt(handles);
|
|
278
|
+
return {
|
|
279
|
+
clearValues: result.clearValues,
|
|
280
|
+
abiEncodedClearValues: result.abiEncodedClearValues,
|
|
281
|
+
decryptionProof: result.decryptionProof
|
|
282
|
+
};
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
async createDelegatedUserDecryptEIP712(publicKey, contractAddresses, delegatorAddress, startTimestamp, durationDays = 7) {
|
|
286
|
+
const pool = await this.#ensurePool();
|
|
287
|
+
return pool.createDelegatedUserDecryptEIP712({
|
|
288
|
+
publicKey,
|
|
289
|
+
contractAddresses,
|
|
290
|
+
delegatorAddress,
|
|
291
|
+
startTimestamp,
|
|
292
|
+
durationDays
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
async delegatedUserDecrypt(params) {
|
|
296
|
+
return withRetry(async () => {
|
|
297
|
+
const pool = await this.#ensurePool();
|
|
298
|
+
const result = await pool.delegatedUserDecrypt(params);
|
|
299
|
+
return result.clearValues;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async requestZKProofVerification(zkProof) {
|
|
303
|
+
return withRetry(async () => {
|
|
304
|
+
const pool = await this.#ensurePool();
|
|
305
|
+
return pool.requestZKProofVerification(zkProof);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
async getPublicKey() {
|
|
309
|
+
const pool = await this.#ensurePool();
|
|
310
|
+
return (await pool.getPublicKey()).result;
|
|
311
|
+
}
|
|
312
|
+
async getPublicParams(bits) {
|
|
313
|
+
const pool = await this.#ensurePool();
|
|
314
|
+
return (await pool.getPublicParams(bits)).result;
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
var AsyncLocalMapStorage = class {
|
|
318
|
+
#als = new AsyncLocalStorage();
|
|
319
|
+
/** Execute `fn` within an isolated storage context. */
|
|
320
|
+
run(fn) {
|
|
321
|
+
return this.#als.run(/* @__PURE__ */ new Map(), fn);
|
|
322
|
+
}
|
|
323
|
+
async get(key) {
|
|
324
|
+
return this.#als.getStore()?.get(key) ?? null;
|
|
325
|
+
}
|
|
326
|
+
async set(key, value) {
|
|
327
|
+
this.#als.getStore()?.set(key, value);
|
|
328
|
+
}
|
|
329
|
+
async delete(key) {
|
|
330
|
+
this.#als.getStore()?.delete(key);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
var asyncLocalStorage = new AsyncLocalMapStorage();
|
|
334
|
+
|
|
335
|
+
export { AsyncLocalMapStorage, NodeWorkerClient, NodeWorkerPool, RelayerNode, asyncLocalStorage };
|
|
336
|
+
//# sourceMappingURL=index.js.map
|
|
337
|
+
//# 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","../../src/token/async-local-storage.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 { ZamaError, EncryptionFailedError } from \"../token/errors\";\nimport type {\n Address,\n DecryptedValue,\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 encryption/decryption layer using a worker thread pool.\n * Offloads CPU-intensive WASM/FHE operations to `node:worker_threads`.\n *\n * Uses the same promise lock pattern as {@link RelayerWeb}:\n * `#ensureLock` serializes concurrent callers, `#initPromise` caches the\n * resolved pool, and chain switches tear down the old pool within the lock.\n * See the RelayerWeb class doc for a detailed explanation.\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 ZamaError\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, DecryptedValue>> {\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(\n params: DelegatedUserDecryptParams,\n ): Promise<Record<string, DecryptedValue>> {\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","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { GenericStorage } from \"./token.types\";\n\n/**\n * {@link GenericStorage} backed by Node.js {@link AsyncLocalStorage}.\n *\n * Each async context (e.g. HTTP request) gets its own isolated `Map`,\n * so credentials from one request never leak into another.\n *\n * Call {@link run} to establish a context before using the SDK:\n *\n * ```ts\n * import { asyncLocalStorage } from \"@zama-fhe/sdk/node\";\n *\n * app.post(\"/api/transfer\", (req, res) => {\n * asyncLocalStorage.run(async () => {\n * const sdk = new ZamaSDK({ relayer, signer, storage: asyncLocalStorage });\n * // credentials are scoped to this request\n * });\n * });\n * ```\n */\nexport class AsyncLocalMapStorage implements GenericStorage {\n readonly #als = new AsyncLocalStorage<Map<string, unknown>>();\n\n /** Execute `fn` within an isolated storage context. */\n run<R>(fn: () => R | Promise<R>): R | Promise<R> {\n return this.#als.run(new Map(), fn);\n }\n\n async get<T = unknown>(key: string): Promise<T | null> {\n return (this.#als.getStore()?.get(key) as T) ?? null;\n }\n\n async set<T = unknown>(key: string, value: T): Promise<void> {\n this.#als.getStore()?.set(key, value);\n }\n\n async delete(key: string): Promise<void> {\n this.#als.getStore()?.delete(key);\n }\n}\n\n/** Default singleton for application-wide use. */\nexport const asyncLocalStorage = new AsyncLocalMapStorage();\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { F as FHEKeypair, E as EIP712TypedData, a as EncryptParams, b as EncryptResult, U as UserDecryptParams, D as DecryptedValue, P as PublicDecryptResult, c as DelegatedUserDecryptParams } from './relayer-sdk.types-CgHZ6qZn.js';
|
|
2
|
+
import { Address, KmsDelegatedUserDecryptEIP712Type, ZKProofLike, InputProofBytesType } from '@zama-fhe/relayer-sdk/bundle';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for FHE relayer operations.
|
|
6
|
+
* Implemented by `RelayerWeb` (browser, via Web Worker + WASM) and `RelayerNode` (Node.js, direct).
|
|
7
|
+
*/
|
|
8
|
+
interface RelayerSDK {
|
|
9
|
+
/** Generate an FHE keypair (public + private key). */
|
|
10
|
+
generateKeypair(): Promise<FHEKeypair>;
|
|
11
|
+
/** Create EIP-712 typed data for signing an FHE decrypt credential. */
|
|
12
|
+
createEIP712(publicKey: string, contractAddresses: Address[], startTimestamp: number, durationDays?: number): Promise<EIP712TypedData>;
|
|
13
|
+
/** Encrypt plaintext values into FHE ciphertexts. */
|
|
14
|
+
encrypt(params: EncryptParams): Promise<EncryptResult>;
|
|
15
|
+
/** Decrypt FHE ciphertext handles using the user's own credentials. */
|
|
16
|
+
userDecrypt(params: UserDecryptParams): Promise<Record<string, DecryptedValue>>;
|
|
17
|
+
/** Decrypt FHE handles using the network public key (no credential needed). */
|
|
18
|
+
publicDecrypt(handles: string[]): Promise<PublicDecryptResult>;
|
|
19
|
+
/** Create EIP-712 typed data for a delegated user decrypt credential. */
|
|
20
|
+
createDelegatedUserDecryptEIP712(publicKey: string, contractAddresses: Address[], delegatorAddress: string, startTimestamp: number, durationDays?: number): Promise<KmsDelegatedUserDecryptEIP712Type>;
|
|
21
|
+
/** Decrypt FHE handles using delegated user credentials. */
|
|
22
|
+
delegatedUserDecrypt(params: DelegatedUserDecryptParams): Promise<Record<string, DecryptedValue>>;
|
|
23
|
+
/** Submit a ZK proof for on-chain verification. */
|
|
24
|
+
requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType>;
|
|
25
|
+
/** Fetch the FHE network public key. Returns `null` if not available. */
|
|
26
|
+
getPublicKey(): Promise<{
|
|
27
|
+
publicKeyId: string;
|
|
28
|
+
publicKey: Uint8Array;
|
|
29
|
+
} | null>;
|
|
30
|
+
/** Fetch FHE public parameters for a given bit size. Returns `null` if not available. */
|
|
31
|
+
getPublicParams(bits: number): Promise<{
|
|
32
|
+
publicParams: Uint8Array;
|
|
33
|
+
publicParamsId: string;
|
|
34
|
+
} | null>;
|
|
35
|
+
/** Terminate the relayer backend and release resources. */
|
|
36
|
+
terminate(): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type { RelayerSDK as R };
|