@enclave-e3/sdk 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,23 +1,12 @@
1
1
  // src/enclave-sdk.ts
2
- import {
3
- createPublicClient,
4
- createWalletClient,
5
- http,
6
- webSocket
7
- } from "viem";
2
+ import { createPublicClient, createWalletClient, http, webSocket } from "viem";
8
3
  import { privateKeyToAccount } from "viem/accounts";
9
4
  import { hardhat, mainnet, monadTestnet, sepolia } from "viem/chains";
10
5
  import initializeWasm from "@enclave-e3/wasm/init";
11
- import {
12
- CiphernodeRegistryOwnable__factory as CiphernodeRegistryOwnable__factory2,
13
- Enclave__factory as Enclave__factory2
14
- } from "@enclave-e3/contracts/types";
6
+ import { CiphernodeRegistryOwnable__factory as CiphernodeRegistryOwnable__factory2, Enclave__factory as Enclave__factory2 } from "@enclave-e3/contracts/types";
15
7
 
16
8
  // src/contract-client.ts
17
- import {
18
- CiphernodeRegistryOwnable__factory,
19
- Enclave__factory
20
- } from "@enclave-e3/contracts/types";
9
+ import { CiphernodeRegistryOwnable__factory, Enclave__factory, EnclaveToken__factory } from "@enclave-e3/contracts/types";
21
10
 
22
11
  // src/utils.ts
23
12
  import { encodeAbiParameters } from "viem";
