@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/README.md +65 -72
- package/dist/index.cjs +291 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +186 -69
- package/dist/index.d.ts +186 -69
- package/dist/index.js +298 -217
- package/dist/index.js.map +1 -1
- package/package.json +23 -18
- package/LICENSE.md +0 -165
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
|
|
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:
|
|
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
|
-
|
|
194
|
-
|
|
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
|
-
|
|
217
|
-
|
|
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(
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
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:
|
|
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
|
-
|
|
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, {
|
|
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
|
-
|
|
787
|
-
|
|
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
|
-
|
|
793
|
-
config.
|
|
794
|
-
|
|
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
|
-
|
|
832
|
-
|
|
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
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
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
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
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.
|
|
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,
|