@interfold/sdk 0.7.0 → 0.9.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
@@ -331,6 +331,15 @@ const stage = await sdk.getE3Stage(e3Id: bigint);
331
331
  const reason = await sdk.getFailureReason(e3Id: bigint);
332
332
  ```
333
333
 
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.
337
+
338
+ ```ts
339
+ const hash = await sdk.cancelE3(e3Id)
340
+ await sdk.waitForTransaction(hash)
341
+ ```
342
+
334
343
  #### Event Handling
335
344
 
336
345
  ```typescript
@@ -171,6 +171,12 @@ var ContractClient = class _ContractClient {
171
171
  throw new SDKError("No account connected", "NO_ACCOUNT");
172
172
  }
173
173
  const committeeSize = validateCommitteeSize(params.committeeSize);
174
+ const maxFee = params.maxFee ?? await this.getE3Quote(params);
175
+ const expectedCryptoConfigId = await this.publicClient.readContract({
176
+ address: this.contracts.interfold,
177
+ abi: import_types.Interfold__factory.abi,
178
+ functionName: "activeCryptoConfigId"
179
+ });
174
180
  const { request } = await this.publicClient.simulateContract({
175
181
  address: this.contracts.interfold,
176
182
  abi: import_types.Interfold__factory.abi,
@@ -182,7 +188,10 @@ var ContractClient = class _ContractClient {
182
188
  e3Program: params.e3Program,
183
189
  paramSet: params.paramSet,
184
190
  computeProviderParams: params.computeProviderParams,
185
- customParams: params.customParams || "0x"
191
+ customParams: params.customParams || "0x",
192
+ expectedFeeToken: this.contracts.feeToken,
193
+ expectedCryptoConfigId,
194
+ maxFee
186
195
  }
187
196
  ],
188
197
  account,
@@ -193,6 +202,27 @@ var ContractClient = class _ContractClient {
193
202
  throw new SDKError(`Failed to request E3: ${error}`, "REQUEST_E3_FAILED");
194
203
  }
195
204
  }
