@enclave-e3/sdk 0.0.7-test
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +165 -0
- package/README.md +340 -0
- package/dist/index.cjs +1103 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +712 -0
- package/dist/index.d.ts +712 -0
- package/dist/index.js +1053 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1053 @@
|
|
|
1
|
+
// src/enclave-sdk.ts
|
|
2
|
+
import {
|
|
3
|
+
createPublicClient,
|
|
4
|
+
createWalletClient,
|
|
5
|
+
http,
|
|
6
|
+
webSocket
|
|
7
|
+
} from "viem";
|
|
8
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
9
|
+
import { hardhat, mainnet, monadTestnet, sepolia } from "viem/chains";
|
|
10
|
+
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";
|
|
15
|
+
|
|
16
|
+
// src/contract-client.ts
|
|
17
|
+
import {
|
|
18
|
+
CiphernodeRegistryOwnable__factory,
|
|
19
|
+
Enclave__factory
|
|
20
|
+
} from "@enclave-e3/contracts/types";
|
|
21
|
+
|
|
22
|
+
// src/utils.ts
|
|
23
|
+
import { encodeAbiParameters } from "viem";
|
|
24
|
+
var SDKError = class extends Error {
|
|
25
|
+
constructor(message, code) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.code = code;
|
|
28
|
+
this.name = "SDKError";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function isValidAddress(address) {
|
|
32
|
+
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
33
|
+
}
|
|
34
|
+
function isValidHash(hash) {
|
|
35
|
+
return /^0x[a-fA-F0-9]{64}$/.test(hash);
|
|
36
|
+
}
|
|
37
|
+
function formatEventName(contractName, eventName) {
|
|
38
|
+
return `${contractName}.${eventName}`;
|
|
39
|
+
}
|
|
40
|
+
function parseEventData(log) {
|
|
41
|
+
return log.data;
|
|
42
|
+
}
|
|
43
|
+
var sleep = (ms) => {
|
|
44
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
45
|
+
};
|
|
46
|
+
function formatBigInt(value) {
|
|
47
|
+
return value.toString();
|
|
48
|
+
}
|
|
49
|
+
function parseBigInt(value) {
|
|
50
|
+
return BigInt(value);
|
|
51
|
+
}
|
|
52
|
+
function generateEventId(log) {
|
|
53
|
+
return `${log.blockHash}-${log.logIndex}`;
|
|
54
|
+
}
|
|
55
|
+
function getCurrentTimestamp() {
|
|
56
|
+
return Math.floor(Date.now() / 1e3);
|
|
57
|
+
}
|
|
58
|
+
var BFV_PARAMS_SET = {
|
|
59
|
+
degree: 2048,
|
|
60
|
+
plaintext_modulus: 1032193,
|
|
61
|
+
moduli: [0x3fffffff000001n]
|
|
62
|
+
// BigInt for the modulus
|
|
63
|
+
};
|
|
64
|
+
var DEFAULT_COMPUTE_PROVIDER_PARAMS = {
|
|
65
|
+
name: "risc0",
|
|
66
|
+
parallel: false,
|
|
67
|
+
batch_size: 2
|
|
68
|
+
};
|
|
69
|
+
var DEFAULT_E3_CONFIG = {
|
|
70
|
+
threshold_min: 2,
|
|
71
|
+
threshold_max: 3,
|
|
72
|
+
window_size: 120,
|
|
73
|
+
// 2 minutes in seconds
|
|
74
|
+
duration: 1800,
|
|
75
|
+
// 30 minutes in seconds
|
|
76
|
+
payment_amount: "0"
|
|
77
|
+
// 0 ETH in wei
|
|
78
|
+
};
|
|
79
|
+
function encodeBfvParams(degree = BFV_PARAMS_SET.degree, plaintext_modulus = BFV_PARAMS_SET.plaintext_modulus, moduli = BFV_PARAMS_SET.moduli) {
|
|
80
|
+
return encodeAbiParameters(
|
|
81
|
+
[
|
|
82
|
+
{
|
|
83
|
+
name: "bfvParams",
|
|
84
|
+
type: "tuple",
|
|
85
|
+
components: [
|
|
86
|
+
{ name: "degree", type: "uint256" },
|
|
87
|
+
{ name: "plaintext_modulus", type: "uint256" },
|
|
88
|
+
{ name: "moduli", type: "uint256[]" }
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
[
|
|
93
|
+
{
|
|
94
|
+
degree: BigInt(degree),
|
|
95
|
+
plaintext_modulus: BigInt(plaintext_modulus),
|
|
96
|
+
moduli: [...moduli]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
function encodeComputeProviderParams(params) {
|
|
102
|
+
const jsonString = JSON.stringify(params);
|
|
103
|
+
const encoder = new TextEncoder();
|
|
104
|
+
const bytes = encoder.encode(jsonString);
|
|
105
|
+
return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
106
|
+
}
|
|
107
|
+
function calculateStartWindow(windowSize = DEFAULT_E3_CONFIG.window_size) {
|
|
108
|
+
const now = getCurrentTimestamp();
|
|
109
|
+
return [BigInt(now), BigInt(now + windowSize)];
|
|
110
|
+
}
|
|
111
|
+
function decodePlaintextOutput(plaintextOutput) {
|
|
112
|
+
try {
|
|
113
|
+
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
|
+
);
|
|
117
|
+
if (bytes.length < 8) {
|
|
118
|
+
console.warn("Plaintext output too short for u64 decoding");
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
122
|
+
const result = view.getBigUint64(0, true);
|
|
123
|
+
return Number(result);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error("Failed to decode plaintext output:", error);
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/contract-client.ts
|
|
131
|
+
var ContractClient = class {
|
|
132
|
+
constructor(publicClient, walletClient, addresses = {
|
|
133
|
+
enclave: "0x0000000000000000000000000000000000000000",
|
|
134
|
+
ciphernodeRegistry: "0x0000000000000000000000000000000000000000"
|
|
135
|
+
}) {
|
|
136
|
+
this.publicClient = publicClient;
|
|
137
|
+
this.walletClient = walletClient;
|
|
138
|
+
this.addresses = addresses;
|
|
139
|
+
if (!isValidAddress(addresses.enclave)) {
|
|
140
|
+
throw new SDKError("Invalid Enclave contract address", "INVALID_ADDRESS");
|
|
141
|
+
}
|
|
142
|
+
if (!isValidAddress(addresses.ciphernodeRegistry)) {
|
|
143
|
+
throw new SDKError(
|
|
144
|
+
"Invalid CiphernodeRegistry contract address",
|
|
145
|
+
"INVALID_ADDRESS"
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
contractInfo = null;
|
|
150
|
+
/**
|
|
151
|
+
* Initialize contract instances
|
|
152
|
+
*/
|
|
153
|
+
async initialize() {
|
|
154
|
+
try {
|
|
155
|
+
this.contractInfo = {
|
|
156
|
+
enclave: {
|
|
157
|
+
address: this.addresses.enclave,
|
|
158
|
+
abi: Enclave__factory.abi
|
|
159
|
+
},
|
|
160
|
+
ciphernodeRegistry: {
|
|
161
|
+
address: this.addresses.ciphernodeRegistry,
|
|
162
|
+
abi: CiphernodeRegistryOwnable__factory.abi
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
} catch (error) {
|
|
166
|
+
throw new SDKError(
|
|
167
|
+
`Failed to initialize contracts: ${error}`,
|
|
168
|
+
"INITIALIZATION_FAILED"
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Request a new E3 computation
|
|
174
|
+
* request(address filter, uint32[2] threshold, uint256[2] startWindow, uint256 duration, IE3Program e3Program, bytes e3ProgramParams, bytes computeProviderParams)
|
|
175
|
+
*/
|
|
176
|
+
async requestE3(filter, threshold, startWindow, duration, e3Program, e3ProgramParams, computeProviderParams, value, gasLimit) {
|
|
177
|
+
if (!this.walletClient) {
|
|
178
|
+
throw new SDKError(
|
|
179
|
+
"Wallet client required for write operations",
|
|
180
|
+
"NO_WALLET"
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
if (!this.contractInfo) {
|
|
184
|
+
await this.initialize();
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const account = this.walletClient.account;
|
|
188
|
+
if (!account) {
|
|
189
|
+
throw new SDKError("No account connected", "NO_ACCOUNT");
|
|
190
|
+
}
|
|
191
|
+
const { request } = await this.publicClient.simulateContract({
|
|
192
|
+
address: this.addresses.enclave,
|
|
193
|
+
abi: Enclave__factory.abi,
|
|
194
|
+
functionName: "request",
|
|
195
|
+
args: [
|
|
196
|
+
{
|
|
197
|
+
filter,
|
|
198
|
+
threshold,
|
|
199
|
+
startWindow,
|
|
200
|
+
duration,
|
|
201
|
+
e3Program,
|
|
202
|
+
e3ProgramParams,
|
|
203
|
+
computeProviderParams
|
|
204
|
+
}
|
|
205
|
+
],
|
|
206
|
+
account,
|
|
207
|
+
value: value || BigInt(0),
|
|
208
|
+
gas: gasLimit
|
|
209
|
+
});
|
|
210
|
+
const hash = await this.walletClient.writeContract(request);
|
|
211
|
+
return hash;
|
|
212
|
+
} catch (error) {
|
|
213
|
+
throw new SDKError(`Failed to request E3: ${error}`, "REQUEST_E3_FAILED");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Activate an E3 computation
|
|
218
|
+
* activate(uint256 e3Id, bytes memory publicKey)
|
|
219
|
+
*/
|
|
220
|
+
async activateE3(e3Id, publicKey, gasLimit) {
|
|
221
|
+
if (!this.walletClient) {
|
|
222
|
+
throw new SDKError(
|
|
223
|
+
"Wallet client required for write operations",
|
|
224
|
+
"NO_WALLET"
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
if (!this.contractInfo) {
|
|
228
|
+
await this.initialize();
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
const account = this.walletClient.account;
|
|
232
|
+
if (!account) {
|
|
233
|
+
throw new SDKError("No account connected", "NO_ACCOUNT");
|
|
234
|
+
}
|
|
235
|
+
const { request } = await this.publicClient.simulateContract({
|
|
236
|
+
address: this.addresses.enclave,
|
|
237
|
+
abi: Enclave__factory.abi,
|
|
238
|
+
functionName: "activate",
|
|
239
|
+
args: [e3Id, publicKey],
|
|
240
|
+
account,
|
|
241
|
+
gas: gasLimit
|
|
242
|
+
});
|
|
243
|
+
const hash = await this.walletClient.writeContract(request);
|
|
244
|
+
return hash;
|
|
245
|
+
} catch (error) {
|
|
246
|
+
throw new SDKError(
|
|
247
|
+
`Failed to activate E3: ${error}`,
|
|
248
|
+
"ACTIVATE_E3_FAILED"
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Publish input for an E3 computation
|
|
254
|
+
* publishInput(uint256 e3Id, bytes memory data)
|
|
255
|
+
*/
|
|
256
|
+
async publishInput(e3Id, data, gasLimit) {
|
|
257
|
+
if (!this.walletClient) {
|
|
258
|
+
throw new SDKError(
|
|
259
|
+
"Wallet client required for write operations",
|
|
260
|
+
"NO_WALLET"
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
if (!this.contractInfo) {
|
|
264
|
+
await this.initialize();
|
|
265
|
+
}
|
|
266
|
+
try {
|
|
267
|
+
const account = this.walletClient.account;
|
|
268
|
+
if (!account) {
|
|
269
|
+
throw new SDKError("No account connected", "NO_ACCOUNT");
|
|
270
|
+
}
|
|
271
|
+
const { request } = await this.publicClient.simulateContract({
|
|
272
|
+
address: this.addresses.enclave,
|
|
273
|
+
abi: Enclave__factory.abi,
|
|
274
|
+
functionName: "publishInput",
|
|
275
|
+
args: [e3Id, data],
|
|
276
|
+
account,
|
|
277
|
+
gas: gasLimit
|
|
278
|
+
});
|
|
279
|
+
const hash = await this.walletClient.writeContract(request);
|
|
280
|
+
return hash;
|
|
281
|
+
} catch (error) {
|
|
282
|
+
throw new SDKError(
|
|
283
|
+
`Failed to publish input: ${error}`,
|
|
284
|
+
"PUBLISH_INPUT_FAILED"
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Publish ciphertext output for an E3 computation
|
|
290
|
+
* publishCiphertextOutput(uint256 e3Id, bytes memory ciphertextOutput, bytes memory proof)
|
|
291
|
+
*/
|
|
292
|
+
async publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit) {
|
|
293
|
+
if (!this.walletClient) {
|
|
294
|
+
throw new SDKError(
|
|
295
|
+
"Wallet client required for write operations",
|
|
296
|
+
"NO_WALLET"
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
if (!this.contractInfo) {
|
|
300
|
+
await this.initialize();
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
const account = this.walletClient.account;
|
|
304
|
+
if (!account) {
|
|
305
|
+
throw new SDKError("No account connected", "NO_ACCOUNT");
|
|
306
|
+
}
|
|
307
|
+
const { request } = await this.publicClient.simulateContract({
|
|
308
|
+
address: this.addresses.enclave,
|
|
309
|
+
abi: Enclave__factory.abi,
|
|
310
|
+
functionName: "publishCiphertextOutput",
|
|
311
|
+
args: [e3Id, ciphertextOutput, proof],
|
|
312
|
+
account,
|
|
313
|
+
gas: gasLimit
|
|
314
|
+
});
|
|
315
|
+
const hash = await this.walletClient.writeContract(request);
|
|
316
|
+
return hash;
|
|
317
|
+
} catch (error) {
|
|
318
|
+
throw new SDKError(
|
|
319
|
+
`Failed to publish ciphertext output: ${error}`,
|
|
320
|
+
"PUBLISH_CIPHERTEXT_OUTPUT_FAILED"
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Get E3 information
|
|
326
|
+
* Based on the contract: getE3(uint256 e3Id) returns (E3 memory e3)
|
|
327
|
+
*/
|
|
328
|
+
async getE3(e3Id) {
|
|
329
|
+
if (!this.contractInfo) {
|
|
330
|
+
await this.initialize();
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
const result = await this.publicClient.readContract({
|
|
334
|
+
address: this.addresses.enclave,
|
|
335
|
+
abi: Enclave__factory.abi,
|
|
336
|
+
functionName: "getE3",
|
|
337
|
+
args: [e3Id]
|
|
338
|
+
});
|
|
339
|
+
return result;
|
|
340
|
+
} catch (error) {
|
|
341
|
+
throw new SDKError(`Failed to get E3: ${error}`, "GET_E3_FAILED");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Estimate gas for a transaction
|
|
346
|
+
*/
|
|
347
|
+
async estimateGas(functionName, args, contractAddress, abi, value) {
|
|
348
|
+
if (!this.walletClient) {
|
|
349
|
+
throw new SDKError(
|
|
350
|
+
"Wallet client required for gas estimation",
|
|
351
|
+
"NO_WALLET"
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
const account = this.walletClient.account;
|
|
356
|
+
if (!account) {
|
|
357
|
+
throw new SDKError("No account connected", "NO_ACCOUNT");
|
|
358
|
+
}
|
|
359
|
+
const estimateParams = {
|
|
360
|
+
address: contractAddress,
|
|
361
|
+
abi,
|
|
362
|
+
functionName,
|
|
363
|
+
args,
|
|
364
|
+
account,
|
|
365
|
+
...value !== void 0 && { value }
|
|
366
|
+
};
|
|
367
|
+
const gas = await this.publicClient.estimateContractGas(estimateParams);
|
|
368
|
+
return gas;
|
|
369
|
+
} catch (error) {
|
|
370
|
+
throw new SDKError(
|
|
371
|
+
`Failed to estimate gas: ${error}`,
|
|
372
|
+
"GAS_ESTIMATION_FAILED"
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Wait for transaction confirmation
|
|
378
|
+
*/
|
|
379
|
+
async waitForTransaction(hash) {
|
|
380
|
+
try {
|
|
381
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
382
|
+
hash,
|
|
383
|
+
confirmations: 1
|
|
384
|
+
});
|
|
385
|
+
return receipt;
|
|
386
|
+
} catch (error) {
|
|
387
|
+
throw new SDKError(
|
|
388
|
+
`Failed to wait for transaction: ${error}`,
|
|
389
|
+
"TRANSACTION_WAIT_FAILED"
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// src/event-listener.ts
|
|
396
|
+
var EventListener = class {
|
|
397
|
+
constructor(publicClient, config = {}) {
|
|
398
|
+
this.publicClient = publicClient;
|
|
399
|
+
this.config = config;
|
|
400
|
+
}
|
|
401
|
+
listeners = /* @__PURE__ */ new Map();
|
|
402
|
+
activeWatchers = /* @__PURE__ */ new Map();
|
|
403
|
+
isPolling = false;
|
|
404
|
+
lastBlockNumber = BigInt(0);
|
|
405
|
+
/**
|
|
406
|
+
* Listen to specific contract events
|
|
407
|
+
*/
|
|
408
|
+
async watchContractEvent(address, eventType, abi, callback) {
|
|
409
|
+
const watcherKey = `${address}:${eventType}`;
|
|
410
|
+
console.log(`watchContractEvent: ${watcherKey}`);
|
|
411
|
+
if (!this.listeners.has(eventType)) {
|
|
412
|
+
this.listeners.set(eventType, /* @__PURE__ */ new Set());
|
|
413
|
+
}
|
|
414
|
+
console.log("Added callback");
|
|
415
|
+
this.listeners.get(eventType).add(callback);
|
|
416
|
+
const emitter = this;
|
|
417
|
+
if (!this.activeWatchers.has(watcherKey)) {
|
|
418
|
+
console.log("Adding active watcher for " + watcherKey);
|
|
419
|
+
try {
|
|
420
|
+
const unwatch = this.publicClient.watchContractEvent({
|
|
421
|
+
address,
|
|
422
|
+
abi,
|
|
423
|
+
eventName: eventType,
|
|
424
|
+
fromBlock: this.config.fromBlock,
|
|
425
|
+
onLogs(logs) {
|
|
426
|
+
for (let i = 0; i < logs.length; i++) {
|
|
427
|
+
const log = logs[i];
|
|
428
|
+
if (!log) {
|
|
429
|
+
console.log("warning: Log was falsy when a log was expected!");
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
const event = {
|
|
433
|
+
type: eventType,
|
|
434
|
+
data: log.args,
|
|
435
|
+
log,
|
|
436
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
437
|
+
blockNumber: log.blockNumber ?? BigInt(0),
|
|
438
|
+
transactionHash: log.transactionHash ?? "0x"
|
|
439
|
+
};
|
|
440
|
+
console.log("Created event, now emitting event...");
|
|
441
|
+
emitter.emit(event);
|
|
442
|
+
console.log("Event emitted");
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
this.activeWatchers.set(watcherKey, unwatch);
|
|
447
|
+
} catch (error) {
|
|
448
|
+
throw new SDKError(
|
|
449
|
+
`Failed to watch contract event ${eventType} on ${address}: ${error}`,
|
|
450
|
+
"WATCH_EVENT_FAILED"
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Listen to all logs from a specific address
|
|
457
|
+
*/
|
|
458
|
+
async watchLogs(address, callback) {
|
|
459
|
+
const watcherKey = `logs:${address}`;
|
|
460
|
+
if (!this.activeWatchers.has(watcherKey)) {
|
|
461
|
+
try {
|
|
462
|
+
const unwatch = this.publicClient.watchEvent({
|
|
463
|
+
address,
|
|
464
|
+
onLogs: (logs) => {
|
|
465
|
+
logs.forEach((log) => {
|
|
466
|
+
callback(log);
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
this.activeWatchers.set(watcherKey, unwatch);
|
|
471
|
+
} catch (error) {
|
|
472
|
+
throw new SDKError(
|
|
473
|
+
`Failed to watch logs for address ${address}: ${error}`,
|
|
474
|
+
"WATCH_LOGS_FAILED"
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Start polling for historical events
|
|
481
|
+
*/
|
|
482
|
+
async startPolling() {
|
|
483
|
+
if (this.isPolling) return;
|
|
484
|
+
this.isPolling = true;
|
|
485
|
+
try {
|
|
486
|
+
this.lastBlockNumber = await this.publicClient.getBlockNumber();
|
|
487
|
+
void this.pollForEvents();
|
|
488
|
+
} catch (error) {
|
|
489
|
+
this.isPolling = false;
|
|
490
|
+
throw new SDKError(
|
|
491
|
+
`Failed to start polling: ${error}`,
|
|
492
|
+
"POLLING_START_FAILED"
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Stop polling for events
|
|
498
|
+
*/
|
|
499
|
+
stopPolling() {
|
|
500
|
+
this.isPolling = false;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Get historical events
|
|
504
|
+
*/
|
|
505
|
+
async getHistoricalEvents(address, eventType, abi, fromBlock, toBlock) {
|
|
506
|
+
try {
|
|
507
|
+
const logs = await this.publicClient.getContractEvents({
|
|
508
|
+
address,
|
|
509
|
+
abi,
|
|
510
|
+
eventName: eventType,
|
|
511
|
+
fromBlock: fromBlock || this.config.fromBlock,
|
|
512
|
+
toBlock: toBlock || this.config.toBlock
|
|
513
|
+
});
|
|
514
|
+
return logs;
|
|
515
|
+
} catch (error) {
|
|
516
|
+
throw new SDKError(
|
|
517
|
+
`Failed to get historical events: ${error}`,
|
|
518
|
+
"HISTORICAL_EVENTS_FAILED"
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* SDKEventEmitter implementation
|
|
524
|
+
*/
|
|
525
|
+
on(eventType, callback) {
|
|
526
|
+
if (!this.listeners.has(eventType)) {
|
|
527
|
+
this.listeners.set(eventType, /* @__PURE__ */ new Set());
|
|
528
|
+
}
|
|
529
|
+
this.listeners.get(eventType).add(callback);
|
|
530
|
+
}
|
|
531
|
+
off(eventType, callback) {
|
|
532
|
+
const callbacks = this.listeners.get(eventType);
|
|
533
|
+
if (callbacks) {
|
|
534
|
+
callbacks.delete(callback);
|
|
535
|
+
if (callbacks.size === 0) {
|
|
536
|
+
this.listeners.delete(eventType);
|
|
537
|
+
const watchersToRemove = [];
|
|
538
|
+
this.activeWatchers.forEach((unwatch, key) => {
|
|
539
|
+
if (key.endsWith(`:${eventType}`)) {
|
|
540
|
+
try {
|
|
541
|
+
unwatch();
|
|
542
|
+
} catch (error) {
|
|
543
|
+
console.error(`Error unwatching event ${eventType}:`, error);
|
|
544
|
+
}
|
|
545
|
+
watchersToRemove.push(key);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
watchersToRemove.forEach((key) => this.activeWatchers.delete(key));
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
emit(event) {
|
|
553
|
+
console.log("emit() called for " + event.type);
|
|
554
|
+
const callbacks = this.listeners.get(event.type);
|
|
555
|
+
if (callbacks) {
|
|
556
|
+
console.log("Have " + callbacks.size + " callbacks");
|
|
557
|
+
callbacks.forEach((callback) => {
|
|
558
|
+
console.log("Running callback...");
|
|
559
|
+
try {
|
|
560
|
+
void callback(event);
|
|
561
|
+
} catch (error) {
|
|
562
|
+
console.error(`Error in event callback for ${event.type}:`, error);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Clean up all listeners and watchers
|
|
569
|
+
*/
|
|
570
|
+
cleanup() {
|
|
571
|
+
this.stopPolling();
|
|
572
|
+
this.activeWatchers.forEach((unwatch) => {
|
|
573
|
+
try {
|
|
574
|
+
unwatch();
|
|
575
|
+
} catch (error) {
|
|
576
|
+
console.error("Error unwatching during cleanup:", error);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
this.activeWatchers.clear();
|
|
580
|
+
this.listeners.clear();
|
|
581
|
+
}
|
|
582
|
+
async pollForEvents() {
|
|
583
|
+
while (this.isPolling) {
|
|
584
|
+
try {
|
|
585
|
+
const currentBlock = await this.publicClient.getBlockNumber();
|
|
586
|
+
if (currentBlock > this.lastBlockNumber) {
|
|
587
|
+
this.lastBlockNumber = currentBlock;
|
|
588
|
+
}
|
|
589
|
+
await sleep(this.config.pollingInterval || 5e3);
|
|
590
|
+
} catch (error) {
|
|
591
|
+
console.error("Error during polling:", error);
|
|
592
|
+
await sleep(this.config.pollingInterval || 5e3);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/types.ts
|
|
599
|
+
var EnclaveEventType = /* @__PURE__ */ ((EnclaveEventType2) => {
|
|
600
|
+
EnclaveEventType2["E3_REQUESTED"] = "E3Requested";
|
|
601
|
+
EnclaveEventType2["E3_ACTIVATED"] = "E3Activated";
|
|
602
|
+
EnclaveEventType2["INPUT_PUBLISHED"] = "InputPublished";
|
|
603
|
+
EnclaveEventType2["CIPHERTEXT_OUTPUT_PUBLISHED"] = "CiphertextOutputPublished";
|
|
604
|
+
EnclaveEventType2["PLAINTEXT_OUTPUT_PUBLISHED"] = "PlaintextOutputPublished";
|
|
605
|
+
EnclaveEventType2["E3_PROGRAM_ENABLED"] = "E3ProgramEnabled";
|
|
606
|
+
EnclaveEventType2["E3_PROGRAM_DISABLED"] = "E3ProgramDisabled";
|
|
607
|
+
EnclaveEventType2["ENCRYPTION_SCHEME_ENABLED"] = "EncryptionSchemeEnabled";
|
|
608
|
+
EnclaveEventType2["ENCRYPTION_SCHEME_DISABLED"] = "EncryptionSchemeDisabled";
|
|
609
|
+
EnclaveEventType2["CIPHERNODE_REGISTRY_SET"] = "CiphernodeRegistrySet";
|
|
610
|
+
EnclaveEventType2["MAX_DURATION_SET"] = "MaxDurationSet";
|
|
611
|
+
EnclaveEventType2["ALLOWED_E3_PROGRAMS_PARAMS_SET"] = "AllowedE3ProgramsParamsSet";
|
|
612
|
+
EnclaveEventType2["OWNERSHIP_TRANSFERRED"] = "OwnershipTransferred";
|
|
613
|
+
EnclaveEventType2["INITIALIZED"] = "Initialized";
|
|
614
|
+
return EnclaveEventType2;
|
|
615
|
+
})(EnclaveEventType || {});
|
|
616
|
+
var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
|
|
617
|
+
RegistryEventType2["COMMITTEE_REQUESTED"] = "CommitteeRequested";
|
|
618
|
+
RegistryEventType2["COMMITTEE_PUBLISHED"] = "CommitteePublished";
|
|
619
|
+
RegistryEventType2["ENCLAVE_SET"] = "EnclaveSet";
|
|
620
|
+
RegistryEventType2["OWNERSHIP_TRANSFERRED"] = "OwnershipTransferred";
|
|
621
|
+
RegistryEventType2["INITIALIZED"] = "Initialized";
|
|
622
|
+
return RegistryEventType2;
|
|
623
|
+
})(RegistryEventType || {});
|
|
624
|
+
var FheProtocol = /* @__PURE__ */ ((FheProtocol2) => {
|
|
625
|
+
FheProtocol2["BFV"] = "BFV";
|
|
626
|
+
return FheProtocol2;
|
|
627
|
+
})(FheProtocol || {});
|
|
628
|
+
var BfvProtocolParams = {
|
|
629
|
+
/**
|
|
630
|
+
* Recommended parameters for BFV protocol
|
|
631
|
+
* - Degree: 2048
|
|
632
|
+
* - Plaintext modulus: 1032193
|
|
633
|
+
* - Moduli:0x3FFFFFFF000001
|
|
634
|
+
*/
|
|
635
|
+
BFV_NORMAL: {
|
|
636
|
+
degree: 2048,
|
|
637
|
+
plaintextModulus: 1032193n,
|
|
638
|
+
moduli: 0x3FFFFFFF000001n
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// src/enclave-sdk.ts
|
|
643
|
+
import { bfv_encrypt_number, bfv_verifiable_encrypt_number } from "@enclave-e3/wasm";
|
|
644
|
+
|
|
645
|
+
// src/greco.ts
|
|
646
|
+
import { UltraHonkBackend } from "@aztec/bb.js";
|
|
647
|
+
import { Noir } from "@noir-lang/noir_js";
|
|
648
|
+
var convertToPolynomial = (stringArray) => {
|
|
649
|
+
return {
|
|
650
|
+
coefficients: stringArray
|
|
651
|
+
};
|
|
652
|
+
};
|
|
653
|
+
var convertToPolynomialArray = (stringArrays) => {
|
|
654
|
+
return stringArrays.map(convertToPolynomial);
|
|
655
|
+
};
|
|
656
|
+
var generateProof = async (circuitInputs, circuit) => {
|
|
657
|
+
const noir = new Noir(circuit);
|
|
658
|
+
const backend = new UltraHonkBackend(circuit.bytecode, { threads: 4 });
|
|
659
|
+
const pk0is_poly = convertToPolynomialArray(circuitInputs.pk0is);
|
|
660
|
+
const pk1is_poly = convertToPolynomialArray(circuitInputs.pk1is);
|
|
661
|
+
const ct0is_poly = convertToPolynomialArray(circuitInputs.ct0is);
|
|
662
|
+
const ct1is_poly = convertToPolynomialArray(circuitInputs.ct1is);
|
|
663
|
+
const u_poly = convertToPolynomial(circuitInputs.u);
|
|
664
|
+
const e0_poly = convertToPolynomial(circuitInputs.e0);
|
|
665
|
+
const e1_poly = convertToPolynomial(circuitInputs.e1);
|
|
666
|
+
const k1_poly = convertToPolynomial(circuitInputs.k1);
|
|
667
|
+
const r1is_poly = convertToPolynomialArray(circuitInputs.r1is);
|
|
668
|
+
const r2is_poly = convertToPolynomialArray(circuitInputs.r2is);
|
|
669
|
+
const p1is_poly = convertToPolynomialArray(circuitInputs.p1is);
|
|
670
|
+
const p2is_poly = convertToPolynomialArray(circuitInputs.p2is);
|
|
671
|
+
const { witness } = await noir.execute({
|
|
672
|
+
// params: {
|
|
673
|
+
// q_mod_t: circuitInputs.params.q_mod_t,
|
|
674
|
+
// pk_bounds: circuitInputs.params.pk_bounds,
|
|
675
|
+
// e_bound: circuitInputs.params.e_bound,
|
|
676
|
+
// u_bound: circuitInputs.params.u_bound,
|
|
677
|
+
// r1_low_bounds: circuitInputs.params.r1_low_bounds,
|
|
678
|
+
// r1_up_bounds: circuitInputs.params.r1_up_bounds,
|
|
679
|
+
// r2_bounds: circuitInputs.params.r2_bounds,
|
|
680
|
+
// p1_bounds: circuitInputs.params.p1_bounds,
|
|
681
|
+
// p2_bounds: circuitInputs.params.p2_bounds,
|
|
682
|
+
// k1_low_bound: circuitInputs.params.k1_low_bound,
|
|
683
|
+
// k1_up_bound: circuitInputs.params.k1_up_bound,
|
|
684
|
+
// qis: circuitInputs.params.qis,
|
|
685
|
+
// k0is: circuitInputs.params.k0is,
|
|
686
|
+
// size: circuitInputs.params.size,
|
|
687
|
+
// tag: circuitInputs.params.tag,
|
|
688
|
+
// },
|
|
689
|
+
pk0is: pk0is_poly,
|
|
690
|
+
pk1is: pk1is_poly,
|
|
691
|
+
ct0is: ct0is_poly,
|
|
692
|
+
ct1is: ct1is_poly,
|
|
693
|
+
u: u_poly,
|
|
694
|
+
e0: e0_poly,
|
|
695
|
+
e1: e1_poly,
|
|
696
|
+
k1: k1_poly,
|
|
697
|
+
r1is: r1is_poly,
|
|
698
|
+
r2is: r2is_poly,
|
|
699
|
+
p1is: p1is_poly,
|
|
700
|
+
p2is: p2is_poly
|
|
701
|
+
});
|
|
702
|
+
return await backend.generateProof(witness, { keccak: true });
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
// src/enclave-sdk.ts
|
|
706
|
+
var EnclaveSDK = class _EnclaveSDK {
|
|
707
|
+
constructor(config) {
|
|
708
|
+
this.config = config;
|
|
709
|
+
if (!config.publicClient) {
|
|
710
|
+
throw new SDKError("Public client is required", "MISSING_PUBLIC_CLIENT");
|
|
711
|
+
}
|
|
712
|
+
if (!isValidAddress(config.contracts.enclave)) {
|
|
713
|
+
throw new SDKError("Invalid Enclave contract address", "INVALID_ADDRESS");
|
|
714
|
+
}
|
|
715
|
+
if (!isValidAddress(config.contracts.ciphernodeRegistry)) {
|
|
716
|
+
throw new SDKError(
|
|
717
|
+
"Invalid CiphernodeRegistry contract address",
|
|
718
|
+
"INVALID_ADDRESS"
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
this.eventListener = new EventListener(config.publicClient);
|
|
722
|
+
this.contractClient = new ContractClient(
|
|
723
|
+
config.publicClient,
|
|
724
|
+
config.walletClient,
|
|
725
|
+
config.contracts
|
|
726
|
+
);
|
|
727
|
+
this.protocol = config.protocol;
|
|
728
|
+
if (config.protocolParams) {
|
|
729
|
+
this.protocolParams = config.protocolParams;
|
|
730
|
+
} else {
|
|
731
|
+
switch (this.protocol) {
|
|
732
|
+
case "BFV" /* BFV */:
|
|
733
|
+
this.protocolParams = BfvProtocolParams.BFV_NORMAL;
|
|
734
|
+
break;
|
|
735
|
+
default:
|
|
736
|
+
throw new Error("Protocol not supported");
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
static chains = {
|
|
741
|
+
1: mainnet,
|
|
742
|
+
11155111: sepolia,
|
|
743
|
+
41454: monadTestnet,
|
|
744
|
+
31337: hardhat
|
|
745
|
+
};
|
|
746
|
+
eventListener;
|
|
747
|
+
contractClient;
|
|
748
|
+
initialized = false;
|
|
749
|
+
protocol;
|
|
750
|
+
protocolParams;
|
|
751
|
+
/**
|
|
752
|
+
* Initialize the SDK
|
|
753
|
+
*/
|
|
754
|
+
// TODO: Delete this it is redundant
|
|
755
|
+
async initialize() {
|
|
756
|
+
if (this.initialized) return;
|
|
757
|
+
try {
|
|
758
|
+
await this.contractClient.initialize();
|
|
759
|
+
this.initialized = true;
|
|
760
|
+
} catch (error) {
|
|
761
|
+
throw new SDKError(
|
|
762
|
+
`Failed to initialize SDK: ${error}`,
|
|
763
|
+
"SDK_INITIALIZATION_FAILED"
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Encrypt a number using the configured protocol
|
|
769
|
+
* @param data - The number to encrypt
|
|
770
|
+
* @param publicKey - The public key to use for encryption
|
|
771
|
+
* @returns The encrypted number
|
|
772
|
+
*/
|
|
773
|
+
async encryptNumber(data, publicKey) {
|
|
774
|
+
await initializeWasm();
|
|
775
|
+
switch (this.protocol) {
|
|
776
|
+
case "BFV" /* BFV */:
|
|
777
|
+
return bfv_encrypt_number(
|
|
778
|
+
data,
|
|
779
|
+
publicKey,
|
|
780
|
+
this.protocolParams.degree,
|
|
781
|
+
this.protocolParams.plaintextModulus,
|
|
782
|
+
this.protocolParams.moduli
|
|
783
|
+
);
|
|
784
|
+
default:
|
|
785
|
+
throw new Error("Protocol not supported");
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Encrypt a number using the configured protocol and generate a zk-SNARK proof using Greco
|
|
790
|
+
* @param data - The number to encrypt
|
|
791
|
+
* @param publicKey - The public key to use for encryption
|
|
792
|
+
* @param circuit - The circuit to use for proof generation
|
|
793
|
+
* @returns The encrypted number and the proof
|
|
794
|
+
*/
|
|
795
|
+
async encryptNumberAndGenProof(data, publicKey, circuit) {
|
|
796
|
+
await initializeWasm();
|
|
797
|
+
switch (this.protocol) {
|
|
798
|
+
case "BFV" /* BFV */:
|
|
799
|
+
const [encryptedVote, circuitInputs] = bfv_verifiable_encrypt_number(
|
|
800
|
+
data,
|
|
801
|
+
publicKey,
|
|
802
|
+
this.protocolParams.degree,
|
|
803
|
+
this.protocolParams.plaintextModulus,
|
|
804
|
+
this.protocolParams.moduli
|
|
805
|
+
);
|
|
806
|
+
const inputs = JSON.parse(circuitInputs);
|
|
807
|
+
const proof = await generateProof(inputs, circuit);
|
|
808
|
+
return {
|
|
809
|
+
encryptedVote,
|
|
810
|
+
proof
|
|
811
|
+
};
|
|
812
|
+
default:
|
|
813
|
+
throw new Error("Protocol not supported");
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Request a new E3 computation
|
|
818
|
+
*/
|
|
819
|
+
async requestE3(params) {
|
|
820
|
+
console.log(">>> REQUEST");
|
|
821
|
+
if (!this.initialized) {
|
|
822
|
+
await this.initialize();
|
|
823
|
+
}
|
|
824
|
+
return this.contractClient.requestE3(
|
|
825
|
+
params.filter,
|
|
826
|
+
params.threshold,
|
|
827
|
+
params.startWindow,
|
|
828
|
+
params.duration,
|
|
829
|
+
params.e3Program,
|
|
830
|
+
params.e3ProgramParams,
|
|
831
|
+
params.computeProviderParams,
|
|
832
|
+
params.value,
|
|
833
|
+
params.gasLimit
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Activate an E3 computation
|
|
838
|
+
*/
|
|
839
|
+
async activateE3(e3Id, publicKey, gasLimit) {
|
|
840
|
+
if (!this.initialized) {
|
|
841
|
+
await this.initialize();
|
|
842
|
+
}
|
|
843
|
+
return this.contractClient.activateE3(e3Id, publicKey, gasLimit);
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Publish input for an E3 computation
|
|
847
|
+
*/
|
|
848
|
+
async publishInput(e3Id, data, gasLimit) {
|
|
849
|
+
if (!this.initialized) {
|
|
850
|
+
await this.initialize();
|
|
851
|
+
}
|
|
852
|
+
return this.contractClient.publishInput(e3Id, data, gasLimit);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Publish ciphertext output for an E3 computation
|
|
856
|
+
*/
|
|
857
|
+
async publishCiphertextOutput(e3Id, ciphertextOutput, proof, gasLimit) {
|
|
858
|
+
if (!this.initialized) {
|
|
859
|
+
await this.initialize();
|
|
860
|
+
}
|
|
861
|
+
return this.contractClient.publishCiphertextOutput(
|
|
862
|
+
e3Id,
|
|
863
|
+
ciphertextOutput,
|
|
864
|
+
proof,
|
|
865
|
+
gasLimit
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Get E3 information
|
|
870
|
+
*/
|
|
871
|
+
async getE3(e3Id) {
|
|
872
|
+
if (!this.initialized) {
|
|
873
|
+
await this.initialize();
|
|
874
|
+
}
|
|
875
|
+
return this.contractClient.getE3(e3Id);
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Unified Event Listening - Listen to any Enclave or Registry event
|
|
879
|
+
*/
|
|
880
|
+
onEnclaveEvent(eventType, callback) {
|
|
881
|
+
const isEnclaveEvent = Object.values(EnclaveEventType).includes(
|
|
882
|
+
eventType
|
|
883
|
+
);
|
|
884
|
+
const contractAddress = isEnclaveEvent ? this.config.contracts.enclave : this.config.contracts.ciphernodeRegistry;
|
|
885
|
+
const abi = isEnclaveEvent ? Enclave__factory2.abi : CiphernodeRegistryOwnable__factory2.abi;
|
|
886
|
+
void this.eventListener.watchContractEvent(
|
|
887
|
+
contractAddress,
|
|
888
|
+
eventType,
|
|
889
|
+
abi,
|
|
890
|
+
callback
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Remove event listener
|
|
895
|
+
*/
|
|
896
|
+
off(eventType, callback) {
|
|
897
|
+
this.eventListener.off(eventType, callback);
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Handle an event only once
|
|
901
|
+
*/
|
|
902
|
+
once(type, callback) {
|
|
903
|
+
const handler = (event) => {
|
|
904
|
+
this.off(type, handler);
|
|
905
|
+
const prom = callback(event);
|
|
906
|
+
if (prom) {
|
|
907
|
+
prom.catch((e) => console.log(e));
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
this.onEnclaveEvent(type, handler);
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Get historical events
|
|
914
|
+
*/
|
|
915
|
+
async getHistoricalEvents(eventType, fromBlock, toBlock) {
|
|
916
|
+
const isEnclaveEvent = Object.values(EnclaveEventType).includes(
|
|
917
|
+
eventType
|
|
918
|
+
);
|
|
919
|
+
const contractAddress = isEnclaveEvent ? this.config.contracts.enclave : this.config.contracts.ciphernodeRegistry;
|
|
920
|
+
const abi = isEnclaveEvent ? Enclave__factory2.abi : CiphernodeRegistryOwnable__factory2.abi;
|
|
921
|
+
return this.eventListener.getHistoricalEvents(
|
|
922
|
+
contractAddress,
|
|
923
|
+
eventType,
|
|
924
|
+
abi,
|
|
925
|
+
fromBlock,
|
|
926
|
+
toBlock
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Start polling for events
|
|
931
|
+
*/
|
|
932
|
+
async startEventPolling() {
|
|
933
|
+
void this.eventListener.startPolling();
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Stop polling for events
|
|
937
|
+
*/
|
|
938
|
+
stopEventPolling() {
|
|
939
|
+
this.eventListener.stopPolling();
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Utility methods
|
|
943
|
+
*/
|
|
944
|
+
/**
|
|
945
|
+
* Estimate gas for a transaction
|
|
946
|
+
*/
|
|
947
|
+
async estimateGas(functionName, args, contractAddress, abi, value) {
|
|
948
|
+
return this.contractClient.estimateGas(
|
|
949
|
+
functionName,
|
|
950
|
+
args,
|
|
951
|
+
contractAddress,
|
|
952
|
+
abi,
|
|
953
|
+
value
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Wait for transaction confirmation
|
|
958
|
+
*/
|
|
959
|
+
async waitForTransaction(hash) {
|
|
960
|
+
return this.contractClient.waitForTransaction(hash);
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Clean up resources
|
|
964
|
+
*/
|
|
965
|
+
cleanup() {
|
|
966
|
+
this.eventListener.cleanup();
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* Update SDK configuration
|
|
970
|
+
*/
|
|
971
|
+
// TODO: We should delete this as we don't want a stateful client.
|
|
972
|
+
updateConfig(newConfig) {
|
|
973
|
+
if (newConfig.publicClient) {
|
|
974
|
+
this.config.publicClient = newConfig.publicClient;
|
|
975
|
+
this.eventListener = new EventListener(newConfig.publicClient);
|
|
976
|
+
}
|
|
977
|
+
if (newConfig.walletClient) {
|
|
978
|
+
this.config.walletClient = newConfig.walletClient;
|
|
979
|
+
}
|
|
980
|
+
if (newConfig.contracts) {
|
|
981
|
+
this.config.contracts = {
|
|
982
|
+
...this.config.contracts,
|
|
983
|
+
...newConfig.contracts
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
if (newConfig.chainId) {
|
|
987
|
+
this.config.chainId = newConfig.chainId;
|
|
988
|
+
}
|
|
989
|
+
this.contractClient = new ContractClient(
|
|
990
|
+
this.config.publicClient,
|
|
991
|
+
this.config.walletClient,
|
|
992
|
+
this.config.contracts
|
|
993
|
+
);
|
|
994
|
+
this.initialized = false;
|
|
995
|
+
}
|
|
996
|
+
static create(options) {
|
|
997
|
+
const chain = _EnclaveSDK.chains[options.chainId];
|
|
998
|
+
const isWebSocket = options.rpcUrl.startsWith("ws://") || options.rpcUrl.startsWith("wss://");
|
|
999
|
+
const transport = isWebSocket ? webSocket(options.rpcUrl, {
|
|
1000
|
+
keepAlive: { interval: 3e4 },
|
|
1001
|
+
reconnect: { attempts: 5, delay: 2e3 }
|
|
1002
|
+
}) : http(options.rpcUrl);
|
|
1003
|
+
const publicClient = createPublicClient({
|
|
1004
|
+
chain,
|
|
1005
|
+
transport
|
|
1006
|
+
});
|
|
1007
|
+
let walletClient = void 0;
|
|
1008
|
+
if (options.privateKey) {
|
|
1009
|
+
const account = privateKeyToAccount(options.privateKey);
|
|
1010
|
+
walletClient = createWalletClient({
|
|
1011
|
+
account,
|
|
1012
|
+
chain,
|
|
1013
|
+
transport
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
return new _EnclaveSDK({
|
|
1017
|
+
publicClient,
|
|
1018
|
+
walletClient,
|
|
1019
|
+
contracts: options.contracts,
|
|
1020
|
+
chainId: options.chainId,
|
|
1021
|
+
protocol: options.protocol,
|
|
1022
|
+
protocolParams: options.protocolParams
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
export {
|
|
1027
|
+
BFV_PARAMS_SET,
|
|
1028
|
+
BfvProtocolParams,
|
|
1029
|
+
ContractClient,
|
|
1030
|
+
DEFAULT_COMPUTE_PROVIDER_PARAMS,
|
|
1031
|
+
DEFAULT_E3_CONFIG,
|
|
1032
|
+
EnclaveEventType,
|
|
1033
|
+
EnclaveSDK,
|
|
1034
|
+
EventListener,
|
|
1035
|
+
FheProtocol,
|
|
1036
|
+
RegistryEventType,
|
|
1037
|
+
SDKError,
|
|
1038
|
+
calculateStartWindow,
|
|
1039
|
+
decodePlaintextOutput,
|
|
1040
|
+
encodeBfvParams,
|
|
1041
|
+
encodeComputeProviderParams,
|
|
1042
|
+
formatBigInt,
|
|
1043
|
+
formatEventName,
|
|
1044
|
+
generateEventId,
|
|
1045
|
+
generateProof,
|
|
1046
|
+
getCurrentTimestamp,
|
|
1047
|
+
isValidAddress,
|
|
1048
|
+
isValidHash,
|
|
1049
|
+
parseBigInt,
|
|
1050
|
+
parseEventData,
|
|
1051
|
+
sleep
|
|
1052
|
+
};
|
|
1053
|
+
//# sourceMappingURL=index.js.map
|