@interfold/sdk 0.12.1 → 0.14.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/dist/index.cjs CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  FailureReason: () => FailureReason,
41
41
  InterfoldEventType: () => InterfoldEventType,
42
42
  InterfoldSDK: () => InterfoldSDK,
43
+ RandomnessProviderEventType: () => RandomnessProviderEventType,
43
44
  RegistryEventType: () => RegistryEventType,
44
45
  SDKError: () => SDKError,
45
46
  ThresholdBfvParamsPresetNames: () => ThresholdBfvParamsPresetNames,
@@ -131,6 +132,15 @@ var DEFAULT_E3_CONFIG = {
131
132
  payment_amount: "0"
132
133
  // 0 ETH in wei
133
134
  };
135
+ function cryptoConfigIdForParamSet(paramSet) {
136
+ if (paramSet === 0) {
137
+ return "0x04f3677e73b0f5066d6caf5cbd92e3fb2e38338edaf5cfc971ab28f7b684da78";
138
+ }
139
+ if (paramSet === 1) {
140
+ return "0xd9c86e581f8291ffb5b63595600e8d096ed30b16e2e0a6634a76c22b1f58fb4e";
141
+ }
142
+ throw new SDKError(`Unsupported BFV parameter set: ${paramSet}`, "UNSUPPORTED_CRYPTO_CONFIG");
143
+ }
134
144
  function encodeBfvParams(params) {
135
145
  const { degree, plaintextModulus, moduli, error1Variance } = params;
136
146
  if (error1Variance === void 0) {
@@ -341,11 +351,7 @@ var ContractClient = class _ContractClient {
341
351
  }
342
352
  const committeeSize = validateCommitteeSize(params.committeeSize);
343
353
  const maxFee = params.maxFee ?? await this.getE3Quote(params);
344
- const expectedCryptoConfigId = await this.publicClient.readContract({
345
- address: this.contracts.interfold,
346
- abi: import_types.Interfold__factory.abi,
347
- functionName: "activeCryptoConfigId"
348
- });
354
+ const expectedCryptoConfigId = cryptoConfigIdForParamSet(params.paramSet);
349
355
  const { request } = await this.publicClient.simulateContract({
350
356
  address: this.contracts.interfold,
351
357
  abi: import_types.Interfold__factory.abi,
@@ -430,11 +436,7 @@ var ContractClient = class _ContractClient {
430
436
  async getE3Quote(requestParams) {
431
437
  try {
432
438
  const committeeSize = validateCommitteeSize(requestParams.committeeSize);
433
- const expectedCryptoConfigId = await this.publicClient.readContract({
434
- address: this.contracts.interfold,
435
- abi: import_types.Interfold__factory.abi,
436
- functionName: "activeCryptoConfigId"
437
- });
439
+ const expectedCryptoConfigId = cryptoConfigIdForParamSet(requestParams.paramSet);
438
440
  return this.publicClient.readContract({
439
441
  address: this.contracts.interfold,
440
442
  abi: import_types.Interfold__factory.abi,
@@ -547,6 +549,8 @@ var InterfoldEventType = /* @__PURE__ */ ((InterfoldEventType2) => {
547
549
  })(InterfoldEventType || {});
548
550
  var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
549
551
  RegistryEventType2["COMMITTEE_REQUESTED"] = "CommitteeRequested";
552
+ RegistryEventType2["COMMITTEE_RANDOMNESS_REQUESTED"] = "CommitteeRandomnessRequested";
553
+ RegistryEventType2["RANDOMNESS_CIRCUIT_BREAKER_TRIPPED"] = "RandomnessCircuitBreakerTripped";
550
554
  RegistryEventType2["COMMITTEE_PUBLISHED"] = "CommitteePublished";
551
555
  RegistryEventType2["COMMITTEE_FINALIZED"] = "SortitionCommitteeFinalized";
552
556
  RegistryEventType2["INTERFOLD_SET"] = "InterfoldSet";
@@ -554,11 +558,20 @@ var RegistryEventType = /* @__PURE__ */ ((RegistryEventType2) => {
554
558
  RegistryEventType2["INITIALIZED"] = "Initialized";
555
559
  return RegistryEventType2;
556
560
  })(RegistryEventType || {});
561
+ var RandomnessProviderEventType = /* @__PURE__ */ ((RandomnessProviderEventType2) => {
562
+ RandomnessProviderEventType2["RANDOMNESS_FULFILLED"] = "RandomnessFulfilled";
563
+ return RandomnessProviderEventType2;
564
+ })(RandomnessProviderEventType || {});
557
565
 
558
566
  // src/events/event-listener.ts
559
567
  var EventListener = class _EventListener {
568
+ static DEFAULT_HISTORICAL_BLOCK_RANGE = 10000n;
569
+ static MAX_REMEMBERED_LOGS = 1e4;
560
570
  listeners = /* @__PURE__ */ new Map();
561
571
  activeWatchers = /* @__PURE__ */ new Map();
572
+ watcherStartBlocks = /* @__PURE__ */ new Map();
573
+ randomnessProviderListeners = /* @__PURE__ */ new Map();
574
+ seenLiveLogs = /* @__PURE__ */ new Map();
562
575
  isPolling = false;
563
576
  lastBlockNumber = BigInt(0);
564
577
  publicClient;
@@ -575,6 +588,8 @@ var EventListener = class _EventListener {
575
588
  // runtime; those default to the Interfold contract.
576
589
  static REGISTRY_ONLY_EVENTS = /* @__PURE__ */ new Set([
577
590
  "CommitteeRequested" /* COMMITTEE_REQUESTED */,
591
+ "CommitteeRandomnessRequested" /* COMMITTEE_RANDOMNESS_REQUESTED */,
592
+ "RandomnessCircuitBreakerTripped" /* RANDOMNESS_CIRCUIT_BREAKER_TRIPPED */,
578
593
  "CommitteePublished" /* COMMITTEE_PUBLISHED */,
579
594
  "SortitionCommitteeFinalized" /* COMMITTEE_FINALIZED */,
580
595
  "InterfoldSet" /* INTERFOLD_SET */
@@ -590,6 +605,93 @@ var EventListener = class _EventListener {
590
605
  const { address, abi } = this.resolveContract(eventType);
591
606
  return this.watchContractEvent(address, eventType, abi, callback);
592
607
  }
608
+ async onRandomnessProviderEvent(provider, eventType, callback, fromBlock) {
609
+ const listenerKey = `${provider.toLowerCase()}:${eventType}`;
610
+ const watcherKey = `randomness-provider:${listenerKey}`;
611
+ const requestedStartBlock = fromBlock ?? this.config.fromBlock;
612
+ let callbacks = this.randomnessProviderListeners.get(listenerKey);
613
+ if (!callbacks) {
614
+ callbacks = /* @__PURE__ */ new Set();
615
+ this.randomnessProviderListeners.set(listenerKey, callbacks);
616
+ }
617
+ if (this.activeWatchers.has(watcherKey)) {
618
+ const activeStartBlock = this.watcherStartBlocks.get(watcherKey);
619
+ if (fromBlock !== void 0 && requestedStartBlock !== activeStartBlock) {
620
+ throw new SDKError(
621
+ `Randomness provider watcher for ${eventType} on ${provider} already starts at ${activeStartBlock ?? "latest"}; requested ${requestedStartBlock ?? "latest"}`,
622
+ "INVALID_EVENT_CONFIG"
623
+ );
624
+ }
625
+ callbacks.add(callback);
626
+ return;
627
+ }
628
+ callbacks.add(callback);
629
+ try {
630
+ const unwatch = this.publicClient.watchContractEvent({
631
+ address: provider,
632
+ abi: import_types3.IRandomnessProvider__factory.abi,
633
+ eventName: eventType,
634
+ fromBlock: requestedStartBlock,
635
+ onLogs: (logs) => {
636
+ for (const log of logs) {
637
+ if (!this.rememberLiveLog(log)) continue;
638
+ const event = {
639
+ type: eventType,
640
+ data: log.args,
641
+ provider,
642
+ log,
643
+ timestamp: /* @__PURE__ */ new Date(),
644
+ blockNumber: log.blockNumber ?? 0n,
645
+ transactionHash: log.transactionHash ?? "0x"
646
+ };
647
+ const currentCallbacks = this.randomnessProviderListeners.get(listenerKey);
648
+ currentCallbacks?.forEach((currentCallback) => {
649
+ try {
650
+ const result = currentCallback(event);
651
+ if (result) {
652
+ void result.catch((error) => {
653
+ console.error(`Error in randomness provider callback for ${eventType}:`, error);
654
+ });
655
+ }
656
+ } catch (error) {
657
+ console.error(`Error in randomness provider callback for ${eventType}:`, error);
658
+ }
659
+ });
660
+ }
661
+ }
662
+ });
663
+ this.activeWatchers.set(watcherKey, unwatch);
664
+ this.watcherStartBlocks.set(watcherKey, requestedStartBlock);
665
+ } catch (error) {
666
+ callbacks.delete(callback);
667
+ if (callbacks.size === 0) this.randomnessProviderListeners.delete(listenerKey);
668
+ throw new SDKError(`Failed to watch randomness provider event ${eventType} on ${provider}: ${error}`, "WATCH_EVENT_FAILED");
669
+ }
670
+ }
671
+ offRandomnessProviderEvent(provider, eventType, callback) {
672
+ const listenerKey = `${provider.toLowerCase()}:${eventType}`;
673
+ const callbacks = this.randomnessProviderListeners.get(listenerKey);
674
+ callbacks?.delete(callback);
675
+ if (callbacks && callbacks.size === 0) {
676
+ this.randomnessProviderListeners.delete(listenerKey);
677
+ const watcherKey = `randomness-provider:${listenerKey}`;
678
+ const unwatch = this.activeWatchers.get(watcherKey);
679
+ if (unwatch) unwatch();
680
+ this.activeWatchers.delete(watcherKey);
681
+ this.watcherStartBlocks.delete(watcherKey);
682
+ }
683
+ }
684
+ async getHistoricalRandomnessProviderEvents(provider, eventType, fromBlock, toBlock) {
685
+ const start = fromBlock ?? this.config.fromBlock;
686
+ if (start === void 0) {
687
+ throw new SDKError("Randomness provider history requires fromBlock or EventListenerConfig.fromBlock", "INVALID_EVENT_CONFIG");
688
+ }
689
+ try {
690
+ return await this.getHistoricalContractEvents(provider, import_types3.IRandomnessProvider__factory.abi, eventType, start, toBlock);
691
+ } catch (error) {
692
+ throw new SDKError(`Failed to get randomness provider events from ${provider}: ${error}`, "HISTORICAL_EVENTS_FAILED");
693
+ }
694
+ }
593
695
  async once(type, callback) {
594
696
  const handler = (event) => {
595
697
  this.off(type, handler);
@@ -618,6 +720,7 @@ var EventListener = class _EventListener {
618
720
  for (let i = 0; i < logs.length; i++) {
619
721
  const log = logs[i];
620
722
  if (!log) break;
723
+ if (!emitter.rememberLiveLog(log)) continue;
621
724
  const event = {
622
725
  type: eventType,
623
726
  data: log.args,
@@ -671,13 +774,7 @@ var EventListener = class _EventListener {
671
774
  async getHistoricalEvents(eventType, fromBlock, toBlock) {
672
775
  const { address, abi } = this.resolveContract(eventType);
673
776
  try {
674
- return await this.publicClient.getContractEvents({
675
- address,
676
- abi,
677
- eventName: eventType,
678
- fromBlock: fromBlock ?? this.config.fromBlock,
679
- toBlock: toBlock ?? this.config.toBlock
680
- });
777
+ return await this.getHistoricalContractEvents(address, abi, eventType, fromBlock, toBlock);
681
778
  } catch (error) {
682
779
  throw new SDKError(`Failed to get historical events: ${error}`, "HISTORICAL_EVENTS_FAILED");
683
780
  }
@@ -736,7 +833,65 @@ var EventListener = class _EventListener {
736
833
  }
737
834
  });
738
835
  this.activeWatchers.clear();
836
+ this.watcherStartBlocks.clear();
739
837
  this.listeners.clear();
838
+ this.randomnessProviderListeners.clear();
839
+ this.seenLiveLogs.clear();
840
+ }
841
+ logIdentity(log) {
842
+ if (log.blockHash && log.transactionHash && log.logIndex !== null && log.logIndex !== void 0) {
843
+ return `${log.blockHash}:${log.transactionHash}:${log.logIndex}:${Boolean(log.removed)}`;
844
+ }
845
+ return void 0;
846
+ }
847
+ rememberLiveLog(log) {
848
+ const identity = this.logIdentity(log);
849
+ if (!identity) return true;
850
+ if (this.seenLiveLogs.has(identity)) return false;
851
+ this.seenLiveLogs.set(identity, true);
852
+ if (this.seenLiveLogs.size > _EventListener.MAX_REMEMBERED_LOGS) {
853
+ const oldest = this.seenLiveLogs.keys().next().value;
854
+ if (oldest !== void 0) this.seenLiveLogs.delete(oldest);
855
+ }
856
+ return true;
857
+ }
858
+ async getHistoricalContractEvents(address, abi, eventName, fromBlock, toBlock) {
859
+ const start = fromBlock ?? this.config.fromBlock;
860
+ const configuredEnd = toBlock ?? this.config.toBlock;
861
+ if (start === void 0) {
862
+ return await this.publicClient.getContractEvents({
863
+ address,
864
+ abi,
865
+ eventName,
866
+ toBlock: configuredEnd
867
+ });
868
+ }
869
+ const end = configuredEnd ?? await this.publicClient.getBlockNumber({ cacheTime: 0 });
870
+ if (end < start) return [];
871
+ const range = this.config.historicalBlockRange ?? _EventListener.DEFAULT_HISTORICAL_BLOCK_RANGE;
872
+ if (range <= 0n) throw new SDKError("Historical block range must be greater than zero", "INVALID_EVENT_CONFIG");
873
+ const logs = [];
874
+ const seen = /* @__PURE__ */ new Set();
875
+ for (let cursor = start; cursor <= end; cursor += range) {
876
+ const chunkEnd = cursor + range - 1n < end ? cursor + range - 1n : end;
877
+ const chunk = await this.publicClient.getContractEvents({
878
+ address,
879
+ abi,
880
+ eventName,
881
+ fromBlock: cursor,
882
+ toBlock: chunkEnd
883
+ });
884
+ for (const log of chunk) {
885
+ const identity = this.logIdentity(log);
886
+ if (identity && seen.has(identity)) continue;
887
+ if (identity) {
888
+ seen.add(identity);
889
+ this.rememberLiveLog(log);
890
+ }
891
+ logs.push(log);
892
+ }
893
+ }
894
+ return logs;
740
895
  }
741
896
  async pollForEvents() {
742
897
  while (this.isPolling) {
@@ -1102,6 +1257,15 @@ var InterfoldSDK = class _InterfoldSDK {
1102
1257
  async onInterfoldEvent(eventType, callback) {
1103
1258
  return this.eventListener.onInterfoldEvent(eventType, callback);
1104
1259
  }
1260
+ async onRandomnessProviderEvent(provider, eventType, callback, fromBlock) {
1261
+ return this.eventListener.onRandomnessProviderEvent(provider, eventType, callback, fromBlock);
1262
+ }
1263
+ offRandomnessProviderEvent(provider, eventType, callback) {
1264
+ this.eventListener.offRandomnessProviderEvent(provider, eventType, callback);
1265
+ }
1266
+ async getHistoricalRandomnessProviderEvents(provider, eventType, fromBlock, toBlock) {
1267
+ return this.eventListener.getHistoricalRandomnessProviderEvents(provider, eventType, fromBlock, toBlock);
1268
+ }
1105
1269
  off(eventType, callback) {
1106
1270
  this.eventListener.off(eventType, callback);
1107
1271
  }
@@ -1161,6 +1325,7 @@ var InterfoldSDK = class _InterfoldSDK {
1161
1325
  FailureReason,
1162
1326
  InterfoldEventType,
1163
1327
  InterfoldSDK,
1328
+ RandomnessProviderEventType,
1164
1329
  RegistryEventType,
1165
1330
  SDKError,
1166
1331
  ThresholdBfvParamsPresetNames,