205
+ async cancelE3(e3Id) {
206
+ if (!this.walletClient) {
207
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
208
+ }
209
+ const account = this.walletClient.account;
210
+ if (!account) {
211
+ throw new SDKError("No account connected", "NO_ACCOUNT");
212
+ }
213
+ try {
214
+ const { request } = await this.publicClient.simulateContract({
215
+ address: this.contracts.interfold,
216
+ abi: import_types.Interfold__factory.abi,
217
+ functionName: "cancelE3",
218
+ args: [e3Id],
219
+ account
220
+ });
221
+ return await this.walletClient.writeContract(request);
222
+ } catch (error) {
223
+ throw new SDKError(`Failed to cancel E3: ${error}`, "CANCEL_E3_FAILED");
224
+ }
225
+ }
196
226
  async publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof, gasLimit) {
197
227
  if (!this.walletClient) {
198
228
  throw new SDKError("Wallet client required for write operations", "NO_WALLET");
@@ -242,7 +272,10 @@ var ContractClient = class _ContractClient {
242
272
  e3Program: requestParams.e3Program,
243
273
  paramSet: requestParams.paramSet,
244
274
  computeProviderParams: requestParams.computeProviderParams,
245
- customParams: requestParams.customParams || "0x"
275
+ customParams: requestParams.customParams || "0x",
276
+ expectedFeeToken: this.contracts.feeToken,
277
+ expectedCryptoConfigId: import_viem2.zeroHash,
278
+ maxFee: requestParams.maxFee ?? 0n
246
279
  }
247
280
  ]
248
281
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/contracts/index.ts","../../src/contracts/contract-client.ts","../../src/utils.ts","../../src/contracts/types.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 { ContractClient } from './contract-client'\nexport type { ContractClientConfig } from './contract-client'\nexport type { ContractAddresses, E3, E3RequestParams } from './types'\nexport { E3Stage, FailureReason } 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 {\n type Abi,\n type Chain,\n type Hash,\n type PublicClient,\n type TransactionReceipt,\n type WalletClient,\n createPublicClient,\n createWalletClient,\n http,\n webSocket,\n} from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\n\nimport { CiphernodeRegistryOwnable__factory, Interfold__factory, InterfoldToken__factory } from '@interfold/contracts/types'\nimport type { ContractAddresses, E3, E3RequestParams, E3Stage, FailureReason } from './types'\nimport { validateCommitteeSize } from './types'\nimport { SDKError, isValidAddress } from '../utils'\n\nexport interface ContractClientConfig {\n publicClient: PublicClient\n walletClient?: WalletClient\n contracts: ContractAddresses\n}\n\nexport class ContractClient {\n private publicClient: PublicClient\n private walletClient?: WalletClient\n private contracts: ContractAddresses\n private contractInfo: {\n interfold: { address: `0x${string}`; abi: Abi }\n ciphernodeRegistry: { address: `0x${string}`; abi: Abi }\n feeToken: { address: `0x${string}`; abi: Abi }\n }\n\n constructor(config: ContractClientConfig) {\n const { publicClient, walletClient, contracts } = config\n\n if (!isValidAddress(contracts.interfold)) {\n throw new SDKError('Invalid Interfold contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.ciphernodeRegistry)) {\n throw new SDKError('Invalid CiphernodeRegistry contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.feeToken)) {\n throw new SDKError('Invalid FeeToken contract address', 'INVALID_ADDRESS')\n }\n\n this.publicClient = publicClient\n this.walletClient = walletClient\n this.contracts = contracts\n\n this.contractInfo = {\n interfold: {\n address: contracts.interfold,\n abi: Interfold__factory.abi,\n },\n ciphernodeRegistry: {\n address: contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n },\n feeToken: {\n address: contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n },\n }\n }\n\n public static create(options: {\n rpcUrl: string\n contracts: ContractAddresses\n privateKey?: `0x${string}`\n chain: Chain\n }): ContractClient {\n const isWebSocket = options.rpcUrl.startsWith('ws://') || options.rpcUrl.startsWith('wss://')\n const transport = isWebSocket\n ? webSocket(options.rpcUrl, {\n keepAlive: { interval: 30_000 },\n reconnect: { attempts: 5, delay: 2_000 },\n })\n : http(options.rpcUrl)\n\n const publicClient = createPublicClient({\n chain: options.chain,\n transport,\n }) as PublicClient\n\n let walletClient: WalletClient | undefined\n if (options.privateKey) {\n const account = privateKeyToAccount(options.privateKey)\n walletClient = createWalletClient({\n account,\n chain: options.chain,\n transport,\n })\n }\n\n return new ContractClient({ publicClient, walletClient, contracts: options.contracts })\n }\n\n public getPublicClient(): PublicClient {\n return this.publicClient\n }\n\n public async approveFeeToken(amount: bigint): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n functionName: 'approve',\n args: [this.contracts.interfold, amount],\n account,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to approve fee token: ${error}`, 'APPROVE_FEE_TOKEN_FAILED')\n }\n }\n\n public async requestE3(params: E3RequestParams): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const committeeSize = validateCommitteeSize(params.committeeSize)\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'request',\n args: [\n {\n committeeSize,\n inputWindow: params.inputWindow,\n e3Program: params.e3Program,\n paramSet: params.paramSet,\n computeProviderParams: params.computeProviderParams,\n customParams: params.customParams || '0x',\n },\n ],\n account,\n gas: params.gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to request E3: ${error}`, 'REQUEST_E3_FAILED')\n }\n }\n\n public async publishCiphertextOutput(\n e3Id: bigint,\n ciphertextOutput: `0x${string}`,\n ciphertextCommitment: `0x${string}`,\n proof: `0x${string}`,\n gasLimit?: bigint,\n ): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'publishCiphertextOutput',\n args: [e3Id, ciphertextOutput, ciphertextCommitment, proof],\n account,\n gas: gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to publish ciphertext output: ${error}`, 'PUBLISH_CIPHERTEXT_OUTPUT_FAILED')\n }\n }\n\n public async getE3(e3Id: bigint): Promise<E3> {\n try {\n const result: E3 = await this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3: ${error}`, 'GET_E3_FAILED')\n }\n }\n\n public async getE3Quote(requestParams: E3RequestParams): Promise<bigint> {\n try {\n const committeeSize = validateCommitteeSize(requestParams.committeeSize)\n\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Quote',\n args: [\n {\n committeeSize,\n inputWindow: requestParams.inputWindow,\n e3Program: requestParams.e3Program,\n paramSet: requestParams.paramSet,\n computeProviderParams: requestParams.computeProviderParams,\n customParams: requestParams.customParams || '0x',\n },\n ],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 quote: ${error}`, 'GET_E3_QUOTE_FAILED')\n }\n }\n\n public async getFailureReason(e3Id: bigint): Promise<FailureReason> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getFailureReason',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get failure reason: ${error}`, 'GET_FAILURE_REASON_FAILED')\n }\n }\n\n public async getE3PublicKey(e3Id: bigint): Promise<`0x${string}`> {\n try {\n const result: `0x${string}` = await this.publicClient.readContract({\n address: this.contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n functionName: 'committeePublicKey',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3 public key: ${error}`, 'GET_E3_PUBLIC_KEY_FAILED')\n }\n }\n\n public async getE3Stage(e3Id: bigint): Promise<E3Stage> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Stage',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 stage: ${error}`, 'GET_E3_STAGE_FAILED')\n }\n }\n\n public async estimateGas(\n functionName: string,\n args: readonly unknown[],\n contractAddress: `0x${string}`,\n abi: Abi,\n value?: bigint,\n ): Promise<bigint> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for gas estimation', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const estimateParams = {\n address: contractAddress,\n abi,\n functionName,\n args,\n account,\n ...(value !== undefined && { value }),\n }\n\n return await this.publicClient.estimateContractGas(estimateParams)\n } catch (error) {\n throw new SDKError(`Failed to estimate gas: ${error}`, 'GAS_ESTIMATION_FAILED')\n }\n }\n\n public async waitForTransaction(hash: Hash): Promise<TransactionReceipt> {\n try {\n return await this.publicClient.waitForTransactionReceipt({\n hash,\n confirmations: 1,\n })\n } catch (error) {\n throw new SDKError(`Failed to wait for transaction: ${error}`, 'TRANSACTION_WAIT_FAILED')\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 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","// 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 { SDKError } from '../utils'\n\nexport interface ContractAddresses {\n interfold: `0x${string}`\n ciphernodeRegistry: `0x${string}`\n feeToken: `0x${string}`\n}\n\n/** On-chain `IInterfold.CommitteeSize`: Minimum (N=3), Micro (N=9), Small (N=19). */\nexport enum CommitteeSize {\n Minimum = 0,\n Micro = 1,\n Small = 2,\n}\n\n/** Fail fast on out-of-range committee sizes before they hit the contract. */\nexport function validateCommitteeSize(value: number | CommitteeSize): CommitteeSize {\n if (!Number.isInteger(value) || value < CommitteeSize.Minimum || value > CommitteeSize.Small) {\n throw new SDKError(\n `Invalid committeeSize ${value}. Use CommitteeSize.Minimum (0), CommitteeSize.Micro (1), or CommitteeSize.Small (2).`,\n 'INVALID_COMMITTEE_SIZE',\n )\n }\n return value\n}\n\nexport enum ParamSet {\n Insecure512 = 0,\n Secure8192 = 1,\n}\n\nexport interface 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\nexport interface RequestParams {\n gasLimit?: bigint\n}\n\nexport interface E3RequestParams extends RequestParams {\n committeeSize: number\n inputWindow: readonly [bigint, bigint]\n e3Program: `0x${string}`\n paramSet: number\n computeProviderParams: `0x${string}`\n customParams?: `0x${string}`\n}\n\nexport enum E3Stage {\n None,\n Requested,\n CommitteeFinalized,\n KeyPublished,\n CiphertextReady,\n Complete,\n Failed,\n}\n\nexport enum FailureReason {\n None,\n CommitteeFormationTimeout,\n InsufficientCommitteeMembers,\n DKGTimeout,\n DKGInvalidShares,\n NoInputsReceived,\n ComputeTimeout,\n ComputeProviderExpired,\n ComputeProviderFailed,\n RequesterCancelled,\n DecryptionTimeout,\n DecryptionInvalidShares,\n VerificationFailed,\n}\n"],"mappings":"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","names":["import_viem","E3Stage","FailureReason"]}
1
+ {"version":3,"sources":["../../src/contracts/index.ts","../../src/contracts/contract-client.ts","../../src/utils.ts","../../src/contracts/types.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 { ContractClient } from './contract-client'\nexport type { ContractClientConfig } from './contract-client'\nexport type { ContractAddresses, E3, E3RequestParams } from './types'\nexport { E3Stage, FailureReason } 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 {\n type Abi,\n type Chain,\n type Hash,\n type PublicClient,\n type TransactionReceipt,\n type WalletClient,\n createPublicClient,\n createWalletClient,\n http,\n zeroHash,\n webSocket,\n} from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\n\nimport { CiphernodeRegistryOwnable__factory, Interfold__factory, InterfoldToken__factory } from '@interfold/contracts/types'\nimport type { ContractAddresses, E3, E3RequestParams, E3Stage, FailureReason } from './types'\nimport { validateCommitteeSize } from './types'\nimport { SDKError, isValidAddress } from '../utils'\n\nexport interface ContractClientConfig {\n publicClient: PublicClient\n walletClient?: WalletClient\n contracts: ContractAddresses\n}\n\nexport class ContractClient {\n private publicClient: PublicClient\n private walletClient?: WalletClient\n private contracts: ContractAddresses\n private contractInfo: {\n interfold: { address: `0x${string}`; abi: Abi }\n ciphernodeRegistry: { address: `0x${string}`; abi: Abi }\n feeToken: { address: `0x${string}`; abi: Abi }\n }\n\n constructor(config: ContractClientConfig) {\n const { publicClient, walletClient, contracts } = config\n\n if (!isValidAddress(contracts.interfold)) {\n throw new SDKError('Invalid Interfold contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.ciphernodeRegistry)) {\n throw new SDKError('Invalid CiphernodeRegistry contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.feeToken)) {\n throw new SDKError('Invalid FeeToken contract address', 'INVALID_ADDRESS')\n }\n\n this.publicClient = publicClient\n this.walletClient = walletClient\n this.contracts = contracts\n\n this.contractInfo = {\n interfold: {\n address: contracts.interfold,\n abi: Interfold__factory.abi,\n },\n ciphernodeRegistry: {\n address: contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n },\n feeToken: {\n address: contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n },\n }\n }\n\n public static create(options: {\n rpcUrl: string\n contracts: ContractAddresses\n privateKey?: `0x${string}`\n chain: Chain\n }): ContractClient {\n const isWebSocket = options.rpcUrl.startsWith('ws://') || options.rpcUrl.startsWith('wss://')\n const transport = isWebSocket\n ? webSocket(options.rpcUrl, {\n keepAlive: { interval: 30_000 },\n reconnect: { attempts: 5, delay: 2_000 },\n })\n : http(options.rpcUrl)\n\n const publicClient = createPublicClient({\n chain: options.chain,\n transport,\n }) as PublicClient\n\n let walletClient: WalletClient | undefined\n if (options.privateKey) {\n const account = privateKeyToAccount(options.privateKey)\n walletClient = createWalletClient({\n account,\n chain: options.chain,\n transport,\n })\n }\n\n return new ContractClient({ publicClient, walletClient, contracts: options.contracts })\n }\n\n public getPublicClient(): PublicClient {\n return this.publicClient\n }\n\n public async approveFeeToken(amount: bigint): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n functionName: 'approve',\n args: [this.contracts.interfold, amount],\n account,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to approve fee token: ${error}`, 'APPROVE_FEE_TOKEN_FAILED')\n }\n }\n\n public async requestE3(params: E3RequestParams): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const committeeSize = validateCommitteeSize(params.committeeSize)\n const maxFee = params.maxFee ?? (await this.getE3Quote(params))\n const expectedCryptoConfigId = await this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'activeCryptoConfigId',\n })\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'request',\n args: [\n {\n committeeSize,\n inputWindow: params.inputWindow,\n e3Program: params.e3Program,\n paramSet: params.paramSet,\n computeProviderParams: params.computeProviderParams,\n customParams: params.customParams || '0x',\n expectedFeeToken: this.contracts.feeToken,\n expectedCryptoConfigId,\n maxFee,\n },\n ],\n account,\n gas: params.gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to request E3: ${error}`, 'REQUEST_E3_FAILED')\n }\n }\n\n public async cancelE3(e3Id: bigint): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n try {\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'cancelE3',\n args: [e3Id],\n account,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to cancel E3: ${error}`, 'CANCEL_E3_FAILED')\n }\n }\n\n public async publishCiphertextOutput(\n e3Id: bigint,\n ciphertextOutput: `0x${string}`,\n ciphertextCommitment: `0x${string}`,\n proof: `0x${string}`,\n gasLimit?: bigint,\n ): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'publishCiphertextOutput',\n args: [e3Id, ciphertextOutput, ciphertextCommitment, proof],\n account,\n gas: gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to publish ciphertext output: ${error}`, 'PUBLISH_CIPHERTEXT_OUTPUT_FAILED')\n }\n }\n\n public async getE3(e3Id: bigint): Promise<E3> {\n try {\n const result: E3 = await this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3: ${error}`, 'GET_E3_FAILED')\n }\n }\n\n public async getE3Quote(requestParams: E3RequestParams): Promise<bigint> {\n try {\n const committeeSize = validateCommitteeSize(requestParams.committeeSize)\n\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Quote',\n args: [\n {\n committeeSize,\n inputWindow: requestParams.inputWindow,\n e3Program: requestParams.e3Program,\n paramSet: requestParams.paramSet,\n computeProviderParams: requestParams.computeProviderParams,\n customParams: requestParams.customParams || '0x',\n expectedFeeToken: this.contracts.feeToken,\n expectedCryptoConfigId: zeroHash,\n maxFee: requestParams.maxFee ?? 0n,\n },\n ],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 quote: ${error}`, 'GET_E3_QUOTE_FAILED')\n }\n }\n\n public async getFailureReason(e3Id: bigint): Promise<FailureReason> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getFailureReason',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get failure reason: ${error}`, 'GET_FAILURE_REASON_FAILED')\n }\n }\n\n public async getE3PublicKey(e3Id: bigint): Promise<`0x${string}`> {\n try {\n const result: `0x${string}` = await this.publicClient.readContract({\n address: this.contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n functionName: 'committeePublicKey',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3 public key: ${error}`, 'GET_E3_PUBLIC_KEY_FAILED')\n }\n }\n\n public async getE3Stage(e3Id: bigint): Promise<E3Stage> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Stage',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 stage: ${error}`, 'GET_E3_STAGE_FAILED')\n }\n }\n\n public async estimateGas(\n functionName: string,\n args: readonly unknown[],\n contractAddress: `0x${string}`,\n abi: Abi,\n value?: bigint,\n ): Promise<bigint> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for gas estimation', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const estimateParams = {\n address: contractAddress,\n abi,\n functionName,\n args,\n account,\n ...(value !== undefined && { value }),\n }\n\n return await this.publicClient.estimateContractGas(estimateParams)\n } catch (error) {\n throw new SDKError(`Failed to estimate gas: ${error}`, 'GAS_ESTIMATION_FAILED')\n }\n }\n\n public async waitForTransaction(hash: Hash): Promise<TransactionReceipt> {\n try {\n return await this.publicClient.waitForTransactionReceipt({\n hash,\n confirmations: 1,\n })\n } catch (error) {\n throw new SDKError(`Failed to wait for transaction: ${error}`, 'TRANSACTION_WAIT_FAILED')\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 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","// 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 { SDKError } from '../utils'\n\nexport interface ContractAddresses {\n interfold: `0x${string}`\n ciphernodeRegistry: `0x${string}`\n feeToken: `0x${string}`\n}\n\n/** On-chain `IInterfold.CommitteeSize`: Minimum (N=3), Micro (N=9), Small (N=19). */\nexport enum CommitteeSize {\n Minimum = 0,\n Micro = 1,\n Small = 2,\n}\n\n/** Fail fast on out-of-range committee sizes before they hit the contract. */\nexport function validateCommitteeSize(value: number | CommitteeSize): CommitteeSize {\n if (!Number.isInteger(value) || value < CommitteeSize.Minimum || value > CommitteeSize.Small) {\n throw new SDKError(\n `Invalid committeeSize ${value}. Use CommitteeSize.Minimum (0), CommitteeSize.Micro (1), or CommitteeSize.Small (2).`,\n 'INVALID_COMMITTEE_SIZE',\n )\n }\n return value\n}\n\nexport enum ParamSet {\n Insecure512 = 0,\n Secure8192 = 1,\n}\n\nexport interface 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\nexport interface RequestParams {\n gasLimit?: bigint\n}\n\nexport interface E3RequestParams extends RequestParams {\n committeeSize: number\n inputWindow: readonly [bigint, bigint]\n e3Program: `0x${string}`\n paramSet: number\n computeProviderParams: `0x${string}`\n customParams?: `0x${string}`\n /** Maximum fee token amount accepted. Defaults to a fresh quote. */\n maxFee?: bigint\n}\n\nexport enum E3Stage {\n None,\n Requested,\n CommitteeFinalized,\n KeyPublished,\n CiphertextReady,\n Complete,\n Failed,\n}\n\nexport enum FailureReason {\n None,\n CommitteeFormationTimeout,\n InsufficientCommitteeMembers,\n DKGTimeout,\n DKGInvalidShares,\n NoInputsReceived,\n ComputeTimeout,\n ComputeProviderExpired,\n ComputeProviderFailed,\n RequesterCancelled,\n DecryptionTimeout,\n DecryptionInvalidShares,\n VerificationFailed,\n}\n"],"mappings":"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","names":["import_viem","E3Stage","FailureReason"]}
@@ -1,5 +1,5 @@
1
1
  import { PublicClient, WalletClient, Chain, Hash, Abi, TransactionReceipt } from 'viem';
2
- import { C as ContractAddresses, a as E3RequestParams, E as E3, F as FailureReason, b as E3Stage } from '../types-s67c2A1z.js';
2
+ import { C as ContractAddresses, E as E3RequestParams, a as E3, F as FailureReason, b as E3Stage } from '../types-Cwx_flfX.js';
3
3
 
4
4
  interface ContractClientConfig {
5
5
  publicClient: PublicClient;
@@ -21,6 +21,7 @@ declare class ContractClient {
21
21
  getPublicClient(): PublicClient;
22
22
  approveFeeToken(amount: bigint): Promise<Hash>;
23
23
  requestE3(params: E3RequestParams): Promise<Hash>;
24
+ cancelE3(e3Id: bigint): Promise<Hash>;
24
25
  publishCiphertextOutput(e3Id: bigint, ciphertextOutput: `0x${string}`, ciphertextCommitment: `0x${string}`, proof: `0x${string}`, gasLimit?: bigint): Promise<Hash>;
25
26
  getE3(e3Id: bigint): Promise<E3>;
26
27
  getE3Quote(requestParams: E3RequestParams): Promise<bigint>;
@@ -3,6 +3,7 @@ import {
3
3
  createPublicClient,
4
4
  createWalletClient,
5
5
  http,
6
+ zeroHash,
6
7
  webSocket
7
8
  } from "viem";
8
9
  import { privateKeyToAccount } from "viem/accounts";
@@ -148,6 +149,12 @@ var ContractClient = class _ContractClient {
148
149
  throw new SDKError("No account connected", "NO_ACCOUNT");
149
150
  }
150
151
  const committeeSize = validateCommitteeSize(params.committeeSize);
152
+ const maxFee = params.maxFee ?? await this.getE3Quote(params);
153
+ const expectedCryptoConfigId = await this.publicClient.readContract({
154
+ address: this.contracts.interfold,
155
+ abi: Interfold__factory.abi,
156
+ functionName: "activeCryptoConfigId"
157
+ });
151
158
  const { request } = await this.publicClient.simulateContract({
152
159
  address: this.contracts.interfold,
153
160
  abi: Interfold__factory.abi,
@@ -159,7 +166,10 @@ var ContractClient = class _ContractClient {
159
166
  e3Program: params.e3Program,
160
167
  paramSet: params.paramSet,
161
168
  computeProviderParams: params.computeProviderParams,
162
- customParams: params.customParams || "0x"
169
+ customParams: params.customParams || "0x",
170
+ expectedFeeToken: this.contracts.feeToken,
171
+ expectedCryptoConfigId,
172
+ maxFee
163
173
  }
164
174
  ],
165
175
  account,
@@ -170,6 +180,27 @@ var ContractClient = class _ContractClient {
170
180
  throw new SDKError(`Failed to request E3: ${error}`, "REQUEST_E3_FAILED");
171
181
  }
172
182
  }
183
+ async cancelE3(e3Id) {
184
+ if (!this.walletClient) {
185
+ throw new SDKError("Wallet client required for write operations", "NO_WALLET");
186
+ }
187
+ const account = this.walletClient.account;
188
+ if (!account) {
189
+ throw new SDKError("No account connected", "NO_ACCOUNT");
190
+ }
191
+ try {
192
+ const { request } = await this.publicClient.simulateContract({
193
+ address: this.contracts.interfold,
194
+ abi: Interfold__factory.abi,
195
+ functionName: "cancelE3",
196
+ args: [e3Id],
197
+ account
198
+ });
199
+ return await this.walletClient.writeContract(request);
200
+ } catch (error) {
201
+ throw new SDKError(`Failed to cancel E3: ${error}`, "CANCEL_E3_FAILED");
202
+ }
203
+ }
173
204
  async publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof, gasLimit) {
174
205
  if (!this.walletClient) {
175
206
  throw new SDKError("Wallet client required for write operations", "NO_WALLET");
@@ -219,7 +250,10 @@ var ContractClient = class _ContractClient {
219
250
  e3Program: requestParams.e3Program,
220
251
  paramSet: requestParams.paramSet,
221
252
  computeProviderParams: requestParams.computeProviderParams,
222
- customParams: requestParams.customParams || "0x"
253
+ customParams: requestParams.customParams || "0x",
254
+ expectedFeeToken: this.contracts.feeToken,
255
+ expectedCryptoConfigId: zeroHash,
256
+ maxFee: requestParams.maxFee ?? 0n
223
257
  }
224
258
  ]
225
259
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/contracts/contract-client.ts","../../src/utils.ts","../../src/contracts/types.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\nimport {\n type Abi,\n type Chain,\n type Hash,\n type PublicClient,\n type TransactionReceipt,\n type WalletClient,\n createPublicClient,\n createWalletClient,\n http,\n webSocket,\n} from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\n\nimport { CiphernodeRegistryOwnable__factory, Interfold__factory, InterfoldToken__factory } from '@interfold/contracts/types'\nimport type { ContractAddresses, E3, E3RequestParams, E3Stage, FailureReason } from './types'\nimport { validateCommitteeSize } from './types'\nimport { SDKError, isValidAddress } from '../utils'\n\nexport interface ContractClientConfig {\n publicClient: PublicClient\n walletClient?: WalletClient\n contracts: ContractAddresses\n}\n\nexport class ContractClient {\n private publicClient: PublicClient\n private walletClient?: WalletClient\n private contracts: ContractAddresses\n private contractInfo: {\n interfold: { address: `0x${string}`; abi: Abi }\n ciphernodeRegistry: { address: `0x${string}`; abi: Abi }\n feeToken: { address: `0x${string}`; abi: Abi }\n }\n\n constructor(config: ContractClientConfig) {\n const { publicClient, walletClient, contracts } = config\n\n if (!isValidAddress(contracts.interfold)) {\n throw new SDKError('Invalid Interfold contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.ciphernodeRegistry)) {\n throw new SDKError('Invalid CiphernodeRegistry contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.feeToken)) {\n throw new SDKError('Invalid FeeToken contract address', 'INVALID_ADDRESS')\n }\n\n this.publicClient = publicClient\n this.walletClient = walletClient\n this.contracts = contracts\n\n this.contractInfo = {\n interfold: {\n address: contracts.interfold,\n abi: Interfold__factory.abi,\n },\n ciphernodeRegistry: {\n address: contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n },\n feeToken: {\n address: contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n },\n }\n }\n\n public static create(options: {\n rpcUrl: string\n contracts: ContractAddresses\n privateKey?: `0x${string}`\n chain: Chain\n }): ContractClient {\n const isWebSocket = options.rpcUrl.startsWith('ws://') || options.rpcUrl.startsWith('wss://')\n const transport = isWebSocket\n ? webSocket(options.rpcUrl, {\n keepAlive: { interval: 30_000 },\n reconnect: { attempts: 5, delay: 2_000 },\n })\n : http(options.rpcUrl)\n\n const publicClient = createPublicClient({\n chain: options.chain,\n transport,\n }) as PublicClient\n\n let walletClient: WalletClient | undefined\n if (options.privateKey) {\n const account = privateKeyToAccount(options.privateKey)\n walletClient = createWalletClient({\n account,\n chain: options.chain,\n transport,\n })\n }\n\n return new ContractClient({ publicClient, walletClient, contracts: options.contracts })\n }\n\n public getPublicClient(): PublicClient {\n return this.publicClient\n }\n\n public async approveFeeToken(amount: bigint): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n functionName: 'approve',\n args: [this.contracts.interfold, amount],\n account,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to approve fee token: ${error}`, 'APPROVE_FEE_TOKEN_FAILED')\n }\n }\n\n public async requestE3(params: E3RequestParams): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const committeeSize = validateCommitteeSize(params.committeeSize)\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'request',\n args: [\n {\n committeeSize,\n inputWindow: params.inputWindow,\n e3Program: params.e3Program,\n paramSet: params.paramSet,\n computeProviderParams: params.computeProviderParams,\n customParams: params.customParams || '0x',\n },\n ],\n account,\n gas: params.gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to request E3: ${error}`, 'REQUEST_E3_FAILED')\n }\n }\n\n public async publishCiphertextOutput(\n e3Id: bigint,\n ciphertextOutput: `0x${string}`,\n ciphertextCommitment: `0x${string}`,\n proof: `0x${string}`,\n gasLimit?: bigint,\n ): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'publishCiphertextOutput',\n args: [e3Id, ciphertextOutput, ciphertextCommitment, proof],\n account,\n gas: gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to publish ciphertext output: ${error}`, 'PUBLISH_CIPHERTEXT_OUTPUT_FAILED')\n }\n }\n\n public async getE3(e3Id: bigint): Promise<E3> {\n try {\n const result: E3 = await this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3: ${error}`, 'GET_E3_FAILED')\n }\n }\n\n public async getE3Quote(requestParams: E3RequestParams): Promise<bigint> {\n try {\n const committeeSize = validateCommitteeSize(requestParams.committeeSize)\n\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Quote',\n args: [\n {\n committeeSize,\n inputWindow: requestParams.inputWindow,\n e3Program: requestParams.e3Program,\n paramSet: requestParams.paramSet,\n computeProviderParams: requestParams.computeProviderParams,\n customParams: requestParams.customParams || '0x',\n },\n ],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 quote: ${error}`, 'GET_E3_QUOTE_FAILED')\n }\n }\n\n public async getFailureReason(e3Id: bigint): Promise<FailureReason> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getFailureReason',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get failure reason: ${error}`, 'GET_FAILURE_REASON_FAILED')\n }\n }\n\n public async getE3PublicKey(e3Id: bigint): Promise<`0x${string}`> {\n try {\n const result: `0x${string}` = await this.publicClient.readContract({\n address: this.contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n functionName: 'committeePublicKey',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3 public key: ${error}`, 'GET_E3_PUBLIC_KEY_FAILED')\n }\n }\n\n public async getE3Stage(e3Id: bigint): Promise<E3Stage> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Stage',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 stage: ${error}`, 'GET_E3_STAGE_FAILED')\n }\n }\n\n public async estimateGas(\n functionName: string,\n args: readonly unknown[],\n contractAddress: `0x${string}`,\n abi: Abi,\n value?: bigint,\n ): Promise<bigint> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for gas estimation', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const estimateParams = {\n address: contractAddress,\n abi,\n functionName,\n args,\n account,\n ...(value !== undefined && { value }),\n }\n\n return await this.publicClient.estimateContractGas(estimateParams)\n } catch (error) {\n throw new SDKError(`Failed to estimate gas: ${error}`, 'GAS_ESTIMATION_FAILED')\n }\n }\n\n public async waitForTransaction(hash: Hash): Promise<TransactionReceipt> {\n try {\n return await this.publicClient.waitForTransactionReceipt({\n hash,\n confirmations: 1,\n })\n } catch (error) {\n throw new SDKError(`Failed to wait for transaction: ${error}`, 'TRANSACTION_WAIT_FAILED')\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 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","// 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 { SDKError } from '../utils'\n\nexport interface ContractAddresses {\n interfold: `0x${string}`\n ciphernodeRegistry: `0x${string}`\n feeToken: `0x${string}`\n}\n\n/** On-chain `IInterfold.CommitteeSize`: Minimum (N=3), Micro (N=9), Small (N=19). */\nexport enum CommitteeSize {\n Minimum = 0,\n Micro = 1,\n Small = 2,\n}\n\n/** Fail fast on out-of-range committee sizes before they hit the contract. */\nexport function validateCommitteeSize(value: number | CommitteeSize): CommitteeSize {\n if (!Number.isInteger(value) || value < CommitteeSize.Minimum || value > CommitteeSize.Small) {\n throw new SDKError(\n `Invalid committeeSize ${value}. Use CommitteeSize.Minimum (0), CommitteeSize.Micro (1), or CommitteeSize.Small (2).`,\n 'INVALID_COMMITTEE_SIZE',\n )\n }\n return value\n}\n\nexport enum ParamSet {\n Insecure512 = 0,\n Secure8192 = 1,\n}\n\nexport interface 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\nexport interface RequestParams {\n gasLimit?: bigint\n}\n\nexport interface E3RequestParams extends RequestParams {\n committeeSize: number\n inputWindow: readonly [bigint, bigint]\n e3Program: `0x${string}`\n paramSet: number\n computeProviderParams: `0x${string}`\n customParams?: `0x${string}`\n}\n\nexport enum E3Stage {\n None,\n Requested,\n CommitteeFinalized,\n KeyPublished,\n CiphertextReady,\n Complete,\n Failed,\n}\n\nexport enum FailureReason {\n None,\n CommitteeFormationTimeout,\n InsufficientCommitteeMembers,\n DKGTimeout,\n DKGInvalidShares,\n NoInputsReceived,\n ComputeTimeout,\n ComputeProviderExpired,\n ComputeProviderFailed,\n RequesterCancelled,\n DecryptionTimeout,\n DecryptionInvalidShares,\n VerificationFailed,\n}\n"],"mappings":"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","names":["E3Stage","FailureReason"]}
1
+ {"version":3,"sources":["../../src/contracts/contract-client.ts","../../src/utils.ts","../../src/contracts/types.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\nimport {\n type Abi,\n type Chain,\n type Hash,\n type PublicClient,\n type TransactionReceipt,\n type WalletClient,\n createPublicClient,\n createWalletClient,\n http,\n zeroHash,\n webSocket,\n} from 'viem'\nimport { privateKeyToAccount } from 'viem/accounts'\n\nimport { CiphernodeRegistryOwnable__factory, Interfold__factory, InterfoldToken__factory } from '@interfold/contracts/types'\nimport type { ContractAddresses, E3, E3RequestParams, E3Stage, FailureReason } from './types'\nimport { validateCommitteeSize } from './types'\nimport { SDKError, isValidAddress } from '../utils'\n\nexport interface ContractClientConfig {\n publicClient: PublicClient\n walletClient?: WalletClient\n contracts: ContractAddresses\n}\n\nexport class ContractClient {\n private publicClient: PublicClient\n private walletClient?: WalletClient\n private contracts: ContractAddresses\n private contractInfo: {\n interfold: { address: `0x${string}`; abi: Abi }\n ciphernodeRegistry: { address: `0x${string}`; abi: Abi }\n feeToken: { address: `0x${string}`; abi: Abi }\n }\n\n constructor(config: ContractClientConfig) {\n const { publicClient, walletClient, contracts } = config\n\n if (!isValidAddress(contracts.interfold)) {\n throw new SDKError('Invalid Interfold contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.ciphernodeRegistry)) {\n throw new SDKError('Invalid CiphernodeRegistry contract address', 'INVALID_ADDRESS')\n }\n if (!isValidAddress(contracts.feeToken)) {\n throw new SDKError('Invalid FeeToken contract address', 'INVALID_ADDRESS')\n }\n\n this.publicClient = publicClient\n this.walletClient = walletClient\n this.contracts = contracts\n\n this.contractInfo = {\n interfold: {\n address: contracts.interfold,\n abi: Interfold__factory.abi,\n },\n ciphernodeRegistry: {\n address: contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n },\n feeToken: {\n address: contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n },\n }\n }\n\n public static create(options: {\n rpcUrl: string\n contracts: ContractAddresses\n privateKey?: `0x${string}`\n chain: Chain\n }): ContractClient {\n const isWebSocket = options.rpcUrl.startsWith('ws://') || options.rpcUrl.startsWith('wss://')\n const transport = isWebSocket\n ? webSocket(options.rpcUrl, {\n keepAlive: { interval: 30_000 },\n reconnect: { attempts: 5, delay: 2_000 },\n })\n : http(options.rpcUrl)\n\n const publicClient = createPublicClient({\n chain: options.chain,\n transport,\n }) as PublicClient\n\n let walletClient: WalletClient | undefined\n if (options.privateKey) {\n const account = privateKeyToAccount(options.privateKey)\n walletClient = createWalletClient({\n account,\n chain: options.chain,\n transport,\n })\n }\n\n return new ContractClient({ publicClient, walletClient, contracts: options.contracts })\n }\n\n public getPublicClient(): PublicClient {\n return this.publicClient\n }\n\n public async approveFeeToken(amount: bigint): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.feeToken,\n abi: InterfoldToken__factory.abi,\n functionName: 'approve',\n args: [this.contracts.interfold, amount],\n account,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to approve fee token: ${error}`, 'APPROVE_FEE_TOKEN_FAILED')\n }\n }\n\n public async requestE3(params: E3RequestParams): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const committeeSize = validateCommitteeSize(params.committeeSize)\n const maxFee = params.maxFee ?? (await this.getE3Quote(params))\n const expectedCryptoConfigId = await this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'activeCryptoConfigId',\n })\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'request',\n args: [\n {\n committeeSize,\n inputWindow: params.inputWindow,\n e3Program: params.e3Program,\n paramSet: params.paramSet,\n computeProviderParams: params.computeProviderParams,\n customParams: params.customParams || '0x',\n expectedFeeToken: this.contracts.feeToken,\n expectedCryptoConfigId,\n maxFee,\n },\n ],\n account,\n gas: params.gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to request E3: ${error}`, 'REQUEST_E3_FAILED')\n }\n }\n\n public async cancelE3(e3Id: bigint): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n try {\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'cancelE3',\n args: [e3Id],\n account,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to cancel E3: ${error}`, 'CANCEL_E3_FAILED')\n }\n }\n\n public async publishCiphertextOutput(\n e3Id: bigint,\n ciphertextOutput: `0x${string}`,\n ciphertextCommitment: `0x${string}`,\n proof: `0x${string}`,\n gasLimit?: bigint,\n ): Promise<Hash> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for write operations', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const { request } = await this.publicClient.simulateContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'publishCiphertextOutput',\n args: [e3Id, ciphertextOutput, ciphertextCommitment, proof],\n account,\n gas: gasLimit,\n })\n\n return await this.walletClient.writeContract(request)\n } catch (error) {\n throw new SDKError(`Failed to publish ciphertext output: ${error}`, 'PUBLISH_CIPHERTEXT_OUTPUT_FAILED')\n }\n }\n\n public async getE3(e3Id: bigint): Promise<E3> {\n try {\n const result: E3 = await this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3: ${error}`, 'GET_E3_FAILED')\n }\n }\n\n public async getE3Quote(requestParams: E3RequestParams): Promise<bigint> {\n try {\n const committeeSize = validateCommitteeSize(requestParams.committeeSize)\n\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Quote',\n args: [\n {\n committeeSize,\n inputWindow: requestParams.inputWindow,\n e3Program: requestParams.e3Program,\n paramSet: requestParams.paramSet,\n computeProviderParams: requestParams.computeProviderParams,\n customParams: requestParams.customParams || '0x',\n expectedFeeToken: this.contracts.feeToken,\n expectedCryptoConfigId: zeroHash,\n maxFee: requestParams.maxFee ?? 0n,\n },\n ],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 quote: ${error}`, 'GET_E3_QUOTE_FAILED')\n }\n }\n\n public async getFailureReason(e3Id: bigint): Promise<FailureReason> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getFailureReason',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get failure reason: ${error}`, 'GET_FAILURE_REASON_FAILED')\n }\n }\n\n public async getE3PublicKey(e3Id: bigint): Promise<`0x${string}`> {\n try {\n const result: `0x${string}` = await this.publicClient.readContract({\n address: this.contracts.ciphernodeRegistry,\n abi: CiphernodeRegistryOwnable__factory.abi,\n functionName: 'committeePublicKey',\n args: [e3Id],\n })\n\n return result\n } catch (error) {\n throw new SDKError(`Failed to get E3 public key: ${error}`, 'GET_E3_PUBLIC_KEY_FAILED')\n }\n }\n\n public async getE3Stage(e3Id: bigint): Promise<E3Stage> {\n try {\n return this.publicClient.readContract({\n address: this.contracts.interfold,\n abi: Interfold__factory.abi,\n functionName: 'getE3Stage',\n args: [e3Id],\n })\n } catch (error) {\n throw new SDKError(`Failed to get E3 stage: ${error}`, 'GET_E3_STAGE_FAILED')\n }\n }\n\n public async estimateGas(\n functionName: string,\n args: readonly unknown[],\n contractAddress: `0x${string}`,\n abi: Abi,\n value?: bigint,\n ): Promise<bigint> {\n if (!this.walletClient) {\n throw new SDKError('Wallet client required for gas estimation', 'NO_WALLET')\n }\n\n try {\n const account = this.walletClient.account\n if (!account) {\n throw new SDKError('No account connected', 'NO_ACCOUNT')\n }\n\n const estimateParams = {\n address: contractAddress,\n abi,\n functionName,\n args,\n account,\n ...(value !== undefined && { value }),\n }\n\n return await this.publicClient.estimateContractGas(estimateParams)\n } catch (error) {\n throw new SDKError(`Failed to estimate gas: ${error}`, 'GAS_ESTIMATION_FAILED')\n }\n }\n\n public async waitForTransaction(hash: Hash): Promise<TransactionReceipt> {\n try {\n return await this.publicClient.waitForTransactionReceipt({\n hash,\n confirmations: 1,\n })\n } catch (error) {\n throw new SDKError(`Failed to wait for transaction: ${error}`, 'TRANSACTION_WAIT_FAILED')\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 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","// 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 { SDKError } from '../utils'\n\nexport interface ContractAddresses {\n interfold: `0x${string}`\n ciphernodeRegistry: `0x${string}`\n feeToken: `0x${string}`\n}\n\n/** On-chain `IInterfold.CommitteeSize`: Minimum (N=3), Micro (N=9), Small (N=19). */\nexport enum CommitteeSize {\n Minimum = 0,\n Micro = 1,\n Small = 2,\n}\n\n/** Fail fast on out-of-range committee sizes before they hit the contract. */\nexport function validateCommitteeSize(value: number | CommitteeSize): CommitteeSize {\n if (!Number.isInteger(value) || value < CommitteeSize.Minimum || value > CommitteeSize.Small) {\n throw new SDKError(\n `Invalid committeeSize ${value}. Use CommitteeSize.Minimum (0), CommitteeSize.Micro (1), or CommitteeSize.Small (2).`,\n 'INVALID_COMMITTEE_SIZE',\n )\n }\n return value\n}\n\nexport enum ParamSet {\n Insecure512 = 0,\n Secure8192 = 1,\n}\n\nexport interface 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\nexport interface RequestParams {\n gasLimit?: bigint\n}\n\nexport interface E3RequestParams extends RequestParams {\n committeeSize: number\n inputWindow: readonly [bigint, bigint]\n e3Program: `0x${string}`\n paramSet: number\n computeProviderParams: `0x${string}`\n customParams?: `0x${string}`\n /** Maximum fee token amount accepted. Defaults to a fresh quote. */\n maxFee?: bigint\n}\n\nexport enum E3Stage {\n None,\n Requested,\n CommitteeFinalized,\n KeyPublished,\n CiphertextReady,\n Complete,\n Failed,\n}\n\nexport enum FailureReason {\n None,\n CommitteeFormationTimeout,\n InsufficientCommitteeMembers,\n DKGTimeout,\n DKGInvalidShares,\n NoInputsReceived,\n ComputeTimeout,\n ComputeProviderExpired,\n ComputeProviderFailed,\n RequesterCancelled,\n DecryptionTimeout,\n DecryptionInvalidShares,\n VerificationFailed,\n}\n"],"mappings":"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","names":["E3Stage","FailureReason"]}
@@ -36,7 +36,6 @@ var InterfoldEventType = /* @__PURE__ */ ((InterfoldEventType2) => {
36
36
  InterfoldEventType2["PLAINTEXT_OUTPUT_PUBLISHED"] = "PlaintextOutputPublished";
37
37
  InterfoldEventType2["E3_PROGRAM_REGISTERED"] = "E3ProgramRegistered";
38
38
  InterfoldEventType2["ENCRYPTION_SCHEME_ENABLED"] = "EncryptionSchemeEnabled";
39
- InterfoldEventType2["ENCRYPTION_SCHEME_DISABLED"] = "EncryptionSchemeDisabled";
40
39
  InterfoldEventType2["CIPHERNODE_REGISTRY_SET"] = "CiphernodeRegistrySet";
41
40
  InterfoldEventType2["MAX_DURATION_SET"] = "MaxDurationSet";
42
41
  InterfoldEventType2["PARAM_SET_REGISTERED"] = "ParamSetRegistered";
@@ -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 ENCRYPTION_SCHEME_DISABLED = 'EncryptionSchemeDisabled',\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 filter: string\n e3Program: 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 seed: 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.ENCRYPTION_SCHEME_DISABLED]: { 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,gCAA6B;AAC7B,EAAAA,oBAAA,6BAA0B;AAC1B,EAAAA,oBAAA,sBAAmB;AACnB,EAAAA,oBAAA,0BAAuB;AACvB,EAAAA,oBAAA,2BAAwB;AACxB,EAAAA,oBAAA,iBAAc;AAXJ,SAAAA;AAAA,GAAA;AAcL,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;;;AChBZ,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, 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":"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","names":["InterfoldEventType","RegistryEventType"]}
@@ -1,5 +1,5 @@
1
1
  import { Log, PublicClient, Abi } from 'viem';
2
- import { C as ContractAddresses } from '../types-s67c2A1z.js';
2
+ import { C as ContractAddresses } from '../types-Cwx_flfX.js';
3
3
 
4
4
  declare enum InterfoldEventType {
5
5
  E3_REQUESTED = "E3Requested",
@@ -7,7 +7,6 @@ declare enum InterfoldEventType {
7
7
  PLAINTEXT_OUTPUT_PUBLISHED = "PlaintextOutputPublished",
8
8
  E3_PROGRAM_REGISTERED = "E3ProgramRegistered",
9
9
  ENCRYPTION_SCHEME_ENABLED = "EncryptionSchemeEnabled",
10
- ENCRYPTION_SCHEME_DISABLED = "EncryptionSchemeDisabled",
11
10
  CIPHERNODE_REGISTRY_SET = "CiphernodeRegistrySet",
12
11
  MAX_DURATION_SET = "MaxDurationSet",
13
12
  PARAM_SET_REGISTERED = "ParamSetRegistered",
@@ -39,8 +38,7 @@ interface E3RequestedData {
39
38
  ciphertextCommitment: string;
40
39
  plaintextOutput: string;
41
40
  };
42
- filter: string;
43
- e3Program: string;
41
+ cryptoConfigId: string;
44
42
  }
45
43
  interface E3ActivatedData {
46
44
  e3Id: bigint;
@@ -71,7 +69,7 @@ interface CiphernodeRemovedData {
71
69
  }
72
70
  interface CommitteeRequestedData {
73
71
  e3Id: bigint;
74
- seed: bigint;
72
+ entropyBlock: bigint;
75
73
  threshold: [bigint, bigint];
76
74
  requestBlock: bigint;
77
75
  committeeDeadline: bigint;
@@ -99,9 +97,6 @@ interface InterfoldEventData {
99
97
  [InterfoldEventType.ENCRYPTION_SCHEME_ENABLED]: {
100
98
  encryptionSchemeId: string;
101
99
  };
102
- [InterfoldEventType.ENCRYPTION_SCHEME_DISABLED]: {
103
- encryptionSchemeId: string;
104
- };
105
100
  [InterfoldEventType.CIPHERNODE_REGISTRY_SET]: {
106
101
  ciphernodeRegistry: string;
107
102
  };