@zama-fhe/sdk 3.3.0 → 3.3.1-alpha.2

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.
Files changed (119) hide show
  1. package/README.md +0 -2
  2. package/dist/cjs/base-signer.cjs +1 -1
  3. package/dist/cjs/base-signer.cjs.map +1 -1
  4. package/dist/cjs/chains.cjs +1 -1
  5. package/dist/cjs/chains.cjs.map +1 -1
  6. package/dist/cjs/cleartext/index.cjs +1 -1
  7. package/dist/cjs/cleartext.cjs +2 -0
  8. package/dist/cjs/cleartext.cjs.map +1 -0
  9. package/dist/cjs/ethers/index.cjs.map +1 -1
  10. package/dist/cjs/fhevm-relayer.cjs +2 -0
  11. package/dist/cjs/fhevm-relayer.cjs.map +1 -0
  12. package/dist/cjs/index.cjs +1 -1
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs/node/index.cjs +2 -0
  15. package/dist/cjs/node/index.cjs.map +1 -0
  16. package/dist/cjs/query/index.cjs +1 -1
  17. package/dist/cjs/query/index.cjs.map +1 -1
  18. package/dist/cjs/relayer.cjs +1 -1
  19. package/dist/cjs/relayer.cjs.map +1 -1
  20. package/dist/cjs/token.cjs +1 -1
  21. package/dist/cjs/token.cjs.map +1 -1
  22. package/dist/cjs/viem/index.cjs +1 -1
  23. package/dist/cjs/viem/index.cjs.map +1 -1
  24. package/dist/cjs/web/index.cjs +1 -590
  25. package/dist/cjs/web/index.cjs.map +1 -1
  26. package/dist/cjs/wrappers-registry.cjs.map +1 -1
  27. package/dist/esm/base-signer-CI-FYai2.js +2 -0
  28. package/dist/esm/base-signer-CI-FYai2.js.map +1 -0
  29. package/dist/esm/{base-signer-C3Wc5oi9.d.ts → base-signer-Q2EJECrc.d.ts} +2 -2
  30. package/dist/esm/chains/index.d.ts +2 -3
  31. package/dist/esm/chains/index.js +1 -1
  32. package/dist/esm/chains-CLv9HEJ_.js +2 -0
  33. package/dist/esm/chains-CLv9HEJ_.js.map +1 -0
  34. package/dist/esm/cleartext/index.d.ts +3 -2
  35. package/dist/esm/cleartext/index.js +1 -1
  36. package/dist/esm/cleartext-BfXTVQu-.js +2 -0
  37. package/dist/esm/cleartext-BfXTVQu-.js.map +1 -0
  38. package/dist/esm/cleartext-U6sPs_Kd.d.ts +19 -0
  39. package/dist/esm/ethers/index.d.ts +4 -5
  40. package/dist/esm/ethers/index.js +1 -1
  41. package/dist/esm/ethers/index.js.map +1 -1
  42. package/dist/esm/fhevm-relayer-B-lEKfPQ.js +2 -0
  43. package/dist/esm/fhevm-relayer-B-lEKfPQ.js.map +1 -0
  44. package/dist/esm/index-BnIp_-Ak.d.ts +328 -0
  45. package/dist/esm/{index-CYBH0nyo.d.ts → index-D66eC3G7.d.ts} +60 -13
  46. package/dist/esm/index.d.ts +8 -11
  47. package/dist/esm/index.js +1 -1
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/esm/node/index.d.ts +5 -194
  50. package/dist/esm/node/index.js +1 -1
  51. package/dist/esm/node/index.js.map +1 -1
  52. package/dist/esm/query/index.d.ts +3 -380
  53. package/dist/esm/query/index.js +1 -1
  54. package/dist/esm/query/index.js.map +1 -1
  55. package/dist/esm/relayer-BYq9bLh8.js +2 -0
  56. package/dist/esm/relayer-BYq9bLh8.js.map +1 -0
  57. package/dist/esm/token-CmHTAAWW.js +2 -0
  58. package/dist/esm/token-CmHTAAWW.js.map +1 -0
  59. package/dist/esm/{types-piBsdTIP.d.ts → types-Bov8XY36.d.ts} +3 -3
  60. package/dist/esm/{types-OHIaPwCy.d.ts → types-BpvL50qX.d.ts} +3 -3
  61. package/dist/esm/types-C-WTLcHZ.d.ts +988 -0
  62. package/dist/esm/viem/index.d.ts +4 -5
  63. package/dist/esm/viem/index.js +1 -1
  64. package/dist/esm/viem/index.js.map +1 -1
  65. package/dist/esm/web/index.d.ts +6 -9
  66. package/dist/esm/web/index.js +1 -590
  67. package/dist/esm/web/index.js.map +1 -1
  68. package/dist/esm/{wrappers-registry-C1oK8Bi6.js → wrappers-registry-xZWzyAi4.js} +2 -2
  69. package/dist/esm/wrappers-registry-xZWzyAi4.js.map +1 -0
  70. package/dist/esm/{index-C1Mtc8Rw.d.ts → zama-sdk-q4_qt64Q.d.ts} +1471 -1102
  71. package/package.json +6 -2
  72. package/dist/cjs/assertions.cjs +0 -2
  73. package/dist/cjs/assertions.cjs.map +0 -1
  74. package/dist/cjs/encryption.cjs +0 -2
  75. package/dist/cjs/encryption.cjs.map +0 -1
  76. package/dist/cjs/relayer-cleartext.cjs +0 -2
  77. package/dist/cjs/relayer-cleartext.cjs.map +0 -1
  78. package/dist/cjs/relayer-sdk.worker.js +0 -589
  79. package/dist/cjs/timeout.cjs +0 -2
  80. package/dist/cjs/timeout.cjs.map +0 -1
  81. package/dist/cjs/validation.cjs +0 -2
  82. package/dist/cjs/validation.cjs.map +0 -1
  83. package/dist/esm/assertions-zYseN5Xz.js +0 -2
  84. package/dist/esm/assertions-zYseN5Xz.js.map +0 -1
  85. package/dist/esm/base-signer-DjytqPkd.js +0 -2
  86. package/dist/esm/base-signer-DjytqPkd.js.map +0 -1
  87. package/dist/esm/chains-CXcO1DBP.js +0 -2
  88. package/dist/esm/chains-CXcO1DBP.js.map +0 -1
  89. package/dist/esm/cleartext-DAkOTlrE.d.ts +0 -19
  90. package/dist/esm/cleartext-rTWFctyd.js +0 -2
  91. package/dist/esm/cleartext-rTWFctyd.js.map +0 -1
  92. package/dist/esm/encryption-x4Z_Icqk.js +0 -2
  93. package/dist/esm/encryption-x4Z_Icqk.js.map +0 -1
  94. package/dist/esm/hex-A72GrTf9.js +0 -2
  95. package/dist/esm/hex-A72GrTf9.js.map +0 -1
  96. package/dist/esm/indexeddb-storage-Mi-fCWN3.js +0 -2
  97. package/dist/esm/indexeddb-storage-Mi-fCWN3.js.map +0 -1
  98. package/dist/esm/memory-storage-fp9RY5BQ.js +0 -2
  99. package/dist/esm/memory-storage-fp9RY5BQ.js.map +0 -1
  100. package/dist/esm/node/relayer-sdk.node-worker.d.ts +0 -1
  101. package/dist/esm/node/relayer-sdk.node-worker.js +0 -2
  102. package/dist/esm/node/relayer-sdk.node-worker.js.map +0 -1
  103. package/dist/esm/relayer-cleartext-Bp6jtxDd.js +0 -2
  104. package/dist/esm/relayer-cleartext-Bp6jtxDd.js.map +0 -1
  105. package/dist/esm/relayer-cleartext-CSeMlmGO.d.ts +0 -844
  106. package/dist/esm/relayer-eavK5bfZ.js +0 -2
  107. package/dist/esm/relayer-eavK5bfZ.js.map +0 -1
  108. package/dist/esm/relayer-sdk.worker.js +0 -589
  109. package/dist/esm/timeout-CNVfiaJD.js +0 -2
  110. package/dist/esm/timeout-CNVfiaJD.js.map +0 -1
  111. package/dist/esm/token-Bt33g0zQ.js +0 -2
  112. package/dist/esm/token-Bt33g0zQ.js.map +0 -1
  113. package/dist/esm/types-BgczXqW2.d.ts +0 -49
  114. package/dist/esm/types-Gn5MeDsr.d.ts +0 -669
  115. package/dist/esm/validation-DLszOweh.js +0 -2
  116. package/dist/esm/validation-DLszOweh.js.map +0 -1
  117. package/dist/esm/worker.base-client-BVnT4yJa.js +0 -2
  118. package/dist/esm/worker.base-client-BVnT4yJa.js.map +0 -1
  119. package/dist/esm/wrappers-registry-C1oK8Bi6.js.map +0 -1