@@ -55,12 +44,14 @@ function generateEventId(log) {
55
44
  function getCurrentTimestamp() {
56
45
  return Math.floor(Date.now() / 1e3);
57
46
  }
58
- var BFV_PARAMS_SET = {
47
+ var INSECURE_SET_2048_1032193_1 = {
59
48
  degree: 2048,
60
49
  plaintext_modulus: 1032193,
61
- moduli: [0x3fffffff000001n]
50
+ moduli: [0x3fffffff000001n],
62
51
  // BigInt for the modulus
52
+ error1_variance: "10"
63
53
  };
54
+ var BFV_PARAMS_SET = INSECURE_SET_2048_1032193_1;
64
55
  var DEFAULT_COMPUTE_PROVIDER_PARAMS = {
65
56
  name: "risc0",
66
57
  parallel: false,
@@ -68,7 +59,7 @@ var DEFAULT_COMPUTE_PROVIDER_PARAMS = {
68
59
  };
69
60
  var DEFAULT_E3_CONFIG = {
70
61
  threshold_min: 2,
71
- threshold_max: 3,
62
+ threshold_max: 5,
72
63
  window_size: 120,
73
64
  // 2 minutes in seconds
74
65
  duration: 1800,
@@ -76,7 +67,7 @@ var DEFAULT_E3_CONFIG = {
76
67
  payment_amount: "0"
77
68
  // 0 ETH in wei
78
69
  };
79
- function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV_PARAMS_SET.plaintext_modulus, moduli = BFV_PARAMS_SET.moduli) {
70
+ function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV_PARAMS_SET.plaintext_modulus, moduli = BFV_PARAMS_SET.moduli, error1_variance = BFV_PARAMS_SET.error1_variance) {
80
71
  return encodeAbiParameters(
81
72
  [
82
73
  {
@@ -85,7 +76,8 @@ function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV
85
76
  components: [
86
77
  { name: "degree", type: "uint256" },
87
78
  { name: "plaintext_modulus", type: "uint256" },
88
- { name: "moduli", type: "uint256[]" }
79
+ { name: "moduli", type: "uint256[]" },
80
+ { name: "error1_variance", type: "string" }
89
81
  ]
90
82
  }
91
83
  ],
@@ -93,12 +85,22 @@ function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV
93
85
  {
94
86
  degree: BigInt(degree),
95
87
  plaintext_modulus: BigInt(plaintext_modulus),
96
- moduli: [...moduli]
88
+ moduli: [...moduli],
89
+ error1_variance
97
90
  }
98
91
  ]
99
92
  );
100
93
  }
101
- function encodeComputeProviderParams(params) {
94
+ function encodeComputeProviderParams(params, mock = false) {
95
+ if (mock) {
96
+ return `0x${"0".repeat(32)}`;
97
+ }
98
+ const jsonString = JSON.stringify(params);
99
+ const encoder = new TextEncoder();
100
+ const bytes = encoder.encode(jsonString);
101
+ return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
102
+ }
103
+ function encodeCustomParams(params) {
102
104
  const jsonString = JSON.stringify(params);
103
105
  const encoder = new TextEncoder();
104
106
  const bytes = encoder.encode(jsonString);
@@ -111,9 +113,7 @@ function calculateStartWindow(windowSize = DEFAULT_E3_CONFIG.window_size) {
111
113
  function decodePlaintextOutput(plaintextOutput) {
112
114
  try {
113
115
  const hex = plaintextOutput.startsWith("0x") ? plaintextOutput.slice(2) : plaintextOutput;
114
- const bytes = new Uint8Array(
115
- hex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || []
116
- );
116
+ const bytes = new Uint8Array(hex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || []);
117
117
  if (bytes.length < 8) {
118
118
  console.warn("Plaintext output too short for u64 decoding");
119
119
  return null;
@@ -131,7 +131,8 @@ function decodePlaintextOutput(plaintextOutput) {
131
131
  var ContractClient = class {
132
132
  constructor(publicClient, walletClient, addresses = {
133
133
  enclave: "0x0000000000000000000000000000000000000000",
134
- ciphernodeRegistry: "0x0000000000000000000000000000000000000000"
134
+ ciphernodeRegistry: "0x0000000000000000000000000000000000000000",
135
+ feeToken: "0x0000000000000000000000000000000000000000"
135
136
  }) {
136
137
  this.publicClient = publicClient;
137
138
  this.walletClient = walletClient;
@@ -140,10 +141,10 @@ var ContractClient = class {
140
141
  throw new SDKError("Invalid Enclave contract address", "INVALID_ADDRESS");
141
142
  }
142
143
  if (!isValidAddress(addresses.ciphernodeRegistry)) {
143
- throw new SDKError(
144
- "Invalid CiphernodeRegistry contract address",
145
- "INVALID_ADDRESS"
146
- );
144
+ throw new SDKError("Invalid CiphernodeRegistry contract address", "INVALID_ADDRESS");
145
+ }
146
+ if (!isValidAddress(addresses.feeToken)) {
147
+ throw new SDKError("Invalid FeeToken contract address", "INVALID_ADDRESS");
147
148
  }
148
149
  }
149
150
  contractInfo = null;
@@ -160,25 +161,52 @@ var ContractClient = class {
160
161
  ciphernodeRegistry: {
161
162
  address: this.addresses.ciphernodeRegistry,
162
163
  abi: CiphernodeRegistryOwnable__factory.abi
164
+ },
165
+ feeToken: {
166
+ address: this.addresses.feeToken,
167
+ abi: EnclaveToken__factory.abi
163
168
  }
164
169
  };
165
170
  } catch (error) {
166
- throw new SDKError(
167
- `Failed to initialize contracts: ${error}`,
168
- "INITIALIZATION_FAILED"
169
- );
171
+ throw new SDKError(`Failed to initialize contracts: ${error}`, "INITIALIZATION_FAILED");
172
+ }
173
+ }
174
+ /**
175
+ * Approve the fee token for the Enclave
176
+ * approve(address spender, uint256 amount)
177
+ */
178
+ async approveFeeToken(amount) {
179
+ if (!this.walletClient) {
180
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
181
+ }
182
+ if (!this.contractInfo) {
183
+ await this.initialize();
184
+ }
185
+ try {
186
+ const account = this.walletClient.account;
187
+ if (!account) {
188
+ throw new SDKError("No account connected", "NO_ACCOUNT");
189
+ }
190
+ const { request } = await this.publicClient.simulateContract({
191
+ address: this.addresses.feeToken,
192
+ abi: EnclaveToken__factory.abi,
193
+ functionName: "approve",
194
+ args: [this.addresses.enclave, amount],
195
+ account
196
+ });
197
+ const hash = await this.walletClient.writeContract(request);
198
+ return hash;
199
+ } catch (error) {
200
+ throw new SDKError(`Failed to approve fee token: ${error}`, "APPROVE_FEE_TOKEN_FAILED");
170
201
  }
171
202
  }
172
203
  /**
173
204
  * Request a new E3 computation
174
- * request(address filter, uint32[2] threshold, uint256[2] startWindow, uint256 duration, IE3Program e3Program, bytes e3ProgramParams, bytes computeProviderParams)
205
+ * request(address filter, uint32[2] threshold, uint256[2] startWindow, uint256 duration, IE3Program e3Program, bytes e3ProgramParams, bytes computeProviderParams, bytes customParams)
175
206
  */
176
- async requestE3(filter, threshold, startWindow, duration, e3Program, e3ProgramParams, computeProviderParams, value, gasLimit) {
207
+ async requestE3(threshold, startWindow, duration, e3Program, e3ProgramParams, computeProviderParams, customParams, gasLimit) {
177
208
  if (!this.walletClient) {
178
- throw new SDKError(
179
- "Wallet client required for write operations",
180
- "NO_WALLET"
181
- );
209
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
182
210
  }
183
211
  if (!this.contractInfo) {
184
212
  await this.initialize();
@@ -192,17 +220,18 @@ var ContractClient = class {
192
220
  address: this.addresses.enclave,
193
221
  abi: Enclave__factory.abi,
194
222
  functionName: "request",
195
- args: [{
196
- filter,
197
- threshold,
198
- startWindow,
199
- duration,
200
- e3Program,
201
- e3ProgramParams,
202
- computeProviderParams
203
- }],
223
+ args: [
224
+ {
225
+ threshold,
226
+ startWindow,
227
+ duration,
228
+ e3Program,
229
+ e3ProgramParams,
230
+ computeProviderParams,
231
+ customParams: customParams || "0x"
232
+ }
233
+ ],
204
234
  account,
205
- value: value || BigInt(0),
206
235
  gas: gasLimit
207
236
  });
208
237
  const hash = await this.walletClient.writeContract(request);
@@ -217,10 +246,7 @@ var ContractClient = class {
217
246
  */
218
247
  async activateE3(e3Id, publicKey, gasLimit) {
219
248
  if (!this.walletClient) {
220
- throw new SDKError(
221
- "Wallet client required for write operations",
222
- "NO_WALLET"
223
- );
249
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
224
250
  }
225
251
  if (!this.contractInfo) {
226
252
  await this.initialize();
@@ -241,10 +267,7 @@ var ContractClient = class {
241
267
  const hash = await this.walletClient.writeContract(request);
242
268
  return hash;
243
269
  } catch (error) {
244
- throw new SDKError(
245
- `Failed to activate E3: ${error}`,
246
- "ACTIVATE_E3_FAILED"
247
- );
270
+ throw new SDKError(`Failed to activate E3: ${error}`, "ACTIVATE_E3_FAILED");
248
271
  }
249
272
  }
250
273
  /**
@@ -253,10 +276,7 @@ var ContractClient = class {
253
276
  */
254
277
  async publishInput(e3Id, data, gasLimit) {
255
278
  if (!this.walletClient) {
256
- throw new SDKError(
257
- "Wallet client required for write operations",
258
- "NO_WALLET"
259
- );
279
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
260
280
  }
261
281
  if (!this.contractInfo) {
262
282
  await this.initialize();
@@ -277,10 +297,7 @@ var ContractClient = class {
277
297
  const hash = await this.walletClient.writeContract(request);
278
298
  return hash;
279
299
  } catch (error) {
280
- throw new SDKError(
281
- `Failed to publish input: ${error}`,
282
- "PUBLISH_INPUT_FAILED"
283
- );
300
+ throw new SDKError(`Failed to publish input: ${error}`, "PUBLISH_INPUT_FAILED");
284
301
  }
285
302
  }
286
303
  /**
@@ -289,10 +306,7 @@ var ContractClient = class {
289
306
  */
290
307
  async publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit) {
291
308
  if (!this.walletClient) {
292
- throw new SDKError(
293
- "Wallet client required for write operations",
294
- "NO_WALLET"
295
- );
309
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
296
310
  }
297
311
  if (!this.contractInfo) {
298
312
  await this.initialize();
@@ -313,10 +327,7 @@ var ContractClient = class {
313
327
  const hash = await this.walletClient.writeContract(request);
314
328
  return hash;
315
329
  } catch (error) {
316
- throw new SDKError(
317
- `Failed to publish ciphertext output: ${error}`,
318
- "PUBLISH_CIPHERTEXT_OUTPUT_FAILED"
319
- );
330
+ throw new SDKError(`Failed to publish ciphertext output: ${error}`, "PUBLISH_CIPHERTEXT_OUTPUT_FAILED");
320
331
  }
321
332
  }
322
333
  /**
@@ -342,7 +353,7 @@ var ContractClient = class {
342
353
  /**
343
354
  * Get the public key for an E3 computation
344
355
  * Based on the contract: committeePublicKey(uint256 e3Id) returns (bytes32 publicKeyHash)
345
- * @param e3Id
356
+ * @param e3Id
346
357
  * @returns The public key
347
358
  */
348
359
  async getE3PublicKey(e3Id) {
@@ -366,10 +377,7 @@ var ContractClient = class {
366
377
  */
367
378
  async estimateGas(functionName, args, contractAddress, abi, value) {
368
379
  if (!this.walletClient) {
369
- throw new SDKError(
370
- "Wallet client required for gas estimation",
371
- "NO_WALLET"
372
- );
380
+ throw new SDKError("Wallet client required for gas estimation", "NO_WALLET");
373
381
  }
374
382
  try {
375
383
  const account = this.walletClient.account;
@@ -387,10 +395,7 @@ var ContractClient = class {
387
395
  const gas = await this.publicClient.estimateContractGas(estimateParams);
388
396
  return gas;
389
397
  } catch (error) {
390
- throw new SDKError(
391
- `Failed to estimate gas: ${error}`,
392
- "GAS_ESTIMATION_FAILED"
393
- );
398
+ throw new SDKError(`Failed to estimate gas: ${error}`, "GAS_ESTIMATION_FAILED");
394
399
  }
395
400
  }
396
401
  /**
@@ -404,10 +409,7 @@ var ContractClient = class {
404
409
  });
405
410
  return receipt;
406
411
  } catch (error) {
407
- throw new SDKError(
408
- `Failed to wait for transaction: ${error}`,
409
- "TRANSACTION_WAIT_FAILED"
410
- );
412
+ throw new SDKError(`Failed to wait for transaction: ${error}`, "TRANSACTION_WAIT_FAILED");
411
413
  }
412
414
  }
413
415
  };
@@ -465,10 +467,7 @@ var EventListener = class {
465
467
  });
466
468
  this.activeWatchers.set(watcherKey, unwatch);
467
469
  } catch (error) {
468
- throw new SDKError(
469
- `Failed to watch contract event ${eventType} on ${address}: ${error}`,
470
- "WATCH_EVENT_FAILED"
471
- );
470
+ throw new SDKError(`Failed to watch contract event ${eventType} on ${address}: ${error}`, "WATCH_EVENT_FAILED");
472
471
  }
473
472
  }
474
473
  }
@@ -489,10 +488,7 @@ var EventListener = class {
489
488
  });
490
489
  this.activeWatchers.set(watcherKey, unwatch);
491
490
  } catch (error) {
492
- throw new SDKError(
493
- `Failed to watch logs for address ${address}: ${error}`,
494
- "WATCH_LOGS_FAILED"
495
- );
491
+ throw new SDKError(`Failed to watch logs for address ${address}: ${error}`, "WATCH_LOGS_FAILED");
496
492
  }
497
493
  }
498
494
  }
@@ -507,10 +503,7 @@ var EventListener = class {
507
503
  void this.pollForEvents();
508
504
  } catch (error) {
509
505
  this.isPolling = false;
510
- throw new SDKError(
511
- `Failed to start polling: ${error}`,
512
- "POLLING_START_FAILED"
513
- );
506
+ throw new SDKError(`Failed to start polling: ${error}`, "POLLING_START_FAILED");
514
507
  }
515
508
  }
516
509
  /**
@@ -533,10 +526,7 @@ var EventListener = class {
533
526
  });
534
527
  return logs;
535
528
  } catch (error) {
536
- throw new SDKError(
537
- `Failed to get historical events: ${error}`,
538
- "HISTORICAL_EVENTS_FAILED"
539
- );
529
+ throw new SDKError(`Failed to get historical events: ${error}`, "HISTORICAL_EVENTS_FAILED");
540
530
  }
541
531
  }
542
532
  /**
@@ -619,7 +609,6 @@ var EventListener = class {
619
609
  var EnclaveEventType = /* @__PURE__ */ ((EnclaveEventType2) => {
620
610
  EnclaveEventType2["E3_REQUESTED"] = "E3Requested";
621
611
  EnclaveEventType2["E3_ACTIVATED"] = "E3Activated";
622
- EnclaveEventType2["INPUT_PUBLISHED"] = "InputPublished";
623
612
  EnclaveEventType2["CIPHERTEXT_OUTPUT_PUBLISHED"] = "CiphertextOutputPublished";
624
613
  EnclaveEventType2["PLAINTEXT_OUTPUT_PUBLISHED"] = "PlaintextOutputPublished";
625
614
  EnclaveEventType2["E3_PROGRAM_ENABLED"] = "E3ProgramEnabled";
@@ -636,6 +625,7 @@ var EnclaveEventType = /* @__PURE__ */ ((EnclaveEventType2) => {
636
625
  var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
637
626
  RegistryEventType2["COMMITTEE_REQUESTED"] = "CommitteeRequested";
638
627
  RegistryEventType2["COMMITTEE_PUBLISHED"] = "CommitteePublished";
628
+ RegistryEventType2["COMMITTEE_FINALIZED"] = "CommitteeFinalized";
639
629
  RegistryEventType2["ENCLAVE_SET"] = "EnclaveSet";
640
630
  RegistryEventType2["OWNERSHIP_TRANSFERRED"] = "OwnershipTransferred";
641
631
  RegistryEventType2["INITIALIZED"] = "Initialized";
@@ -643,28 +633,68 @@ var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
643
633
  })(RegistryEventType || {});
644
634
  var FheProtocol = /* @__PURE__ */ ((FheProtocol2) => {
645
635
  FheProtocol2["BFV"] = "BFV";
636
+ FheProtocol2["TRBFV"] = "TRBFV";
646
637
  return FheProtocol2;
647
638
  })(FheProtocol || {});
648
639
  var BfvProtocolParams = {
649
640
  /**
650
- * Recommended parameters for BFV protocol
651
- * - Degree: 2048
652
- * - Plaintext modulus: 1032193
653
- * - Moduli:0x3FFFFFFF000001
654
- */
641
+ * Recommended parameters for BFV protocol
642
+ * - Degree: 2048
643
+ * - Plaintext modulus: 1032193
644
+ * - Moduli:0x3FFFFFFF000001
645
+ */
655
646
  BFV_NORMAL: {
656
647
  degree: 2048,
657
648
  plaintextModulus: 1032193n,
658
- moduli: 0x3FFFFFFF000001n
649
+ moduli: [0x3fffffff000001n],
650
+ error1Variance: "10"
651
+ },
652
+ /**
653
+ * Recommended parameters for TrBFV protocol
654
+ * - Degree: 8192
655
+ * - Plaintext modulus: 1000
656
+ * - Moduli: [0x00800000022a0001, 0x00800000021a0001, 0x0080000002120001, 0x0080000001f60001]
657
+ */
658
+ BFV_THRESHOLD: {
659
+ degree: 8192,
660
+ plaintextModulus: 1000n,
661
+ moduli: [0x00800000022a0001n, 0x00800000021a0001n, 0x0080000002120001n, 0x0080000001f60001n],
662
+ error1Variance: "10"
659
663
  }
660
664
  };
661
665
 
662
666
  // src/enclave-sdk.ts
663
- import { bfv_encrypt_number, bfv_verifiable_encrypt_number } from "@enclave-e3/wasm";
667
+ import {
668
+ bfv_encrypt_number,
669
+ bfv_encrypt_vector,
670
+ bfv_verifiable_encrypt_number,
671
+ bfv_verifiable_encrypt_vector,
672
+ get_bfv_params
673
+ } from "@enclave-e3/wasm";
664
674
 
665
675
  // src/greco.ts
666
676
  import { UltraHonkBackend } from "@aztec/bb.js";
667
677
  import { Noir } from "@noir-lang/noir_js";
678
+ var defaultParams = {
679
+ bounds: {
680
+ pk_bounds: ["34359701504", "34359615488"],
681
+ e0_bound: "20",
682
+ e1_bound: "20",
683
+ u_bound: "1",
684
+ r1_low_bounds: ["261", "258"],
685
+ r1_up_bounds: ["260", "258"],
686
+ r2_bounds: ["34359701504", "34359615488"],
687
+ p1_bounds: ["256", "256"],
688
+ p2_bounds: ["34359701504", "34359615488"],
689
+ k1_low_bound: "5",
690
+ k1_up_bound: "4"
691
+ },
692
+ crypto: {
693
+ q_mod_t: "3",
694
+ qis: ["68719403009", "68719230977"],
695
+ k0is: ["61847462708", "20615769293"]
696
+ }
697
+ };
668
698
  var convertToPolynomial = (stringArray) => {
669
699
  return {
670
700
  coefficients: stringArray
@@ -683,29 +713,14 @@ var generateProof = async (circuitInputs, circuit) => {
683
713
  const u_poly = convertToPolynomial(circuitInputs.u);
684
714
  const e0_poly = convertToPolynomial(circuitInputs.e0);
685
715
  const e1_poly = convertToPolynomial(circuitInputs.e1);
716
+ const e0is_poly = convertToPolynomialArray(circuitInputs.e0is);
686
717
  const k1_poly = convertToPolynomial(circuitInputs.k1);
687
718
  const r1is_poly = convertToPolynomialArray(circuitInputs.r1is);
688
719
  const r2is_poly = convertToPolynomialArray(circuitInputs.r2is);
689
720
  const p1is_poly = convertToPolynomialArray(circuitInputs.p1is);
690
721
  const p2is_poly = convertToPolynomialArray(circuitInputs.p2is);
691
722
  const { witness } = await noir.execute({
692
- // params: {
693
- // q_mod_t: circuitInputs.params.q_mod_t,
694
- // pk_bounds: circuitInputs.params.pk_bounds,
695
- // e_bound: circuitInputs.params.e_bound,
696
- // u_bound: circuitInputs.params.u_bound,
697
- // r1_low_bounds: circuitInputs.params.r1_low_bounds,
698
- // r1_up_bounds: circuitInputs.params.r1_up_bounds,
699
- // r2_bounds: circuitInputs.params.r2_bounds,
700
- // p1_bounds: circuitInputs.params.p1_bounds,
701
- // p2_bounds: circuitInputs.params.p2_bounds,
702
- // k1_low_bound: circuitInputs.params.k1_low_bound,
703
- // k1_up_bound: circuitInputs.params.k1_up_bound,
704
- // qis: circuitInputs.params.qis,
705
- // k0is: circuitInputs.params.k0is,
706
- // size: circuitInputs.params.size,
707
- // tag: circuitInputs.params.tag,
708
- // },
723
+ params: defaultParams,
709
724
  pk0is: pk0is_poly,
710
725
  pk1is: pk1is_poly,
711
726
  ct0is: ct0is_poly,
@@ -713,17 +728,19 @@ var generateProof = async (circuitInputs, circuit) => {
713
728
  u: u_poly,
714
729
  e0: e0_poly,
715
730
  e1: e1_poly,
731
+ e0is: e0is_poly,
716
732
  k1: k1_poly,
717
733
  r1is: r1is_poly,
718
734
  r2is: r2is_poly,
719
735
  p1is: p1is_poly,
720
736
  p2is: p2is_poly
721
737
  });
722
- return await backend.generateProof(witness, { keccak: true });
738
+ return await backend.generateProof(witness, { keccakZK: true });
723
739
  };
724
740
 
725
741
  // src/enclave-sdk.ts
726
742
  var EnclaveSDK = class _EnclaveSDK {
743
+ // TODO: use zod for config validation
727
744
  constructor(config) {
728
745
  this.config = config;
729
746
  if (!config.publicClient) {
@@ -733,29 +750,21 @@ var EnclaveSDK = class _EnclaveSDK {
733
750
  throw new SDKError("Invalid Enclave contract address", "INVALID_ADDRESS");
734
751
  }
735
752
  if (!isValidAddress(config.contracts.ciphernodeRegistry)) {
736
- throw new SDKError(
737
- "Invalid CiphernodeRegistry contract address",
738
- "INVALID_ADDRESS"
739
- );
753
+ throw new SDKError("Invalid CiphernodeRegistry contract address", "INVALID_ADDRESS");
754
+ }
755
+ if (!isValidAddress(config.contracts.feeToken)) {
756
+ throw new SDKError("Invalid FeeToken contract address", "INVALID_ADDRESS");
740
757
  }
741
758
  this.eventListener = new EventListener(config.publicClient);
742
- this.contractClient = new ContractClient(
743
- config.publicClient,
744
- config.walletClient,
745
- config.contracts
746
- );
759
+ this.contractClient = new ContractClient(config.publicClient, config.walletClient, config.contracts);
760
+ if (!Object.values(FheProtocol).includes(config.protocol)) {
761
+ throw new SDKError(`Invalid protocol: ${config.protocol}`, "INVALID_PROTOCOL");
762
+ }
747
763
  this.protocol = config.protocol;
748
764
  if (config.protocolParams) {
749
765
  this.protocolParams = config.protocolParams;
750
- } else {
751
- switch (this.protocol) {
752
- case "BFV" /* BFV */:
753
- this.protocolParams = BfvProtocolParams.BFV_NORMAL;
754
- break;
755
- default:
756
- throw new Error("Protocol not supported");
757
- }
758
766
  }
767
+ this.publicClient = config.publicClient;
759
768
  }
760
769
  static chains = {
761
770
  1: mainnet,
@@ -768,6 +777,7 @@ var EnclaveSDK = class _EnclaveSDK {
768
777
  initialized = false;
769
778
  protocol;
770
779
  protocolParams;
780
+ publicClient;
771
781
  /**
772
782
  * Initialize the SDK
773
783
  */
@@ -778,10 +788,37 @@ var EnclaveSDK = class _EnclaveSDK {
778
788
  await this.contractClient.initialize();
779
789
  this.initialized = true;
780
790
  } catch (error) {
781
- throw new SDKError(
782
- `Failed to initialize SDK: ${error}`,
783
- "SDK_INITIALIZATION_FAILED"
784
- );
791
+ throw new SDKError(`Failed to initialize SDK: ${error}`, "SDK_INITIALIZATION_FAILED");
792
+ }
793
+ }
794
+ /**
795
+ * Get the public client used by the SDK
796
+ * @returns The public client
797
+ */
798
+ getPublicClient = () => {
799
+ return this.publicClient;
800
+ };
801
+ async getBfvParamsSet(name) {
802
+ await initializeWasm();
803
+ let params = get_bfv_params(name);
804
+ return {
805
+ degree: Number(params.degree),
806
+ // degree is returned as a bigint from wasm
807
+ plaintextModulus: params.plaintext_modulus,
808
+ moduli: params.moduli,
809
+ error1Variance: params.error1_variance
810
+ };
811
+ }
812
+ async getProtocolParams() {
813
+ await initializeWasm();
814
+ if (this.protocolParams) {
815
+ return this.protocolParams;
816
+ }
817
+ switch (this.protocol) {
818
+ case "BFV" /* BFV */:
819
+ return await this.getBfvParamsSet("INSECURE_SET_2048_1032193_1");
820
+ case "TRBFV" /* TRBFV */:
821
+ return await this.getBfvParamsSet("INSECURE_SET_512_10_1");
785
822
  }
786
823
  }
787
824
  /**
@@ -792,18 +829,54 @@ var EnclaveSDK = class _EnclaveSDK {
792
829
  */
793
830
  async encryptNumber(data, publicKey) {
794
831
  await initializeWasm();
795
- switch (this.protocol) {
796
- case "BFV" /* BFV */:
797
- return bfv_encrypt_number(
798
- data,
799
- publicKey,
800
- this.protocolParams.degree,
801
- this.protocolParams.plaintextModulus,
802
- this.protocolParams.moduli
803
- );
804
- default:
805
- throw new Error("Protocol not supported");
806
- }
832
+ const protocolParams = await this.getProtocolParams();
833
+ return bfv_encrypt_number(
834
+ data,
835
+ publicKey,
836
+ protocolParams.degree,
837
+ protocolParams.plaintextModulus,
838
+ BigUint64Array.from(protocolParams.moduli)
839
+ );
840
+ }
841
+ /**
842
+ * Encrypt a vector using the configured protocol
843
+ * @param data - The vector to encrypt
844
+ * @param publicKey - The public key to use for encryption
845
+ * @returns The ciphertext
846
+ */
847
+ async encryptVector(data, publicKey) {
848
+ await initializeWasm();
849
+ const protocolParams = await this.getProtocolParams();
850
+ return bfv_encrypt_vector(
851
+ data,
852
+ publicKey,
853
+ protocolParams.degree,
854
+ protocolParams.plaintextModulus,
855
+ BigUint64Array.from(protocolParams.moduli)
856
+ );
857
+ }
858
+ /**
859
+ * This function encrypts a number using the configured FHE protocol
860
+ * and generates the necessary public inputs for a zk-SNARK proof.
861
+ * @param data The number to encrypt
862
+ * @param publicKey The public key to use for encryption
863
+ * @returns The encrypted number and the inputs for the zk-SNARK proof
864
+ */
865
+ async encryptNumberAndGenInputs(data, publicKey) {
866
+ await initializeWasm();
867
+ const protocolParams = await this.getProtocolParams();
868
+ const [encryptedData, circuitInputs] = bfv_verifiable_encrypt_number(
869
+ data,
870
+ publicKey,
871
+ protocolParams.degree,
872
+ protocolParams.plaintextModulus,
873
+ BigUint64Array.from(protocolParams.moduli)
874
+ );
875
+ const publicInputs = JSON.parse(circuitInputs);
876
+ return {
877
+ encryptedData,
878
+ publicInputs
879
+ };
807
880
  }
808
881
  /**
809
882
  * Encrypt a number using the configured protocol and generate a zk-SNARK proof using Greco
@@ -813,25 +886,61 @@ var EnclaveSDK = class _EnclaveSDK {
813
886
  * @returns The encrypted number and the proof
814
887
  */
815
888
  async encryptNumberAndGenProof(data, publicKey, circuit) {
889
+ const { publicInputs, encryptedData } = await this.encryptNumberAndGenInputs(data, publicKey);
890
+ const proof = await generateProof(publicInputs, circuit);
891
+ return {
892
+ encryptedData,
893
+ proof
894
+ };
895
+ }
896
+ /**
897
+ * Encrypt a vector and generate inputs for an E3 computation
898
+ * @param data - The vector to encrypt
899
+ * @param publicKey - The public key to use for encryption
900
+ * @returns The encrypted vector and the inputs for the E3 computation
901
+ */
902
+ async encryptVectorAndGenInputs(data, publicKey) {
816
903
  await initializeWasm();
817
- switch (this.protocol) {
818
- case "BFV" /* BFV */:
819
- const [encryptedVote, circuitInputs] = bfv_verifiable_encrypt_number(
820
- data,
821
- publicKey,
822
- this.protocolParams.degree,
823
- this.protocolParams.plaintextModulus,
824
- this.protocolParams.moduli
825
- );
826
- const inputs = JSON.parse(circuitInputs);
827
- const proof = await generateProof(inputs, circuit);
828
- return {
829
- encryptedVote,
830
- proof
831
- };
832
- default:
833
- throw new Error("Protocol not supported");
904
+ const protocolParams = await this.getProtocolParams();
905
+ const [encryptedData, circuitInputs] = bfv_verifiable_encrypt_vector(
906
+ data,
907
+ publicKey,
908
+ protocolParams.degree,
909
+ protocolParams.plaintextModulus,
910
+ BigUint64Array.from(protocolParams.moduli)
911
+ );
912
+ const publicInputs = JSON.parse(circuitInputs);
913
+ return {
914
+ encryptedData,
915
+ publicInputs
916
+ };
917
+ }
918
+ /**
919
+ * Encrypt a vector using the configured protocol and generate a zk-SNARK proof using Greco
920
+ * @param data - The vector to encrypt
921
+ * @param publicKey - The public key to use for encryption
922
+ * @param circuit - The circuit to use for proof generation
923
+ * @returns The encrypted vector and the proof
924
+ */
925
+ async encryptVectorAndGenProof(data, publicKey, circuit) {
926
+ const { publicInputs, encryptedData } = await this.encryptVectorAndGenInputs(data, publicKey);
927
+ const proof = await generateProof(publicInputs, circuit);
928
+ return {
929
+ encryptedData,
930
+ proof
931
+ };
932
+ }
933
+ /**
934
+ * Approve the fee token for the Enclave
935
+ * @param amount - The amount to approve
936
+ * @returns The approval transaction hash
937
+ */
938
+ async approveFeeToken(amount) {
939
+ console.log(">>> APPROVE FEE TOKEN");
940
+ if (!this.initialized) {
941
+ await this.initialize();
834
942
  }
943
+ return this.contractClient.approveFeeToken(amount);
835
944
  }
836
945
  /**
837
946
  * Request a new E3 computation
@@ -842,14 +951,13 @@ var EnclaveSDK = class _EnclaveSDK {
842
951
  await this.initialize();
843
952
  }
844
953
  return this.contractClient.requestE3(
845
- params.filter,
846
954
  params.threshold,
847
955
  params.startWindow,
848
956
  params.duration,
849
957
  params.e3Program,
850
958
  params.e3ProgramParams,
851
959
  params.computeProviderParams,
852
- params.value,
960
+ params.customParams,
853
961
  params.gasLimit
854
962
  );
855
963
  }
@@ -889,12 +997,7 @@ var EnclaveSDK = class _EnclaveSDK {
889
997
  if (!this.initialized) {
890
998
  await this.initialize();
891
999
  }
892
- return this.contractClient.publishCiphertextOutput(
893
- e3Id,
894
- ciphertextOutput,
895
- proof,
896
- gasLimit
897
- );
1000
+ return this.contractClient.publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit);
898
1001
  }
899
1002
  /**
900
1003
  * Get E3 information
@@ -909,17 +1012,10 @@ var EnclaveSDK = class _EnclaveSDK {
909
1012
  * Unified Event Listening - Listen to any Enclave or Registry event
910
1013
  */
911
1014
  onEnclaveEvent(eventType, callback) {
912
- const isEnclaveEvent = Object.values(EnclaveEventType).includes(
913
- eventType
914
- );
1015
+ const isEnclaveEvent = Object.values(EnclaveEventType).includes(eventType);
915
1016
  const contractAddress = isEnclaveEvent ? this.config.contracts.enclave : this.config.contracts.ciphernodeRegistry;
916
1017
  const abi = isEnclaveEvent ? Enclave__factory2.abi : CiphernodeRegistryOwnable__factory2.abi;
917
- void this.eventListener.watchContractEvent(
918
- contractAddress,
919
- eventType,
920
- abi,
921
- callback
922
- );
1018
+ void this.eventListener.watchContractEvent(contractAddress, eventType, abi, callback);
923
1019
  }
924
1020
  /**
925
1021
  * Remove event listener
@@ -944,18 +1040,10 @@ var EnclaveSDK = class _EnclaveSDK {
944
1040
  * Get historical events
945
1041
  */
946
1042
  async getHistoricalEvents(eventType, fromBlock, toBlock) {
947
- const isEnclaveEvent = Object.values(EnclaveEventType).includes(
948
- eventType
949
- );
1043
+ const isEnclaveEvent = Object.values(EnclaveEventType).includes(eventType);
950
1044
  const contractAddress = isEnclaveEvent ? this.config.contracts.enclave : this.config.contracts.ciphernodeRegistry;
951
1045
  const abi = isEnclaveEvent ? Enclave__factory2.abi : CiphernodeRegistryOwnable__factory2.abi;
952
- return this.eventListener.getHistoricalEvents(
953
- contractAddress,
954
- eventType,
955
- abi,
956
- fromBlock,
957
- toBlock
958
- );
1046
+ return this.eventListener.getHistoricalEvents(contractAddress, eventType, abi, fromBlock, toBlock);
959
1047
  }
960
1048
  /**
961
1049
  * Start polling for events
@@ -976,13 +1064,7 @@ var EnclaveSDK = class _EnclaveSDK {
976
1064
  * Estimate gas for a transaction
977
1065
  */
978
1066
  async estimateGas(functionName, args, contractAddress, abi, value) {
979
- return this.contractClient.estimateGas(
980
- functionName,
981
- args,
982
- contractAddress,
983
- abi,
984
- value
985
- );
1067
+ return this.contractClient.estimateGas(functionName, args, contractAddress, abi, value);
986
1068
  }
987
1069
  /**
988
1070
  * Wait for transaction confirmation
@@ -1017,11 +1099,7 @@ var EnclaveSDK = class _EnclaveSDK {
1017
1099
  if (newConfig.chainId) {
1018
1100
  this.config.chainId = newConfig.chainId;
1019
1101
  }
1020
- this.contractClient = new ContractClient(
1021
- this.config.publicClient,
1022
- this.config.walletClient,
1023
- this.config.contracts
1024
- );
1102
+ this.contractClient = new ContractClient(this.config.publicClient, this.config.walletClient, this.config.contracts);
1025
1103
  this.initialized = false;
1026
1104
  }
1027
1105
  static create(options) {
@@ -1067,9 +1145,12 @@ export {
1067
1145
  RegistryEventType,
1068
1146
  SDKError,
1069
1147
  calculateStartWindow,
1148
+ convertToPolynomial,
1149
+ convertToPolynomialArray,
1070
1150
  decodePlaintextOutput,
1071
1151
  encodeBfvParams,
1072
1152
  encodeComputeProviderParams,
1153
+ encodeCustomParams,
1073
1154
  formatBigInt,
1074
1155
  formatEventName,
1075
1156
  generateEventId,