@interfold/sdk 0.12.0 → 0.13.0

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 CHANGED
@@ -24,7 +24,7 @@ pnpm add @interfold/sdk
24
24
  ## Quick Start
25
25
 
26
26
  ```typescript
27
- import { InterfoldSDK, InterfoldEventType, RegistryEventType } from '@interfold/sdk'
27
+ import { CommitteeSize, InterfoldSDK, InterfoldEventType, RegistryEventType } from '@interfold/sdk'
28
28
  import { createPublicClient, createWalletClient, http, custom } from 'viem'
29
29
  import { sepolia } from 'viem/chains'
30
30
 
@@ -49,8 +49,8 @@ const sdk = new InterfoldSDK({
49
49
  feeToken: '0x...', // Your ERC-20 fee token address
50
50
  },
51
51
  chain: sepolia,
52
- // Use 'SECURE_THRESHOLD_8192' for production; 'INSECURE_THRESHOLD_512' for local dev only
53
- thresholdBfvParamsPresetName: 'SECURE_THRESHOLD_8192',
52
+ // 'INSECURE_THRESHOLD_512' for local dev and Sepolia; 'SECURE_THRESHOLD_8192' for production
53
+ thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_512',
54
54
  })
55
55
 
56
56
  // Listen to events with the unified event system
@@ -58,19 +58,24 @@ sdk.onInterfoldEvent(InterfoldEventType.E3_REQUESTED, (event) => {
58
58
  console.log('E3 Requested:', event.data)
59
59
  })
60
60
 
61
- sdk.onInterfoldEvent(RegistryEventType.COMMITTEE_REQUESTED, (event) => {
62
- console.log('Committee Requested:', event.data)
61
+ sdk.onInterfoldEvent(RegistryEventType.COMMITTEE_RANDOMNESS_REQUESTED, (event) => {
62
+ console.log('Committee randomness requested:', event.data)
63
63
  })
64
64
 
65
65
  // Interact with contracts
66
- const hash = await sdk.requestE3({
67
- threshold: [1, 3],
68
- inputWindow: [BigInt(0), BigInt(100)],
66
+ const now = BigInt(Math.floor(Date.now() / 1000))
67
+ const requestParams = {
68
+ committeeSize: CommitteeSize.Minimum,
69
+ inputWindow: [now, now + 300n] as const,
69
70
  e3Program: '0x...',
70
- e3ProgramParams: '0x...',
71
+ paramSet: 0, // Insecure512 for development
71
72
  computeProviderParams: '0x...',
72
73
  customParams: '0x...',
73
- })
74
+ }
75
+ const quote = await sdk.getE3Quote(requestParams)
76
+ const approvalHash = await sdk.approveFeeToken(quote)
77
+ await sdk.waitForTransaction(approvalHash)
78
+ const hash = await sdk.requestE3({ ...requestParams, maxFee: quote })
74
79
  ```
75
80
 
76
81
  ### Factory Method
@@ -90,8 +95,8 @@ const sdk = InterfoldSDK.create({
90
95
  },
91
96
  chain: sepolia,
92
97
  privateKey: '0x...', // optional — omit for read-only
93
- // Use 'SECURE_THRESHOLD_8192' for production; 'INSECURE_THRESHOLD_512' for local dev only
94
- thresholdBfvParamsPresetName: 'SECURE_THRESHOLD_8192',
98
+ // 'INSECURE_THRESHOLD_512' for local dev and Sepolia; 'SECURE_THRESHOLD_8192' for production
99
+ thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_512',
95
100
  })
96
101
  ```
97
102
 
@@ -137,17 +142,15 @@ enum InterfoldEventType {
137
142
  PLAINTEXT_OUTPUT_PUBLISHED = 'PlaintextOutputPublished',
138
143
 
139
144
  // E3 Program Management
140
- E3_PROGRAM_ENABLED = 'E3ProgramEnabled',
141
- E3_PROGRAM_DISABLED = 'E3ProgramDisabled',
145
+ E3_PROGRAM_REGISTERED = 'E3ProgramRegistered',
142
146
 
143
147
  // Encryption Scheme Management
144
148
  ENCRYPTION_SCHEME_ENABLED = 'EncryptionSchemeEnabled',
145
- ENCRYPTION_SCHEME_DISABLED = 'EncryptionSchemeDisabled',
146
149
 
147
150
  // Configuration
148
151
  CIPHERNODE_REGISTRY_SET = 'CiphernodeRegistrySet',
149
152
  MAX_DURATION_SET = 'MaxDurationSet',
150
- ALLOWED_E3_PROGRAMS_PARAMS_SET = 'AllowedE3ProgramsParamsSet',
153
+ PARAM_SET_REGISTERED = 'ParamSetRegistered',
151
154
  OWNERSHIP_TRANSFERRED = 'OwnershipTransferred',
152
155
  INITIALIZED = 'Initialized',
153
156
  }
@@ -157,15 +160,45 @@ enum InterfoldEventType {
157
160
 
158
161
  ```typescript
159
162
  enum RegistryEventType {
163
+ // On-chain legacy event retained only for pre-VRF registry logs. The
164
+ // ciphernode runtime creates its separate durable CommitteeRequested event
165
+ // after the Registry accepts a VRF response.
160
166
  COMMITTEE_REQUESTED = 'CommitteeRequested',
167
+ COMMITTEE_RANDOMNESS_REQUESTED = 'CommitteeRandomnessRequested',
168
+ RANDOMNESS_CIRCUIT_BREAKER_TRIPPED = 'RandomnessCircuitBreakerTripped',
161
169
  COMMITTEE_PUBLISHED = 'CommitteePublished',
162
- COMMITTEE_FINALIZED = 'CommitteeFinalized',
170
+ COMMITTEE_FINALIZED = 'SortitionCommitteeFinalized',
163
171
  INTERFOLD_SET = 'InterfoldSet',
164
172
  OWNERSHIP_TRANSFERRED = 'OwnershipTransferred',
165
173
  INITIALIZED = 'Initialized',
166
174
  }
167
175
  ```
168
176
 
177
+ ### Randomness Provider Events
178
+
179
+ The provider address is frozen for each E3 and can change after governance rotation, so it is not
180
+ part of the static SDK contract addresses. Read `provider`, `requestId`, and `e3Id` from
181
+ `CommitteeRandomnessRequested`, then watch that provider through the main SDK:
182
+
183
+ ```typescript
184
+ await sdk.onRandomnessProviderEvent(
185
+ provider,
186
+ RandomnessProviderEventType.RANDOMNESS_FULFILLED,
187
+ ({ data }) => {
188
+ console.log(data.requestId, data.e3Id, data.fulfilledAt)
189
+ },
190
+ )
191
+ ```
192
+
193
+ Use `sdk.getHistoricalRandomnessProviderEvents` with explicit block bounds to recover earlier
194
+ fulfillments. Start the live watcher at `historicalToBlock + 1n` so the historical and live ranges
195
+ do not overlap. Historical reads are split into bounded RPC queries, and live watchers suppress
196
+ duplicate delivery of the same log. `RandomnessFulfilled` proves that the provider stored a
197
+ response. The Registry remains authoritative about whether that response was timely and usable. If
198
+ the listener config does not define `fromBlock`, the history method requires it as an argument.
199
+ Subscribers that share one provider and event watcher must use the same explicit `fromBlock`, or
200
+ omit it to join the active watcher.
201
+
169
202
  ### Event Data Structure
170
203
 
171
204
  Each event follows a consistent structure:
@@ -209,8 +242,8 @@ function MyComponent() {
209
242
  feeToken: '0x...',
210
243
  },
211
244
  autoConnect: true,
212
- // Use 'SECURE_THRESHOLD_8192' for production; 'INSECURE_THRESHOLD_512' for local dev only
213
- thresholdBfvParamsPresetName: 'SECURE_THRESHOLD_8192',
245
+ // 'INSECURE_THRESHOLD_512' for local dev and Sepolia; 'SECURE_THRESHOLD_8192' for production
246
+ thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_512',
214
247
  })
215
248
 
216
249
  useEffect(() => {
@@ -272,8 +305,8 @@ import {
272
305
  getThresholdBfvParamsSet,
273
306
  } from '@interfold/sdk'
274
307
 
275
- // Use 'SECURE_THRESHOLD_8192' for production; 'INSECURE_THRESHOLD_512' for local dev only
276
- const presetName = 'SECURE_THRESHOLD_8192'
308
+ // 'INSECURE_THRESHOLD_512' for local dev and Sepolia; 'SECURE_THRESHOLD_8192' for production
309
+ const presetName = 'INSECURE_THRESHOLD_512'
277
310
 
278
311
  const publicKey = await generatePublicKey(presetName)
279
312
  const encrypted = await encryptNumber(42n, publicKey, presetName)
@@ -311,13 +344,14 @@ await sdk.approveFeeToken(amount: bigint);
311
344
 
312
345
  // Request a new E3 computation
313
346
  await sdk.requestE3({
314
- threshold: [number, number],
347
+ committeeSize: CommitteeSize.Minimum,
315
348
  inputWindow: [bigint, bigint],
316
349
  e3Program: `0x${string}`,
317
- e3ProgramParams: `0x${string}`,
350
+ paramSet: 0,
318
351
  computeProviderParams: `0x${string}`,
319
- customParams?: `0x${string}`,
320
- gasLimit?: bigint
352
+ customParams: '0x',
353
+ maxFee: amount,
354
+ gasLimit: 1_500_000n
321
355
  });
322
356
 
323
357
  // Publish ciphertext output
@@ -331,9 +365,9 @@ const stage = await sdk.getE3Stage(e3Id: bigint);
331
365
  const reason = await sdk.getFailureReason(e3Id: bigint);
332
366
  ```
333
367
 
334
- The original requester can cancel an E3 while it is in `Requested`, `CommitteeFinalized`,
335
- `KeyPublished`, or `CiphertextReady`. Operators retain the configured value of completed milestones,
336
- and the remaining work allocation becomes claimable through the refund manager.
368
+ The original requester can cancel only while the E3 is `Requested`, after the randomness deadline,
369
+ and only if no timely VRF result is usable. A valid result disables cancellation. The failure path
370
+ returns all service fee escrow and keeps the flat randomness fee charged.
337
371
 
