- Enclave is a protocol for Encrypted Execution Environments (E3) that enables secure computations on private data using fully
- homomorphic encryption (FHE), zero-knowledge proofs, and distributed key cryptography. Connect your wallet to experience
- privacy-preserving computation.
-
-
-
- How it works: You'll request an E3 computation → Ciphernode committee is selected → Committee publishes shared
- public key → You encrypt and submit inputs → Secure computation executes → Only verified outputs are decrypted by the committee.
-
- Request an E3 computation from Enclave's decentralized network. This initiates the selection of a Ciphernode Committee through
- cryptographic sortition, who will generate shared keys for securing your computation without any single point of trust.
-
-
-
- Process: Request E3 → Committee Selection via Sortition → Key Generation → Ready for Activation
-
- 🔑 Committee Published Public Key!
-
- Public Key: {e3State.publicKey.slice(0, 20)}...{e3State.publicKey.slice(-10)}
-
- Ready to activate E3 environment.
-
-
- ) : (
-
-
-
-
- ⏳ Waiting for committee to publish public key...
-
- The computation committee is being selected and will provide the public key shortly.
-
- Activate the E3 using the Ciphernode Committee's shared public key. This distributed key ensures no single node can decrypt your
- inputs or intermediate states - only the verified final output can be collectively decrypted by the committee.
-
- Your inputs are being encrypted to the committee's public key and submitted to the E3. The Compute Provider will execute the
- FHE computation over your encrypted data...
-
-
-
- Process: Encrypt to Key → Submit to E3 → FHE Computation → Ciphertext Output
-
-
-
- )}
-
- {inputPublishError && (
-
-
-
-
- )}
-
- {inputPublishSuccess && (
-
-
-
-
-
-
- ✅ Inputs Successfully Submitted!
-
- Your encrypted inputs have been published to the E3. The Compute Provider is executing the FHE computation and will publish
- the ciphertext output for committee decryption.
-
-
-
-
-
-
-
- Computing... Waiting for the Ciphernode Committee to collectively decrypt the verified output.
-
- Raw Output: {e3State.plaintextOutput.slice(0, 20)}...
-
-
- )}
-
-
-
-
- 🔒 Cryptographic Guarantees: Your inputs remained encrypted throughout the entire process. The Ciphernode
- Committee used distributed key cryptography to decrypt only the verified output, ensuring data privacy, data integrity, and
- correct execution.
-
+ )
+})
+
+export default StepIndicator
diff --git a/templates/default/client/src/pages/steps/ActivateE3.tsx b/templates/default/client/src/pages/steps/ActivateE3.tsx
new file mode 100644
index 0000000000..f71da5d0ec
--- /dev/null
+++ b/templates/default/client/src/pages/steps/ActivateE3.tsx
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+//
+// This file is provided WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+
+import React, { useState, useEffect } from 'react'
+import { LockIcon } from '@phosphor-icons/react'
+import CardContent from '../components/CardContent'
+import Spinner from '../components/Spinner'
+import ErrorDisplay from '../components/ErrorDisplay'
+import { useWizard, WizardStep } from '../../context/WizardContext'
+
+/**
+ * ActivateE3 component - Third step in the Enclave wizard flow
+ *
+ * This component handles the activation of the E3 using the Ciphernode Committee's
+ * shared public key. It provides feedback on the activation process and displays
+ * the status of the activation.
+ */
+const ActivateE3: React.FC = () => {
+ const { e3State, setE3State, setLastTransactionHash, setCurrentStep, sdk } = useWizard()
+ const { isInitialized, activateE3, onEnclaveEvent, off, EnclaveEventType } = sdk
+
+ const [isRequesting, setIsRequesting] = useState(false)
+ const [requestError, setRequestError] = useState(null)
+ const [requestSuccess, setRequestSuccess] = useState(false)
+ const [lastTransactionHash, setLocalTransactionHash] = useState()
+ const [showErrorDetails, setShowErrorDetails] = useState(false)
+
+ // Set up event listeners for this step
+ useEffect(() => {
+ if (!isInitialized) return
+
+ const handleE3Activated = (event: any) => {
+ const { e3Id, expiration } = event.data
+ setE3State((prev) => {
+ if (prev.id !== null && e3Id === prev.id) {
+ return {
+ ...prev,
+ isActivated: true,
+ expiresAt: expiration || null,
+ }
+ }
+ return prev
+ })
+ }
+
+ onEnclaveEvent(EnclaveEventType.E3_ACTIVATED, handleE3Activated)
+
+ return () => {
+ off(EnclaveEventType.E3_ACTIVATED, handleE3Activated)
+ }
+ }, [isInitialized, onEnclaveEvent, off, EnclaveEventType, setE3State])
+
+ // Auto-advance to next step when E3 is activated
+ useEffect(() => {
+ if (e3State.isActivated) {
+ setCurrentStep(WizardStep.ENTER_INPUTS)
+ }
+ }, [e3State.isActivated, setCurrentStep])
+
+ const handleActivateE3 = async () => {
+ console.log('handleActivateE3')
+
+ if (e3State.id === null || e3State.publicKey === null) {
+ console.log('refusing to run handler because id or publicKey is null')
+ return
+ }
+ setIsRequesting(true)
+ setRequestError(null)
+
+ try {
+ const hash = await activateE3(e3State.id, e3State.publicKey)
+ setLocalTransactionHash(hash)
+ setLastTransactionHash(hash)
+ setRequestSuccess(true)
+ } catch (error) {
+ setRequestError(error)
+ console.error('Error activating E3:', error)
+ } finally {
+ setIsRequesting(false)
+ }
+ }
+
+ return (
+
+
+
+
+
+
Step 3: Activate E3
+
+
Activate Encrypted Execution Environment
+
+ Activate the E3 using the Ciphernode Committee's shared public key. This distributed key ensures no single node can decrypt your
+ inputs or intermediate states - only the verified final output can be collectively decrypted by the committee.
+
+
+ )
+}
+
+export default ActivateE3
diff --git a/templates/default/client/src/pages/steps/ConnectWallet.tsx b/templates/default/client/src/pages/steps/ConnectWallet.tsx
new file mode 100644
index 0000000000..4dc6b796e8
--- /dev/null
+++ b/templates/default/client/src/pages/steps/ConnectWallet.tsx
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+//
+// This file is provided WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+
+import React from 'react'
+import { ConnectKitButton } from 'connectkit'
+import { WalletIcon } from '@phosphor-icons/react'
+import CardContent from '../components/CardContent'
+
+/**
+ * ConnectWallet component - First step in the Enclave wizard flow
+ *
+ * This component introduces users to the Enclave protocol and provides the initial
+ * wallet connection interface. It explains the E3 (Encrypted Execution Environment)
+ * concept and guides users through the secure computation workflow using FHE,
+ * zero-knowledge proofs, and distributed key cryptography.
+ */
+const ConnectWallet: React.FC = () => {
+ return (
+
+
+
+
+
+
Step 1: Connect Your Wallet
+
+
Welcome to Enclave
+
+ Enclave is a protocol for Encrypted Execution Environments (E3) that enables secure computations on private data using fully
+ homomorphic encryption (FHE), zero-knowledge proofs, and distributed key cryptography. Connect your wallet to experience
+ privacy-preserving computation.
+
+
+
+ How it works: You'll request an E3 computation → Ciphernode committee is selected → Committee publishes
+ shared public key → You encrypt and submit inputs → Secure computation executes → Only verified outputs are decrypted by the
+ committee.
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ConnectWallet
diff --git a/templates/default/client/src/pages/steps/EncryptSubmit.tsx b/templates/default/client/src/pages/steps/EncryptSubmit.tsx
new file mode 100644
index 0000000000..cce62ef1f6
--- /dev/null
+++ b/templates/default/client/src/pages/steps/EncryptSubmit.tsx
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+//
+// This file is provided WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+
+import React, { useState, useEffect } from 'react'
+import { LockIcon, CheckCircleIcon } from '@phosphor-icons/react'
+import CardContent from '../components/CardContent'
+import Spinner from '../components/Spinner'
+import ErrorDisplay from '../components/ErrorDisplay'
+import { useWizard, WizardStep } from '../../context/WizardContext'
+import { decodePlaintextOutput } from '@enclave-e3/sdk'
+
+/**
+ * EncryptSubmit component - Fifth step in the Enclave wizard flow
+ *
+ * This component handles the encryption and submission of user inputs to the E3.
+ * It provides feedback on the encryption process and displays the status of the
+ * submission to the E3.
+ */
+const EncryptSubmit: React.FC = () => {
+ const { e3State, setE3State, setResult, setCurrentStep, inputPublishError, inputPublishSuccess, handleTryAgain, sdk } = useWizard()
+ const { isInitialized, onEnclaveEvent, off, EnclaveEventType } = sdk
+
+ const [showErrorDetails, setShowErrorDetails] = useState(false)
+
+ // Set up event listeners for this step
+ useEffect(() => {
+ if (!isInitialized) return
+
+ const handlePlaintextOutput = (event: any) => {
+ const { e3Id, plaintextOutput } = event.data
+ setE3State((prev) => {
+ if (prev.id !== null && e3Id === prev.id) {
+ const decodedResult = decodePlaintextOutput(plaintextOutput)
+ setResult(decodedResult)
+ return {
+ ...prev,
+ plaintextOutput: plaintextOutput as string,
+ hasPlaintextOutput: true,
+ }
+ }
+ return prev
+ })
+ }
+
+ onEnclaveEvent(EnclaveEventType.PLAINTEXT_OUTPUT_PUBLISHED, handlePlaintextOutput)
+
+ return () => {
+ off(EnclaveEventType.PLAINTEXT_OUTPUT_PUBLISHED, handlePlaintextOutput)
+ }
+ }, [isInitialized, onEnclaveEvent, off, EnclaveEventType, setE3State, setResult])
+
+ // Auto-advance to results when output is available
+ useEffect(() => {
+ if (e3State.hasPlaintextOutput) {
+ setCurrentStep(WizardStep.RESULTS)
+ }
+ }, [e3State.hasPlaintextOutput, setCurrentStep])
+
+ return (
+
+
+ Your inputs are being encrypted to the committee's public key and submitted to the E3. The Compute Provider will execute the
+ FHE computation over your encrypted data...
+
+
+
+ Process: Encrypt to Key → Submit to E3 → FHE Computation → Ciphertext Output
+
+ ✅ Inputs Successfully Submitted!
+
+ Your encrypted inputs have been published to the E3. The Compute Provider is executing the FHE computation and will
+ publish the ciphertext output for committee decryption.
+
+
+
+
+
+
+
+ Computing... Waiting for the Ciphernode Committee to collectively decrypt the verified output.
+
+
+
+ )}
+
+
+
+ )
+}
+
+export default EncryptSubmit
diff --git a/templates/default/client/src/pages/steps/EnterInputs.tsx b/templates/default/client/src/pages/steps/EnterInputs.tsx
new file mode 100644
index 0000000000..f65b575007
--- /dev/null
+++ b/templates/default/client/src/pages/steps/EnterInputs.tsx
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+//
+// This file is provided WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+
+import React, { useState } from 'react'
+import { NumberSquareOneIcon } from '@phosphor-icons/react'
+import { hexToBytes } from 'viem'
+import CardContent from '../components/CardContent'
+import { useWizard, WizardStep } from '../../context/WizardContext'
+
+/**
+ * EnterInputs component - Fourth step in the Enclave wizard flow
+ *
+ * This component handles the input of two numbers for a privacy-preserving addition
+ * using fully homomorphic encryption (FHE). It provides feedback on the input process
+ * and displays the status of the input submission.
+ */
+const EnterInputs: React.FC = () => {
+ const [input1, setInput1] = useState('')
+ const [input2, setInput2] = useState('')
+ const { e3State, setCurrentStep, setLastTransactionHash, setInputPublishError, setInputPublishSuccess, setSubmittedInputs, sdk } =
+ useWizard()
+ const { publishInput } = sdk
+
+ const handleInputSubmit = async (e: React.FormEvent) => {
+ e.preventDefault()
+ console.log('handleInputSubmit')
+ if (!input1 || !input2 || e3State.publicKey === null || e3State.id === null) {
+ console.log('Refusing to submit input because input is empty or publickey is null or is is null')
+ return
+ }
+
+ setCurrentStep(WizardStep.ENCRYPT_SUBMIT)
+ setInputPublishError(null)
+ setInputPublishSuccess(false)
+
+ try {
+ // Store the inputs in context for the Results component
+ setSubmittedInputs({ input1, input2 })
+
+ // Parse inputs
+ const num1 = BigInt(input1)
+ const num2 = BigInt(input2)
+
+ // Convert hex public key to bytes
+ const publicKeyBytes = hexToBytes(e3State.publicKey)
+
+ // Encrypt both inputs
+ const encryptedInput1 = await sdk.sdk?.encryptNumber(num1, publicKeyBytes)
+ const encryptedInput2 = await sdk.sdk?.encryptNumber(num2, publicKeyBytes)
+
+ if (!encryptedInput1 || !encryptedInput2) {
+ throw new Error('Failed to encrypt inputs')
+ }
+
+ // Publish first input
+ await publishInput(e3State.id, `0x${Array.from(encryptedInput1, (b) => b.toString(16).padStart(2, '0')).join('')}` as `0x${string}`)
+
+ // Publish second input
+ const hash2 = await publishInput(
+ e3State.id,
+ `0x${Array.from(encryptedInput2, (b: any) => b.toString(16).padStart(2, '0')).join('')}` as `0x${string}`,
+ )
+
+ setLastTransactionHash(hash2)
+ setInputPublishSuccess(true)
+ } catch (error) {
+ setInputPublishError(error instanceof Error ? error.message : 'Failed to encrypt and publish inputs')
+ console.error('Error encrypting/publishing inputs:', error)
+ }
+ }
+
+ return (
+
+
+
+ )
+}
+
+export default EnterInputs
diff --git a/templates/default/client/src/pages/steps/RequestComputation.tsx b/templates/default/client/src/pages/steps/RequestComputation.tsx
new file mode 100644
index 0000000000..0916fe0bd1
--- /dev/null
+++ b/templates/default/client/src/pages/steps/RequestComputation.tsx
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+//
+// This file is provided WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+
+import React, { useState, useEffect } from 'react'
+import { CalculatorIcon } from '@phosphor-icons/react'
+import CardContent from '../components/CardContent'
+import Spinner from '../components/Spinner'
+import ErrorDisplay from '../components/ErrorDisplay'
+import { useWizard, WizardStep } from '../../context/WizardContext'
+import {
+ encodeBfvParams,
+ encodeComputeProviderParams,
+ calculateStartWindow,
+ DEFAULT_COMPUTE_PROVIDER_PARAMS,
+ DEFAULT_E3_CONFIG,
+} from '@enclave-e3/sdk'
+import { getContractAddresses } from '@/utils/env-config'
+
+/**
+ * RequestComputation component - Second step in the Enclave wizard flow
+ *
+ * This component handles the request for an E3 computation from the Enclave network.
+ * It provides feedback on the request process and displays the status of the request.
+ */
+const RequestComputation: React.FC = () => {
+ const { e3State, setE3State, setLastTransactionHash, setCurrentStep, sdk } = useWizard()
+ const { isInitialized, requestE3, onEnclaveEvent, off, EnclaveEventType, RegistryEventType } = sdk
+
+ const contracts = getContractAddresses()
+
+ const [isRequesting, setIsRequesting] = useState(false)
+ const [requestError, setRequestError] = useState(null)
+ const [requestSuccess, setRequestSuccess] = useState(false)
+ const [lastTransactionHash, setLocalTransactionHash] = useState()
+ const [showErrorDetails, setShowErrorDetails] = useState(false)
+
+ // Set up event listeners for this step
+ useEffect(() => {
+ if (!isInitialized) return
+
+ const handleE3Requested = (event: any) => {
+ const e3Id = event.data.e3Id
+ setE3State((prev) => ({
+ ...prev,
+ id: e3Id,
+ isRequested: true,
+ }))
+ }
+
+ const handleCommitteePublished = (event: any) => {
+ const { e3Id, publicKey } = event.data
+
+ // Add a 2 second delay to show the waiting state
+ setTimeout(() => {
+ setE3State((prev) => {
+ if (prev.id !== null && e3Id === prev.id) {
+ return {
+ ...prev,
+ isCommitteePublished: true,
+ publicKey: publicKey as `0x${string}`,
+ }
+ }
+ return prev
+ })
+ }, 2000)
+ }
+
+ onEnclaveEvent(EnclaveEventType.E3_REQUESTED, handleE3Requested)
+ onEnclaveEvent(RegistryEventType.COMMITTEE_PUBLISHED, handleCommitteePublished)
+
+ return () => {
+ off(EnclaveEventType.E3_REQUESTED, handleE3Requested)
+ off(RegistryEventType.COMMITTEE_PUBLISHED, handleCommitteePublished)
+ }
+ }, [isInitialized, onEnclaveEvent, off, EnclaveEventType, RegistryEventType])
+
+ // Auto-advance to next step when committee publishes
+ useEffect(() => {
+ if (e3State.isCommitteePublished && e3State.publicKey) {
+ setCurrentStep(WizardStep.ACTIVATE_E3)
+ }
+ }, [e3State.isCommitteePublished, e3State.publicKey, setCurrentStep])
+
+ const handleRequestComputation = async () => {
+ console.log('handleRequestComputation')
+ setIsRequesting(true)
+ setRequestError(null)
+ setRequestSuccess(false)
+
+ // Reset E3 state
+ setE3State({
+ id: null,
+ isRequested: false,
+ isCommitteePublished: false,
+ isActivated: false,
+ publicKey: null,
+ expiresAt: null,
+ plaintextOutput: null,
+ hasPlaintextOutput: false,
+ })
+
+ try {
+ const threshold: [number, number] = [DEFAULT_E3_CONFIG.threshold_min, DEFAULT_E3_CONFIG.threshold_max]
+ const startWindow = calculateStartWindow(60) // 1 minute
+ const duration = BigInt(60) // 1 minute
+ const e3ProgramParams = encodeBfvParams()
+ const computeProviderParams = encodeComputeProviderParams(DEFAULT_COMPUTE_PROVIDER_PARAMS)
+
+ console.log('requestE3')
+ const hash = await requestE3({
+ filter: contracts.filterRegistry,
+ threshold,
+ startWindow,
+ duration,
+ e3Program: contracts.e3Program,
+ e3ProgramParams,
+ computeProviderParams,
+ value: BigInt('1000000000000000'), // 0.001 ETH
+ })
+
+ setLocalTransactionHash(hash)
+ setLastTransactionHash(hash)
+ setRequestSuccess(true)
+ } catch (error) {
+ setRequestError(error)
+ console.error('Error requesting computation:', error)
+ } finally {
+ setIsRequesting(false)
+ }
+ }
+
+ return (
+
+
+
+
+
+
Step 2: Request Computation
+
+
Request Encrypted Execution Environment
+
+ Request an E3 computation from Enclave's decentralized network. This initiates the selection of a Ciphernode Committee through
+ cryptographic sortition, who will generate shared keys for securing your computation without any single point of trust.
+
+
+
+ Process: Request E3 → Committee Selection via Sortition → Key Generation → Ready for Activation
+
+ 🔑 Committee Published Public Key!
+
+ Public Key: {e3State.publicKey.slice(0, 20)}...{e3State.publicKey.slice(-10)}
+
+ Ready to activate E3 environment.
+
+
+ ) : (
+
+
+
+
+ ⏳ Waiting for committee to publish public key...
+
+ The computation committee is being selected and will provide the public key shortly.
+
+ Raw Output: {e3State.plaintextOutput.slice(0, 20)}...
+
+
+ )}
+
+
+
+
+ 🔒 Cryptographic Guarantees: Your inputs remained encrypted throughout the entire process. The Ciphernode
+ Committee used distributed key cryptography to decrypt only the verified output, ensuring data privacy, data integrity, and
+ correct execution.
+
+
+
+
+
+
+
+ )
+}
+
+export default Results
diff --git a/templates/default/client/src/utils/env-config.ts b/templates/default/client/src/utils/env-config.ts
index 464edc1064..a2cf0408fc 100644
--- a/templates/default/client/src/utils/env-config.ts
+++ b/templates/default/client/src/utils/env-config.ts
@@ -10,40 +10,25 @@ export const REGISTRY_ADDRESS = import.meta.env.VITE_REGISTRY_ADDRESS
export const FILTER_REGISTRY_ADDRESS = import.meta.env.VITE_FILTER_REGISTRY_ADDRESS
export const RPC_URL = import.meta.env.VITE_RPC_URL || 'http://localhost:8545'
-const requiredEnvVars = {
- VITE_ENCLAVE_ADDRESS: ENCLAVE_ADDRESS,
- VITE_E3_PROGRAM_ADDRESS: E3_PROGRAM_ADDRESS,
- VITE_REGISTRY_ADDRESS: REGISTRY_ADDRESS,
- VITE_FILTER_REGISTRY_ADDRESS: FILTER_REGISTRY_ADDRESS,
-}
-
-export const MISSING_ENV_VARS = Object.entries(requiredEnvVars)
- .filter(([, value]) => !value)
- .map(([key]) => key)
-
-export const HAS_MISSING_ENV_VARS = MISSING_ENV_VARS.length > 0
-
-/**
- * Validate environment variables and throw an error if any are missing
- */
-export function validateEnvVars(): void {
- if (HAS_MISSING_ENV_VARS) {
- throw new Error(
- `Missing required environment variables: ${MISSING_ENV_VARS.join(', ')}\n` +
- 'Please check your .env file and ensure all required variables are set.'
- )
- }
-}
+// Get the missing environment variables.
+// This is used to check if the environment variables are set.
+export const MISSING_ENV_VARS = Object.entries({
+ VITE_ENCLAVE_ADDRESS: ENCLAVE_ADDRESS,
+ VITE_E3_PROGRAM_ADDRESS: E3_PROGRAM_ADDRESS,
+ VITE_REGISTRY_ADDRESS: REGISTRY_ADDRESS,
+ VITE_FILTER_REGISTRY_ADDRESS: FILTER_REGISTRY_ADDRESS,
+})
+ .filter(([, value]) => !value)
+ .map(([key]) => key)
/**
- * Get validated contract addresses
+ * Get validated contract addresses.
*/
export function getContractAddresses() {
- validateEnvVars()
- return {
- enclave: ENCLAVE_ADDRESS as `0x${string}`,
- ciphernodeRegistry: REGISTRY_ADDRESS as `0x${string}`,
- filterRegistry: FILTER_REGISTRY_ADDRESS as `0x${string}`,
- e3Program: E3_PROGRAM_ADDRESS as `0x${string}`,
- }
-}
\ No newline at end of file
+ return {
+ enclave: ENCLAVE_ADDRESS as `0x${string}`,
+ ciphernodeRegistry: REGISTRY_ADDRESS as `0x${string}`,
+ filterRegistry: FILTER_REGISTRY_ADDRESS as `0x${string}`,
+ e3Program: E3_PROGRAM_ADDRESS as `0x${string}`,
+ }
+}
diff --git a/templates/default/client/src/utils/sdk-config.ts b/templates/default/client/src/utils/sdk-config.ts
new file mode 100644
index 0000000000..0318a930b1
--- /dev/null
+++ b/templates/default/client/src/utils/sdk-config.ts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+//
+// This file is provided WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE.
+
+import { FheProtocol } from '@enclave-e3/sdk'
+import { getContractAddresses } from './env-config'
+
+/**
+ * Get the Enclave SDK configuration.
+ */
+export function getEnclaveSDKConfig() {
+ const contracts = getContractAddresses()
+ return {
+ autoConnect: true,
+ contracts: {
+ enclave: contracts.enclave,
+ ciphernodeRegistry: contracts.ciphernodeRegistry,
+ },
+ protocol: FheProtocol.BFV,
+ }
+}