@gnosis-guild/enclave-react
Version:
React hooks and utilities for Enclave SDK
132 lines (131 loc) • 4.28 kB
JavaScript
import { useState, useEffect, useCallback, useRef } from "react";
import { useWalletClient, usePublicClient } from "wagmi";
import { EnclaveSDK, EnclaveEventType, RegistryEventType, SDKError, } from "@gnosis-guild/enclave/sdk";
/**
* React hook for interacting with Enclave SDK
*
* @param config Configuration for the SDK initialization
* @returns Object containing SDK instance and helper methods
*
* @example
* ```tsx
* import { useEnclaveSDK } from '@gnosis-guild/enclave-react';
*
* function MyComponent() {
* const {
* sdk,
* isInitialized,
* error,
* requestE3,
* onEnclaveEvent
* } = useEnclaveSDK({
* autoConnect: true,
* contracts: {
* enclave: '0x...',
* ciphernodeRegistry: '0x...'
* }
* });
*
* // Use the SDK...
* }
* ```
*/
export const useEnclaveSDK = (config) => {
const [sdk, setSdk] = useState(null);
const [isInitialized, setIsInitialized] = useState(false);
const [error, setError] = useState(null);
const sdkRef = useRef(null);
const publicClient = usePublicClient();
const { data: walletClient } = useWalletClient();
const initializeSDK = useCallback(async () => {
try {
setError(null);
if (!publicClient) {
throw new Error("Public client not available");
}
if (sdk) {
sdk.cleanup();
}
const sdkConfig = {
publicClient,
walletClient: walletClient || undefined,
contracts: config.contracts || {
enclave: "0x0000000000000000000000000000000000000000",
ciphernodeRegistry: "0x0000000000000000000000000000000000000000",
},
chainId: config.chainId,
};
const newSdk = new EnclaveSDK(sdkConfig);
await newSdk.initialize();
setSdk(newSdk);
sdkRef.current = newSdk;
setIsInitialized(true);
}
catch (err) {
const errorMessage = err instanceof SDKError
? `SDK Error (${err.code}): ${err.message}`
: `Failed to initialize SDK: ${err}`;
setError(errorMessage);
console.error("SDK initialization failed:", err);
}
}, [publicClient, walletClient, config.contracts, config.chainId]);
// Initialize SDK when wagmi clients are available
useEffect(() => {
if (config.autoConnect && publicClient && !isInitialized) {
initializeSDK();
}
}, [config.autoConnect, publicClient, isInitialized, initializeSDK]);
// Re-initialize when wallet client changes (connect/disconnect)
useEffect(() => {
if (isInitialized && publicClient && walletClient) {
initializeSDK();
}
}, [walletClient, initializeSDK]);
// Cleanup on unmount
useEffect(() => {
return () => {
if (sdkRef.current) {
sdkRef.current.cleanup();
}
};
}, []);
// Contract interaction methods
const requestE3 = useCallback((...args) => {
if (!sdk)
throw new Error("SDK not initialized");
return sdk.requestE3(...args);
}, [sdk]);
const activateE3 = useCallback((...args) => {
if (!sdk)
throw new Error("SDK not initialized");
return sdk.activateE3(...args);
}, [sdk]);
const publishInput = useCallback((...args) => {
if (!sdk)
throw new Error("SDK not initialized");
return sdk.publishInput(...args);
}, [sdk]);
// Event handling methods
const onEnclaveEvent = useCallback((eventType, callback) => {
if (!sdk)
throw new Error("SDK not initialized");
return sdk.onEnclaveEvent(eventType, callback);
}, [sdk]);
const off = useCallback((eventType, callback) => {
if (!sdk)
throw new Error("SDK not initialized");
return sdk.off(eventType, callback);
}, [sdk]);
return {
sdk,
isInitialized,
error,
requestE3,
activateE3,
publishInput,
onEnclaveEvent,
off,
EnclaveEventType,
RegistryEventType,
};
};