@enclave-e3/sdk 0.1.4 → 0.1.6

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.cjs CHANGED
@@ -42,9 +42,12 @@ __export(index_exports, {
42
42
  RegistryEventType: () => RegistryEventType,
43
43
  SDKError: () => SDKError,
44
44
  calculateStartWindow: () => calculateStartWindow,
45
+ convertToPolynomial: () => convertToPolynomial,
46
+ convertToPolynomialArray: () => convertToPolynomialArray,
45
47
  decodePlaintextOutput: () => decodePlaintextOutput,
46
48
  encodeBfvParams: () => encodeBfvParams,
47
49
  encodeComputeProviderParams: () => encodeComputeProviderParams,
50
+ encodeCustomParams: () => encodeCustomParams,
48
51
  formatBigInt: () => formatBigInt,
49
52
  formatEventName: () => formatEventName,
50
53
  generateEventId: () => generateEventId,
@@ -104,12 +107,14 @@ function generateEventId(log) {
104
107
  function getCurrentTimestamp() {
105
108
  return Math.floor(Date.now() / 1e3);
106
109
  }
107
- var BFV_PARAMS_SET = {
110
+ var INSECURE_SET_2048_1032193_1 = {
108
111
  degree: 2048,
109
112
  plaintext_modulus: 1032193,
110
- moduli: [0x3fffffff000001n]
113
+ moduli: [0x3fffffff000001n],
111
114
  // BigInt for the modulus
115
+ error1_variance: "10"
112
116
  };
117
+ var BFV_PARAMS_SET = INSECURE_SET_2048_1032193_1;
113
118
  var DEFAULT_COMPUTE_PROVIDER_PARAMS = {
114
119
  name: "risc0",
115
120
  parallel: false,
@@ -117,7 +122,7 @@ var DEFAULT_COMPUTE_PROVIDER_PARAMS = {
117
122
  };
118
123
  var DEFAULT_E3_CONFIG = {
119
124
  threshold_min: 2,
120
- threshold_max: 3,
125
+ threshold_max: 5,
121
126
  window_size: 120,
122
127
  // 2 minutes in seconds
123
128
  duration: 1800,
@@ -125,7 +130,7 @@ var DEFAULT_E3_CONFIG = {
125
130
  payment_amount: "0"
126
131
  // 0 ETH in wei
127
132
  };
128
- function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV_PARAMS_SET.plaintext_modulus, moduli = BFV_PARAMS_SET.moduli) {
133
+ 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) {
129
134
  return (0, import_viem.encodeAbiParameters)(
130
135
  [
131
136
  {
@@ -134,7 +139,8 @@ function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV
134
139
  components: [
135
140
  { name: "degree", type: "uint256" },
136
141
  { name: "plaintext_modulus", type: "uint256" },
137
- { name: "moduli", type: "uint256[]" }
142
+ { name: "moduli", type: "uint256[]" },
143
+ { name: "error1_variance", type: "string" }
138
144
  ]
139
145
  }
140
146
  ],
@@ -142,12 +148,22 @@ function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV
142
148
  {
143
149
  degree: BigInt(degree),
144
150
  plaintext_modulus: BigInt(plaintext_modulus),
145
- moduli: [...moduli]
151
+ moduli: [...moduli],
152
+ error1_variance
146
153
  }
147
154
  ]
148
155
  );
149
156
  }
150
- function encodeComputeProviderParams(params) {
157
+ function encodeComputeProviderParams(params, mock = false) {
158
+ if (mock) {
159
+ return `0x${"0".repeat(32)}`;
160
+ }
161
+ const jsonString = JSON.stringify(params);
162
+ const encoder = new TextEncoder();
163
+ const bytes = encoder.encode(jsonString);
164
+ return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
165
+ }
166
+ function encodeCustomParams(params) {
151
167
  const jsonString = JSON.stringify(params);
152
168
  const encoder = new TextEncoder();
153
169
  const bytes = encoder.encode(jsonString);
@@ -160,9 +176,7 @@ function calculateStartWindow(windowSize = DEFAULT_E3_CONFIG.window_size) {
160
176
  function decodePlaintextOutput(plaintextOutput) {
161
177
  try {
162
178
  const hex = plaintextOutput.startsWith("0x") ? plaintextOutput.slice(2) : plaintextOutput;
163
- const bytes = new Uint8Array(
164
- hex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || []
165
- );
179
+ const bytes = new Uint8Array(hex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || []);
166
180
  if (bytes.length < 8) {
167
181
  console.warn("Plaintext output too short for u64 decoding");
168
182
  return null;
@@ -180,7 +194,8 @@ function decodePlaintextOutput(plaintextOutput) {
180
194
  var ContractClient = class {
181
195
  constructor(publicClient, walletClient, addresses = {
182
196
  enclave: "0x0000000000000000000000000000000000000000",
183
- ciphernodeRegistry: "0x0000000000000000000000000000000000000000"
197
+ ciphernodeRegistry: "0x0000000000000000000000000000000000000000",
198
+ feeToken: "0x0000000000000000000000000000000000000000"
184
199
  }) {
185
200
  this.publicClient = publicClient;
186
201
  this.walletClient = walletClient;
@@ -189,10 +204,10 @@ var ContractClient = class {
189
204
  throw new SDKError("Invalid Enclave contract address", "INVALID_ADDRESS");
190
205
  }
191
206
  if (!isValidAddress(addresses.ciphernodeRegistry)) {
192
- throw new SDKError(
193
- "Invalid CiphernodeRegistry contract address",
194
- "INVALID_ADDRESS"
195
- );
207
+ throw new SDKError("Invalid CiphernodeRegistry contract address", "INVALID_ADDRESS");
208
+ }
209
+ if (!isValidAddress(addresses.feeToken)) {
210
+ throw new SDKError("Invalid FeeToken contract address", "INVALID_ADDRESS");
196
211
  }
197
212
  }
198
213
  contractInfo = null;
@@ -209,25 +224,52 @@ var ContractClient = class {
209
224
  ciphernodeRegistry: {
210
225
  address: this.addresses.ciphernodeRegistry,
211
226
  abi: import_types.CiphernodeRegistryOwnable__factory.abi
227
+ },
228
+ feeToken: {
229
+ address: this.addresses.feeToken,
230
+ abi: import_types.EnclaveToken__factory.abi
212
231
  }
213
232
  };
214
233
  } catch (error) {
215
- throw new SDKError(
216
- `Failed to initialize contracts: ${error}`,
217
- "INITIALIZATION_FAILED"
218
- );
234
+ throw new SDKError(`Failed to initialize contracts: ${error}`, "INITIALIZATION_FAILED");
235
+ }
236
+ }
237
+ /**
238
+ * Approve the fee token for the Enclave
239
+ * approve(address spender, uint256 amount)
240
+ */
241
+ async approveFeeToken(amount) {
242
+ if (!this.walletClient) {
243
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
244
+ }
245
+ if (!this.contractInfo) {
246
+ await this.initialize();
247
+ }
248
+ try {
249
+ const account = this.walletClient.account;
250
+ if (!account) {
251
+ throw new SDKError("No account connected", "NO_ACCOUNT");
252
+ }
253
+ const { request } = await this.publicClient.simulateContract({
254
+ address: this.addresses.feeToken,
255
+ abi: import_types.EnclaveToken__factory.abi,
256
+ functionName: "approve",
257
+ args: [this.addresses.enclave, amount],
258
+ account
259
+ });
260
+ const hash = await this.walletClient.writeContract(request);
261
+ return hash;
262
+ } catch (error) {
263
+ throw new SDKError(`Failed to approve fee token: ${error}`, "APPROVE_FEE_TOKEN_FAILED");
219
264
  }
220
265
  }
221
266
  /**
222
267
  * Request a new E3 computation
223
- * request(address filter, uint32[2] threshold, uint256[2] startWindow, uint256 duration, IE3Program e3Program, bytes e3ProgramParams, bytes computeProviderParams)
268
+ * request(address filter, uint32[2] threshold, uint256[2] startWindow, uint256 duration, IE3Program e3Program, bytes e3ProgramParams, bytes computeProviderParams, bytes customParams)
224
269
  */
225
- async requestE3(filter, threshold, startWindow, duration, e3Program, e3ProgramParams, computeProviderParams, value, gasLimit) {
270
+ async requestE3(threshold, startWindow, duration, e3Program, e3ProgramParams, computeProviderParams, customParams, gasLimit) {
226
271
  if (!this.walletClient) {
227
- throw new SDKError(
228
- "Wallet client required for write operations",
229
- "NO_WALLET"
230
- );
272
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
231
273
  }
232
274
  if (!this.contractInfo) {
233
275
  await this.initialize();
@@ -241,17 +283,18 @@ var ContractClient = class {
241
283
  address: this.addresses.enclave,
242
284
  abi: import_types.Enclave__factory.abi,
243
285
  functionName: "request",
244
- args: [{
245
- filter,
246
- threshold,
247
- startWindow,
248
- duration,
249
- e3Program,
250
- e3ProgramParams,
251
- computeProviderParams
252
- }],
286
+ args: [
287
+ {
288
+ threshold,
289
+ startWindow,
290
+ duration,
291
+ e3Program,
292
+ e3ProgramParams,
293
+ computeProviderParams,
294
+ customParams: customParams || "0x"
295
+ }
296
+ ],
253
297
  account,
254
- value: value || BigInt(0),
255
298
  gas: gasLimit
256
299
  });
257
300
  const hash = await this.walletClient.writeContract(request);
@@ -266,10 +309,7 @@ var ContractClient = class {
266
309
  */
267
310
  async activateE3(e3Id, publicKey, gasLimit) {
268
311
  if (!this.walletClient) {
269
- throw new SDKError(
270
- "Wallet client required for write operations",
271
- "NO_WALLET"
272
- );
312
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
273
313
  }
274
314
  if (!this.contractInfo) {
275
315
  await this.initialize();
@@ -290,10 +330,7 @@ var ContractClient = class {
290
330
  const hash = await this.walletClient.writeContract(request);
291
331
  return hash;
292
332
  } catch (error) {
293
- throw new SDKError(
294
- `Failed to activate E3: ${error}`,
295
- "ACTIVATE_E3_FAILED"
296
- );
333
+ throw new SDKError(`Failed to activate E3: ${error}`, "ACTIVATE_E3_FAILED");
297
334
  }
298
335
  }
299
336
  /**
@@ -302,10 +339,7 @@ var ContractClient = class {
302
339
  */
303
340
  async publishInput(e3Id, data, gasLimit) {
304
341
  if (!this.walletClient) {
305
- throw new SDKError(
306
- "Wallet client required for write operations",
307
- "NO_WALLET"
308
- );
342
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
309
343
  }
310
344
  if (!this.contractInfo) {
311
345
  await this.initialize();
@@ -326,10 +360,7 @@ var ContractClient = class {
326
360
  const hash = await this.walletClient.writeContract(request);
327
361
  return hash;
328
362
  } catch (error) {
329
- throw new SDKError(
330
- `Failed to publish input: ${error}`,
331
- "PUBLISH_INPUT_FAILED"
332
- );
363
+ throw new SDKError(`Failed to publish input: ${error}`, "PUBLISH_INPUT_FAILED");
333
364
  }
334
365
  }
335
366
  /**
@@ -338,10 +369,7 @@ var ContractClient = class {
338
369
  */
339
370
  async publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit) {
340
371
  if (!this.walletClient) {
341
- throw new SDKError(
342
- "Wallet client required for write operations",
343
- "NO_WALLET"
344
- );
372
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
345
373
  }
346
374
  if (!this.contractInfo) {
347
375
  await this.initialize();
@@ -362,10 +390,7 @@ var ContractClient = class {
362
390
  const hash = await this.walletClient.writeContract(request);
363
391
  return hash;
364
392
  } catch (error) {
365
- throw new SDKError(
366
- `Failed to publish ciphertext output: ${error}`,
367
- "PUBLISH_CIPHERTEXT_OUTPUT_FAILED"
368
- );
393
+ throw new SDKError(`Failed to publish ciphertext output: ${error}`, "PUBLISH_CIPHERTEXT_OUTPUT_FAILED");
369
394
  }
370
395
  }
371
396
  /**
@@ -391,7 +416,7 @@ var ContractClient = class {
391
416
  /**
392
417
  * Get the public key for an E3 computation
393
418
  * Based on the contract: committeePublicKey(uint256 e3Id) returns (bytes32 publicKeyHash)
394
- * @param e3Id
419
+ * @param e3Id
395
420
  * @returns The public key
396
421
  */
397
422
  async getE3PublicKey(e3Id) {
@@ -415,10 +440,7 @@ var ContractClient = class {
415
440
  */
416
441
  async estimateGas(functionName, args, contractAddress, abi, value) {
417
442
  if (!this.walletClient) {
418
- throw new SDKError(
419
- "Wallet client required for gas estimation",
420
- "NO_WALLET"
421
- );
443
+ throw new SDKError("Wallet client required for gas estimation", "NO_WALLET");
422
444
  }
423
445
  try {
424
446
  const account = this.walletClient.account;
@@ -436,10 +458,7 @@ var ContractClient = class {
436
458
  const gas = await this.publicClient.estimateContractGas(estimateParams);
437
459
  return gas;
438
460
  } catch (error) {
439
- throw new SDKError(
440
- `Failed to estimate gas: ${error}`,
441
- "GAS_ESTIMATION_FAILED"
442
- );
461
+ throw new SDKError(`Failed to estimate gas: ${error}`, "GAS_ESTIMATION_FAILED");
443
462
  }
444
463
  }
445
464
  /**
@@ -453,10 +472,7 @@ var ContractClient = class {
453
472
  });
454
473
  return receipt;
455
474
  } catch (error) {
456
- throw new SDKError(
457
- `Failed to wait for transaction: ${error}`,
458
- "TRANSACTION_WAIT_FAILED"
459
- );
475
+ throw new SDKError(`Failed to wait for transaction: ${error}`, "TRANSACTION_WAIT_FAILED");
460
476
  }
461
477
  }
462
478
  };
@@ -514,10 +530,7 @@ var EventListener = class {
514
530
  });
515
531
  this.activeWatchers.set(watcherKey, unwatch);
516
532
  } catch (error) {
517
- throw new SDKError(
518
- `Failed to watch contract event ${eventType} on ${address}: ${error}`,
519
- "WATCH_EVENT_FAILED"
520
- );
533
+ throw new SDKError(`Failed to watch contract event ${eventType} on ${address}: ${error}`, "WATCH_EVENT_FAILED");
521
534
  }
522
535
  }
523
536
  }
@@ -538,10 +551,7 @@ var EventListener = class {
538
551
  });
539
552
  this.activeWatchers.set(watcherKey, unwatch);
540
553
  } catch (error) {
541
- throw new SDKError(
542
- `Failed to watch logs for address ${address}: ${error}`,
543
- "WATCH_LOGS_FAILED"
544
- );
554
+ throw new SDKError(`Failed to watch logs for address ${address}: ${error}`, "WATCH_LOGS_FAILED");
545
555
  }
546
556
  }
547
557
  }
@@ -556,10 +566,7 @@ var EventListener = class {
556
566
  void this.pollForEvents();
557
567
  } catch (error) {
558
568
  this.isPolling = false;
559
- throw new SDKError(
560
- `Failed to start polling: ${error}`,
561
- "POLLING_START_FAILED"
562
- );
569
+ throw new SDKError(`Failed to start polling: ${error}`, "POLLING_START_FAILED");
563
570
  }
564
571
  }
565
572
  /**
@@ -582,10 +589,7 @@ var EventListener = class {
582
589
  });
583
590
  return logs;
584
591
  } catch (error) {
585
- throw new SDKError(
586
- `Failed to get historical events: ${error}`,
587
- "HISTORICAL_EVENTS_FAILED"
588
- );
592
+ throw new SDKError(`Failed to get historical events: ${error}`, "HISTORICAL_EVENTS_FAILED");
589
593
  }
590
594
  }
591
595
  /**
@@ -668,7 +672,6 @@ var EventListener = class {
668
672
  var EnclaveEventType = /* @__PURE__ */ ((EnclaveEventType2) => {
669
673
  EnclaveEventType2["E3_REQUESTED"] = "E3Requested";
670
674
  EnclaveEventType2["E3_ACTIVATED"] = "E3Activated";
671
- EnclaveEventType2["INPUT_PUBLISHED"] = "InputPublished";
672
675
  EnclaveEventType2["CIPHERTEXT_OUTPUT_PUBLISHED"] = "CiphertextOutputPublished";
673
676
  EnclaveEventType2["PLAINTEXT_OUTPUT_PUBLISHED"] = "PlaintextOutputPublished";
674
677
  EnclaveEventType2["E3_PROGRAM_ENABLED"] = "E3ProgramEnabled";
@@ -685,6 +688,7 @@ var EnclaveEventType = /* @__PURE__ */ ((EnclaveEventType2) => {
685
688
  var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
686
689
  RegistryEventType2["COMMITTEE_REQUESTED"] = "CommitteeRequested";
687
690
  RegistryEventType2["COMMITTEE_PUBLISHED"] = "CommitteePublished";
691
+ RegistryEventType2["COMMITTEE_FINALIZED"] = "CommitteeFinalized";
688
692
  RegistryEventType2["ENCLAVE_SET"] = "EnclaveSet";
689
693
  RegistryEventType2["OWNERSHIP_TRANSFERRED"] = "OwnershipTransferred";
690
694
  RegistryEventType2["INITIALIZED"] = "Initialized";
@@ -692,19 +696,33 @@ var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
692
696
  })(RegistryEventType || {});
693
697
  var FheProtocol = /* @__PURE__ */ ((FheProtocol2) => {
694
698
  FheProtocol2["BFV"] = "BFV";
699
+ FheProtocol2["TRBFV"] = "TRBFV";
695
700
  return FheProtocol2;
696
701
  })(FheProtocol || {});
697
702
  var BfvProtocolParams = {
698
703
  /**
699
- * Recommended parameters for BFV protocol
700
- * - Degree: 2048
701
- * - Plaintext modulus: 1032193
702
- * - Moduli:0x3FFFFFFF000001
703
- */
704
+ * Recommended parameters for BFV protocol
705
+ * - Degree: 2048
706
+ * - Plaintext modulus: 1032193
707
+ * - Moduli:0x3FFFFFFF000001
708
+ */
704
709
  BFV_NORMAL: {
705
710
  degree: 2048,
706
711
  plaintextModulus: 1032193n,
707
- moduli: 0x3FFFFFFF000001n
712
+ moduli: [0x3fffffff000001n],
713
+ error1Variance: "10"
714
+ },
715
+ /**
716
+ * Recommended parameters for TrBFV protocol
717
+ * - Degree: 8192
718
+ * - Plaintext modulus: 1000
719
+ * - Moduli: [0x00800000022a0001, 0x00800000021a0001, 0x0080000002120001, 0x0080000001f60001]
720
+ */
721
+ BFV_THRESHOLD: {
722
+ degree: 8192,
723
+ plaintextModulus: 1000n,
724
+ moduli: [0x00800000022a0001n, 0x00800000021a0001n, 0x0080000002120001n, 0x0080000001f60001n],
725
+ error1Variance: "10"
708
726
  }
709
727
  };
710
728
 
@@ -714,6 +732,26 @@ var import_wasm = require("@enclave-e3/wasm");
714
732
  // src/greco.ts
715
733
  var import_bb = require("@aztec/bb.js");
716
734
  var import_noir_js = require("@noir-lang/noir_js");
735
+ var defaultParams = {
736
+ bounds: {
737
+ pk_bounds: ["34359701504", "34359615488"],
738
+ e0_bound: "20",
739
+ e1_bound: "20",
740
+ u_bound: "1",
741
+ r1_low_bounds: ["261", "258"],
742
+ r1_up_bounds: ["260", "258"],
743
+ r2_bounds: ["34359701504", "34359615488"],
744
+ p1_bounds: ["256", "256"],
745
+ p2_bounds: ["34359701504", "34359615488"],
746
+ k1_low_bound: "5",
747
+ k1_up_bound: "4"
748
+ },
749
+ crypto: {
750
+ q_mod_t: "3",
751
+ qis: ["68719403009", "68719230977"],
752
+ k0is: ["61847462708", "20615769293"]
753
+ }
754
+ };
717
755
  var convertToPolynomial = (stringArray) => {
718
756
  return {
719
757
  coefficients: stringArray
@@ -732,29 +770,14 @@ var generateProof = async (circuitInputs, circuit) => {
732
770
  const u_poly = convertToPolynomial(circuitInputs.u);
733
771
  const e0_poly = convertToPolynomial(circuitInputs.e0);
734
772
  const e1_poly = convertToPolynomial(circuitInputs.e1);
773
+ const e0is_poly = convertToPolynomialArray(circuitInputs.e0is);
735
774
  const k1_poly = convertToPolynomial(circuitInputs.k1);
736
775
  const r1is_poly = convertToPolynomialArray(circuitInputs.r1is);
737
776
  const r2is_poly = convertToPolynomialArray(circuitInputs.r2is);
738
777
  const p1is_poly = convertToPolynomialArray(circuitInputs.p1is);
739
778
  const p2is_poly = convertToPolynomialArray(circuitInputs.p2is);
740
779
  const { witness } = await noir.execute({
741
- // params: {
742
- // q_mod_t: circuitInputs.params.q_mod_t,
743
- // pk_bounds: circuitInputs.params.pk_bounds,
744
- // e_bound: circuitInputs.params.e_bound,
745
- // u_bound: circuitInputs.params.u_bound,
746
- // r1_low_bounds: circuitInputs.params.r1_low_bounds,
747
- // r1_up_bounds: circuitInputs.params.r1_up_bounds,
748
- // r2_bounds: circuitInputs.params.r2_bounds,
749
- // p1_bounds: circuitInputs.params.p1_bounds,
750
- // p2_bounds: circuitInputs.params.p2_bounds,
751
- // k1_low_bound: circuitInputs.params.k1_low_bound,
752
- // k1_up_bound: circuitInputs.params.k1_up_bound,
753
- // qis: circuitInputs.params.qis,
754
- // k0is: circuitInputs.params.k0is,
755
- // size: circuitInputs.params.size,
756
- // tag: circuitInputs.params.tag,
757
- // },
780
+ params: defaultParams,
758
781
  pk0is: pk0is_poly,
759
782
  pk1is: pk1is_poly,
760
783
  ct0is: ct0is_poly,
@@ -762,17 +785,19 @@ var generateProof = async (circuitInputs, circuit) => {
762
785
  u: u_poly,
763
786
  e0: e0_poly,
764
787
  e1: e1_poly,
788
+ e0is: e0is_poly,
765
789
  k1: k1_poly,
766
790
  r1is: r1is_poly,
767
791
  r2is: r2is_poly,
768
792
  p1is: p1is_poly,
769
793
  p2is: p2is_poly
770
794
  });
771
- return await backend.generateProof(witness, { keccak: true });
795
+ return await backend.generateProof(witness, { keccakZK: true });
772
796
  };
773
797
 
774
798
  // src/enclave-sdk.ts
775
799
  var EnclaveSDK = class _EnclaveSDK {
800
+ // TODO: use zod for config validation
776
801
  constructor(config) {
777
802
  this.config = config;
778
803
  if (!config.publicClient) {
@@ -782,29 +807,21 @@ var EnclaveSDK = class _EnclaveSDK {
782
807
  throw new SDKError("Invalid Enclave contract address", "INVALID_ADDRESS");
783
808
  }
784
809
  if (!isValidAddress(config.contracts.ciphernodeRegistry)) {
785
- throw new SDKError(
786
- "Invalid CiphernodeRegistry contract address",
787
- "INVALID_ADDRESS"
788
- );
810
+ throw new SDKError("Invalid CiphernodeRegistry contract address", "INVALID_ADDRESS");
811
+ }
812
+ if (!isValidAddress(config.contracts.feeToken)) {
813
+ throw new SDKError("Invalid FeeToken contract address", "INVALID_ADDRESS");
789
814
  }
790
815
  this.eventListener = new EventListener(config.publicClient);
791
- this.contractClient = new ContractClient(
792
- config.publicClient,
793
- config.walletClient,
794
- config.contracts
795
- );
816
+ this.contractClient = new ContractClient(config.publicClient, config.walletClient, config.contracts);
817
+ if (!Object.values(FheProtocol).includes(config.protocol)) {
818
+ throw new SDKError(`Invalid protocol: ${config.protocol}`, "INVALID_PROTOCOL");
819
+ }
796
820
  this.protocol = config.protocol;
797
821
  if (config.protocolParams) {
798
822
  this.protocolParams = config.protocolParams;
799
- } else {
800
- switch (this.protocol) {
801
- case "BFV" /* BFV */:
802
- this.protocolParams = BfvProtocolParams.BFV_NORMAL;
803
- break;
804
- default:
805
- throw new Error("Protocol not supported");
806
- }
807
823
  }
824
+ this.publicClient = config.publicClient;
808
825
  }
809
826
  static chains = {
810
827
  1: import_chains.mainnet,
@@ -817,6 +834,7 @@ var EnclaveSDK = class _EnclaveSDK {
817
834
  initialized = false;
818
835
  protocol;
819
836
  protocolParams;
837
+ publicClient;
820
838
  /**
821
839
  * Initialize the SDK
822
840
  */
@@ -827,10 +845,37 @@ var EnclaveSDK = class _EnclaveSDK {
827
845
  await this.contractClient.initialize();
828
846
  this.initialized = true;
829
847
  } catch (error) {
830
- throw new SDKError(
831
- `Failed to initialize SDK: ${error}`,
832
- "SDK_INITIALIZATION_FAILED"
833
- );
848
+ throw new SDKError(`Failed to initialize SDK: ${error}`, "SDK_INITIALIZATION_FAILED");
849
+ }
850
+ }
851
+ /**
852
+ * Get the public client used by the SDK
853
+ * @returns The public client
854
+ */
855
+ getPublicClient = () => {
856
+ return this.publicClient;
857
+ };
858
+ async getBfvParamsSet(name) {
859
+ await (0, import_init.default)();
860
+ let params = (0, import_wasm.get_bfv_params)(name);
861
+ return {
862
+ degree: Number(params.degree),
863
+ // degree is returned as a bigint from wasm
864
+ plaintextModulus: params.plaintext_modulus,
865
+ moduli: params.moduli,
866
+ error1Variance: params.error1_variance
867
+ };
868
+ }
869
+ async getProtocolParams() {
870
+ await (0, import_init.default)();
871
+ if (this.protocolParams) {
872
+ return this.protocolParams;
873
+ }
874
+ switch (this.protocol) {
875
+ case "BFV" /* BFV */:
876
+ return await this.getBfvParamsSet("INSECURE_SET_2048_1032193_1");
877
+ case "TRBFV" /* TRBFV */:
878
+ return await this.getBfvParamsSet("INSECURE_SET_512_10_1");
834
879
  }
835
880
  }
836
881
  /**
@@ -841,18 +886,54 @@ var EnclaveSDK = class _EnclaveSDK {
841
886
  */
842
887
  async encryptNumber(data, publicKey) {
843
888
  await (0, import_init.default)();
844
- switch (this.protocol) {
845
- case "BFV" /* BFV */:
846
- return (0, import_wasm.bfv_encrypt_number)(
847
- data,
848
- publicKey,
849
- this.protocolParams.degree,
850
- this.protocolParams.plaintextModulus,
851
- this.protocolParams.moduli
852
- );
853
- default:
854
- throw new Error("Protocol not supported");
855
- }
889
+ const protocolParams = await this.getProtocolParams();
890
+ return (0, import_wasm.bfv_encrypt_number)(
891
+ data,
892
+ publicKey,
893
+ protocolParams.degree,
894
+ protocolParams.plaintextModulus,
895
+ BigUint64Array.from(protocolParams.moduli)
896
+ );
897
+ }
898
+ /**
899
+ * Encrypt a vector using the configured protocol
900
+ * @param data - The vector to encrypt
901
+ * @param publicKey - The public key to use for encryption
902
+ * @returns The ciphertext
903
+ */
904
+ async encryptVector(data, publicKey) {
905
+ await (0, import_init.default)();
906
+ const protocolParams = await this.getProtocolParams();
907
+ return (0, import_wasm.bfv_encrypt_vector)(
908
+ data,
909
+ publicKey,
910
+ protocolParams.degree,
911
+ protocolParams.plaintextModulus,
912
+ BigUint64Array.from(protocolParams.moduli)
913
+ );
914
+ }
915
+ /**
916
+ * This function encrypts a number using the configured FHE protocol
917
+ * and generates the necessary public inputs for a zk-SNARK proof.
918
+ * @param data The number to encrypt
919
+ * @param publicKey The public key to use for encryption
920
+ * @returns The encrypted number and the inputs for the zk-SNARK proof
921
+ */
922
+ async encryptNumberAndGenInputs(data, publicKey) {
923
+ await (0, import_init.default)();
924
+ const protocolParams = await this.getProtocolParams();
925
+ const [encryptedData, circuitInputs] = (0, import_wasm.bfv_verifiable_encrypt_number)(
926
+ data,
927
+ publicKey,
928
+ protocolParams.degree,
929
+ protocolParams.plaintextModulus,
930
+ BigUint64Array.from(protocolParams.moduli)
931
+ );
932
+ const publicInputs = JSON.parse(circuitInputs);
933
+ return {
934
+ encryptedData,
935
+ publicInputs
936
+ };
856
937
  }
857
938
  /**
858
939
  * Encrypt a number using the configured protocol and generate a zk-SNARK proof using Greco
@@ -862,25 +943,61 @@ var EnclaveSDK = class _EnclaveSDK {
862
943
  * @returns The encrypted number and the proof
863
944
  */
864
945
  async encryptNumberAndGenProof(data, publicKey, circuit) {
946
+ const { publicInputs, encryptedData } = await this.encryptNumberAndGenInputs(data, publicKey);
947
+ const proof = await generateProof(publicInputs, circuit);
948
+ return {
949
+ encryptedData,
950
+ proof
951
+ };
952
+ }
953
+ /**
954
+ * Encrypt a vector and generate inputs for an E3 computation
955
+ * @param data - The vector to encrypt
956
+ * @param publicKey - The public key to use for encryption
957
+ * @returns The encrypted vector and the inputs for the E3 computation
958
+ */
959
+ async encryptVectorAndGenInputs(data, publicKey) {
865
960
  await (0, import_init.default)();
866
- switch (this.protocol) {
867
- case "BFV" /* BFV */:
868
- const [encryptedVote, circuitInputs] = (0, import_wasm.bfv_verifiable_encrypt_number)(
869
- data,
870
- publicKey,
871
- this.protocolParams.degree,
872
- this.protocolParams.plaintextModulus,
873
- this.protocolParams.moduli
874
- );
875
- const inputs = JSON.parse(circuitInputs);
876
- const proof = await generateProof(inputs, circuit);
877
- return {
878
- encryptedVote,
879
- proof
880
- };
881
- default:
882
- throw new Error("Protocol not supported");
961
+ const protocolParams = await this.getProtocolParams();
962
+ const [encryptedData, circuitInputs] = (0, import_wasm.bfv_verifiable_encrypt_vector)(
963
+ data,
964
+ publicKey,
965
+ protocolParams.degree,
966
+ protocolParams.plaintextModulus,
967
+ BigUint64Array.from(protocolParams.moduli)
968
+ );
969
+ const publicInputs = JSON.parse(circuitInputs);
970
+ return {
971
+ encryptedData,
972
+ publicInputs
973
+ };
974
+ }
975
+ /**
976
+ * Encrypt a vector using the configured protocol and generate a zk-SNARK proof using Greco
977
+ * @param data - The vector to encrypt
978
+ * @param publicKey - The public key to use for encryption
979
+ * @param circuit - The circuit to use for proof generation
980
+ * @returns The encrypted vector and the proof
981
+ */
982
+ async encryptVectorAndGenProof(data, publicKey, circuit) {
983
+ const { publicInputs, encryptedData } = await this.encryptVectorAndGenInputs(data, publicKey);
984
+ const proof = await generateProof(publicInputs, circuit);
985
+ return {
986
+ encryptedData,
987
+ proof
988
+ };
989
+ }
990
+ /**
991
+ * Approve the fee token for the Enclave
992
+ * @param amount - The amount to approve
993
+ * @returns The approval transaction hash
994
+ */
995
+ async approveFeeToken(amount) {
996
+ console.log(">>> APPROVE FEE TOKEN");
997
+ if (!this.initialized) {
998
+ await this.initialize();
883
999
  }
1000
+ return this.contractClient.approveFeeToken(amount);
884
1001
  }
885
1002
  /**
886
1003
  * Request a new E3 computation
@@ -891,14 +1008,13 @@ var EnclaveSDK = class _EnclaveSDK {
891
1008
  await this.initialize();
892
1009
  }
893
1010
  return this.contractClient.requestE3(
894
- params.filter,
895
1011
  params.threshold,
896
1012
  params.startWindow,
897
1013
  params.duration,
898
1014
  params.e3Program,
899
1015
  params.e3ProgramParams,
900
1016
  params.computeProviderParams,
901
- params.value,
1017
+ params.customParams,
902
1018
  params.gasLimit
903
1019
  );
904
1020
  }
@@ -938,12 +1054,7 @@ var EnclaveSDK = class _EnclaveSDK {
938
1054
  if (!this.initialized) {
939
1055
  await this.initialize();
940
1056
  }
941
- return this.contractClient.publishCiphertextOutput(
942
- e3Id,
943
- ciphertextOutput,
944
- proof,
945
- gasLimit
946
- );
1057
+ return this.contractClient.publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit);
947
1058
  }
948
1059
  /**
949
1060
  * Get E3 information
@@ -958,17 +1069,10 @@ var EnclaveSDK = class _EnclaveSDK {
958
1069
  * Unified Event Listening - Listen to any Enclave or Registry event
959
1070
  */
960
1071
  onEnclaveEvent(eventType, callback) {
961
- const isEnclaveEvent = Object.values(EnclaveEventType).includes(
962
- eventType
963
- );
1072
+ const isEnclaveEvent = Object.values(EnclaveEventType).includes(eventType);
964
1073
  const contractAddress = isEnclaveEvent ? this.config.contracts.enclave : this.config.contracts.ciphernodeRegistry;
965
1074
  const abi = isEnclaveEvent ? import_types2.Enclave__factory.abi : import_types2.CiphernodeRegistryOwnable__factory.abi;
966
- void this.eventListener.watchContractEvent(
967
- contractAddress,
968
- eventType,
969
- abi,
970
- callback
971
- );
1075
+ void this.eventListener.watchContractEvent(contractAddress, eventType, abi, callback);
972
1076
  }
973
1077
  /**
974
1078
  * Remove event listener
@@ -993,18 +1097,10 @@ var EnclaveSDK = class _EnclaveSDK {
993
1097
  * Get historical events
994
1098
  */
995
1099
  async getHistoricalEvents(eventType, fromBlock, toBlock) {
996
- const isEnclaveEvent = Object.values(EnclaveEventType).includes(
997
- eventType
998
- );
1100
+ const isEnclaveEvent = Object.values(EnclaveEventType).includes(eventType);
999
1101
  const contractAddress = isEnclaveEvent ? this.config.contracts.enclave : this.config.contracts.ciphernodeRegistry;
1000
1102
  const abi = isEnclaveEvent ? import_types2.Enclave__factory.abi : import_types2.CiphernodeRegistryOwnable__factory.abi;
1001
- return this.eventListener.getHistoricalEvents(
1002
- contractAddress,
1003
- eventType,
1004
- abi,
1005
- fromBlock,
1006
- toBlock
1007
- );
1103
+ return this.eventListener.getHistoricalEvents(contractAddress, eventType, abi, fromBlock, toBlock);
1008
1104
  }
1009
1105
  /**
1010
1106
  * Start polling for events
@@ -1025,13 +1121,7 @@ var EnclaveSDK = class _EnclaveSDK {
1025
1121
  * Estimate gas for a transaction
1026
1122
  */
1027
1123
  async estimateGas(functionName, args, contractAddress, abi, value) {
1028
- return this.contractClient.estimateGas(
1029
- functionName,
1030
- args,
1031
- contractAddress,
1032
- abi,
1033
- value
1034
- );
1124
+ return this.contractClient.estimateGas(functionName, args, contractAddress, abi, value);
1035
1125
  }
1036
1126
  /**
1037
1127
  * Wait for transaction confirmation
@@ -1066,11 +1156,7 @@ var EnclaveSDK = class _EnclaveSDK {
1066
1156
  if (newConfig.chainId) {
1067
1157
  this.config.chainId = newConfig.chainId;
1068
1158
  }
1069
- this.contractClient = new ContractClient(
1070
- this.config.publicClient,
1071
- this.config.walletClient,
1072
- this.config.contracts
1073
- );
1159
+ this.contractClient = new ContractClient(this.config.publicClient, this.config.walletClient, this.config.contracts);
1074
1160
  this.initialized = false;
1075
1161
  }
1076
1162
  static create(options) {
@@ -1117,9 +1203,12 @@ var EnclaveSDK = class _EnclaveSDK {
1117
1203
  RegistryEventType,
1118
1204
  SDKError,
1119
1205
  calculateStartWindow,
1206
+ convertToPolynomial,
1207
+ convertToPolynomialArray,
1120
1208
  decodePlaintextOutput,
1121
1209
  encodeBfvParams,
1122
1210
  encodeComputeProviderParams,
1211
+ encodeCustomParams,
1123
1212
  formatBigInt,
1124
1213
  formatEventName,
1125
1214
  generateEventId,