UNPKG

@gnosis-guild/enclave-react

Version:

React hooks and utilities for Enclave SDK

132 lines (131 loc) 4.28 kB
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, }; };