@@ -1,194 +1,5 @@
1
- import { n as FheChain } from "../types-BgczXqW2.js";
2
- import { a as hoodi, c as sepolia, i as hardhat, n as bscTestnet, o as ingenTestnet, r as chains, s as mainnet, t as anvil } from "../index-CYBH0nyo.js";
3
- import { $ as CreateDelegatedEIP712Request, At as WorkerEnv, C as BaseWorkerClient, Ct as RequestZKProofVerificationRequest, Dt as UserDecryptPayload, Et as UpdateCsrfRequest, Mt as WorkerRequestType, N as GenericStorage, Nt as WorkerResponse, Ot as UserDecryptRequest, Pt as SerializedError, Q as CreateDelegatedEIP712Payload, St as PublicDecryptResponseData, Tt as SuccessResponse, Z as BaseRequest, _ as PublicParamsData, _t as GetPublicParamsResponseData, at as DelegatedUserDecryptRequest, bt as PublicDecryptPayload, c as DelegatedUserDecryptParams, ct as EncryptRequest, d as EncryptParams, dt as GenerateKeypairRequest, et as CreateDelegatedEIP712ResponseData, f as EncryptResult, ft as GenerateKeypairResponseData, g as PublicDecryptResult, gt as GetPublicParamsRequest, ht as GetPublicKeyResponseData, it as DelegatedUserDecryptPayload, jt as WorkerRequest, kt as UserDecryptResponseData, l as EIP712TypedData, lt as EncryptResponseData, m as FheEncryptionKey, mt as GetPublicKeyRequest, n as RelayerSDK, nt as CreateEIP712Request, o as TransportKeyPair, ot as DelegatedUserDecryptResponseData, p as EncryptedValue, pt as GenericLogger, rt as CreateEIP712ResponseData, s as ClearValue, st as EncryptPayload, tt as CreateEIP712Payload, ut as ErrorResponse, vt as InitPayload, w as WorkerClientTimeoutConfig, wt as RequestZKProofVerificationResponseData, x as UserDecryptParams, xt as PublicDecryptRequest, yt as InitRequest } from "../relayer-cleartext-CSeMlmGO.js";
4
- import { l as BaseRelayer, n as RelayerConfig } from "../types-Gn5MeDsr.js";
5
- import { t as cleartext } from "../cleartext-DAkOTlrE.js";
6
- import { Address, Hex } from "viem";
7
- import { Worker } from "node:worker_threads";
8
- import { InputProofBytesType, KmsDelegatedUserDecryptEIP712Type, ZKProofLike } from "@zama-fhe/relayer-sdk/node";
9
-
10
- //#region src/worker/worker.node-client.d.ts
11
- interface NodeWorkerClientConfig extends WorkerClientTimeoutConfig {
12
- chains: FheChain[];
13
- /** SDK-wide logger for tracing worker request lifecycle. */
14
- logger: GenericLogger;
15
- }
16
- //#endregion
17
- //#region src/worker/worker.node-pool.d.ts
18
- interface NodeWorkerPoolConfig extends NodeWorkerClientConfig {
19
- poolSize?: number;
20
- }
21
- /**
22
- * Pool of Node.js worker threads for parallel FHE operations.
23
- *
24
- * **Default pool size:** `min(os.availableParallelism(), 4)`. Each worker loads
25
- * the full WASM module (~50–100 MB), so size the pool based on available memory.
26
- *
27
- * **Scheduling:** Least-connections — each request is dispatched to the worker
28
- * with the fewest in-flight operations.
29
- *
30
- * **When to override pool size:**
31
- * - High-throughput batch processing (e.g. bulk encryptions): increase to match CPU cores.
32
- * - Memory-constrained environments: decrease to 1–2 workers.
33
- *
34
- * **Lifecycle:**
35
- * 1. Initialize all workers: `await pool.initPool()`
36
- * 2. Use: `await pool.encrypt(...)`, `await pool.userDecrypt(...)`, etc.
37
- * 3. Shut down: `pool.terminate()`
38
- *
39
- * `initPool()` is idempotent — concurrent calls share the same initialization promise.
40
- * If any worker fails to initialize, all workers are terminated and the error is propagated.
41
- *
42
- * @internal Instantiated by the `node()` transport factory — not part of the public API.
43
- */
44
- declare class NodeWorkerPool {
45
- #private;
46
- /**
47
- * @param config - Pool configuration. Set `poolSize` to override the default
48
- * (`min(os.availableParallelism(), 4)`).
49
- */
50
- constructor(config: NodeWorkerPoolConfig);
51
- get poolSize(): number;
52
- initPool(): Promise<void>;
53
- terminate(): void;
54
- generateKeypair(params: GenerateKeypairRequest["payload"]): Promise<GenerateKeypairResponseData>;
55
- createEIP712(params: CreateEIP712Payload): Promise<CreateEIP712ResponseData>;
56
- encrypt(params: EncryptPayload): Promise<EncryptResponseData>;
57
- userDecrypt(params: UserDecryptPayload): Promise<UserDecryptResponseData>;
58
- publicDecrypt(params: PublicDecryptPayload): Promise<PublicDecryptResponseData>;
59
- createDelegatedUserDecryptEIP712(params: CreateDelegatedEIP712Payload): Promise<CreateDelegatedEIP712ResponseData>;
60
- delegatedUserDecrypt(params: DelegatedUserDecryptPayload): Promise<DelegatedUserDecryptResponseData>;
61
- requestZKProofVerification(params: RequestZKProofVerificationRequest["payload"]): Promise<RequestZKProofVerificationResponseData>;
62
- getPublicKey(params: GetPublicKeyRequest["payload"]): Promise<GetPublicKeyResponseData>;
63
- getPublicParams(params: GetPublicParamsRequest["payload"]): Promise<GetPublicParamsResponseData>;
64
- }
65
- //#endregion
66
- //#region src/relayer/relayer-node.d.ts
67
- interface RelayerNodeConfig {
68
- /** FHE chain configuration. */
69
- chain: FheChain;
70
- /** Worker thread pool — handles WASM operations off the main thread. */
71
- pool: NodeWorkerPool;
72
- /** SDK-wide logger for observing worker lifecycle and request timing. */
73
- logger: GenericLogger;
74
- /**
75
- * Persistent storage for caching FHE public key and params across sessions.
76
- * Defaults to `new MemoryStorage()` (in-process, lost on restart).
77
- * Pass a custom `GenericStorage` with redis for cross-restart persistence.
78
- */
79
- fheArtifactStorage?: GenericStorage;
80
- /** Cache TTL in seconds for FHE public material. Default: 86 400 (24 h). Set to 0 to revalidate on every operation. */
81
- fheArtifactCacheTTL?: number;
82
- }
83
- /**
84
- * RelayerNode — Node.js encryption/decryption layer.
85
- * The pool is injected at construction time; the relayer does not own its lifecycle.
86
- */
87
- declare class RelayerNode extends BaseRelayer implements RelayerSDK, Disposable {
88
- #private;
89
- constructor(config: RelayerNodeConfig);
90
- protected get chain(): FheChain;
91
- protected init(): Promise<void>;
92
- /**
93
- * Terminate clears the artifact cache only.
94
- * The pool is externally owned — the relayer does not terminate it.
95
- */
96
- terminate(): void;
97
- /** Calls {@link terminate}. */
98
- [Symbol.dispose](): void;
99
- generateTransportKeyPair(): Promise<TransportKeyPair>;
100
- createEIP712(publicKey: Hex, contractAddresses: Address[], startTimestamp: number, durationDays?: number): Promise<EIP712TypedData>;
101
- encrypt(params: EncryptParams): Promise<EncryptResult>;
102
- userDecrypt(params: UserDecryptParams): Promise<Readonly<Record<EncryptedValue, ClearValue>>>;
103
- publicDecrypt(encryptedValues: EncryptedValue[]): Promise<PublicDecryptResult>;
104
- createDelegatedUserDecryptEIP712(publicKey: Hex, contractAddresses: Address[], delegatorAddress: Address, startTimestamp: number, durationDays?: number): Promise<KmsDelegatedUserDecryptEIP712Type>;
105
- delegatedUserDecrypt(params: DelegatedUserDecryptParams): Promise<Readonly<Record<EncryptedValue, ClearValue>>>;
106
- requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType>;
107
- fetchFheEncryptionKeyBytes(): Promise<FheEncryptionKey | null>;
108
- getPublicParams(bits: number): Promise<PublicParamsData | null>;
109
- }
110
- //#endregion
111
- //#region src/node/config.d.ts
112
- /**
113
- * Pool options for the `node()` transport factory.
114
- *
115
- * Logging is configured once, SDK-wide, via `createConfig({ logger })` — there
116
- * is deliberately no per-relayer logger option.
117
- */
118
- interface NodePoolOptions {
119
- poolSize?: number;
120
- fheArtifactStorage?: GenericStorage;
121
- fheArtifactCacheTTL?: number;
122
- /**
123
- * Per-operation worker timeout in **seconds** (encrypt / decrypt / etc.).
124
- * Defaults to 30. A timed-out operation rejects with `WorkerTimeoutError` and
125
- * recycles the worker (see {@link recycleWorkerOnTimeout}).
126
- */
127
- operationTimeout?: number;
128
- /** WASM-init timeout in **seconds**. Defaults to 60. */
129
- initTimeout?: number;
130
- /**
131
- * Terminate + re-init the worker after an operation timeout so a hung thread
132
- * can't keep serving requests. Defaults to `true`. Note: a timeout caused by a
133
- * slow/down relayer (not a stuck thread) also recycles an otherwise-healthy
134
- * worker, paying a WASM re-init on the next call — when fronting a flaky
135
- * relayer, prefer `false` with a higher `operationTimeout`.
136
- */
137
- recycleWorkerOnTimeout?: boolean;
138
- }
139
- /** Node transport — narrows worker type to `NodeWorkerPool`. */
140
- interface NodeRelayerConfig extends RelayerConfig {
141
- readonly type: "node";
142
- readonly createWorker: (chains: FheChain[], logger: GenericLogger) => NodeWorkerPool;
143
- readonly createRelayer: (chain: FheChain, worker: NodeWorkerPool, logger: GenericLogger) => RelayerNode;
144
- }
145
- /**
146
- * Node.js transport — routes to RelayerNode (worker thread pool).
147
- *
148
- * @param options - Pool options: `poolSize`, `fheArtifactStorage`,
149
- * `fheArtifactCacheTTL`, and the worker-timeout knobs `operationTimeout` /
150
- * `initTimeout` (seconds) and `recycleWorkerOnTimeout`.
151
- *
152
- * @example
153
- * ```ts
154
- * relayers: {
155
- * [sepolia.id]: node(),
156
- * [mainnet.id]: node({ poolSize: 4, operationTimeout: 10 }),
157
- * }
158
- * ```
159
- */
160
- declare function node(options?: NodePoolOptions): NodeRelayerConfig;
161
- //#endregion
162
- //#region src/storage/async-local-storage.d.ts
163
- /**
164
- * {@link GenericStorage} backed by Node.js {@link AsyncLocalStorage}.
165
- *
166
- * Each async context (e.g. HTTP request) gets its own isolated `Map`,
167
- * so credentials from one request never leak into another.
168
- *
169
- * Call {@link run} to establish a context before using the SDK:
170
- *
171
- * ```ts
172
- * import { asyncLocalStorage } from "@zama-fhe/sdk/node";
173
- *
174
- * app.post("/api/transfer", (req, res) => {
175
- * asyncLocalStorage.run(async () => {
176
- * const sdk = new ZamaSDK({ relayer, signer, storage: asyncLocalStorage });
177
- * // credentials are scoped to this request
178
- * });
179
- * });
180
- * ```
181
- */
182
- declare class AsyncLocalMapStorage implements GenericStorage {
183
- #private;
184
- /** Execute `fn` within an isolated storage context. */
185
- run<R>(fn: () => R | Promise<R>): R | Promise<R>;
186
- get<T = unknown>(key: string): Promise<T | null>;
187
- set<T = unknown>(key: string, value: T): Promise<void>;
188
- delete(key: string): Promise<void>;
189
- }
190
- /** Default singleton for application-wide use. */
191
- declare const asyncLocalStorage: AsyncLocalMapStorage;
192
- //#endregion
193
- export { AsyncLocalMapStorage, type BaseRequest, BaseWorkerClient, type ClearValue, type CreateDelegatedEIP712Payload, type CreateDelegatedEIP712Request, type CreateDelegatedEIP712ResponseData, type CreateEIP712Payload, type CreateEIP712Request, type CreateEIP712ResponseData, type PublicDecryptResult as DecryptPublicValuesResult, type UserDecryptParams as DecryptValuesParams, type DelegatedUserDecryptParams as DelegatedDecryptValuesParams, type DelegatedUserDecryptPayload, type DelegatedUserDecryptRequest, type DelegatedUserDecryptResponseData, type EIP712TypedData, type EncryptParams, type EncryptPayload, type EncryptRequest, type EncryptResponseData, type EncryptResult, type ErrorResponse, type GenerateKeypairRequest, type GenerateKeypairResponseData, type GenericLogger, type GetPublicKeyRequest, type GetPublicKeyResponseData, type GetPublicParamsRequest, type GetPublicParamsResponseData, type InitPayload, type InitRequest, type NodePoolOptions, type NodeRelayerConfig, type NodeWorkerClientConfig, type NodeWorkerPoolConfig, type PublicDecryptRequest, type PublicDecryptResponseData, type RelayerConfig, type RelayerNodeConfig, type RelayerSDK, type RequestZKProofVerificationRequest, type RequestZKProofVerificationResponseData, type SerializedError, type SuccessResponse, type UpdateCsrfRequest, type UserDecryptPayload, type UserDecryptRequest, type UserDecryptResponseData, type WorkerEnv, type WorkerRequest, type WorkerRequestType, type WorkerResponse, anvil, asyncLocalStorage, bscTestnet, chains, cleartext, hardhat, hoodi, ingenTestnet, mainnet, node, sepolia };
194
- //# sourceMappingURL=index.d.ts.map
1
+ import { a as hoodi, c as sepolia, i as hardhat, n as bscTestnet, o as ingenTestnet, r as chains, s as mainnet, t as anvil } from "../index-D66eC3G7.js";
2
+ import { It as EIP712TypedData, Nt as ClearValue, Pt as DecryptPublicValuesResult, Rt as EncryptParams, Ut as FhevmRelayerSDK, n as RelayerConfig, s as GenericLogger } from "../types-C-WTLcHZ.js";
3
+ import { t as cleartext } from "../cleartext-U6sPs_Kd.js";
4
+ import { i as node, n as asyncLocalStorage, r as NodeRelayerConfig, t as AsyncLocalMapStorage } from "../index-BnIp_-Ak.js";
5
+ export { AsyncLocalMapStorage, type ClearValue, type DecryptPublicValuesResult, type EIP712TypedData, type EncryptParams, type GenericLogger, type NodeRelayerConfig, type RelayerConfig, type FhevmRelayerSDK as RelayerSDK, anvil, asyncLocalStorage, bscTestnet, chains, cleartext, hardhat, hoodi, ingenTestnet, mainnet, node, sepolia };
@@ -1,2 +1,2 @@
1
- import{n as e}from"../assertions-zYseN5Xz.js";import{t}from"../cleartext-rTWFctyd.js";import{t as n}from"../memory-storage-fp9RY5BQ.js";import{a as r,c as i,i as a,n as o,o as s,r as c,s as l,t as u}from"../chains-CXcO1DBP.js";import{t as d}from"../validation-DLszOweh.js";import{i as f,n as p,r as m,t as h}from"../worker.base-client-BVnT4yJa.js";import{toHex as g}from"viem";import{z as _}from"zod/mini";import{availableParallelism as v}from"node:os";import{Worker as y}from"node:worker_threads";import{randomUUID as b}from"node:crypto";import{createRequire as x}from"node:module";import{pathToFileURL as S}from"node:url";import{AsyncLocalStorage as C}from"node:async_hooks";var w=class extends f{#e;#t=null;constructor(e){super(),this.#e={fheArtifactStorage:new n,...e}}get chain(){return this.#e.chain}async init(){await this.#n.initPool()}get#n(){return this.#e.pool}#r(){return this.#e.fheArtifactStorage?(this.#t||=new m({storage:this.#e.fheArtifactStorage,chainId:this.chain.id,relayerUrl:this.chain.relayerUrl,ttl:this.#e.fheArtifactCacheTTL,logger:this.#e.logger}),this.#t):null}terminate(){this.#t=null,this.resetInit()}[Symbol.dispose](){this.terminate()}async generateTransportKeyPair(){await this.ensureInit();let e=this.chain.id,t=await this.#n.generateKeypair({chainId:e});return{publicKey:t.publicKey,privateKey:t.privateKey}}async createEIP712(e,t,n,r=7){await this.ensureInit();let i=this.chain.id;return this.#n.createEIP712({chainId:i,publicKey:e,contractAddresses:t,startTimestamp:n,durationDays:r})}async encrypt(e){await this.ensureInit();let t=this.chain.id;return p(async()=>{let n=await this.#n.encrypt({chainId:t,...e});return{encryptedValues:n.handles.map(e=>g(e)),inputProof:g(n.inputProof)}})}async userDecrypt(e){await this.ensureInit();let t=this.chain.id;return p(async()=>(await this.#n.userDecrypt({chainId:t,...e})).clearValues)}async publicDecrypt(e){await this.ensureInit();let t=this.chain.id;return p(async()=>{let n=await this.#n.publicDecrypt({chainId:t,encryptedValues:e});return{clearValues:n.clearValues,abiEncodedClearValues:n.abiEncodedClearValues,decryptionProof:n.decryptionProof}})}async createDelegatedUserDecryptEIP712(e,t,n,r,i=7){await this.ensureInit();let a=this.chain.id;return this.#n.createDelegatedUserDecryptEIP712({chainId:a,publicKey:e,contractAddresses:t,delegatorAddress:n,startTimestamp:r,durationDays:i})}async delegatedUserDecrypt(e){await this.ensureInit();let t=this.chain.id;return p(async()=>(await this.#n.delegatedUserDecrypt({chainId:t,...e})).clearValues)}async requestZKProofVerification(e){await this.ensureInit();let t=this.chain.id;return p(async()=>this.#n.requestZKProofVerification({chainId:t,zkProof:e}))}async fetchFheEncryptionKeyBytes(){await this.ensureInit();let e=this.chain.id,t=this.#r();return t?t.fetchFheEncryptionKeyBytes(async()=>(await this.#n.getPublicKey({chainId:e})).result):(await this.#n.getPublicKey({chainId:e})).result}async getPublicParams(e){await this.ensureInit();let t=this.chain.id,n=this.#r();return n?n.getPublicParams(e,async()=>(await this.#n.getPublicParams({chainId:t,bits:e})).result):(await this.#n.getPublicParams({chainId:t,bits:e})).result}},T=class extends h{env=`node`;constructor(e){super(e,e.logger)}createWorker(){let e=S(x(import.meta.url).resolve(`@zama-fhe/sdk/node`));return new y(new URL(`relayer-sdk.node-worker.js`,e))}wireEvents(e){e.on(`message`,e=>this.handleResponse(e)),e.on(`error`,e=>this.handleWorkerError(e.message)),e.on(`messageerror`,()=>this.handleWorkerMessageError())}postMessage(e,t){e.postMessage(t)}terminateWorker(e){e.terminate()}generateRequestId(){return b()}getInitPayload(){return{type:`INIT`,payload:{env:`node`,chains:this.config.chains}}}onWorkerReady(e){e.unref()}},E=class{#e=[];#t=[];#n;#r;#i=null;constructor(e){this.#n=e,this.#r=e.poolSize??Math.min(v(),4)}get poolSize(){return this.#r}async initPool(){if(!(this.#e.length>0))return this.#i||=this.#a().finally(()=>{this.#i=null}),this.#i}async#a(){for(let e=0;e<this.#r;e++)this.#e.push(new T({...this.#n,workerLabel:`node-worker-${e}`})),this.#t.push(0);try{await Promise.all(this.#e.map(e=>e.initWorker()))}catch(e){for(let e of this.#e)e.terminate();throw this.#e.length=0,this.#t.length=0,e}}terminate(){let e=[];for(let t of this.#e)try{t.terminate()}catch(t){e.push(t instanceof Error?t:Error(String(t)))}if(this.#e.length=0,this.#t.length=0,e.length>0)throw AggregateError(e,`Failed to terminate worker pool`)}#o(){let e=0,t=this.#t[0];for(let n=1;n<this.#t.length;n++)this.#t[n]<t&&(t=this.#t[n],e=n);return e}async#s(e){if(this.#e.length===0)throw Error(`NodeWorkerPool not initialized. Call initPool() first.`);let t=this.#o();this.#t[t]++;try{return await e(this.#e[t])}finally{this.#t[t]--}}async generateKeypair(e){return this.#s(t=>t.generateKeypair(e))}async createEIP712(e){return this.#s(t=>t.createEIP712(e))}async encrypt(e){return this.#s(t=>t.encrypt(e))}async userDecrypt(e){return this.#s(t=>t.userDecrypt(e))}async publicDecrypt(e){return this.#s(t=>t.publicDecrypt(e))}async createDelegatedUserDecryptEIP712(e){return this.#s(t=>t.createDelegatedUserDecryptEIP712(e))}async delegatedUserDecrypt(e){return this.#s(t=>t.delegatedUserDecrypt(e))}async requestZKProofVerification(e){return this.#s(t=>t.requestZKProofVerification(e))}async getPublicKey(e){return this.#s(t=>t.getPublicKey(e))}async getPublicParams(e){return this.#s(t=>t.getPublicParams(e))}};const D=3600,O=_.object({poolSize:_.optional(_.int().check(_.positive())),fheArtifactCacheTTL:_.optional(_.int().check(_.nonnegative())),operationTimeout:_.optional(_.int().check(_.positive(),_.lte(D))),initTimeout:_.optional(_.int().check(_.positive(),_.lte(D))),recycleWorkerOnTimeout:_.optional(_.boolean())});function k(t){return t!==void 0&&d(O,t),{type:`node`,createWorker:(e,n)=>new E({chains:e,...t,logger:n}),createRelayer:(n,r,i)=>(e(!!r,`node() relayer requires a worker pool — createWorker must be called first.`),new w({chain:n,pool:r,...t,logger:i}))}}var A=class{#e=new C;run(e){return this.#e.run(new Map,e)}async get(e){return this.#e.getStore()?.get(e)??null}async set(e,t){this.#e.getStore()?.set(e,t)}async delete(e){this.#e.getStore()?.delete(e)}};const j=new A;export{A as AsyncLocalMapStorage,h as BaseWorkerClient,u as anvil,j as asyncLocalStorage,o as bscTestnet,c as chains,t as cleartext,a as hardhat,r as hoodi,s as ingenTestnet,l as mainnet,k as node,i as sepolia};
1
+ import{t as e}from"../fhevm-relayer-B-lEKfPQ.js";import{t}from"../cleartext-BfXTVQu-.js";import{a as n,c as r,i,n as a,o,r as s,s as c,t as l}from"../chains-CLv9HEJ_.js";import{AsyncLocalStorage as u}from"node:async_hooks";function d(t){return{type:`node`,createRelayer:n=>new e({chain:n,options:t})}}var f=class{#e=new u;run(e){return this.#e.run(new Map,e)}async get(e){return this.#e.getStore()?.get(e)??null}async set(e,t){this.#e.getStore()?.set(e,t)}async delete(e){this.#e.getStore()?.delete(e)}};const p=new f;export{f as AsyncLocalMapStorage,l as anvil,p as asyncLocalStorage,a as bscTestnet,s as chains,t as cleartext,i as hardhat,n as hoodi,o as ingenTestnet,c as mainnet,d as node,r as sepolia};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#config","#pool","#artifactCache","#getArtifactCache","#workers","#activeCount","#config","#poolSize","#initPromise","#doInitPool","#dispatch","#leastBusyIndex","#als"],"sources":["../../../src/relayer/relayer-node.ts","../../../src/worker/worker.node-client.ts","../../../src/worker/worker.node-pool.ts","../../../src/node/config.ts","../../../src/storage/async-local-storage.ts"],"sourcesContent":["import type {\n InputProofBytesType,\n KmsDelegatedUserDecryptEIP712Type,\n ZKProofLike,\n} from \"@zama-fhe/relayer-sdk/node\";\nimport { toHex } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport { MemoryStorage } from \"../storage/memory-storage\";\nimport type { GenericStorage } from \"../types\";\nimport type { NodeWorkerPool } from \"../worker/worker.node-pool\";\nimport type { GenericLogger } from \"../worker/worker.types\";\nimport type { FheChain } from \"../chains/types\";\nimport type { TransportKeyPair } from \"../credentials/types\";\nimport { BaseRelayer } from \"./base-relayer\";\nimport { FheArtifactCache } from \"./fhe-artifact-cache\";\nimport type { RelayerSDK } from \"./relayer-sdk\";\nimport type {\n ClearValue,\n DelegatedUserDecryptParams,\n EIP712TypedData,\n EncryptParams,\n EncryptResult,\n EncryptedValue,\n FheEncryptionKey,\n PublicDecryptResult,\n PublicParamsData,\n UserDecryptParams,\n} from \"./relayer-sdk.types\";\nimport { withRetry } from \"./relayer-utils\";\n\nexport interface RelayerNodeConfig {\n /** FHE chain configuration. */\n chain: FheChain;\n /** Worker thread pool — handles WASM operations off the main thread. */\n pool: NodeWorkerPool;\n /** SDK-wide logger for observing worker lifecycle and request timing. */\n logger: GenericLogger;\n /**\n * Persistent storage for caching FHE public key and params across sessions.\n * Defaults to `new MemoryStorage()` (in-process, lost on restart).\n * Pass a custom `GenericStorage` with redis for cross-restart persistence.\n */\n fheArtifactStorage?: GenericStorage;\n /** Cache TTL in seconds for FHE public material. Default: 86 400 (24 h). Set to 0 to revalidate on every operation. */\n fheArtifactCacheTTL?: number;\n}\n\n/**\n * RelayerNode — Node.js encryption/decryption layer.\n * The pool is injected at construction time; the relayer does not own its lifecycle.\n */\nexport class RelayerNode extends BaseRelayer implements RelayerSDK, Disposable {\n readonly #config: RelayerNodeConfig;\n #artifactCache: FheArtifactCache | null = null;\n\n constructor(config: RelayerNodeConfig) {\n super();\n this.#config = { fheArtifactStorage: new MemoryStorage(), ...config };\n }\n\n protected get chain(): FheChain {\n return this.#config.chain;\n }\n\n protected async init(): Promise<void> {\n await this.#pool.initPool();\n }\n\n get #pool(): NodeWorkerPool {\n return this.#config.pool;\n }\n\n #getArtifactCache(): FheArtifactCache | null {\n if (!this.#config.fheArtifactStorage) {\n return null;\n }\n if (!this.#artifactCache) {\n this.#artifactCache = new FheArtifactCache({\n storage: this.#config.fheArtifactStorage,\n chainId: this.chain.id,\n relayerUrl: this.chain.relayerUrl,\n ttl: this.#config.fheArtifactCacheTTL,\n logger: this.#config.logger,\n });\n }\n return this.#artifactCache;\n }\n\n /**\n * Terminate clears the artifact cache only.\n * The pool is externally owned — the relayer does not terminate it.\n */\n terminate(): void {\n this.#artifactCache = null;\n this.resetInit();\n }\n\n /** Calls {@link terminate}. */\n [Symbol.dispose](): void {\n this.terminate();\n }\n\n async generateTransportKeyPair(): Promise<TransportKeyPair> {\n await this.ensureInit();\n const chainId = this.chain.id;\n const result = await this.#pool.generateKeypair({ chainId });\n return { publicKey: result.publicKey, privateKey: result.privateKey };\n }\n\n async createEIP712(\n publicKey: Hex,\n contractAddresses: Address[],\n startTimestamp: number,\n durationDays = 7,\n ): Promise<EIP712TypedData> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return this.#pool.createEIP712({\n chainId,\n publicKey,\n contractAddresses,\n startTimestamp,\n durationDays,\n });\n }\n\n async encrypt(params: EncryptParams): Promise<EncryptResult> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return withRetry(async () => {\n const result = await this.#pool.encrypt({ chainId, ...params });\n return {\n encryptedValues: result.handles.map((handle) => toHex(handle)),\n inputProof: toHex(result.inputProof),\n };\n });\n }\n\n async userDecrypt(\n params: UserDecryptParams,\n ): Promise<Readonly<Record<EncryptedValue, ClearValue>>> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return withRetry(async () => {\n const result = await this.#pool.userDecrypt({ chainId, ...params });\n return result.clearValues;\n });\n }\n\n async publicDecrypt(encryptedValues: EncryptedValue[]): Promise<PublicDecryptResult> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return withRetry(async () => {\n const result = await this.#pool.publicDecrypt({ chainId, encryptedValues });\n return {\n clearValues: result.clearValues,\n abiEncodedClearValues: result.abiEncodedClearValues,\n decryptionProof: result.decryptionProof,\n };\n });\n }\n\n async createDelegatedUserDecryptEIP712(\n publicKey: Hex,\n contractAddresses: Address[],\n delegatorAddress: Address,\n startTimestamp: number,\n durationDays = 7,\n ): Promise<KmsDelegatedUserDecryptEIP712Type> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return this.#pool.createDelegatedUserDecryptEIP712({\n chainId,\n publicKey,\n contractAddresses,\n delegatorAddress,\n startTimestamp,\n durationDays,\n });\n }\n\n async delegatedUserDecrypt(\n params: DelegatedUserDecryptParams,\n ): Promise<Readonly<Record<EncryptedValue, ClearValue>>> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return withRetry(async () => {\n const result = await this.#pool.delegatedUserDecrypt({ chainId, ...params });\n return result.clearValues;\n });\n }\n\n async requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType> {\n await this.ensureInit();\n const chainId = this.chain.id;\n return withRetry(async () => {\n return this.#pool.requestZKProofVerification({ chainId, zkProof });\n });\n }\n\n async fetchFheEncryptionKeyBytes(): Promise<FheEncryptionKey | null> {\n await this.ensureInit();\n const chainId = this.chain.id;\n const artifactCache = this.#getArtifactCache();\n if (artifactCache) {\n return artifactCache.fetchFheEncryptionKeyBytes(\n async () => (await this.#pool.getPublicKey({ chainId })).result,\n );\n }\n return (await this.#pool.getPublicKey({ chainId })).result;\n }\n\n async getPublicParams(bits: number): Promise<PublicParamsData | null> {\n await this.ensureInit();\n const chainId = this.chain.id;\n const artifactCache = this.#getArtifactCache();\n if (artifactCache) {\n return artifactCache.getPublicParams(\n bits,\n async () => (await this.#pool.getPublicParams({ chainId, bits })).result,\n );\n }\n return (await this.#pool.getPublicParams({ chainId, bits })).result;\n }\n}\n","import { Worker } from \"node:worker_threads\";\nimport { randomUUID } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\nimport type { FheChain } from \"../chains/types\";\nimport type {\n GenericLogger,\n WorkerEnv,\n WorkerRequest,\n WorkerRequestType,\n WorkerResponse,\n} from \"./worker.types\";\nimport { BaseWorkerClient } from \"./worker.base-client\";\nimport type { WorkerClientTimeoutConfig } from \"./worker.base-client\";\n\nexport interface NodeWorkerClientConfig extends WorkerClientTimeoutConfig {\n chains: FheChain[];\n /** SDK-wide 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 protected readonly env: WorkerEnv = \"node\";\n\n constructor(config: NodeWorkerClientConfig) {\n super(config, config.logger);\n }\n\n protected createWorker(): Worker {\n // Resolve relative to the @zama-fhe/sdk/node entry point so the path is\n // correct regardless of which rolldown chunk this code lands in.\n //\n // Use createRequire(...).resolve rather than import.meta.resolve: Vite's\n // SSR transform (Ponder and other server-side bundlers) rewrites\n // `import.meta.resolve` to `__vite_ssr_import_meta__.resolve`, which is\n // undefined at runtime and makes this throw. createRequire only relies on\n // `import.meta.url`, which those transforms preserve. See SDK-235.\n const require = createRequire(import.meta.url);\n const nodeEntry = pathToFileURL(require.resolve(\"@zama-fhe/sdk/node\"));\n return new Worker(new URL(\"relayer-sdk.node-worker.js\", nodeEntry));\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 void worker.terminate();\n }\n\n protected generateRequestId(): string {\n return randomUUID();\n }\n\n protected getInitPayload(): { type: WorkerRequestType; payload: WorkerRequest[\"payload\"] } {\n return { type: \"INIT\", payload: { env: \"node\" as const, chains: this.config.chains } };\n }\n\n protected override 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 {\n CreateDelegatedEIP712Payload,\n CreateDelegatedEIP712ResponseData,\n CreateEIP712Payload,\n CreateEIP712ResponseData,\n DelegatedUserDecryptPayload,\n DelegatedUserDecryptResponseData,\n EncryptPayload,\n EncryptResponseData,\n GenerateKeypairRequest,\n GenerateKeypairResponseData,\n GetPublicKeyRequest,\n GetPublicKeyResponseData,\n GetPublicParamsRequest,\n GetPublicParamsResponseData,\n PublicDecryptPayload,\n PublicDecryptResponseData,\n RequestZKProofVerificationRequest,\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. Initialize all workers: `await pool.initPool()`\n * 2. Use: `await pool.encrypt(...)`, `await pool.userDecrypt(...)`, etc.\n * 3. 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 *\n * @internal Instantiated by the `node()` transport factory — not part of the public API.\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) {\n return;\n }\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 // Stamp a per-worker label so a WorkerTimeoutError names which worker stalled.\n this.#workers.push(\n new NodeWorkerClient({ ...this.#config, workerLabel: `node-worker-${i}` }),\n );\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 const errors: Error[] = [];\n for (const worker of this.#workers) {\n try {\n worker.terminate();\n } catch (e) {\n errors.push(e instanceof Error ? e : new Error(String(e)));\n }\n }\n this.#workers.length = 0;\n this.#activeCount.length = 0;\n if (errors.length > 0) {\n throw new AggregateError(errors, \"Failed to terminate worker pool\");\n }\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(\n params: GenerateKeypairRequest[\"payload\"],\n ): Promise<GenerateKeypairResponseData> {\n return this.#dispatch((w) => w.generateKeypair(params));\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(params: PublicDecryptPayload): Promise<PublicDecryptResponseData> {\n return this.#dispatch((w) => w.publicDecrypt(params));\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 params: RequestZKProofVerificationRequest[\"payload\"],\n ): Promise<RequestZKProofVerificationResponseData> {\n return this.#dispatch((w) => w.requestZKProofVerification(params));\n }\n\n async getPublicKey(params: GetPublicKeyRequest[\"payload\"]): Promise<GetPublicKeyResponseData> {\n return this.#dispatch((w) => w.getPublicKey(params));\n }\n\n async getPublicParams(\n params: GetPublicParamsRequest[\"payload\"],\n ): Promise<GetPublicParamsResponseData> {\n return this.#dispatch((w) => w.getPublicParams(params));\n }\n}\n","import { z } from \"zod/mini\";\nimport type { RelayerConfig } from \"../config/types\";\nimport type { GenericLogger } from \"../worker/worker.types\";\nimport { RelayerNode } from \"../relayer/relayer-node\";\nimport type { FheChain } from \"../chains/types\";\nimport type { GenericStorage } from \"../types\";\nimport { parseConfiguration } from \"../validation\";\nimport { NodeWorkerPool } from \"../worker/worker.node-pool\";\nimport { assertCondition } from \"../utils\";\n\n/**\n * Pool options for the `node()` transport factory.\n *\n * Logging is configured once, SDK-wide, via `createConfig({ logger })` — there\n * is deliberately no per-relayer logger option.\n */\nexport interface NodePoolOptions {\n poolSize?: number;\n fheArtifactStorage?: GenericStorage;\n fheArtifactCacheTTL?: number;\n /**\n * Per-operation worker timeout in **seconds** (encrypt / decrypt / etc.).\n * Defaults to 30. A timed-out operation rejects with `WorkerTimeoutError` and\n * recycles the worker (see {@link recycleWorkerOnTimeout}).\n */\n operationTimeout?: number;\n /** WASM-init timeout in **seconds**. Defaults to 60. */\n initTimeout?: number;\n /**\n * Terminate + re-init the worker after an operation timeout so a hung thread\n * can't keep serving requests. Defaults to `true`. Note: a timeout caused by a\n * slow/down relayer (not a stuck thread) also recycles an otherwise-healthy\n * worker, paying a WASM re-init on the next call — when fronting a flaky\n * relayer, prefer `false` with a higher `operationTimeout`.\n */\n recycleWorkerOnTimeout?: boolean;\n}\n\n/** Node transport — narrows worker type to `NodeWorkerPool`. */\nexport interface NodeRelayerConfig extends RelayerConfig {\n readonly type: \"node\";\n readonly createWorker: (chains: FheChain[], logger: GenericLogger) => NodeWorkerPool;\n readonly createRelayer: (\n chain: FheChain,\n worker: NodeWorkerPool,\n logger: GenericLogger,\n ) => RelayerNode;\n}\n\n/**\n * Upper bound (seconds) for the worker-timeout knobs. Timeouts are passed to\n * `setTimeout`, whose delay is a 32-bit signed int of **milliseconds**: a value\n * over ~24.8 days overflows and clamps to ~1 ms, silently firing instantly. Cap\n * well below that (1 hour is already far beyond any legitimate FHE operation) so\n * an absurd config fails loudly at the factory boundary instead of misbehaving.\n */\nconst MAX_WORKER_TIMEOUT_SECONDS = 3_600;\n\nconst NodePoolOptionsSchema = z.object({\n poolSize: z.optional(z.int().check(z.positive())),\n fheArtifactCacheTTL: z.optional(z.int().check(z.nonnegative())),\n operationTimeout: z.optional(z.int().check(z.positive(), z.lte(MAX_WORKER_TIMEOUT_SECONDS))),\n initTimeout: z.optional(z.int().check(z.positive(), z.lte(MAX_WORKER_TIMEOUT_SECONDS))),\n recycleWorkerOnTimeout: z.optional(z.boolean()),\n});\n\n/**\n * Node.js transport — routes to RelayerNode (worker thread pool).\n *\n * @param options - Pool options: `poolSize`, `fheArtifactStorage`,\n * `fheArtifactCacheTTL`, and the worker-timeout knobs `operationTimeout` /\n * `initTimeout` (seconds) and `recycleWorkerOnTimeout`.\n *\n * @example\n * ```ts\n * relayers: {\n * [sepolia.id]: node(),\n * [mainnet.id]: node({ poolSize: 4, operationTimeout: 10 }),\n * }\n * ```\n */\nexport function node(options?: NodePoolOptions): NodeRelayerConfig {\n if (options !== undefined) {\n parseConfiguration(NodePoolOptionsSchema, options);\n }\n return {\n type: \"node\",\n createWorker: (chains, logger) => new NodeWorkerPool({ chains, ...options, logger }),\n createRelayer: (chain, pool, logger) => {\n assertCondition(\n !!pool,\n \"node() relayer requires a worker pool — createWorker must be called first.\",\n );\n return new RelayerNode({ chain, pool, ...options, logger });\n },\n };\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { GenericStorage } from \"../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"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["#als"],"sources":["../../../src/node/config.ts","../../../src/storage/async-local-storage.ts"],"sourcesContent":["import type { FheChain } from \"../chains/types\";\nimport type { RelayerConfig } from \"../config/types\";\nimport { FhevmRelayer } from \"../relayer/fhevm-relayer\";\nimport type { RelayerOptions } from \"../relayer/types\";\n\n/** Node transport — drives the FHE backend directly on the calling thread. */\nexport interface NodeRelayerConfig extends RelayerConfig {\n readonly type: \"node\";\n readonly createRelayer: (chain: FheChain) => FhevmRelayer;\n}\n\n/**\n * Node.js transport — drives `@fhevm/sdk` via {@link FhevmRelayer} on the calling thread.\n *\n * @example\n * ```ts\n * relayers: {\n * [sepolia.id]: node({ timeout: 5 * 60_000 }),\n * [mainnet.id]: node({ batchRpcCalls: true }),\n * }\n * ```\n */\nexport function node(options?: RelayerOptions): NodeRelayerConfig {\n return { type: \"node\", createRelayer: (chain) => new FhevmRelayer({ chain, options }) };\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { GenericStorage } from \"../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"],"mappings":"+NAsBA,SAAgB,EAAK,EAA6C,CAChE,MAAO,CAAE,KAAM,OAAQ,cAAgB,GAAU,IAAI,EAAa,CAAE,QAAO,SAAQ,CAAC,CAAE,CACxF,CCFA,IAAa,EAAb,KAA4D,CAC1D,GAAgB,IAAI,EAGpB,IAAO,EAA0C,CAC/C,OAAO,KAAKA,GAAK,IAAI,IAAI,IAAO,CAAE,CACpC,CAEA,MAAM,IAAiB,EAAgC,CACrD,OAAQ,KAAKA,GAAK,SAAS,CAAC,EAAE,IAAI,CAAG,GAAW,IAClD,CAEA,MAAM,IAAiB,EAAa,EAAyB,CAC3D,KAAKA,GAAK,SAAS,CAAC,EAAE,IAAI,EAAK,CAAK,CACtC,CAEA,MAAM,OAAO,EAA4B,CACvC,KAAKA,GAAK,SAAS,CAAC,EAAE,OAAO,CAAG,CAClC,CACF,EAGA,MAAa,EAAoB,IAAI"}