338
372
  ```ts
339
373
  const hash = await sdk.cancelE3(e3Id)
@@ -434,13 +468,35 @@ interface SDKConfig {
434
468
  `thresholdBfvParamsPresetName` selects the BFV parameter set used for encryption. It must match the
435
469
  on-chain `paramSet` index registered in the Interfold contract:
436
470
 
437
- | Preset name | On-chain `paramSet` index | Use case |
438
- | -------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------- |
439
- | `'INSECURE_THRESHOLD_512'` | `0` | Local development and testing only — small polynomial degree (N=512), fast but not cryptographically secure |
440
- | `'SECURE_THRESHOLD_8192'` | `1` | Production — full security parameters (N=8192, L=4 CRT moduli) |
441
-
442
- Always use `'SECURE_THRESHOLD_8192'` in production. The insecure preset exists solely to speed up
443
- local dev cycles.
471
+ | Preset name | On-chain `paramSet` index | Use case |
472
+ | -------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------ |
473
+ | `'INSECURE_THRESHOLD_512'` | `0` | Local development and Sepolia — small polynomial degree (N=512), fast but not cryptographically secure |
474
+ | `'SECURE_THRESHOLD_8192'` | `1` | Production — full security parameters (N=8192, L=3 CRT moduli) |
475
+
476
+ | Network | Preset | `paramSet` |
477
+ | ---------------------- | -------------------------- | ---------- |
478
+ | Local development | `'INSECURE_THRESHOLD_512'` | `0` |
479
+ | Sepolia testnet | `'INSECURE_THRESHOLD_512'` | `0` |
480
+ | Mainnet and production | `'SECURE_THRESHOLD_8192'` | `1` |
481
+
482
+ Use `'INSECURE_THRESHOLD_512'` on Sepolia: the Sepolia ciphernodes run the insecure preset, and the
483
+ circuit artifacts bundled in this package are compiled for it. Use `'SECURE_THRESHOLD_8192'` in
484
+ production, together with your own `secure-8192` circuit artifacts (see
485
+ [Proving](#proving-embedded-circuits-or-your-own)).
486
+
487
+ ### Proving: embedded circuits or your own
488
+
489
+ `generateProof()`, `encryptNumberAndGenProof()`, and `encryptVectorAndGenProof()` run the
490
+ user-data-encryption (UDE) circuits bundled in this package. Those artifacts are compiled with
491
+ `--preset insecure-512 --committee minimum` (`scripts/compile-circuits.sh`), so they only match
492
+ `'INSECURE_THRESHOLD_512'` and a minimum-size committee. With `'SECURE_THRESHOLD_8192'`,
493
+ `encryptNumberAndGenInputs()` returns N=8192 circuit inputs that the bundled N=512 circuits cannot
494
+ execute.
495
+
496
+ For on-chain Honk verification, compile your own UDE, app, and fold circuits for the preset and
497
+ committee your deployment uses, emit the Solidity verifier from them, and feed them the witness from
498
+ `encryptNumberAndGenInputs()`. `examples/CRISP` in the monorepo shows the full flow. Secure
499
+ artifacts may ship here in a later release.
444
500
 
445
501
  ## Error Handling
446
502
 
@@ -22,6 +22,7 @@ var events_exports = {};
22
22
  __export(events_exports, {
23
23
  EventListener: () => EventListener,
24
24
  InterfoldEventType: () => InterfoldEventType,
25
+ RandomnessProviderEventType: () => RandomnessProviderEventType,
25
26
  RegistryEventType: () => RegistryEventType
26
27
  });
27
28
  module.exports = __toCommonJS(events_exports);
@@ -45,6 +46,8 @@ var InterfoldEventType = /* @__PURE__ */ ((InterfoldEventType2) => {
45
46
  })(InterfoldEventType || {});
46
47
  var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
47
48
  RegistryEventType2["COMMITTEE_REQUESTED"] = "CommitteeRequested";
49
+ RegistryEventType2["COMMITTEE_RANDOMNESS_REQUESTED"] = "CommitteeRandomnessRequested";
50
+ RegistryEventType2["RANDOMNESS_CIRCUIT_BREAKER_TRIPPED"] = "RandomnessCircuitBreakerTripped";
48
51
  RegistryEventType2["COMMITTEE_PUBLISHED"] = "CommitteePublished";
49
52
  RegistryEventType2["COMMITTEE_FINALIZED"] = "SortitionCommitteeFinalized";
50
53
  RegistryEventType2["INTERFOLD_SET"] = "InterfoldSet";
@@ -52,6 +55,10 @@ var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
52
55
  RegistryEventType2["INITIALIZED"] = "Initialized";
53
56
  return RegistryEventType2;
54
57
  })(RegistryEventType || {});
58
+ var RandomnessProviderEventType = /* @__PURE__ */ ((RandomnessProviderEventType2) => {
59
+ RandomnessProviderEventType2["RANDOMNESS_FULFILLED"] = "RandomnessFulfilled";
60
+ return RandomnessProviderEventType2;
61
+ })(RandomnessProviderEventType || {});
55
62
 
56
63
  // src/utils.ts
57
64
  var import_viem = require("viem");
@@ -68,8 +75,13 @@ var sleep = (ms) => {
68
75
 
69
76
  // src/events/event-listener.ts
70
77
  var EventListener = class _EventListener {
78
+ static DEFAULT_HISTORICAL_BLOCK_RANGE = 10000n;
79
+ static MAX_REMEMBERED_LOGS = 1e4;
71
80
  listeners = /* @__PURE__ */ new Map();
72
81
  activeWatchers = /* @__PURE__ */ new Map();
82
+ watcherStartBlocks = /* @__PURE__ */ new Map();
83
+ randomnessProviderListeners = /* @__PURE__ */ new Map();
84
+ seenLiveLogs = /* @__PURE__ */ new Map();
73
85
  isPolling = false;
74
86
  lastBlockNumber = BigInt(0);
75
87
  publicClient;
@@ -86,6 +98,8 @@ var EventListener = class _EventListener {
86
98
  // runtime; those default to the Interfold contract.
87
99
  static REGISTRY_ONLY_EVENTS = /* @__PURE__ */ new Set([
88
100
  "CommitteeRequested" /* COMMITTEE_REQUESTED */,
101
+ "CommitteeRandomnessRequested" /* COMMITTEE_RANDOMNESS_REQUESTED */,
102
+ "RandomnessCircuitBreakerTripped" /* RANDOMNESS_CIRCUIT_BREAKER_TRIPPED */,
89
103
  "CommitteePublished" /* COMMITTEE_PUBLISHED */,
90
104
  "SortitionCommitteeFinalized" /* COMMITTEE_FINALIZED */,
91
105
  "InterfoldSet" /* INTERFOLD_SET */
@@ -101,6 +115,93 @@ var EventListener = class _EventListener {
101
115
  const { address, abi } = this.resolveContract(eventType);
102
116
  return this.watchContractEvent(address, eventType, abi, callback);
103
117
  }
118
+ async onRandomnessProviderEvent(provider, eventType, callback, fromBlock) {
119
+ const listenerKey = `${provider.toLowerCase()}:${eventType}`;
120
+ const watcherKey = `randomness-provider:${listenerKey}`;
121
+ const requestedStartBlock = fromBlock ?? this.config.fromBlock;
122
+ let callbacks = this.randomnessProviderListeners.get(listenerKey);
123
+ if (!callbacks) {
124
+ callbacks = /* @__PURE__ */ new Set();
125
+ this.randomnessProviderListeners.set(listenerKey, callbacks);
126
+ }
127
+ if (this.activeWatchers.has(watcherKey)) {
128
+ const activeStartBlock = this.watcherStartBlocks.get(watcherKey);
129
+ if (fromBlock !== void 0 && requestedStartBlock !== activeStartBlock) {
130
+ throw new SDKError(
131
+ `Randomness provider watcher for ${eventType} on ${provider} already starts at ${activeStartBlock ?? "latest"}; requested ${requestedStartBlock ?? "latest"}`,
132
+ "INVALID_EVENT_CONFIG"
133
+ );
134
+ }
135
+ callbacks.add(callback);
136
+ return;
137
+ }
138
+ callbacks.add(callback);
139
+ try {
140
+ const unwatch = this.publicClient.watchContractEvent({
141
+ address: provider,
142
+ abi: import_types.IRandomnessProvider__factory.abi,
143
+ eventName: eventType,
144
+ fromBlock: requestedStartBlock,
145
+ onLogs: (logs) => {
146
+ for (const log of logs) {
147
+ if (!this.rememberLiveLog(log)) continue;
148
+ const event = {
149
+ type: eventType,
150
+ data: log.args,
151
+ provider,
152
+ log,
153
+ timestamp: /* @__PURE__ */ new Date(),
154
+ blockNumber: log.blockNumber ?? 0n,
155
+ transactionHash: log.transactionHash ?? "0x"
156
+ };
157
+ const currentCallbacks = this.randomnessProviderListeners.get(listenerKey);
158
+ currentCallbacks?.forEach((currentCallback) => {
159
+ try {
160
+ const result = currentCallback(event);
161
+ if (result) {
162
+ void result.catch((error) => {
163
+ console.error(`Error in randomness provider callback for ${eventType}:`, error);
164
+ });
165
+ }
166
+ } catch (error) {
167
+ console.error(`Error in randomness provider callback for ${eventType}:`, error);
168
+ }
169
+ });
170
+ }
171
+ }
172
+ });
173
+ this.activeWatchers.set(watcherKey, unwatch);
174
+ this.watcherStartBlocks.set(watcherKey, requestedStartBlock);
175
+ } catch (error) {
176
+ callbacks.delete(callback);
177
+ if (callbacks.size === 0) this.randomnessProviderListeners.delete(listenerKey);
178
+ throw new SDKError(`Failed to watch randomness provider event ${eventType} on ${provider}: ${error}`, "WATCH_EVENT_FAILED");
179
+ }
180
+ }
181
+ offRandomnessProviderEvent(provider, eventType, callback) {
182
+ const listenerKey = `${provider.toLowerCase()}:${eventType}`;
183
+ const callbacks = this.randomnessProviderListeners.get(listenerKey);
184
+ callbacks?.delete(callback);
185
+ if (callbacks && callbacks.size === 0) {
186
+ this.randomnessProviderListeners.delete(listenerKey);
187
+ const watcherKey = `randomness-provider:${listenerKey}`;
188
+ const unwatch = this.activeWatchers.get(watcherKey);
189
+ if (unwatch) unwatch();
190
+ this.activeWatchers.delete(watcherKey);
191
+ this.watcherStartBlocks.delete(watcherKey);
192
+ }
193
+ }
194
+ async getHistoricalRandomnessProviderEvents(provider, eventType, fromBlock, toBlock) {
195
+ const start = fromBlock ?? this.config.fromBlock;
196
+ if (start === void 0) {
197
+ throw new SDKError("Randomness provider history requires fromBlock or EventListenerConfig.fromBlock", "INVALID_EVENT_CONFIG");
198
+ }
199
+ try {
200
+ return await this.getHistoricalContractEvents(provider, import_types.IRandomnessProvider__factory.abi, eventType, start, toBlock);
201
+ } catch (error) {
202
+ throw new SDKError(`Failed to get randomness provider events from ${provider}: ${error}`, "HISTORICAL_EVENTS_FAILED");
203
+ }
204
+ }
104
205
  async once(type, callback) {
105
206
  const handler = (event) => {
106
207
  this.off(type, handler);
@@ -129,6 +230,7 @@ var EventListener = class _EventListener {
129
230
  for (let i = 0; i < logs.length; i++) {
130
231
  const log = logs[i];
131
232
  if (!log) break;
233
+ if (!emitter.rememberLiveLog(log)) continue;
132
234
  const event = {
133
235
  type: eventType,
134
236
  data: log.args,
@@ -182,13 +284,7 @@ var EventListener = class _EventListener {
182
284
  async getHistoricalEvents(eventType, fromBlock, toBlock) {
183
285
  const { address, abi } = this.resolveContract(eventType);
184
286
  try {
185
- return await this.publicClient.getContractEvents({
186
- address,
187
- abi,
188
- eventName: eventType,
189
- fromBlock: fromBlock ?? this.config.fromBlock,
190
- toBlock: toBlock ?? this.config.toBlock
191
- });
287
+ return await this.getHistoricalContractEvents(address, abi, eventType, fromBlock, toBlock);
192
288
  } catch (error) {
193
289
  throw new SDKError(`Failed to get historical events: ${error}`, "HISTORICAL_EVENTS_FAILED");
194
290
  }
@@ -247,7 +343,65 @@ var EventListener = class _EventListener {
247
343
  }
248
344
  });
249
345
  this.activeWatchers.clear();
346
+ this.watcherStartBlocks.clear();
250
347
  this.listeners.clear();
348
+ this.randomnessProviderListeners.clear();
349
+ this.seenLiveLogs.clear();
350
+ }
351
+ logIdentity(log) {
352
+ if (log.blockHash && log.transactionHash && log.logIndex !== null && log.logIndex !== void 0) {
353
+ return `${log.blockHash}:${log.transactionHash}:${log.logIndex}:${Boolean(log.removed)}`;
354
+ }
355
+ return void 0;
356
+ }
357
+ rememberLiveLog(log) {
358
+ const identity = this.logIdentity(log);
359
+ if (!identity) return true;
360
+ if (this.seenLiveLogs.has(identity)) return false;
361
+ this.seenLiveLogs.set(identity, true);
362
+ if (this.seenLiveLogs.size > _EventListener.MAX_REMEMBERED_LOGS) {
363
+ const oldest = this.seenLiveLogs.keys().next().value;
364
+ if (oldest !== void 0) this.seenLiveLogs.delete(oldest);
365
+ }
366
+ return true;
367
+ }
368
+ async getHistoricalContractEvents(address, abi, eventName, fromBlock, toBlock) {
369
+ const start = fromBlock ?? this.config.fromBlock;
370
+ const configuredEnd = toBlock ?? this.config.toBlock;
371
+ if (start === void 0) {
372
+ return await this.publicClient.getContractEvents({
373
+ address,
374
+ abi,
375
+ eventName,
376
+ toBlock: configuredEnd
377
+ });
378
+ }
379
+ const end = configuredEnd ?? await this.publicClient.getBlockNumber({ cacheTime: 0 });
380
+ if (end < start) return [];
381
+ const range = this.config.historicalBlockRange ?? _EventListener.DEFAULT_HISTORICAL_BLOCK_RANGE;
382
+ if (range <= 0n) throw new SDKError("Historical block range must be greater than zero", "INVALID_EVENT_CONFIG");
383
+ const logs = [];
384
+ const seen = /* @__PURE__ */ new Set();
385
+ for (let cursor = start; cursor <= end; cursor += range) {
386
+ const chunkEnd = cursor + range - 1n < end ? cursor + range - 1n : end;
387
+ const chunk = await this.publicClient.getContractEvents({
388
+ address,
389
+ abi,
390
+ eventName,
391
+ fromBlock: cursor,
392
+ toBlock: chunkEnd
393
+ });
394
+ for (const log of chunk) {
395
+ const identity = this.logIdentity(log);
396
+ if (identity && seen.has(identity)) continue;
397
+ if (identity) {
398
+ seen.add(identity);
399
+ this.rememberLiveLog(log);
400
+ }
401
+ logs.push(log);
402
+ }
403
+ }
404
+ return logs;
251
405
  }
252
406
  async pollForEvents() {
253
407
  while (this.isPolling) {
@@ -268,6 +422,7 @@ var EventListener = class _EventListener {
268
422
  0 && (module.exports = {
269
423
  EventListener,
270
424
  InterfoldEventType,
425
+ RandomnessProviderEventType,
271
426
  RegistryEventType
272
427
  });
273
428
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/index.ts","../../src/events/event-listener.ts","../../src/events/types.ts","../../src/utils.ts"],"sourcesContent":["// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nexport { EventListener } from './event-listener'\nexport type { EventListenerOptions } from './event-listener'\n\nexport { InterfoldEventType, RegistryEventType } from './types'\n\nexport type {\n AllEventTypes,\n InterfoldEvent,\n EventCallback,\n EventFilter,\n SDKEventEmitter,\n EventListenerConfig,\n E3RequestedData,\n E3ActivatedData,\n CiphertextOutputPublishedData,\n PlaintextOutputPublishedData,\n CiphernodeAddedData,\n CiphernodeRemovedData,\n CommitteeRequestedData,\n CommitteePublishedData,\n CommitteeFinalizedData,\n InterfoldEventData,\n RegistryEventData,\n} from './types'\n","// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nimport { type Abi, type Log, type PublicClient } from 'viem'\nimport { CiphernodeRegistryOwnable__factory, Interfold__factory } from '@interfold/contracts/types'\n\nimport {\n RegistryEventType,\n type AllEventTypes,\n type InterfoldEvent,\n type InterfoldEventData,\n type InterfoldEventType as InterfoldEventTypeT,\n type EventCallback,\n type EventListenerConfig,\n type RegistryEventData,\n type RegistryEventType as RegistryEventTypeT,\n type SDKEventEmitter,\n} from './types'\nimport type { ContractAddresses } from '../contracts/types'\nimport { SDKError, sleep } from '../utils'\n\nexport interface EventListenerOptions {\n publicClient: PublicClient\n contracts: ContractAddresses\n config?: EventListenerConfig\n}\n\nexport class EventListener implements SDKEventEmitter {\n private listeners: Map<AllEventTypes, Set<EventCallback>> = new Map()\n private activeWatchers: Map<string, () => void> = new Map()\n private isPolling = false\n private lastBlockNumber: bigint = BigInt(0)\n private publicClient: PublicClient\n private contracts: ContractAddresses\n private config: EventListenerConfig\n\n constructor(options: EventListenerOptions) {\n this.publicClient = options.publicClient\n this.contracts = options.contracts\n this.config = options.config || {}\n }\n\n // Registry-exclusive event names that don't collide with InterfoldEventType.\n // Shared names like 'OwnershipTransferred' and 'Initialized' exist in both\n // enums with the same string value, so they cannot be disambiguated at\n // runtime; those default to the Interfold contract.\n private static readonly REGISTRY_ONLY_EVENTS: ReadonlySet<string> = new Set([\n RegistryEventType.COMMITTEE_REQUESTED,\n RegistryEventType.COMMITTEE_PUBLISHED,\n RegistryEventType.COMMITTEE_FINALIZED,\n RegistryEventType.INTERFOLD_SET,\n ])\n\n private resolveContract(eventType: AllEventTypes): { address: `0x${string}`; abi: Abi } {\n const isRegistryEvent = EventListener.REGISTRY_ONLY_EVENTS.has(eventType as string)\n return {\n address: isRegistryEvent ? this.contracts.ciphernodeRegistry : this.contracts.interfold,\n abi: isRegistryEvent ? CiphernodeRegistryOwnable__factory.abi : Interfold__factory.abi,\n }\n }\n\n public async onInterfoldEvent<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): Promise<void> {\n const { address, abi } = this.resolveContract(eventType)\n return this.watchContractEvent(address, eventType, abi, callback)\n }\n\n public async once<T extends AllEventTypes>(type: T, callback: EventCallback<T>): Promise<void> {\n const handler: EventCallback<T> = (event) => {\n this.off(type, handler)\n const prom = callback(event)\n if (prom) {\n prom.catch((e) => console.error(e))\n }\n }\n return this.onInterfoldEvent(type, handler)\n }\n\n public async watchContractEvent<T extends AllEventTypes>(\n address: `0x${string}`,\n eventType: T,\n abi: Abi,\n callback: EventCallback<T>,\n ): Promise<void> {\n const watcherKey = `${address}:${eventType}`\n\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set())\n }\n this.listeners.get(eventType)!.add(callback as EventCallback)\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const emitter = this\n\n if (!this.activeWatchers.has(watcherKey)) {\n try {\n const unwatch = this.publicClient.watchContractEvent({\n address,\n abi,\n eventName: eventType as string,\n fromBlock: this.config.fromBlock,\n onLogs(logs: Log[]) {\n for (let i = 0; i < logs.length; i++) {\n const log = logs[i]\n if (!log) break\n const event: InterfoldEvent<T> = {\n type: eventType,\n data: (log as unknown as { args: unknown }).args as T extends InterfoldEventTypeT\n ? InterfoldEventData[T]\n : T extends RegistryEventTypeT\n ? RegistryEventData[T]\n : unknown,\n log,\n timestamp: new Date(),\n blockNumber: log.blockNumber ?? BigInt(0),\n transactionHash: log.transactionHash ?? '0x',\n }\n emitter.emit(event)\n }\n },\n })\n\n this.activeWatchers.set(watcherKey, unwatch)\n } catch (error) {\n throw new SDKError(`Failed to watch contract event ${eventType} on ${address}: ${error}`, 'WATCH_EVENT_FAILED')\n }\n }\n }\n\n public async watchLogs(address: `0x${string}`, callback: (log: Log) => void): Promise<void> {\n const watcherKey = `logs:${address}`\n\n if (!this.activeWatchers.has(watcherKey)) {\n try {\n const unwatch = this.publicClient.watchEvent({\n address,\n onLogs: (logs: Log[]) => {\n logs.forEach((log: Log) => {\n callback(log)\n })\n },\n })\n\n this.activeWatchers.set(watcherKey, unwatch)\n } catch (error) {\n throw new SDKError(`Failed to watch logs for address ${address}: ${error}`, 'WATCH_LOGS_FAILED')\n }\n }\n }\n\n public async startPolling(): Promise<void> {\n if (this.isPolling) return\n\n this.isPolling = true\n\n try {\n this.lastBlockNumber = await this.publicClient.getBlockNumber()\n void this.pollForEvents()\n } catch (error) {\n this.isPolling = false\n throw new SDKError(`Failed to start polling: ${error}`, 'POLLING_START_FAILED')\n }\n }\n\n public stopPolling(): void {\n this.isPolling = false\n }\n\n public async getHistoricalEvents(eventType: AllEventTypes, fromBlock?: bigint, toBlock?: bigint): Promise<Log[]> {\n const { address, abi } = this.resolveContract(eventType)\n\n try {\n return await this.publicClient.getContractEvents({\n address,\n abi,\n eventName: eventType as string,\n fromBlock: fromBlock ?? this.config.fromBlock,\n toBlock: toBlock ?? this.config.toBlock,\n })\n } catch (error) {\n throw new SDKError(`Failed to get historical events: ${error}`, 'HISTORICAL_EVENTS_FAILED')\n }\n }\n\n public on<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set())\n }\n this.listeners.get(eventType)!.add(callback as EventCallback)\n }\n\n public off<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void {\n const callbacks = this.listeners.get(eventType)\n if (callbacks) {\n callbacks.delete(callback as EventCallback)\n if (callbacks.size === 0) {\n this.listeners.delete(eventType)\n const watchersToRemove: string[] = []\n this.activeWatchers.forEach((unwatch, key) => {\n if (key.endsWith(`:${eventType}`)) {\n try {\n unwatch()\n } catch (error) {\n console.error(`Error unwatching event ${eventType}:`, error)\n }\n watchersToRemove.push(key)\n }\n })\n watchersToRemove.forEach((key) => this.activeWatchers.delete(key))\n }\n }\n }\n\n public emit<T extends AllEventTypes>(event: InterfoldEvent<T>): void {\n const callbacks = this.listeners.get(event.type)\n if (callbacks) {\n callbacks.forEach((callback) => {\n try {\n const result = (callback as EventCallback<T>)(event)\n if (result) {\n void result.catch((error) => {\n console.error(`Error in event callback for ${event.type}:`, error)\n })\n }\n } catch (error) {\n console.error(`Error in event callback for ${event.type}:`, error)\n }\n })\n }\n }\n\n public cleanup(): void {\n this.stopPolling()\n\n this.activeWatchers.forEach((unwatch) => {\n try {\n unwatch()\n } catch (error) {\n console.error('Error unwatching during cleanup:', error)\n }\n })\n this.activeWatchers.clear()\n this.listeners.clear()\n }\n\n private async pollForEvents(): Promise<void> {\n while (this.isPolling) {\n try {\n const currentBlock = await this.publicClient.getBlockNumber()\n\n if (currentBlock > this.lastBlockNumber) {\n this.lastBlockNumber = currentBlock\n }\n\n await sleep(this.config.pollingInterval || 5000)\n } catch (error) {\n console.error('Error during polling:', error)\n await sleep(this.config.pollingInterval || 5000)\n }\n }\n }\n}\n","// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nimport type { Log } from 'viem'\n\nexport enum InterfoldEventType {\n E3_REQUESTED = 'E3Requested',\n CIPHERTEXT_OUTPUT_PUBLISHED = 'CiphertextOutputPublished',\n PLAINTEXT_OUTPUT_PUBLISHED = 'PlaintextOutputPublished',\n E3_PROGRAM_REGISTERED = 'E3ProgramRegistered',\n ENCRYPTION_SCHEME_ENABLED = 'EncryptionSchemeEnabled',\n CIPHERNODE_REGISTRY_SET = 'CiphernodeRegistrySet',\n MAX_DURATION_SET = 'MaxDurationSet',\n PARAM_SET_REGISTERED = 'ParamSetRegistered',\n OWNERSHIP_TRANSFERRED = 'OwnershipTransferred',\n INITIALIZED = 'Initialized',\n}\n\nexport enum RegistryEventType {\n COMMITTEE_REQUESTED = 'CommitteeRequested',\n COMMITTEE_PUBLISHED = 'CommitteePublished',\n COMMITTEE_FINALIZED = 'SortitionCommitteeFinalized',\n INTERFOLD_SET = 'InterfoldSet',\n OWNERSHIP_TRANSFERRED = 'OwnershipTransferred',\n INITIALIZED = 'Initialized',\n}\n\nexport type AllEventTypes = InterfoldEventType | RegistryEventType\n\nexport interface E3RequestedData {\n e3Id: bigint\n e3: {\n seed: bigint\n committeeSize: number\n requestBlock: bigint\n inputWindow: readonly [bigint, bigint]\n encryptionSchemeId: string\n e3Program: string\n paramSet: number\n decryptionVerifier: string\n committeePublicKey: string\n ciphertextOutput: string\n ciphertextCommitment: string\n plaintextOutput: string\n }\n cryptoConfigId: string\n}\n\nexport interface E3ActivatedData {\n e3Id: bigint\n expiration: bigint\n committeePublicKey: string\n}\n\nexport interface CiphertextOutputPublishedData {\n e3Id: bigint\n ciphertextOutput: string\n ciphertextCommitment: string\n}\n\nexport interface PlaintextOutputPublishedData {\n e3Id: bigint\n plaintextOutput: string\n proof: string\n}\n\nexport interface CiphernodeAddedData {\n node: string\n index: bigint\n numNodes: bigint\n size: bigint\n}\n\nexport interface CiphernodeRemovedData {\n node: string\n index: bigint\n numNodes: bigint\n size: bigint\n}\n\nexport interface CommitteeRequestedData {\n e3Id: bigint\n entropyBlock: bigint\n threshold: [bigint, bigint]\n requestBlock: bigint\n committeeDeadline: bigint\n ticketPrice: bigint\n}\n\nexport interface CommitteePublishedData {\n e3Id: bigint\n nodes: string[]\n publicKey: string\n pkCommitment: string\n proof: string\n}\n\nexport interface CommitteeFinalizedData {\n e3Id: bigint\n committee: string[]\n scores: bigint[]\n}\n\nexport interface InterfoldEventData {\n [InterfoldEventType.E3_REQUESTED]: E3RequestedData\n [InterfoldEventType.CIPHERTEXT_OUTPUT_PUBLISHED]: CiphertextOutputPublishedData\n [InterfoldEventType.PLAINTEXT_OUTPUT_PUBLISHED]: PlaintextOutputPublishedData\n [InterfoldEventType.E3_PROGRAM_REGISTERED]: { e3Program: string }\n [InterfoldEventType.ENCRYPTION_SCHEME_ENABLED]: { encryptionSchemeId: string }\n [InterfoldEventType.CIPHERNODE_REGISTRY_SET]: { ciphernodeRegistry: string }\n [InterfoldEventType.MAX_DURATION_SET]: { maxDuration: bigint }\n [InterfoldEventType.PARAM_SET_REGISTERED]: { paramSet: number; encodedParams: string }\n [InterfoldEventType.OWNERSHIP_TRANSFERRED]: { previousOwner: string; newOwner: string }\n [InterfoldEventType.INITIALIZED]: { version: bigint }\n}\n\nexport interface RegistryEventData {\n [RegistryEventType.COMMITTEE_REQUESTED]: CommitteeRequestedData\n [RegistryEventType.COMMITTEE_PUBLISHED]: CommitteePublishedData\n [RegistryEventType.COMMITTEE_FINALIZED]: CommitteeFinalizedData\n [RegistryEventType.INTERFOLD_SET]: { interfold: string }\n [RegistryEventType.OWNERSHIP_TRANSFERRED]: { previousOwner: string; newOwner: string }\n [RegistryEventType.INITIALIZED]: { version: bigint }\n}\n\nexport interface InterfoldEvent<T extends AllEventTypes> {\n type: T\n data: T extends InterfoldEventType ? InterfoldEventData[T] : T extends RegistryEventType ? RegistryEventData[T] : unknown\n log: Log\n timestamp: Date\n blockNumber: bigint\n transactionHash: string\n}\n\nexport type EventCallback<T extends AllEventTypes = AllEventTypes> = (event: InterfoldEvent<T>) => void | Promise<void>\n\nexport interface EventFilter<T = unknown> {\n address?: `0x${string}`\n fromBlock?: bigint\n toBlock?: bigint\n args?: Partial<T>\n}\n\nexport interface SDKEventEmitter {\n on<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void\n off<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void\n emit<T extends AllEventTypes>(event: InterfoldEvent<T>): void\n}\n\nexport interface EventListenerConfig {\n fromBlock?: bigint\n toBlock?: bigint\n polling?: boolean\n pollingInterval?: number\n}\n","// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nimport { type Address, type Hash, type Log, PublicClient, encodeAbiParameters } from 'viem'\nimport type { BfvParams } from './types'\n\nexport class SDKError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n }\n}\n\nexport function isValidAddress(address: string): address is Address {\n return /^0x[a-fA-F0-9]{40}$/.test(address)\n}\n\nexport function isValidHash(hash: string): hash is Hash {\n return /^0x[a-fA-F0-9]{64}$/.test(hash)\n}\n\nexport function formatEventName(contractName: string, eventName: string): string {\n return `${contractName}.${eventName}`\n}\n\nexport function parseEventData<T>(log: Log): T {\n return log.data as unknown as T\n}\n\n/**\n * Sleep for a specified number of milliseconds\n */\nexport const sleep = (ms: number): Promise<void> => {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport function formatBigInt(value: bigint): string {\n return value.toString()\n}\n\nexport function parseBigInt(value: string): bigint {\n return BigInt(value)\n}\n\nexport function generateEventId(log: Log): string {\n return `${log.blockHash}-${log.logIndex}`\n}\n\n/**\n * Get the current timestamp in seconds\n * from onchain\n * @param publicClient - The public client to use\n */\nexport async function getCurrentTimestamp(publicClient: PublicClient): Promise<bigint> {\n const block = await publicClient.getBlock()\n return block.timestamp\n}\n\n// Compute provider parameters structure\nexport interface ComputeProviderParams {\n name: string\n parallel: boolean\n batch_size: number\n}\n\n// Default compute provider configuration\nexport const DEFAULT_COMPUTE_PROVIDER_PARAMS: ComputeProviderParams = {\n name: 'risc0',\n parallel: false,\n batch_size: 2,\n}\n\n// Default E3 configuration (`committeeSize` is `IInterfold.CommitteeSize`, not circuit N_PARTIES).\nexport const DEFAULT_E3_CONFIG = {\n committeeSize: 0, // CommitteeSize.Minimum\n duration: 1800, // 30 minutes in seconds\n payment_amount: '0', // 0 ETH in wei\n} as const\n\n/**\n * Encode BFV parameters for the smart contract\n * BFV (Brakerski-Fan-Vercauteren) is a type of fully homomorphic encryption\n */\nexport function encodeBfvParams(params: BfvParams): `0x${string}` {\n const { degree, plaintextModulus, moduli, error1Variance } = params\n\n if (error1Variance === undefined) {\n throw new SDKError(\n 'error1Variance is required in ProtocolParams. All BFV parameter sets must specify error1_variance.',\n 'MISSING_ERROR1_VARIANCE',\n )\n }\n\n return encodeAbiParameters(\n [\n {\n name: 'bfvParams',\n type: 'tuple',\n components: [\n { name: 'degree', type: 'uint256' },\n { name: 'plaintext_modulus', type: 'uint256' },\n { name: 'moduli', type: 'uint256[]' },\n { name: 'error1_variance', type: 'string' },\n ],\n },\n ],\n [\n {\n degree: BigInt(degree),\n plaintext_modulus: BigInt(plaintextModulus),\n moduli: [...moduli],\n error1_variance: error1Variance,\n },\n ],\n )\n}\n\n/**\n * Encode compute provider parameters for the smart contract'\n * If mock is true, the compute provider parameters will return 32 bytes of 0x00\n */\nexport function encodeComputeProviderParams(params: ComputeProviderParams, mock: boolean = false): `0x${string}` {\n if (mock) {\n return `0x${'00'.repeat(32)}` as `0x${string}`\n }\n\n const jsonString = JSON.stringify(params)\n const encoder = new TextEncoder()\n const bytes = encoder.encode(jsonString)\n\n return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')}`\n}\n\n/**\n * Encode custom parameters for the smart contract.\n */\nexport function encodeCustomParams(params: Record<string, unknown>): `0x${string}` {\n const jsonString = JSON.stringify(params)\n const encoder = new TextEncoder()\n const bytes = encoder.encode(jsonString)\n\n return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')}`\n}\n\n// inputWindow[0] is always larger than now and dkg deadline\nexport const inputWindowStartBuffer = 15n\n\n/**\n * Calculate start window for E3 request\n * @dev This function can be used for testing purposes, or for E3s which need to start as soon as possible.\n * @param publicClient - The public client to use\n * @param duration - The duration of the input window in seconds\n * @param startBuffer - Buffer in seconds added to current timestamp for input window start\n */\nexport async function calculateInputWindow(\n publicClient: PublicClient,\n duration: number = DEFAULT_E3_CONFIG.duration,\n startBuffer: bigint = inputWindowStartBuffer,\n): Promise<[bigint, bigint]> {\n const now = await getCurrentTimestamp(publicClient)\n return [BigInt(now) + startBuffer, BigInt(now) + startBuffer + BigInt(duration)]\n}\n\n/**\n * Decode plaintextOutput bytes to get the actual result number\n */\nexport function decodePlaintextOutput(plaintextOutput: string): number | null {\n try {\n // Remove '0x' prefix if present\n const hex = plaintextOutput.startsWith('0x') ? plaintextOutput.slice(2) : plaintextOutput\n\n // Convert hex to bytes\n const bytes = new Uint8Array(hex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [])\n\n if (bytes.length < 8) {\n console.warn('Plaintext output too short for u64 decoding')\n return null\n }\n\n // Decode first u64 (8 bytes) as little-endian\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n const result = view.getBigUint64(0, true) // true for little-endian\n\n return Number(result)\n } catch (error) {\n console.error('Failed to decode plaintext output:', error)\n return null\n }\n}\n\n// Helper function to convert proof bytes to field elements\nexport function proofToFields(proof: Uint8Array): string[] {\n const fields: string[] = []\n for (let i = 0; i < proof.length; i += 32) {\n const chunk = proof.slice(i, i + 32)\n fields.push('0x' + Buffer.from(chunk).toString('hex'))\n }\n return fields\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOA,mBAAuE;;;ACChE,IAAK,qBAAL,kBAAKA,wBAAL;AACL,EAAAA,oBAAA,kBAAe;AACf,EAAAA,oBAAA,iCAA8B;AAC9B,EAAAA,oBAAA,gCAA6B;AAC7B,EAAAA,oBAAA,2BAAwB;AACxB,EAAAA,oBAAA,+BAA4B;AAC5B,EAAAA,oBAAA,6BAA0B;AAC1B,EAAAA,oBAAA,sBAAmB;AACnB,EAAAA,oBAAA,0BAAuB;AACvB,EAAAA,oBAAA,2BAAwB;AACxB,EAAAA,oBAAA,iBAAc;AAVJ,SAAAA;AAAA,GAAA;AAaL,IAAK,oBAAL,kBAAKC,uBAAL;AACL,EAAAA,mBAAA,yBAAsB;AACtB,EAAAA,mBAAA,yBAAsB;AACtB,EAAAA,mBAAA,yBAAsB;AACtB,EAAAA,mBAAA,mBAAgB;AAChB,EAAAA,mBAAA,2BAAwB;AACxB,EAAAA,mBAAA,iBAAc;AANJ,SAAAA;AAAA,GAAA;;;ACfZ,kBAAqF;AAG9E,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YACE,SACgB,MAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAqBO,IAAM,QAAQ,CAAC,OAA8B;AAClD,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;;;AFVO,IAAM,gBAAN,MAAM,eAAyC;AAAA,EAC5C,YAAoD,oBAAI,IAAI;AAAA,EAC5D,iBAA0C,oBAAI,IAAI;AAAA,EAClD,YAAY;AAAA,EACZ,kBAA0B,OAAO,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAA+B;AACzC,SAAK,eAAe,QAAQ;AAC5B,SAAK,YAAY,QAAQ;AACzB,SAAK,SAAS,QAAQ,UAAU,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAwB,uBAA4C,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAK5E,CAAC;AAAA,EAEO,gBAAgB,WAAgE;AACtF,UAAM,kBAAkB,eAAc,qBAAqB,IAAI,SAAmB;AAClF,WAAO;AAAA,MACL,SAAS,kBAAkB,KAAK,UAAU,qBAAqB,KAAK,UAAU;AAAA,MAC9E,KAAK,kBAAkB,gDAAmC,MAAM,gCAAmB;AAAA,IACrF;AAAA,EACF;AAAA,EAEA,MAAa,iBAA0C,WAAc,UAA2C;AAC9G,UAAM,EAAE,SAAS,IAAI,IAAI,KAAK,gBAAgB,SAAS;AACvD,WAAO,KAAK,mBAAmB,SAAS,WAAW,KAAK,QAAQ;AAAA,EAClE;AAAA,EAEA,MAAa,KAA8B,MAAS,UAA2C;AAC7F,UAAM,UAA4B,CAAC,UAAU;AAC3C,WAAK,IAAI,MAAM,OAAO;AACtB,YAAM,OAAO,SAAS,KAAK;AAC3B,UAAI,MAAM;AACR,aAAK,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,CAAC;AAAA,MACpC;AAAA,IACF;AACA,WAAO,KAAK,iBAAiB,MAAM,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAa,mBACX,SACA,WACA,KACA,UACe;AACf,UAAM,aAAa,GAAG,OAAO,IAAI,SAAS;AAE1C,QAAI,CAAC,KAAK,UAAU,IAAI,SAAS,GAAG;AAClC,WAAK,UAAU,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,IACzC;AACA,SAAK,UAAU,IAAI,SAAS,EAAG,IAAI,QAAyB;AAG5D,UAAM,UAAU;AAEhB,QAAI,CAAC,KAAK,eAAe,IAAI,UAAU,GAAG;AACxC,UAAI;AACF,cAAM,UAAU,KAAK,aAAa,mBAAmB;AAAA,UACnD;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX,WAAW,KAAK,OAAO;AAAA,UACvB,OAAO,MAAa;AAClB,qBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,oBAAM,MAAM,KAAK,CAAC;AAClB,kBAAI,CAAC,IAAK;AACV,oBAAM,QAA2B;AAAA,gBAC/B,MAAM;AAAA,gBACN,MAAO,IAAqC;AAAA,gBAK5C;AAAA,gBACA,WAAW,oBAAI,KAAK;AAAA,gBACpB,aAAa,IAAI,eAAe,OAAO,CAAC;AAAA,gBACxC,iBAAiB,IAAI,mBAAmB;AAAA,cAC1C;AACA,sBAAQ,KAAK,KAAK;AAAA,YACpB;AAAA,UACF;AAAA,QACF,CAAC;AAED,aAAK,eAAe,IAAI,YAAY,OAAO;AAAA,MAC7C,SAAS,OAAO;AACd,cAAM,IAAI,SAAS,kCAAkC,SAAS,OAAO,OAAO,KAAK,KAAK,IAAI,oBAAoB;AAAA,MAChH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,UAAU,SAAwB,UAA6C;AAC1F,UAAM,aAAa,QAAQ,OAAO;AAElC,QAAI,CAAC,KAAK,eAAe,IAAI,UAAU,GAAG;AACxC,UAAI;AACF,cAAM,UAAU,KAAK,aAAa,WAAW;AAAA,UAC3C;AAAA,UACA,QAAQ,CAAC,SAAgB;AACvB,iBAAK,QAAQ,CAAC,QAAa;AACzB,uBAAS,GAAG;AAAA,YACd,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAED,aAAK,eAAe,IAAI,YAAY,OAAO;AAAA,MAC7C,SAAS,OAAO;AACd,cAAM,IAAI,SAAS,oCAAoC,OAAO,KAAK,KAAK,IAAI,mBAAmB;AAAA,MACjG;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,eAA8B;AACzC,QAAI,KAAK,UAAW;AAEpB,SAAK,YAAY;AAEjB,QAAI;AACF,WAAK,kBAAkB,MAAM,KAAK,aAAa,eAAe;AAC9D,WAAK,KAAK,cAAc;AAAA,IAC1B,SAAS,OAAO;AACd,WAAK,YAAY;AACjB,YAAM,IAAI,SAAS,4BAA4B,KAAK,IAAI,sBAAsB;AAAA,IAChF;AAAA,EACF;AAAA,EAEO,cAAoB;AACzB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAa,oBAAoB,WAA0B,WAAoB,SAAkC;AAC/G,UAAM,EAAE,SAAS,IAAI,IAAI,KAAK,gBAAgB,SAAS;AAEvD,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,kBAAkB;AAAA,QAC/C;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,WAAW,aAAa,KAAK,OAAO;AAAA,QACpC,SAAS,WAAW,KAAK,OAAO;AAAA,MAClC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,SAAS,oCAAoC,KAAK,IAAI,0BAA0B;AAAA,IAC5F;AAAA,EACF;AAAA,EAEO,GAA4B,WAAc,UAAkC;AACjF,QAAI,CAAC,KAAK,UAAU,IAAI,SAAS,GAAG;AAClC,WAAK,UAAU,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,IACzC;AACA,SAAK,UAAU,IAAI,SAAS,EAAG,IAAI,QAAyB;AAAA,EAC9D;AAAA,EAEO,IAA6B,WAAc,UAAkC;AAClF,UAAM,YAAY,KAAK,UAAU,IAAI,SAAS;AAC9C,QAAI,WAAW;AACb,gBAAU,OAAO,QAAyB;AAC1C,UAAI,UAAU,SAAS,GAAG;AACxB,aAAK,UAAU,OAAO,SAAS;AAC/B,cAAM,mBAA6B,CAAC;AACpC,aAAK,eAAe,QAAQ,CAAC,SAAS,QAAQ;AAC5C,cAAI,IAAI,SAAS,IAAI,SAAS,EAAE,GAAG;AACjC,gBAAI;AACF,sBAAQ;AAAA,YACV,SAAS,OAAO;AACd,sBAAQ,MAAM,0BAA0B,SAAS,KAAK,KAAK;AAAA,YAC7D;AACA,6BAAiB,KAAK,GAAG;AAAA,UAC3B;AAAA,QACF,CAAC;AACD,yBAAiB,QAAQ,CAAC,QAAQ,KAAK,eAAe,OAAO,GAAG,CAAC;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KAA8B,OAAgC;AACnE,UAAM,YAAY,KAAK,UAAU,IAAI,MAAM,IAAI;AAC/C,QAAI,WAAW;AACb,gBAAU,QAAQ,CAAC,aAAa;AAC9B,YAAI;AACF,gBAAM,SAAU,SAA8B,KAAK;AACnD,cAAI,QAAQ;AACV,iBAAK,OAAO,MAAM,CAAC,UAAU;AAC3B,sBAAQ,MAAM,+BAA+B,MAAM,IAAI,KAAK,KAAK;AAAA,YACnE,CAAC;AAAA,UACH;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,MAAM,+BAA+B,MAAM,IAAI,KAAK,KAAK;AAAA,QACnE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEO,UAAgB;AACrB,SAAK,YAAY;AAEjB,SAAK,eAAe,QAAQ,CAAC,YAAY;AACvC,UAAI;AACF,gBAAQ;AAAA,MACV,SAAS,OAAO;AACd,gBAAQ,MAAM,oCAAoC,KAAK;AAAA,MACzD;AAAA,IACF,CAAC;AACD,SAAK,eAAe,MAAM;AAC1B,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,MAAc,gBAA+B;AAC3C,WAAO,KAAK,WAAW;AACrB,UAAI;AACF,cAAM,eAAe,MAAM,KAAK,aAAa,eAAe;AAE5D,YAAI,eAAe,KAAK,iBAAiB;AACvC,eAAK,kBAAkB;AAAA,QACzB;AAEA,cAAM,MAAM,KAAK,OAAO,mBAAmB,GAAI;AAAA,MACjD,SAAS,OAAO;AACd,gBAAQ,MAAM,yBAAyB,KAAK;AAC5C,cAAM,MAAM,KAAK,OAAO,mBAAmB,GAAI;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACF;","names":["InterfoldEventType","RegistryEventType"]}
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/events/event-listener.ts","../../src/events/types.ts","../../src/utils.ts"],"sourcesContent":["// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nexport { EventListener } from './event-listener'\nexport type { EventListenerOptions } from './event-listener'\n\nexport { InterfoldEventType, RandomnessProviderEventType, RegistryEventType } from './types'\n\nexport type {\n AllEventTypes,\n InterfoldEvent,\n EventCallback,\n EventFilter,\n SDKEventEmitter,\n EventListenerConfig,\n E3RequestedData,\n E3ActivatedData,\n CiphertextOutputPublishedData,\n PlaintextOutputPublishedData,\n CiphernodeAddedData,\n CiphernodeRemovedData,\n CommitteeRequestedData,\n CommitteeRandomnessRequestedData,\n RandomnessCircuitBreakerTrippedData,\n RandomnessFulfilledData,\n RandomnessProviderEvent,\n RandomnessProviderEventCallback,\n CommitteePublishedData,\n CommitteeFinalizedData,\n InterfoldEventData,\n RegistryEventData,\n} from './types'\n","// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nimport { type Abi, type Log, type PublicClient } from 'viem'\nimport { CiphernodeRegistryOwnable__factory, Interfold__factory, IRandomnessProvider__factory } from '@interfold/contracts/types'\n\nimport {\n RegistryEventType,\n type RandomnessProviderEvent,\n type RandomnessProviderEventCallback,\n type RandomnessProviderEventType,\n type AllEventTypes,\n type InterfoldEvent,\n type InterfoldEventData,\n type InterfoldEventType as InterfoldEventTypeT,\n type EventCallback,\n type EventListenerConfig,\n type RegistryEventData,\n type RegistryEventType as RegistryEventTypeT,\n type SDKEventEmitter,\n} from './types'\nimport type { ContractAddresses } from '../contracts/types'\nimport { SDKError, sleep } from '../utils'\n\nexport interface EventListenerOptions {\n publicClient: PublicClient\n contracts: ContractAddresses\n config?: EventListenerConfig\n}\n\nexport class EventListener implements SDKEventEmitter {\n private static readonly DEFAULT_HISTORICAL_BLOCK_RANGE = 10_000n\n private static readonly MAX_REMEMBERED_LOGS = 10_000\n private listeners: Map<AllEventTypes, Set<EventCallback>> = new Map()\n private activeWatchers: Map<string, () => void> = new Map()\n private watcherStartBlocks: Map<string, bigint | undefined> = new Map()\n private randomnessProviderListeners: Map<string, Set<RandomnessProviderEventCallback>> = new Map()\n private seenLiveLogs: Map<string, true> = new Map()\n private isPolling = false\n private lastBlockNumber: bigint = BigInt(0)\n private publicClient: PublicClient\n private contracts: ContractAddresses\n private config: EventListenerConfig\n\n constructor(options: EventListenerOptions) {\n this.publicClient = options.publicClient\n this.contracts = options.contracts\n this.config = options.config || {}\n }\n\n // Registry-exclusive event names that don't collide with InterfoldEventType.\n // Shared names like 'OwnershipTransferred' and 'Initialized' exist in both\n // enums with the same string value, so they cannot be disambiguated at\n // runtime; those default to the Interfold contract.\n private static readonly REGISTRY_ONLY_EVENTS: ReadonlySet<string> = new Set([\n RegistryEventType.COMMITTEE_REQUESTED,\n RegistryEventType.COMMITTEE_RANDOMNESS_REQUESTED,\n RegistryEventType.RANDOMNESS_CIRCUIT_BREAKER_TRIPPED,\n RegistryEventType.COMMITTEE_PUBLISHED,\n RegistryEventType.COMMITTEE_FINALIZED,\n RegistryEventType.INTERFOLD_SET,\n ])\n\n private resolveContract(eventType: AllEventTypes): { address: `0x${string}`; abi: Abi } {\n const isRegistryEvent = EventListener.REGISTRY_ONLY_EVENTS.has(eventType as string)\n return {\n address: isRegistryEvent ? this.contracts.ciphernodeRegistry : this.contracts.interfold,\n abi: isRegistryEvent ? CiphernodeRegistryOwnable__factory.abi : Interfold__factory.abi,\n }\n }\n\n public async onInterfoldEvent<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): Promise<void> {\n const { address, abi } = this.resolveContract(eventType)\n return this.watchContractEvent(address, eventType, abi, callback)\n }\n\n public async onRandomnessProviderEvent<T extends RandomnessProviderEventType>(\n provider: `0x${string}`,\n eventType: T,\n callback: RandomnessProviderEventCallback<T>,\n fromBlock?: bigint,\n ): Promise<void> {\n const listenerKey = `${provider.toLowerCase()}:${eventType}`\n const watcherKey = `randomness-provider:${listenerKey}`\n const requestedStartBlock = fromBlock ?? this.config.fromBlock\n let callbacks = this.randomnessProviderListeners.get(listenerKey)\n if (!callbacks) {\n callbacks = new Set()\n this.randomnessProviderListeners.set(listenerKey, callbacks)\n }\n\n if (this.activeWatchers.has(watcherKey)) {\n const activeStartBlock = this.watcherStartBlocks.get(watcherKey)\n if (fromBlock !== undefined && requestedStartBlock !== activeStartBlock) {\n throw new SDKError(\n `Randomness provider watcher for ${eventType} on ${provider} already starts at ${activeStartBlock ?? 'latest'}; requested ${requestedStartBlock ?? 'latest'}`,\n 'INVALID_EVENT_CONFIG',\n )\n }\n callbacks.add(callback as RandomnessProviderEventCallback)\n return\n }\n\n callbacks.add(callback as RandomnessProviderEventCallback)\n\n try {\n const unwatch = this.publicClient.watchContractEvent({\n address: provider,\n abi: IRandomnessProvider__factory.abi,\n eventName: eventType,\n fromBlock: requestedStartBlock,\n onLogs: (logs: Log[]) => {\n for (const log of logs) {\n if (!this.rememberLiveLog(log)) continue\n const event: RandomnessProviderEvent<T> = {\n type: eventType,\n data: (log as unknown as { args: RandomnessProviderEvent<T>['data'] }).args,\n provider,\n log,\n timestamp: new Date(),\n blockNumber: log.blockNumber ?? 0n,\n transactionHash: log.transactionHash ?? '0x',\n }\n const currentCallbacks = this.randomnessProviderListeners.get(listenerKey)\n currentCallbacks?.forEach((currentCallback) => {\n try {\n const result = currentCallback(event)\n if (result) {\n void result.catch((error) => {\n console.error(`Error in randomness provider callback for ${eventType}:`, error)\n })\n }\n } catch (error) {\n console.error(`Error in randomness provider callback for ${eventType}:`, error)\n }\n })\n }\n },\n })\n this.activeWatchers.set(watcherKey, unwatch)\n this.watcherStartBlocks.set(watcherKey, requestedStartBlock)\n } catch (error) {\n callbacks.delete(callback as RandomnessProviderEventCallback)\n if (callbacks.size === 0) this.randomnessProviderListeners.delete(listenerKey)\n throw new SDKError(`Failed to watch randomness provider event ${eventType} on ${provider}: ${error}`, 'WATCH_EVENT_FAILED')\n }\n }\n\n public offRandomnessProviderEvent<T extends RandomnessProviderEventType>(\n provider: `0x${string}`,\n eventType: T,\n callback: RandomnessProviderEventCallback<T>,\n ): void {\n const listenerKey = `${provider.toLowerCase()}:${eventType}`\n const callbacks = this.randomnessProviderListeners.get(listenerKey)\n callbacks?.delete(callback as RandomnessProviderEventCallback)\n if (callbacks && callbacks.size === 0) {\n this.randomnessProviderListeners.delete(listenerKey)\n const watcherKey = `randomness-provider:${listenerKey}`\n const unwatch = this.activeWatchers.get(watcherKey)\n if (unwatch) unwatch()\n this.activeWatchers.delete(watcherKey)\n this.watcherStartBlocks.delete(watcherKey)\n }\n }\n\n public async getHistoricalRandomnessProviderEvents(\n provider: `0x${string}`,\n eventType: RandomnessProviderEventType,\n fromBlock?: bigint,\n toBlock?: bigint,\n ): Promise<Log[]> {\n const start = fromBlock ?? this.config.fromBlock\n if (start === undefined) {\n throw new SDKError('Randomness provider history requires fromBlock or EventListenerConfig.fromBlock', 'INVALID_EVENT_CONFIG')\n }\n try {\n return await this.getHistoricalContractEvents(provider, IRandomnessProvider__factory.abi, eventType, start, toBlock)\n } catch (error) {\n throw new SDKError(`Failed to get randomness provider events from ${provider}: ${error}`, 'HISTORICAL_EVENTS_FAILED')\n }\n }\n\n public async once<T extends AllEventTypes>(type: T, callback: EventCallback<T>): Promise<void> {\n const handler: EventCallback<T> = (event) => {\n this.off(type, handler)\n const prom = callback(event)\n if (prom) {\n prom.catch((e) => console.error(e))\n }\n }\n return this.onInterfoldEvent(type, handler)\n }\n\n public async watchContractEvent<T extends AllEventTypes>(\n address: `0x${string}`,\n eventType: T,\n abi: Abi,\n callback: EventCallback<T>,\n ): Promise<void> {\n const watcherKey = `${address}:${eventType}`\n\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set())\n }\n this.listeners.get(eventType)!.add(callback as EventCallback)\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const emitter = this\n\n if (!this.activeWatchers.has(watcherKey)) {\n try {\n const unwatch = this.publicClient.watchContractEvent({\n address,\n abi,\n eventName: eventType as string,\n fromBlock: this.config.fromBlock,\n onLogs(logs: Log[]) {\n for (let i = 0; i < logs.length; i++) {\n const log = logs[i]\n if (!log) break\n if (!emitter.rememberLiveLog(log)) continue\n const event: InterfoldEvent<T> = {\n type: eventType,\n data: (log as unknown as { args: unknown }).args as T extends InterfoldEventTypeT\n ? InterfoldEventData[T]\n : T extends RegistryEventTypeT\n ? RegistryEventData[T]\n : unknown,\n log,\n timestamp: new Date(),\n blockNumber: log.blockNumber ?? BigInt(0),\n transactionHash: log.transactionHash ?? '0x',\n }\n emitter.emit(event)\n }\n },\n })\n\n this.activeWatchers.set(watcherKey, unwatch)\n } catch (error) {\n throw new SDKError(`Failed to watch contract event ${eventType} on ${address}: ${error}`, 'WATCH_EVENT_FAILED')\n }\n }\n }\n\n public async watchLogs(address: `0x${string}`, callback: (log: Log) => void): Promise<void> {\n const watcherKey = `logs:${address}`\n\n if (!this.activeWatchers.has(watcherKey)) {\n try {\n const unwatch = this.publicClient.watchEvent({\n address,\n onLogs: (logs: Log[]) => {\n logs.forEach((log: Log) => {\n callback(log)\n })\n },\n })\n\n this.activeWatchers.set(watcherKey, unwatch)\n } catch (error) {\n throw new SDKError(`Failed to watch logs for address ${address}: ${error}`, 'WATCH_LOGS_FAILED')\n }\n }\n }\n\n public async startPolling(): Promise<void> {\n if (this.isPolling) return\n\n this.isPolling = true\n\n try {\n this.lastBlockNumber = await this.publicClient.getBlockNumber()\n void this.pollForEvents()\n } catch (error) {\n this.isPolling = false\n throw new SDKError(`Failed to start polling: ${error}`, 'POLLING_START_FAILED')\n }\n }\n\n public stopPolling(): void {\n this.isPolling = false\n }\n\n public async getHistoricalEvents(eventType: AllEventTypes, fromBlock?: bigint, toBlock?: bigint): Promise<Log[]> {\n const { address, abi } = this.resolveContract(eventType)\n\n try {\n return await this.getHistoricalContractEvents(address, abi, eventType as string, fromBlock, toBlock)\n } catch (error) {\n throw new SDKError(`Failed to get historical events: ${error}`, 'HISTORICAL_EVENTS_FAILED')\n }\n }\n\n public on<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set())\n }\n this.listeners.get(eventType)!.add(callback as EventCallback)\n }\n\n public off<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void {\n const callbacks = this.listeners.get(eventType)\n if (callbacks) {\n callbacks.delete(callback as EventCallback)\n if (callbacks.size === 0) {\n this.listeners.delete(eventType)\n const watchersToRemove: string[] = []\n this.activeWatchers.forEach((unwatch, key) => {\n if (key.endsWith(`:${eventType}`)) {\n try {\n unwatch()\n } catch (error) {\n console.error(`Error unwatching event ${eventType}:`, error)\n }\n watchersToRemove.push(key)\n }\n })\n watchersToRemove.forEach((key) => this.activeWatchers.delete(key))\n }\n }\n }\n\n public emit<T extends AllEventTypes>(event: InterfoldEvent<T>): void {\n const callbacks = this.listeners.get(event.type)\n if (callbacks) {\n callbacks.forEach((callback) => {\n try {\n const result = (callback as EventCallback<T>)(event)\n if (result) {\n void result.catch((error) => {\n console.error(`Error in event callback for ${event.type}:`, error)\n })\n }\n } catch (error) {\n console.error(`Error in event callback for ${event.type}:`, error)\n }\n })\n }\n }\n\n public cleanup(): void {\n this.stopPolling()\n\n this.activeWatchers.forEach((unwatch) => {\n try {\n unwatch()\n } catch (error) {\n console.error('Error unwatching during cleanup:', error)\n }\n })\n this.activeWatchers.clear()\n this.watcherStartBlocks.clear()\n this.listeners.clear()\n this.randomnessProviderListeners.clear()\n this.seenLiveLogs.clear()\n }\n\n private logIdentity(log: Log): string | undefined {\n if (log.blockHash && log.transactionHash && log.logIndex !== null && log.logIndex !== undefined) {\n return `${log.blockHash}:${log.transactionHash}:${log.logIndex}:${Boolean(log.removed)}`\n }\n return undefined\n }\n\n private rememberLiveLog(log: Log): boolean {\n const identity = this.logIdentity(log)\n if (!identity) return true\n if (this.seenLiveLogs.has(identity)) return false\n\n this.seenLiveLogs.set(identity, true)\n if (this.seenLiveLogs.size > EventListener.MAX_REMEMBERED_LOGS) {\n const oldest = this.seenLiveLogs.keys().next().value\n if (oldest !== undefined) this.seenLiveLogs.delete(oldest)\n }\n return true\n }\n\n private async getHistoricalContractEvents(\n address: `0x${string}`,\n abi: Abi,\n eventName: string,\n fromBlock?: bigint,\n toBlock?: bigint,\n ): Promise<Log[]> {\n const start = fromBlock ?? this.config.fromBlock\n const configuredEnd = toBlock ?? this.config.toBlock\n if (start === undefined) {\n return (await this.publicClient.getContractEvents({\n address,\n abi,\n eventName,\n toBlock: configuredEnd,\n })) as Log[]\n }\n\n const end = configuredEnd ?? (await this.publicClient.getBlockNumber({ cacheTime: 0 }))\n if (end < start) return []\n\n const range = this.config.historicalBlockRange ?? EventListener.DEFAULT_HISTORICAL_BLOCK_RANGE\n if (range <= 0n) throw new SDKError('Historical block range must be greater than zero', 'INVALID_EVENT_CONFIG')\n\n const logs: Log[] = []\n const seen = new Set<string>()\n for (let cursor = start; cursor <= end; cursor += range) {\n const chunkEnd = cursor + range - 1n < end ? cursor + range - 1n : end\n const chunk = (await this.publicClient.getContractEvents({\n address,\n abi,\n eventName,\n fromBlock: cursor,\n toBlock: chunkEnd,\n })) as Log[]\n for (const log of chunk) {\n const identity = this.logIdentity(log)\n if (identity && seen.has(identity)) continue\n if (identity) {\n seen.add(identity)\n this.rememberLiveLog(log)\n }\n logs.push(log)\n }\n }\n return logs\n }\n\n private async pollForEvents(): Promise<void> {\n while (this.isPolling) {\n try {\n const currentBlock = await this.publicClient.getBlockNumber()\n\n if (currentBlock > this.lastBlockNumber) {\n this.lastBlockNumber = currentBlock\n }\n\n await sleep(this.config.pollingInterval || 5000)\n } catch (error) {\n console.error('Error during polling:', error)\n await sleep(this.config.pollingInterval || 5000)\n }\n }\n }\n}\n","// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nimport type { Log } from 'viem'\n\nexport enum InterfoldEventType {\n E3_REQUESTED = 'E3Requested',\n CIPHERTEXT_OUTPUT_PUBLISHED = 'CiphertextOutputPublished',\n PLAINTEXT_OUTPUT_PUBLISHED = 'PlaintextOutputPublished',\n E3_PROGRAM_REGISTERED = 'E3ProgramRegistered',\n ENCRYPTION_SCHEME_ENABLED = 'EncryptionSchemeEnabled',\n CIPHERNODE_REGISTRY_SET = 'CiphernodeRegistrySet',\n MAX_DURATION_SET = 'MaxDurationSet',\n PARAM_SET_REGISTERED = 'ParamSetRegistered',\n OWNERSHIP_TRANSFERRED = 'OwnershipTransferred',\n INITIALIZED = 'Initialized',\n}\n\nexport enum RegistryEventType {\n COMMITTEE_REQUESTED = 'CommitteeRequested',\n COMMITTEE_RANDOMNESS_REQUESTED = 'CommitteeRandomnessRequested',\n RANDOMNESS_CIRCUIT_BREAKER_TRIPPED = 'RandomnessCircuitBreakerTripped',\n COMMITTEE_PUBLISHED = 'CommitteePublished',\n COMMITTEE_FINALIZED = 'SortitionCommitteeFinalized',\n INTERFOLD_SET = 'InterfoldSet',\n OWNERSHIP_TRANSFERRED = 'OwnershipTransferred',\n INITIALIZED = 'Initialized',\n}\n\nexport enum RandomnessProviderEventType {\n RANDOMNESS_FULFILLED = 'RandomnessFulfilled',\n}\n\nexport type AllEventTypes = InterfoldEventType | RegistryEventType\n\nexport interface E3RequestedData {\n e3Id: bigint\n e3: {\n seed: bigint\n committeeSize: number\n requestBlock: bigint\n inputWindow: readonly [bigint, bigint]\n encryptionSchemeId: string\n e3Program: string\n paramSet: number\n decryptionVerifier: string\n committeePublicKey: string\n ciphertextOutput: string\n ciphertextCommitment: string\n plaintextOutput: string\n }\n cryptoConfigId: string\n}\n\nexport interface E3ActivatedData {\n e3Id: bigint\n expiration: bigint\n committeePublicKey: string\n}\n\nexport interface CiphertextOutputPublishedData {\n e3Id: bigint\n ciphertextOutput: string\n ciphertextCommitment: string\n}\n\nexport interface PlaintextOutputPublishedData {\n e3Id: bigint\n plaintextOutput: string\n proof: string\n}\n\nexport interface CiphernodeAddedData {\n node: string\n index: bigint\n numNodes: bigint\n size: bigint\n}\n\nexport interface CiphernodeRemovedData {\n node: string\n index: bigint\n numNodes: bigint\n size: bigint\n}\n\nexport interface CommitteeRequestedData {\n e3Id: bigint\n entropyBlock: bigint\n threshold: [bigint, bigint]\n requestBlock: bigint\n committeeDeadline: bigint\n ticketPrice: bigint\n}\n\nexport interface CommitteeRandomnessRequestedData {\n e3Id: bigint\n requestId: bigint\n provider: string\n randomnessDeadline: bigint\n}\n\nexport interface RandomnessCircuitBreakerTrippedData {\n e3Id: bigint\n requestId: bigint\n randomnessProvider: string\n}\n\nexport interface RandomnessFulfilledData {\n requestId: bigint\n e3Id: bigint\n randomWord: bigint\n fulfilledAt: bigint\n}\n\nexport interface CommitteePublishedData {\n e3Id: bigint\n nodes: string[]\n publicKey: string\n pkCommitment: string\n proof: string\n}\n\nexport interface CommitteeFinalizedData {\n e3Id: bigint\n committee: string[]\n scores: bigint[]\n}\n\nexport interface InterfoldEventData {\n [InterfoldEventType.E3_REQUESTED]: E3RequestedData\n [InterfoldEventType.CIPHERTEXT_OUTPUT_PUBLISHED]: CiphertextOutputPublishedData\n [InterfoldEventType.PLAINTEXT_OUTPUT_PUBLISHED]: PlaintextOutputPublishedData\n [InterfoldEventType.E3_PROGRAM_REGISTERED]: { e3Program: string }\n [InterfoldEventType.ENCRYPTION_SCHEME_ENABLED]: { encryptionSchemeId: string }\n [InterfoldEventType.CIPHERNODE_REGISTRY_SET]: { ciphernodeRegistry: string }\n [InterfoldEventType.MAX_DURATION_SET]: { maxDuration: bigint }\n [InterfoldEventType.PARAM_SET_REGISTERED]: { paramSet: number; encodedParams: string }\n [InterfoldEventType.OWNERSHIP_TRANSFERRED]: { previousOwner: string; newOwner: string }\n [InterfoldEventType.INITIALIZED]: { version: bigint }\n}\n\nexport interface RegistryEventData {\n [RegistryEventType.COMMITTEE_REQUESTED]: CommitteeRequestedData\n [RegistryEventType.COMMITTEE_RANDOMNESS_REQUESTED]: CommitteeRandomnessRequestedData\n [RegistryEventType.RANDOMNESS_CIRCUIT_BREAKER_TRIPPED]: RandomnessCircuitBreakerTrippedData\n [RegistryEventType.COMMITTEE_PUBLISHED]: CommitteePublishedData\n [RegistryEventType.COMMITTEE_FINALIZED]: CommitteeFinalizedData\n [RegistryEventType.INTERFOLD_SET]: { interfold: string }\n [RegistryEventType.OWNERSHIP_TRANSFERRED]: { previousOwner: string; newOwner: string }\n [RegistryEventType.INITIALIZED]: { version: bigint }\n}\n\nexport interface InterfoldEvent<T extends AllEventTypes> {\n type: T\n data: T extends InterfoldEventType ? InterfoldEventData[T] : T extends RegistryEventType ? RegistryEventData[T] : unknown\n log: Log\n timestamp: Date\n blockNumber: bigint\n transactionHash: string\n}\n\nexport interface RandomnessProviderEvent<T extends RandomnessProviderEventType = RandomnessProviderEventType> {\n type: T\n data: RandomnessFulfilledData\n provider: `0x${string}`\n log: Log\n timestamp: Date\n blockNumber: bigint\n transactionHash: string\n}\n\nexport type RandomnessProviderEventCallback<T extends RandomnessProviderEventType = RandomnessProviderEventType> = (\n event: RandomnessProviderEvent<T>,\n) => void | Promise<void>\n\nexport type EventCallback<T extends AllEventTypes = AllEventTypes> = (event: InterfoldEvent<T>) => void | Promise<void>\n\nexport interface EventFilter<T = unknown> {\n address?: `0x${string}`\n fromBlock?: bigint\n toBlock?: bigint\n args?: Partial<T>\n}\n\nexport interface SDKEventEmitter {\n on<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void\n off<T extends AllEventTypes>(eventType: T, callback: EventCallback<T>): void\n emit<T extends AllEventTypes>(event: InterfoldEvent<T>): void\n}\n\nexport interface EventListenerConfig {\n fromBlock?: bigint\n toBlock?: bigint\n /** Maximum block span for each historical RPC query. */\n historicalBlockRange?: bigint\n polling?: boolean\n pollingInterval?: number\n}\n","// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nimport { type Address, type Hash, type Log, PublicClient, encodeAbiParameters } from 'viem'\nimport type { BfvParams } from './types'\n\nexport class SDKError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n ) {\n super(message)\n this.name = 'SDKError'\n }\n}\n\nexport function isValidAddress(address: string): address is Address {\n return /^0x[a-fA-F0-9]{40}$/.test(address)\n}\n\nexport function isValidHash(hash: string): hash is Hash {\n return /^0x[a-fA-F0-9]{64}$/.test(hash)\n}\n\nexport function formatEventName(contractName: string, eventName: string): string {\n return `${contractName}.${eventName}`\n}\n\nexport function parseEventData<T>(log: Log): T {\n return log.data as unknown as T\n}\n\n/**\n * Sleep for a specified number of milliseconds\n */\nexport const sleep = (ms: number): Promise<void> => {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport function formatBigInt(value: bigint): string {\n return value.toString()\n}\n\nexport function parseBigInt(value: string): bigint {\n return BigInt(value)\n}\n\nexport function generateEventId(log: Log): string {\n return `${log.blockHash}-${log.logIndex}`\n}\n\n/**\n * Get the current timestamp in seconds\n * from onchain\n * @param publicClient - The public client to use\n */\nexport async function getCurrentTimestamp(publicClient: PublicClient): Promise<bigint> {\n const block = await publicClient.getBlock()\n return block.timestamp\n}\n\n// Compute provider parameters structure\nexport interface ComputeProviderParams {\n name: string\n parallel: boolean\n batch_size: number\n}\n\n// Default compute provider configuration\nexport const DEFAULT_COMPUTE_PROVIDER_PARAMS: ComputeProviderParams = {\n name: 'risc0',\n parallel: false,\n batch_size: 2,\n}\n\n// Default E3 configuration (`committeeSize` is `IInterfold.CommitteeSize`, not circuit N_PARTIES).\nexport const DEFAULT_E3_CONFIG = {\n committeeSize: 0, // CommitteeSize.Minimum\n duration: 1800, // 30 minutes in seconds\n payment_amount: '0', // 0 ETH in wei\n} as const\n\n/**\n * Encode BFV parameters for the smart contract\n * BFV (Brakerski-Fan-Vercauteren) is a type of fully homomorphic encryption\n */\nexport function encodeBfvParams(params: BfvParams): `0x${string}` {\n const { degree, plaintextModulus, moduli, error1Variance } = params\n\n if (error1Variance === undefined) {\n throw new SDKError(\n 'error1Variance is required in ProtocolParams. All BFV parameter sets must specify error1_variance.',\n 'MISSING_ERROR1_VARIANCE',\n )\n }\n\n return encodeAbiParameters(\n [\n {\n name: 'bfvParams',\n type: 'tuple',\n components: [\n { name: 'degree', type: 'uint256' },\n { name: 'plaintext_modulus', type: 'uint256' },\n { name: 'moduli', type: 'uint256[]' },\n { name: 'error1_variance', type: 'string' },\n ],\n },\n ],\n [\n {\n degree: BigInt(degree),\n plaintext_modulus: BigInt(plaintextModulus),\n moduli: [...moduli],\n error1_variance: error1Variance,\n },\n ],\n )\n}\n\n/**\n * Encode compute provider parameters for the smart contract'\n * If mock is true, the compute provider parameters will return 32 bytes of 0x00\n */\nexport function encodeComputeProviderParams(params: ComputeProviderParams, mock: boolean = false): `0x${string}` {\n if (mock) {\n return `0x${'00'.repeat(32)}` as `0x${string}`\n }\n\n const jsonString = JSON.stringify(params)\n const encoder = new TextEncoder()\n const bytes = encoder.encode(jsonString)\n\n return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')}`\n}\n\n/**\n * Encode custom parameters for the smart contract.\n */\nexport function encodeCustomParams(params: Record<string, unknown>): `0x${string}` {\n const jsonString = JSON.stringify(params)\n const encoder = new TextEncoder()\n const bytes = encoder.encode(jsonString)\n\n return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('')}`\n}\n\n// inputWindow[0] is always larger than now and dkg deadline\nexport const inputWindowStartBuffer = 15n\n\n/**\n * Calculate start window for E3 request\n * @dev This function can be used for testing purposes, or for E3s which need to start as soon as possible.\n * @param publicClient - The public client to use\n * @param duration - The duration of the input window in seconds\n * @param startBuffer - Buffer in seconds added to current timestamp for input window start\n */\nexport async function calculateInputWindow(\n publicClient: PublicClient,\n duration: number = DEFAULT_E3_CONFIG.duration,\n startBuffer: bigint = inputWindowStartBuffer,\n): Promise<[bigint, bigint]> {\n const now = await getCurrentTimestamp(publicClient)\n return [BigInt(now) + startBuffer, BigInt(now) + startBuffer + BigInt(duration)]\n}\n\n/**\n * Decode plaintextOutput bytes to get the actual result number\n */\nexport function decodePlaintextOutput(plaintextOutput: string): number | null {\n try {\n // Remove '0x' prefix if present\n const hex = plaintextOutput.startsWith('0x') ? plaintextOutput.slice(2) : plaintextOutput\n\n // Convert hex to bytes\n const bytes = new Uint8Array(hex.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) || [])\n\n if (bytes.length < 8) {\n console.warn('Plaintext output too short for u64 decoding')\n return null\n }\n\n // Decode first u64 (8 bytes) as little-endian\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n const result = view.getBigUint64(0, true) // true for little-endian\n\n return Number(result)\n } catch (error) {\n console.error('Failed to decode plaintext output:', error)\n return null\n }\n}\n\n// Helper function to convert proof bytes to field elements\nexport function proofToFields(proof: Uint8Array): string[] {\n const fields: string[] = []\n for (let i = 0; i < proof.length; i += 32) {\n const chunk = proof.slice(i, i + 32)\n fields.push('0x' + Buffer.from(chunk).toString('hex'))\n }\n return fields\n}\n"],"mappings":"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","names":["InterfoldEventType","RegistryEventType","RandomnessProviderEventType"]}